diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..9fe17bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ \ No newline at end of file diff --git a/COPYING.txt b/COPYING old mode 100644 new mode 100755 similarity index 99% rename from COPYING.txt rename to COPYING index 94a9ed0..f288702 --- a/COPYING.txt +++ b/COPYING @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. @@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see -. +. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. +. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md old mode 100644 new mode 100755 index f337203..284e8f4 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -1,20 +1,35 @@ # Semi Automatic Classification Plugin (SCP) -![SCP](semiautomaticclassificationplugin.png) The Semi-Automatic Classification Plugin (SCP) is a free open source plugin for QGIS that allows for the supervised classification of remote sensing images, providing tools for the download, the preprocessing and postprocessing of images. - -The overall objective of SCP is to provide a set of intertwined tools for raster processing in order to make an automatic workflow and ease the land cover classification, which could be performed also by people whose main field is not remote sensing. - -Search and download is available for ASTER, GOES, Landsat, MODIS, Sentinel-1, Sentinel-2, and Sentinel-3 images. Several algorithms are available for the land cover classification. This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib. Some tools require also the installation of SNAP (ESA Sentinel Application Platform). +![SCP](semiautomaticclassificationplugin.png) +The Semi-Automatic Classification +Plugin (SCP) is a free open source plugin for QGIS that allows for the +supervised classification of remote sensing images, providing tools for the +download, the preprocessing and postprocessing of images. + +The overall objective of SCP is to provide a set of intertwined tools for +raster processing in order to make an automatic workflow and ease the land +cover classification, which could be performed also by people whose main field +is not remote sensing. + +Search and download is available for Landsat, Sentinel-2 images. +Several algorithms are available for the land cover classification. +This plugin requires the installation of Remotior Sensus, GDAL, OGR, Numpy, +SciPy, and Matplotlib. ## Contributing to the development -These instructions will get you a copy of the plugin up and running on your local machine for development and testing purposes. +These instructions will get you a copy of the plugin up and running +on your local machine for development and testing purposes. -You do not need any of these steps if you are just interested in using the plugin. +You do not need any of these steps if you are just interested in using +the plugin. ## Before contributing -If you find a bug of if you want to add a new feature, create a new issue on GitHub to discuss it with the community. Other developers can provide valuable feedback that can improve and make your proposal or your fix even better. +If you find a bug of if you want to add a new feature, +create a new issue on GitHub to discuss it with the community. +Other developers can provide valuable feedback that can improve +and make your proposal or your fix even better. ### Prerequisites @@ -29,13 +44,12 @@ import scipy; >>> print(scipy.__version__); 1.0.0 ``` -Do the same for `matplotlib` and `numpy`. +Do the same for `remotior-sensus`, `matplotlib` and `numpy`. -If necessary, install the required libraries, using `easy_install` or `pip`. -Use `easy_install3` and `pip3` if you have both Python 2.x and 3.x. +If necessary, install the required libraries using `pip3`. ```bash -sudo easy_install3 scipy +sudo pip3 install scipy ``` ### Workflow overview @@ -48,7 +62,7 @@ Clone your fork on your local computer. You can do it on the command line with: mkdir -p ~/dev git clone git@github.com:yourgithubusername/SemiAutomaticClassificationPlugin.git ``` -Your fork will called `origin`. Check that with: +Your fork will be called `origin`. Check that with: ```bash cd SemiAutomaticClassificationPlugin @@ -68,7 +82,8 @@ Create a new branch. git checkout -b mycontribution ``` -Make your changes. Compile and test your changes (more details about this on the next section). +Make your changes. +Compile and test your changes (more details about this on the next section). When you have done your edits, commit your local changes, with something like: @@ -80,7 +95,8 @@ Push your changes back to your GitHub repository fork with: ```bash git push origin mycontribution ``` -You are now ready to issue your Pull Request. Go to your GitHub repository interface and make your Pull Request online. +You are now ready to issue your Pull Request. +Go to your GitHub repository interface and make your Pull Request online. ### Compile and deploy on your local computer @@ -98,25 +114,29 @@ make package VERSION=mycontribution This will create a new archive `SemiAutomaticClassificationPlugin.zip`. -In QGIS 3 you can install a plugin from the zip archive using the plugin manager interface. +In QGIS 3 you can install a plugin from the zip archive using +the plugin manager interface. -![Install SCP from zip archive](docs/install%20SCP%20from%20zip%20archive.png) +![Install SCP from zip archive](docs/install_archive.png) ## Test the SCP -Start QGIS 3 and check if the plugin is properly installed. If you are running QGIS in another computer or using another profile, install the plugin from the zip file. - -and install the plugin from the zip file created. +Start QGIS 3 and check if the plugin is properly installed. +If you are running QGIS in another computer or using another profile, +install the plugin from the zip file. ### End user test -Test your bug fixes or new features carefully. Make sure you did not break any existing code. +Test your bug fixes or new features carefully. +Make sure you did not break any existing code. -Do some screen captures of the new enhancements to publish if you want to issue a pull request. +Do some screen captures of the new enhancements to publish if you want +to issue a pull request. ## Contributing -If the code is working as you expect, follow the steps already mentioned to issue a pull request. +If the code is working as you expect, follow the steps already mentioned +to issue a pull request. 1. Commit your local changes, with something like: @@ -128,9 +148,12 @@ Push your changes to your GitHub repository with: ```bash git push origin mycontribution ``` -Go to your GitHub repository interface and make your Pull Request. Please be verbose on your comments. +Go to your GitHub repository interface and make your Pull Request. +Please be verbose on your comments. -After doing your Pull Request, make sure you are available to provide feedback to questions and comments to your contribution from other developers. In the absence of any feedback concerning your Pull Request, it will be closed. +After doing your Pull Request, make sure you are available to provide +feedback to questions and comments to your contribution from other developers. +In the absence of any feedback concerning your Pull Request, it will be closed. ## Authors @@ -140,4 +163,5 @@ See also the list of [contributors](https://github.com/semiautomaticgit/SemiAuto ## License -This plugin is distributed under a GNU General Public License version 3. To contribute you must accept this license. +This plugin is distributed under a GNU General Public License version 3. +To contribute you must accept this license. diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..ad2bca0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (C) 2012-2023 Luca Congedo. + +Semi-Automatic Classification Plugin is free software: +you can redistribute it and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation, +either version 3 of the License, or (at your option) any later version. +Semi-Automatic Classification Plugin is distributed in the hope that +it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with Semi-Automatic Classification Plugin. +If not, see . \ No newline at end of file diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 2d0862b..51af1f2 --- a/Makefile +++ b/Makefile @@ -1,40 +1,10 @@ -#/************************************************************************************************************************** -# SemiAutomaticClassificationPlugin -# -# The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, -# providing tools for the download, the preprocessing and postprocessing of images. -# -# ------------------- -# begin : 2012-12-29 -# copyright : (C) 2012-2017 by Luca Congedo -# email : ing.congedoluca@gmail.com -#**************************************************************************************************************************/ -# -#/************************************************************************************************************************** -# * -# * This file is part of Semi-Automatic Classification Plugin -# * -# * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under -# * the terms of the GNU General Public License as published by the Free Software Foundation, -# * version 3 of the License. -# * -# * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, -# * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# * FITNESS FOR A PARTICULAR PURPOSE. -# * See the GNU General Public License for more details. -# * -# * You should have received a copy of the GNU General Public License along with -# * Semi-Automatic Classification Plugin. If not, see . -# * -#**************************************************************************************************************************/ - # CONFIGURATION #PLUGIN_UPLOAD = $(CURDIR)/plugin_upload.py -# Makefile for a PyQGIS plugin +# Makefile for a PyQGIS plugin # translation -SOURCES = semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin_welcome.py ui/ui_semiautomaticclassificationplugin_scatter_plot.py ui/ui_semiautomaticclassificationplugin_signature_plot.py ui/ui_semiautomaticclassificationplugin_dock_class.py __init__.py ui/semiautomaticclassificationplugindialog.py +SOURCES = semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin_widget.py ui/ui_semiautomaticclassificationplugin_scatter_plot.py ui/ui_semiautomaticclassificationplugin_signature_plot.py ui/ui_semiautomaticclassificationplugin_dock_class.py __init__.py ui/semiautomaticclassificationplugindialog.py TRANSLATIONS = i18n/semiautomaticclassificationplugin_it.ts i18n/semiautomaticclassificationplugin_es.ts i18n/semiautomaticclassificationplugin_pt_BR.ts i18n/semiautomaticclassificationplugin_pt.ts i18n/semiautomaticclassificationplugin_el_GR.ts i18n/semiautomaticclassificationplugin_uk_UA.ts i18n/semiautomaticclassificationplugin_ar.ts i18n/semiautomaticclassificationplugin_zh_CN.ts i18n/semiautomaticclassificationplugin_fr.ts i18n/semiautomaticclassificationplugin_de.ts i18n/semiautomaticclassificationplugin_ja.ts i18n/semiautomaticclassificationplugin_pl.ts # global @@ -43,9 +13,9 @@ PLUGINNAME = SemiAutomaticClassificationPlugin PY_FILES = semiautomaticclassificationplugin.py ui/semiautomaticclassificationplugindialog.py __init__.py -EXTRAS = semiautomaticclassificationplugin.png +EXTRAS = semiautomaticclassificationplugin.png -UI_FILES = ui/ui_semiautomaticclassificationplugin_scatter_plot.py ui/ui_semiautomaticclassificationplugin_signature_plot.py ui/ui_semiautomaticclassificationplugin_dock_class.py ui/ui_semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin_welcome.py +UI_FILES = ui/ui_semiautomaticclassificationplugin_scatter_plot.py ui/ui_semiautomaticclassificationplugin_signature_plot.py ui/ui_semiautomaticclassificationplugin_dock_class.py ui/ui_semiautomaticclassificationplugin.py ui/ui_semiautomaticclassificationplugin_widget.py RESOURCE_FILES = ui/resources_rc.py @@ -75,11 +45,10 @@ deploy: compile transcompile cp -vf $(EXTRAS) $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) cp -vfr i18n $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) # cp -vfr $(HELP) $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME)/help - cp -vfr ui $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) - cp -vfr spectralsignature $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) - cp -vfr maininterface $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) - cp -vfr dock $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) cp -vfr core $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) + cp -vfr interface $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) + cp -vfr spectral_signature $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) + cp -vfr ui $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) cp -vf metadata.txt $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) # The dclean target removes compiled python files from plugin directory @@ -88,9 +57,7 @@ dclean: find $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) -iname "*.pyc" -delete find $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) -iname "__pycache__" -delete find $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) -iname "*.directory" -delete - find $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) -iname "__0semiautomaticclass.log" -delete find $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME) -iname ".svn" -prune -exec rm -Rf {} \; - echo "firstrun" > $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME)/firstrun # The derase deletes deployed plugin derase: @@ -98,12 +65,12 @@ derase: # The zip target deploys the plugin and creates a zip file with the deployed # content. You can then upload the zip file on http://plugins.qgis.org -zip: deploy dclean +zip: deploy dclean rm -f $(PLUGINNAME).zip cd $(HOME)/.qgis3/python/plugins; zip -9r $(CURDIR)/$(PLUGINNAME).zip $(PLUGINNAME) -# Create a zip package of the plugin named $(PLUGINNAME).zip. -# This requires use of git (your plugin development directory must be a +# Create a zip package of the plugin named $(PLUGINNAME).zip. +# This requires use of git (your plugin development directory must be a # git repository). # To use, pass a valid commit or tag as follows: # make package VERSION=Version_0.3.2 @@ -119,11 +86,11 @@ upload: zip # update .ts translation files transup: #pylupdate5 Makefile - pylupdate5 -noobsolete *.py dock/*.py core/*.py maininterface/*.py spectralsignature/*.py ui/ui_utils.py ui/*.ui -ts i18n/semiautomaticclassificationplugin.ts + pylupdate5 -noobsolete *.py core/*.py interface/*.py spectral_signature/*.py ui/*.ui -ts i18n/semiautomaticclassificationplugin.ts cp -vf $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME)/i18n/semiautomaticclassificationplugin.ts $(HOME)/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$(PLUGINNAME)/i18n/models - pylupdate5 -noobsolete *.py dock/*.py core/*.py maininterface/*.py spectralsignature/*.py ui/ui_utils.py ui/*.ui -ts i18n/semiautomaticclassificationplugin_pl.ts -ts $(TRANSLATIONS) + pylupdate5 -noobsolete *.py core/*.py interface/*.py spectral_signature/*.py ui/*.ui -ts i18n/semiautomaticclassificationplugin_pl.ts -ts $(TRANSLATIONS) + - # transcompile # compile translation files into .qm binary format transcompile: $(TRANSLATIONS:.ts=.qm) @@ -137,5 +104,5 @@ clean: rm $(UI_FILES) $(RESOURCE_FILES) # build documentation with sphinx -doc: - cd help; make html +doc: + cd help; make html \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 1a457ec..28aad77 --- a/README.md +++ b/README.md @@ -1,50 +1,70 @@ # Semi-Automatic Classification Plugin -![SCP](semiautomaticclassificationplugin.png) The Semi-Automatic Classification Plugin (SCP) is a free open source plugin for QGIS that allows for the supervised classification of remote sensing images, providing tools for the download, the preprocessing and postprocessing of images. - -The overall objective of SCP is to provide a set of intertwined tools for raster processing in order to make an automatic workflow and ease the land cover classification, which could be performed also by people whose main field is not remote sensing. - -Search and download is available for ASTER, GOES, Landsat, MODIS, Sentinel-1, Sentinel-2, and Sentinel-3 images. Several algorithms are available for the land cover classification. This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib. Some tools require also the installation of SNAP (ESA Sentinel Application Platform). +![SCP](semiautomaticclassificationplugin.png) The Semi-Automatic Classification +Plugin (SCP) is a free open source plugin for QGIS that allows for the +supervised classification of remote sensing images, providing tools for the +download, the preprocessing and postprocessing of images. + +The overall objective of SCP is to provide a set of intertwined tools for +raster processing in order to make an automatic workflow and ease the land +cover classification, which could be performed also by people whose main field +is not remote sensing. + +Search and download is available for Landsat, Sentinel-2 images. +Several algorithms are available for the land cover classification. +This plugin requires the installation of Remotior Sensus, GDAL, OGR, Numpy, +SciPy, and Matplotlib. Other dependencies are optional for specific functions. +For more information please visit https://fromgistors.blogspot.com . ## Plugin installation The SCP is available for QGIS version 3.x. -The SCP is developed with Python 3 and requires the installation of GDAL (OGR), NumPy, SciPy and Matplotlib. - -For the installation of QGIS and SCP on different operating systems please follow this [guide](https://semiautomaticclassificationmanual.readthedocs.io/en/latest/installation.html). +The SCP is developed with Python 3 and requires the installation of +Remotior Sensus, GDAL (OGR), NumPy, SciPy and Matplotlib. +For the installation of QGIS and SCP on different operating systems please +follow this [guide](https://semiautomaticclassificationmanual.readthedocs.io/en/latest/installation.html). ## Using the plugin -If you are new to SCP, please follow this [tutorial](https://semiautomaticclassificationmanual.readthedocs.io/en/latest/tutorial_1.html). - +If you are new to SCP, please follow +this [tutorial](https://semiautomaticclassificationmanual.readthedocs.io/en/latest/tutorial_1.html). ## Web site -All the SCP information is available from the [SCP website](https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html). +All the SCP information is available from +the [SCP website](https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html). ## Documentation -Check [the user manual](https://semiautomaticclassificationmanual.readthedocs.io) or the online [tutorials](https://fromgistors.blogspot.com/search/label/Tutorial) available. +Check [the user manual](https://semiautomaticclassificationmanual.readthedocs.io) +or the online [tutorials](https://fromgistors.blogspot.com/search/label/Tutorial) +available. [Videos](https://www.youtube.com/user/fromgistors) are also available. ## Contributing to the development -If you find some issue that you are willing to fix, code contributions are welcome. Please read [the development notes](DEVELOPMENT.md) before contributing. +If you find some issue that you are willing to fix, code contributions are +welcome. Please read [the development notes](DEVELOPMENT.md) before +contributing. ## Authors -* **Luca Congedo** +* **Luca Congedo** ## License This plugin is distributed under a GNU General Public License version 3. -## How to cite -Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172 +## How to cite + +Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for +the download and processing of remote sensing images in QGIS. Journal of Open +Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172 [![DOI](https://joss.theoj.org/papers/10.21105/joss.03172/status.svg)](https://doi.org/10.21105/joss.03172) ## Code on Zenodo + [![DOI](https://zenodo.org/badge/18038317.svg)](https://zenodo.org/badge/latestdoi/18038317) diff --git a/__init__.py b/__init__.py old mode 100644 new mode 100755 index dc493f7..3e966e3 --- a/__init__.py +++ b/__init__.py @@ -1,36 +1,24 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . def name(): @@ -38,39 +26,58 @@ def name(): def description(): - return 'A plugin that integrates tools for easing the download, the preprocessing, processing, and postprocessing of remote sensing images.' + return ( + 'A plugin that integrates tools for easing the download, ' + 'the preprocessing, processing, and postprocessing of ' + 'remote sensing images.' + ) def version(): - return 'Version 7.10.11 - Matera' + return 'Version 8.0.0 - Infinity' def icon(): return 'semiautomaticclassificationplugin.png' +# noinspection PyPep8Naming def qgisMinimumVersion(): - return '2.99' + return '3.00' + def author(): return 'Luca Congedo' + def email(): return 'ing.congedoluca@gmail.com' + def category(): return 'Raster' + +# noinspection PyPep8Naming def classFactory(iface): - from .semiautomaticclassificationplugin import SemiAutomaticClassificationPlugin + from .semiautomaticclassificationplugin import ( + SemiAutomaticClassificationPlugin + ) return SemiAutomaticClassificationPlugin(iface) + def homepage(): - return 'https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html' + return ( + 'https://fromgistors.blogspot.com/p' + '/semi-automatic-classification-plugin.html') + def tracker(): - return 'https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/issues' - -def repository(): - return 'https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin' + return ( + 'https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin' + '/issues') + +def repository(): + return ('https://github.com/semiautomaticgit' + '/SemiAutomaticClassificationPlugin') diff --git a/core/__init__.py b/core/__init__.py old mode 100644 new mode 100755 diff --git a/core/config.py b/core/config.py old mode 100644 new mode 100755 index 84d8385..050714f --- a/core/config.py +++ b/core/config.py @@ -1,868 +1,268 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -''' Init ''' -gdalDLLPath = None -iface = None -cnvs = None -mainAction = None -menu = None -tools_menu = None -preprocessing_menu = None -postprocessing_menu = None -settings_menu = None -toolBar = None -projPath = '' -# main interface -ui = None -dlg = None -currentTab = 'bandSetTab' -# roi dock -uid = None -dockdlg = None -# classification dock -uidc = None -dockclassdlg = None -# spectral signature plot -uisp = None -# welcome -wlcmdlg = None -spectralplotdlg = None -SpectralSignaturePlot = None -scatterplotdlg = None -uiscp = None -# USGS spectral Library -usgsLib = None -# input -ipt = None -# legend -lgnd = None -# plugin dir -plgnDir = None -# temp dir -tmpDir = None -tmpExtDir = None -tmpList = [] -# messages -mx = None -# utils -utls = None -# ui utils -uiUtls = None -# accuracy -acc = None -# system platform -sys64bit = None -sysNm = None -# signature importer -sigImport = None -QGISVer = None -sysInfo = None -scipyCheck = None -actionCheck = 'No' -progressBar = None -fSEnc = None -logFile = None -toolPan = None -pntCheck = None -lstPnt = None -# training layer -shpLay = None -# training layer name -trnLay = None -# signature file path -sigFile= None -mskFlPath = '' -mskFlState = 0 -# ROI click -clickROI = None -pntPrvw = None -lstROI = None -lstROI2 = None -sctrROIID = None -sctrROIID_h = {} -pntROI = None -origPoint = None -ROITime = None -lstPrvw = None -prvwSz = None -lastVrt = [] -# band list -bndMdl = None -bndMdls = None -bndMdls2 = None -newClssfctnNm = None -refClssfctnNm = None -rbbrBnd = None -rbbrBndPol = None -ROISigNm = None -ROI_MC_ID = None -ROI_MC_Info = None -ROI_C_ID = None -ROI_C_Info = None -ROI_Count = None -ROI_ShapeID = None -ROISigTypeNm = 'R&S' -ROITypeNm = 'ROI' -SIGTypeNm = 'Sig' -tblOut = None -reportPth = None -errMtrxPth = None -bndSetMaskList = None -mnlROI = None -regionROI = None -allSignCheck = 'No' -allSignCheck2 = 'No' -allSignCheck3 = 'No' -signList = {} -signIDs = {} -undoIDList = {} -undoSpectrPlotList = {} -ROI_SCP_UID = {} -MCID_List = {} -# spectral plot -spectrPlotList = {} -signPlotIDs = {} -scatterPlotIDs = {} -scatterPlotList = {} -tmpROIID = None -tmpROIColor = None -# weights -algBandWeigths = {} -# set classification path -clssPth = None -arrayUnitMemory = 0.000016 -arrayUnitMemory8 = 0.000010 -arrayUnitMemory4 = 0.000006 -tableColString = 'ID' -ROITabEdited = 'No' -SigTabEdited = 'No' -ScatterTabEdited = 'No' -ReclassTabEdited = 'No' -# classification variables -# threshold -algThrshld = 0 -# LC Signature threshold -tableMCID = 'MC ID' -tableCID = 'C ID' -tableMCInfo = 'MC Name' -tableCInfo = 'C Name' -tableColor = 'Color [overlap MC_ID-C_ID]' -tableColor2 = 'Color' -tableMin = 'Min B' -tableMax = 'Max B' -# set vector output variable -vectorOutputCheck = 'No' -reportCheck = 'No' -# raster band pixel count -rasterBandPixelCount = None -# raster pixel count for PCA -rasterPixelCountPCA = {} -# raster clustering -rasterClusteringrasterClustering = {} -# raster class signature -classSignatureNm = 'Class signature' -# remaining time -remainingTime = 0 -# set variable for standard deviation plot -sigmaCheck = 'Yes' -# forbandsinbandset -forbandsinbandset = 'forbandsinbandset' -# forbandsets -forbandsets = 'forbandsets' -# forbsdates -forbsdates = 'forbsdates' -# numpy -numpyn = 'cfg.np.' -# numpy logarithm -logn = 'cfg.np.log' -# numpy logarithm -log10 = 'cfg.np.log10' -# numpy logarithm -numpySqrt = 'cfg.np.sqrt' -# numpy cos -numpyCos = 'cfg.np.cos' -# numpy acos -numpyArcCos = 'cfg.np.arccos' -# numpy sin -numpySin = 'cfg.np.sin' -# numpy asin -numpyArcSin = 'cfg.np.arcsin' -# numpy tan -numpyTan = 'cfg.np.tan' -# numpy atan -numpyArcTan = 'cfg.np.arctan' -# numpy exp -numpyExp = 'cfg.np.exp' -# numpy amin -numpyAMin = 'cfg.np.nanmin' -# numpy amax -numpyAMax = 'cfg.np.nanmax' -# numpy nanpercentile -numpyPercentile = 'cfg.np.nanpercentile' -# numpy numpy.nanmedian -numpyMedian = 'cfg.np.nanmedian' -# numpy numpy.nanmean -numpyMean = 'cfg.np.nanmean' -# numpy numpy.nansum -numpySum = 'cfg.np.nansum' -# numpy numpy.nanstd -numpyStd = 'cfg.np.nanstd' -# numpy where -numpyWhere = 'cfg.np.where' -# land cover change variables -unchngMaskCheck = True -# scatter plot variables -scatterBandX = 1 -scatterBandY = 2 -# fill plot -pF = [] -# virtual raster -landsatVrtNm = 'landsat' -sentinel2VrtNm = 'sentinel2' -tmpVrtNm = 'vrt_temp_' -bndSetVrtNm = 'Virtual Band Set ' -tmpVrt = None -tmpVrtDict = {} -# scp input directory -inptDir = None -scpFlPath = None -backupNm = 'backup' -skipProjectSaved = 'No' -# pixel signature names -pixelNm = 'pixel' -pixelCoords = 'Coords' -# temp ROI -tempROINm = 'tempROI' -# temp scatter -tempScatterNm = 'tempScatter' +""" init """ +iface = map_canvas = dialog = dock_class_dlg = input_interface = utils = None +scp_dock = edit_raster = bst = mx = ui_utils = spectral_plot_dlg = None +scatter_plot_dlg = widget_dialog = settings = system_platform = logger = None +util_qgis = rs = bandset_catalog = plugin_dir = temp_dir = accuracy = None +dialog_accepted = class_report = class_vector = script = band_calc = None +cross_classification = dilation = erosion = sieve = neighbor = rgb_combo = None +reclassification = band_combination = pca_tab = vector_to_raster = None +stack_bandset = split_bands = reproject_bands = masking_bands = None +image_conversion = clip_bands = clip_bands_pointer = mosaic_bandsets = None +download_products = download_products_pointer = util_qt = translate = None +classification = working_toolbar = classification_preview_pointer = None +rgb_composite = signature_threshold = calc_raster_variables = None +first_install = signature_plot = spectral_signature_plotter = None +scatter_plot = scatter_plotter = scp_processing_provider = None +signature_importer = usgs_spectral_lib = multiple_roi = None +smtp_notification = smtp_server = smtp_user = smtp_password = None +smtp_recipients = None +# welcome url +first_reply = second_reply = second_url = None +# QGIS proxy +proxy_enabled = proxy_type = proxy_host = proxy_port = None +proxy_user = proxy_password = None +# temporary directory name +temp_dir_name = 'semiautomatic_classification' +# bandset tabs +bandset_tabs = {} +current_tab = 'bandset_tab' +variable_bandset_name = 'bandset' +# bandset virtual raster +virtual_bandset_name = bandset_tab_name = None +virtual_bandset_dict = {} +# clip rubber poly +clip_rubber_poly = download_rubber_poly = None # empty field name -emptyFN = 'DN' -# band number variable -BLUEBand = None -REDBand = None -NIRBand = None -GREENBand = None -SWIR1Band = None -SWIR2Band = None -BLUECenterBand = 0.475 -BLUEThreshold = 0.2 -GREENCenterBand = 0.56 -GREENThreshold = 0.03 -REDCenterBand = 0.65 -REDThreshold = 0.04 -NIRCenterBand = 0.85 -NIRThreshold = 0.15 -SWIR1CenterBand = 1.61 -SWIR1Threshold = 0.2 -SWIR2CenterBand = 2.2 -SWIR2Threshold = 0.2 -# pansharpening type -IHS_panType = 'Intensity-Hue-Saturation' -BT_panType = 'Brovey Transform' +empty_field_name = 'DN' +# table object +download_table = preprocess_band_table = None +# classification preview layer +classification_preview = classifier_preview = preview_point = None +# saved directory +last_saved_dir = '' +project_path = '' +settings_tab_index = 0 +backup_name = '.backup' + +""" scp dock """ +scp_training = ctrl_click = temporary_roi = second_temporary_roi = None +region_growing_pointer = manual_roi_pointer = roi_map_polygon = None +roi_center_vertex = scp_dock_rubber_roi = scp_layer_name = roi_time = None +last_roi_point = None +temp_roi_name = 'temp_roi' +roi_and_signature_type = 'R&S' +roi_type = 'ROI' +signature_type = 'SIG' +roi_points = [] +qgis_vertex_item_list = [] # contrast type -cumulativeCutContrast = 'cumulativeCut' -stdDevContrast = 'stdDev' -defaultContrast = cumulativeCutContrast -# settings -testGDALV = None -testMatplotlibV = None -testScipyV = None -testNumpyV = None -# debug -debugRasterPath = '/debug/roi_raster.tif' -absolutePath = False -ctrlClick = None -previewSliderActive = None -previewSliderArray = None -msgWar8check = 'No' -lastSaveDir = '' -skipRegistry = True -# band calc -bandCalcIndex = 0 -dockIndex = 0 -bandCalcFunctionNames = [] -bandCalcFunctionNames.append(['Conditional']) -bandCalcFunctionNames.append(['where', 'where(']) -bandCalcFunctionNames.append(['Logical']) -bandCalcFunctionNames.append(['AND', '&']) -bandCalcFunctionNames.append(['OR', '|']) -bandCalcFunctionNames.append(['XOR', '^']) -bandCalcFunctionNames.append(['NOT', '~']) -bandCalcFunctionNames.append(['Statistics']) -bandCalcFunctionNames.append(['max', 'max(']) -bandCalcFunctionNames.append(['min', 'min(']) -bandCalcFunctionNames.append(['mean', 'mean(']) -bandCalcFunctionNames.append(['median', 'median(']) -bandCalcFunctionNames.append(['percentile', 'percentile(']) -bandCalcFunctionNames.append(['std', 'std(']) -bandCalcFunctionNames.append(['sum', 'sum(']) -bandCalcFunctionNames.append(['Operations']) -bandCalcFunctionNames.append(['sin', 'sin(']) -bandCalcFunctionNames.append(['cos', 'cos(']) -bandCalcFunctionNames.append(['tan', 'tan(']) -bandCalcFunctionNames.append(['asin', 'asin(']) -bandCalcFunctionNames.append(['acos', 'acos(']) -bandCalcFunctionNames.append(['atan', 'atan(']) -bandCalcFunctionNames.append(['exp', 'exp(']) -bandCalcFunctionNames.append(['ln', 'ln(']) -bandCalcFunctionNames.append(['log10', 'log10(']) -bandCalcFunctionNames.append(['Indices']) -bandCalcFunctionNames.append(['NDVI', '( "#NIR#" - "#RED#" ) / ( "#NIR#" + "#RED#" ) @NDVI']) -bandCalcFunctionNames.append(['EVI', '2.5 * ( "#NIR#" - "#RED#" ) / ( "#NIR#" + 6 * "#RED#" - 7.5 * "#BLUE#" + 1) @EVI']) -bandCalcFunctionNames.append(['NBR', '( "#NIR#" - "#SWIR2#" ) / ( "#NIR#" + "#SWIR2#" ) @NBR']) -bandCalcFunctionNames.append(['Variables']) -bandCalcFunctionNames.append(['nodata', 'nodata(']) -bandCalcFunctionNames.append(['forbandsets', 'forbandsets[ ]']) -bandCalcFunctionNames.append(['forbsdates', 'forbsdates[ ]']) -bandCalcFunctionNames.append(['forbandsinbandset', 'forbandsinbandset[ ]']) -bandCalcFunctionNames.append(['#BAND#', '#BAND#']) -bandCalcFunctionNames.append(['!function!', '!function!']) -bandCalcFunctionNames.append(['#BANDSET#', '#BANDSET#']) -bandCalcFunctionNames.append(['#DATE#', '#DATE#']) -bandCalcFunctionNames.append(['@', '@']) -bandCalcFunctionNames.append(['Custom']) -# zonal stat raster -statisticList = [] -statisticList.append(['Count', 'np.count_nonzero(~np.isnan(array))']) -statisticList.append(['Max', 'np.nanmax(array)']) -statisticList.append(['Mean', 'np.nanmean(array)']) -statisticList.append(['Median', 'np.nanmedian(array)']) -statisticList.append(['Min', 'np.nanmin(array)']) -statPerc = '@statPerc@' -statisticList.append(['Percentile', 'np.nanpercentile(array, ' + statPerc + ')']) -statisticList.append(['StandardDeviation', 'np.nanstd(array)']) -statisticList.append(['Sum', 'np.nansum(array)']) -# SCP kml name -kmlNm = 'SCP_kml' -# subprocesses dictionary -subprocDictProc={} -parallelArray = 'parallel_array' -parallelRaster = 'parallel_raster' -parallelArrayDict = {} +cumulative_cut_contrast = 'cumulative_cut' +std_dev_contrast = 'std_dev' +default_contrast = cumulative_cut_contrast + +""" Spectral signature plot""" +signature_id_column_name = 'id' -''' Project variables ''' -qmlFl = None -sigClcCheck = '2' -saveInputCheck = '2' -rpdROICheck = '0' -vegIndexCheck = '2' -multiAddFactorsVar = 'multiplicativeAdditiveFactorsVar' -bandSetsList = [] -bndSetNumber = 0 -bndSetTabList = [] -bndSetWidgetReset = 'No' -rasterName = None -cmplClsNm = None -cmplMClsNm = None -treeDockMCItm = {} -treeDockItm = {} -ROIband = 1 -maxROIWdth = 100 -minROISz = 60 -rngRad = 0.01 -ROIID = 1 -ROIInfo = 'C 1' -ROIMacroClassInfo = 'MC 1' -ROIMacroID = 1 -customExpression = '' -macroclassCheckRF = 'Yes' -classRF = '' +""" QGIS Project variables """ +project_registry = {} +# roi cursor index calculation check +reg_index_calculation_check = 'scp_roi_index_calculation_check' +project_registry[reg_index_calculation_check] = 0 +# roi cursor custom index +reg_custom_index_calculation = 'scp_custom_index_calculation' +project_registry[reg_custom_index_calculation] = '' # RGB list -RGBListDef = str(['-', '3-2-1', '4-3-2']) -RGBList = RGBListDef -# Landsat image database -LandsatImageDatabase = None -Landsat7OnImageDatabase = None -Landsat7OffImageDatabase = None -LandsatTM80ImageDatabase = None -LandsatTM90ImageDatabase = None -LandsatTM00ImageDatabase = None -LandsatTM10ImageDatabase = None -Landsat8ImageDatabase = None -LandsatTMImageDatabase2010 = None -RADIANCE_UNITS = None -expressionDict = {} +reg_rgb_list = 'scp_rgb_list' +project_registry[reg_rgb_list] = ['-', '3-2-1', '4-3-2', '7-3-2'] +# signature calculation check +reg_signature_calculation_check = 'scp_signature_calculation_check' +project_registry[reg_signature_calculation_check] = 2 +# rapid ROI check +reg_rapid_roi_check = 'scp_rapid_roi_check' +project_registry[reg_rapid_roi_check] = 2 +# automatic save training input +reg_save_training_input_check = 'scp_save_training_input_check' +project_registry[reg_save_training_input_check] = 2 +# rapid ROI main band +reg_roi_main_band = 'scp_roi_main_band' +project_registry[reg_roi_main_band] = 1 +# ROI max width +reg_roi_max_width = 'scp_roi_max_width' +project_registry[reg_roi_max_width] = 100 +# ROI min size +reg_roi_min_size = 'scp_roi_min_size' +project_registry[reg_roi_min_size] = 60 +# ROI range radius +reg_roi_range_radius = 'scp_roi_range_radius' +project_registry[reg_roi_range_radius] = 0.01 +# ROI pointer custom expression +reg_roi_custom_expression = 'scp_roi_custom_expression' +project_registry[reg_roi_custom_expression] = '' +# classification preview size +reg_preview_size = 'scp_reg_preview_size' +project_registry[reg_preview_size] = 200 +preview_size = 200 +# ROI class id +reg_roi_class_id = 'scp_roi_class_id' +project_registry[reg_roi_class_id] = 1 +# ROI class name +reg_roi_class_name = 'scp_roi_class_name' +project_registry[reg_roi_class_name] = 'Class 1' +# ROI macroclass id +reg_roi_macroclass_id = 'scp_roi_macroclass_id' +project_registry[reg_roi_macroclass_id] = 1 +# ROI macroclass name +reg_roi_macroclass_name = 'scp_roi_macroclass_name' +project_registry[reg_roi_macroclass_name] = 'Macroclass 1' +# training input path +reg_training_input_path = 'scp_training_input_path' +project_registry[reg_training_input_path] = '' +# active bandset number +reg_active_bandset_number = 'scp_active_bandset_number' +project_registry[reg_active_bandset_number] = 1 +# training bandset number +reg_training_bandset_number = 'scp_training_bandset_number' +project_registry[reg_training_bandset_number] = 1 +# download product table +reg_download_product_table = 'scp_download_product_table' +project_registry[reg_download_product_table] = '' +# bandset count +reg_bandset_count = 'scp_bandset_count' +project_registry[reg_bandset_count] = 1 +project_registry_default = project_registry.copy() -''' QGIS variables ''' -# registry key for first installation -regFirstInstall = 'SemiAutomaticClassificationPlugin/firstInstall' -firstInstallVal = 'Yes' -# registry key for log setting -regLogKey = 'SemiAutomaticClassificationPlugin/logSetting' -logSetVal = 'No' -# registry key for sound -regSound = 'SemiAutomaticClassificationPlugin/useSoundStart' -soundVal = '2' -# registry key for ROI color setting -regROIClr = 'SemiAutomaticClassificationPlugin/ROIColour' -ROIClrValDefault = '#ffaa00' -ROIClrOutlineValDefault = '#53d4e7' -ROIClrVal = ROIClrValDefault -# registry key for ROI transparency setting -regROITransp = 'SemiAutomaticClassificationPlugin/ROITransparency4' -# registry key for download news -downNewsKey = 'SemiAutomaticClassificationPlugin/downloadNewsStart7' -downNewsVal = '2' -# registry key for download news -vrtRstProjKey = 'SemiAutomaticClassificationPlugin/loadVirtualRasterStart' -vrtRstProjVal = '0' -# registry key for algorithm files -regAlgFiles = 'SemiAutomaticClassificationPlugin/algFilesStart' -algFilesCheck = '0' -ROITrnspValDefault = 45 -ROITrnspVal = ROITrnspValDefault -# registry key for temporary raster format -regTempRasterFormat = 'SemiAutomaticClassificationPlugin/tempRastFormat' -# registry key for raster compression -regRasterCompression = 'SemiAutomaticClassificationPlugin/rasterCompression' -# registry key for parallel writing -regparallelWritingCheck = 'SemiAutomaticClassificationPlugin/parallelWritingCheck' +""" bandset registry standard """ +reg_bandset = 'SemiAutomaticClassification_Plugin/scp_bandset_' + +""" QGIS registry keys """ +qgis_registry = {} +# first installation +reg_first_install = 'SemiAutomaticClassification_Plugin/first_install' +# log setting +reg_log_key = 'SemiAutomaticClassification_Plugin/log_setting' +qgis_registry[reg_log_key] = 0 +# sound +reg_sound = 'SemiAutomaticClassification_Plugin/use_sound' +qgis_registry[reg_sound] = 2 +# registry key for temporary directory +reg_temp_dir = 'SemiAutomaticClassification_Plugin/temp_dir' # registry key for RAM value setting -regRAMValue = 'SemiAutomaticClassificationPlugin/RAMValue' -RAMValue = 512 +reg_ram_value = 'SemiAutomaticClassification_Plugin/ram_value' +qgis_registry[reg_ram_value] = 512 # registry key for CPU threads value setting -regThreadsValue = 'SemiAutomaticClassificationPlugin/threadsValue' -threads = 1 +reg_threads_value = 'SemiAutomaticClassification_Plugin/threads_value' +qgis_registry[reg_threads_value] = 2 +reg_earthdata_user = 'SemiAutomaticClassificationPlugin/earthdata_user' +qgis_registry[reg_earthdata_user] = '' +reg_earthdata_pass = 'SemiAutomaticClassificationPlugin/earthdata_pass' +qgis_registry[reg_earthdata_pass] = '' +# registry key for ROI color setting +reg_roi_color = 'SemiAutomaticClassificationPlugin/roi_color' +roi_color_default = '#ffaa00' +qgis_registry[reg_roi_color] = roi_color_default +# registry key for ROI transparency setting +reg_roi_transparency = 'SemiAutomaticClassificationPlugin/roi_transparency' +roi_transparency_default = 45 +qgis_registry[reg_roi_transparency] = roi_transparency_default +# registry key for ROI transparency setting +reg_max_train_buffer = 'SemiAutomaticClassificationPlugin/max_train_buffer' +max_train_buffer_default = 5 +qgis_registry[reg_max_train_buffer] = max_train_buffer_default # gdal path setting -regGDALPathSettings = 'SemiAutomaticClassificationPlugin/GDALPathSettings' -gdalPath = '' -# python path setting -regPythonPathSettings = 'SemiAutomaticClassificationPlugin/PythonPathSettings' -PythonPathSettings = '' -# python modules path setting -regPythonModulesPathSettings = 'SemiAutomaticClassificationPlugin/PythonModulesPathSettings' -PythonModulesPathSettings = '' +reg_gdal_path = 'SemiAutomaticClassificationPlugin/gdal_path' +qgis_registry[reg_gdal_path] = '' +reg_download_news = 'SemiAutomaticClassificationPlugin/download_news' +qgis_registry[reg_download_news] = 2 +reg_raster_compression = 'SemiAutomaticClassificationPlugin/raster_compression' +qgis_registry[reg_raster_compression] = 2 # smtp server -regSMTPCheck = 'SemiAutomaticClassificationPlugin/SMTPCheckStart' -SMTPCheck = '2' -regSMTPServer = 'SemiAutomaticClassificationPlugin/SMTPServer' -SMTPServer = '' -regSMTPtoEmails = 'SemiAutomaticClassificationPlugin/SMTPtoEmails' -SMTPtoEmails = '' -regSMTPUser = 'SemiAutomaticClassificationPlugin/SMTPUser' -SMTPUser = '' -regSMTPPassword = 'SemiAutomaticClassificationPlugin/SMTPPassword' -SMTPPassword = '' -# field names for shapefile -regIDFieldName = 'SemiAutomaticClassificationPlugin/IDFieldName' -# registry key for temporary directory -regTmpDir = 'SemiAutomaticClassificationPlugin/TmpDir' -regUSGSUser = 'SemiAutomaticClassificationPlugin/USGSUser' -USGSUser = '' -regUSGSPass= 'SemiAutomaticClassificationPlugin/USGSPass' -USGSPass = '' -regUSGSUserASTER = 'SemiAutomaticClassificationPlugin/USGSUserASTER' -USGSUserASTER = '' -regUSGSPassASTER = 'SemiAutomaticClassificationPlugin/USGSPassASTER' -USGSPassASTER = '' -regSentinelAlternativeSearch = 'SemiAutomaticClassificationPlugin/SentinelAlternativeSearch' -sentinelAlternativeSearch = '0' -regSciHubUser = 'SemiAutomaticClassificationPlugin/SciHubUser' -SciHubUser = '' -regSciHubPass = 'SemiAutomaticClassificationPlugin/SciHubPass' -SciHubPass = '' -regSciHubService = 'SemiAutomaticClassificationPlugin/SciHubService_5_2' -SciHubServiceNm = 'https://scihub.copernicus.eu/apihub' -SciHubService = SciHubServiceNm -fldMacroID_class_def = 'MC_ID' -fldID_class_def = 'C_ID' -fldROI_info_def = 'C_name' -fldROIMC_info_def = 'MC_name' -ROI_Size_info_def = 'ROI_size' -fldSCP_UID_def= 'SCP_UID' -variableName_def = 'raster' -variableOutName_def = 'output' -vectorVariableName_def = 'vector' -variableBandsetName_def = 'bandset' -variableBlueName_def = '#BLUE#' -variableGreenName_def = '#GREEN#' -variableRedName_def = '#RED#' -variableNIRName_def = '#NIR#' -variableSWIR1Name_def = '#SWIR1#' -variableSWIR2Name_def = '#SWIR2#' -variableOutputNameBandset_def = '#BANDSET#' -variableOutputNameDate_def = '#DATE#' -variableBand_def = '#BAND#' -merged_name = 'merged_' -fldID_class = fldID_class_def -# macroclass ID -regMacroIDFieldName = 'SemiAutomaticClassificationPlugin/MCIDFieldName' -fldMacroID_class = fldMacroID_class_def -# macroclass check -regConsiderMacroclass = 'SemiAutomaticClassificationPlugin/ConsiderMacroclass' -macroclassCheck = 'No' -# LCS -regLCSignature = 'SemiAutomaticClassificationPlugin/LCSignature' -LCsignatureCheckBox = 'No' -# info field -regInfoFieldName = 'SemiAutomaticClassificationPlugin/InfoFieldName' -regMCInfoFieldName = 'SemiAutomaticClassificationPlugin/MCInfoFieldName' -fldROI_info = fldROI_info_def -fldROIMC_info = fldROIMC_info_def -ROI_Size_info = ROI_Size_info_def -fldSCP_UID = fldSCP_UID_def -# variable name -regVariableName = 'SemiAutomaticClassificationPlugin/VariableName' -variableName = variableName_def -variableOutName = variableOutName_def -# variable name -regVectorVariableName = 'SemiAutomaticClassificationPlugin/vectorVariableName' -vectorVariableName = vectorVariableName_def -# variable band set name -regVariableBandsetName = 'SemiAutomaticClassificationPlugin/VariableBandsetName' -variableBandsetName = variableBandsetName_def -variableBlueName = variableBlueName_def -variableGreenName = variableGreenName_def -variableRedName = variableRedName_def -variableNIRName = variableNIRName_def -variableSWIR1Name = variableSWIR1Name_def -variableSWIR2Name = variableSWIR2Name_def -variableOutputNameBandset = variableOutputNameBandset_def -variableOutputNameDate = variableOutputNameDate_def -variableBand = variableBand_def -# band set name -regBandSetName = 'SemiAutomaticClassificationPlugin/BandSetName' -bandSetName = 'Band set ' -# plot variables -#regRoundCharList = 'SemiAutomaticClassificationPlugin/roundCharList' -roundCharList = 15 -# group name for temp ROI and Preview -regGroupName = 'SemiAutomaticClassificationPlugin/groupName' -grpNm_def = 'Class_temp_group' -grpNm = grpNm_def -lastPrev = None -lastScattRaster = None -prevList = [] -# clip prefix -clipNm = 'clip' -# reproject prefix -reprojNm = 'reproj' -# output temp raster format -outTempRastFormat = 'VRT' -rasterCompression = 'Yes' -parallelWritingCheck = 'No' -# raster data type -regRasterDataType = 'SemiAutomaticClassificationPlugin/rasterDataTypeNew' -rasterDataType = 'Float32' -rasterBandCalcType = 'Float32' -# raster data type -regExpressionListBC= 'SemiAutomaticClassificationPlugin/expressionListBC' -expressionListBCbase = [] -expressionListBC = expressionListBCbase -LCSOld = 'Yes' +reg_smtp_check = 'SemiAutomaticClassificationPlugin/smtp_check' +qgis_registry[reg_smtp_check] = 2 +reg_smtp_server = 'SemiAutomaticClassificationPlugin/smtp_server' +qgis_registry[reg_smtp_server] = '' +reg_smtp_emails = 'SemiAutomaticClassificationPlugin/smtp_emails' +qgis_registry[reg_smtp_emails] = '' +reg_smtp_user = 'SemiAutomaticClassificationPlugin/smtp_user' +qgis_registry[reg_smtp_user] = '' +reg_smtp_password = 'SemiAutomaticClassificationPlugin/smtp_password' +qgis_registry[reg_smtp_password] = '' +# raster variable name +reg_raster_variable_name = 'SemiAutomaticClassificationPlugin/raster_var_name' +raster_variable_name_def = 'raster' +qgis_registry[reg_raster_variable_name] = raster_variable_name_def +# group name +reg_group_name = 'SemiAutomaticClassificationPlugin/group_name' +group_name_def = 'scp_class_temp_group' +qgis_registry[reg_group_name] = group_name_def +# band calc functions +reg_custom_functions = 'SemiAutomaticClassificationPlugin/custom_functions' +custom_functions_def = [] +qgis_registry[reg_custom_functions] = custom_functions_def # window size -regWindowSizeW = 'SemiAutomaticClassificationPlugin/windowSizeW' -windowSizeW = '700' -regWindowSizeH = 'SemiAutomaticClassificationPlugin/windowSizeH' -windowSizeH = '500' -regSplitterSizeS = 'SemiAutomaticClassificationPlugin/splitterSizeS' -splitterSizeS = '[100, 100]' - -''' Names ''' -algMinDist = 'Minimum Distance' -algML = 'Maximum Likelihood' -algSAM = 'Spectral Angle Mapping' -uncls = 'Unclassified' -clasfd = 'Classified' -overlap = 'Class Overlap' -algRasterNm = 'alg_raster' -classRasterNm = 'class_raster' -calcRasterNm = 'calc_raster' -calcFunctionNm = '!function!' -calcVarReplace = 'variablereplaceexpression' -scatterRasterNm = 'scatter_raster' -polyRasterNm = 'polyr_raster' -stackRasterNm = 'stack_raster' -virtualRasterNm = 'virt_rast' -errMatrixNm = '_error_matrix.csv' -crossClassNm = '_cross_classification.csv' -PCANm = 'PCA_band_' -PCAReportNm = 'PCA_report.txt' -kmeansNm = 'kmeans_' -kmeansReportNm = 'kmeans_report.txt' -tempMtrxNm = 'tmp_error_matrix' -reportNm = '_report.csv' -sigRasterNm = 'sig' -prvwTempNm = 'previewtemp.tif' -rclssTempNm = 'temporary_ref_reclass' -bsCombTempNm = 'temporary_band_set_comb' -maskRasterNm = 'mskRstr.tif' -subsROINm = 'subset_ROI_temp.tif' -subsTmpRaster = 'subset_temp_b' -subsTmpROI = 'ROI_tmp_copy' -copyTmpROI = 'ROI_rast_temp' -tmpRegionNm = 'region_temp' -tmpROINm = 'temp_ROI' -mapExtent = '\'Map extent\'' -pixelExtent = '\'Pixel extent\'' -splitBndNm = 'splitBand_' -spectralDistNm = 'SpectralDistanceBandSets_' -reflectanceRasterNm = 'reflectance_temp' -NoDataVal = -32768 -NoDataValUInt16 = 65535 -NoDataValInt32 = 2147483647 -NoDataValFloat32 = -3.4028235e+38 -NoDataValUInt32 = 4294967295 -NoDataValUInt64 = 2**64-1 -unclassifiedVal = -1000 -maxLikeNoDataVal = -999999999900000 -maxValDt = 999999999900000 -unclassValue = None -referenceLayer = None -prvwSz = 200 -# alg name -algName = 'Minimum Distance' -kmeansAlgName = 'Minimum Distance' -algLCS = 'Land Cover Signature' -algKmeans = 'K-means' -algISODATA = 'ISODATA' -# type of conversion -convCenterPixels = 'Center of pixels' -convAllPixelsTouch ='All pixels touched' -#index name -indName = 'NDVI' -indNDVI = 'NDVI' -indEVI = 'EVI' -indCustom = 'Custom' -# set mask variable -maskCheck = 'No' -# prefix for ROI signature fields -ROIFieldMean = 'ROIm_b' -ROISigma = 'ROIs_b' -ROINBands = 'ROI_NBands' -# spectral plot -wavelenNm = 'Wavelength' -valNm = 'Values' -standDevNm = 'Standard deviation' -# distances -euclideanDistNm = 'Euclidean distance' -brayCurtisSimNm = 'Bray-Curtis similarity [%]' -spectralAngleNm = 'Spectral angle' -jeffriesMatusitaDistNm = 'Jeffries-Matusita distance' -transformedDivergenceNm = 'Transformed divergence' -notAvailable = 'n/a' -resampling_methods = ['nearest_neighbour', 'average', 'sum', 'maximum', 'minimum', 'mode', 'median', 'first_quartile', 'third_quartile'] - -''' band set ''' -# list of satellites for wavelength -NoSatellite = 'Band order' -satGeoEye1 = 'GeoEye-1 [bands 1, 2, 3, 4]' -satGOES = 'GOES [bands 1, 2, 3, 4, 5, 6]' -satLandsat8 = 'Landsat 8 OLI [bands 1, 2, 3, 4, 5, 6, 7]' -satLandsat7 = 'Landsat 7 ETM+ [bands 1, 2, 3, 4, 5, 7]' -satLandsat45 = 'Landsat 4-5 TM [bands 1, 2, 3, 4, 5, 7]' -satLandsat13 = 'Landsat 1-3 MSS [bands 4, 5, 6, 7]' -satRapidEye = 'RapidEye [bands 1, 2, 3, 4, 5]' -satSentinel1 = 'Sentinel-1 [bands VV, VH]' -satSentinel2 = 'Sentinel-2 [bands 1, 2, 3, 4, 5, 6, 7, 8, 8A, 9, 10, 11, 12]' -satSentinel3 = 'Sentinel-3 [bands 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]' -satASTER = 'ASTER [bands 1, 2, 3N, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]' -satMODIS = 'MODIS [bands 3, 4, 1, 2, 5, 6, 7]' -satMODIS2 = 'MODIS [bands 1, 2]' -satSPOT4 = 'SPOT 4 [bands 1, 2, 3, 4]' -satSPOT5 = 'SPOT 5 [bands 1, 2, 3, 4]' -satSPOT6 = 'SPOT 6 [bands 1, 2, 3, 4]' -satPleiades = 'Pleiades [bands 1, 2, 3, 4]' -satQuickBird = 'QuickBird [bands 1, 2, 3, 4]' -satWorldView23 = 'WorldView-2 -3 Multispectral [bands 1, 2, 3, 4, 5, 6, 7, 8]' -satWlList = ['', NoSatellite, satASTER, satGeoEye1, satGOES, satLandsat8, satLandsat7, satLandsat45, satLandsat13, satMODIS, satMODIS2, satPleiades, satQuickBird, satRapidEye, satSentinel2, satSentinel3, satSPOT4, satSPOT5, satSPOT6, satWorldView23] -usgsLandsat8 = 'L8 L9 OLI/TIRS' -usgsLandsat7 = 'L7 ETM+' -usgsLandsat45 = 'L4-5 TM' -usgsLandsat15 = 'L1-5 MSS' -esaSentinel2 = 'Sentinel-2' -esaSentinel3 = 'Sentinel-3' -esaSentinel1 = 'Sentinel-1' -usgsASTER = 'ASTER Level 1T' -goes16 = 'GOES 16' -goes17 = 'GOES 17' -usgsMODIS_MOD09GQ = 'MOD09GQ_V6' -usgsMODIS_MYD09GQ = 'MYD09GQ_V6' -usgsMODIS_MOD09GA = 'MOD09GA_V6' -usgsMODIS_MYD09GA = 'MYD09GA_V6' -usgsMODIS_MOD09Q1 = 'MOD09Q1_V6' -usgsMODIS_MYD09Q1 = 'MYD09Q1_V6' -usgsMODIS_MOD09A1 = 'MOD09A1_V6' -usgsMODIS_MYD09A1 = 'MYD09A1_V6' -usgsLandsat8Collection = '12864' -usgsLandsat7Collection = '12267' -usgsLandsat45Collection = '12266' -usgsLandsat15Collection = '3120' -usgsASTERCollection = '9380' -NASAMOD09GQCollection = 'C193529903-LPDAAC_ECS' -NASAMYD09GQCollection = 'C193529460-LPDAAC_ECS' -NASAMOD09GACollection = 'C193529902-LPDAAC_ECS' -NASAMYD09GACollection = 'C193529459-LPDAAC_ECS' -NASAMOD09Q1Collection = 'C193529944-LPDAAC_ECS' -NASAMYD09Q1Collection = 'C193529461-LPDAAC_ECS' -NASAMOD09A1Collection = 'C193529899-LPDAAC_ECS' -NASAMYD09A1Collection = 'C193529457-LPDAAC_ECS' -NASAASTERCollection = 'C1000000320-LPDAAC_ECS' -NASALandsat8Collection = 'C1427461962-USGS_EROS' -NASALandsat7Collection = 'C1427459680-USGS_EROS' -NASALandsat45Collection = 'C1427462674-USGS_EROS' -NASALandsat15Collection = 'C1519978054-USGS_EROS' -satSentinelList = [esaSentinel2] -satSentinel3List = [esaSentinel3] -satSentinel1List = [esaSentinel1] -satLandsatList = [usgsLandsat8, usgsLandsat7, usgsLandsat45, usgsLandsat15] -satASTERtList = [usgsASTER] -satGOEStList = [goes16, goes17] -satMODIStList = [usgsMODIS_MOD09GQ, usgsMODIS_MYD09GQ, usgsMODIS_MOD09GA, usgsMODIS_MYD09GA, usgsMODIS_MOD09Q1, usgsMODIS_MYD09Q1, usgsMODIS_MOD09A1, usgsMODIS_MYD09A1] -downProductList = satSentinelList + satSentinel3List + satSentinel1List + satLandsatList + satASTERtList + satMODIStList + satGOEStList -indNDVI = 'NDVI' -indEVI = 'EVI' -indicesList = ['', indNDVI, indEVI] -# unit list -noUnit = 'band number' -wlMicro = 'µm (1 E-6m)' -wlNano = 'nm (1 E-9m)' -unitNano = 'E-9m' -unitMicro = 'E-6m' -unitList = [noUnit, wlMicro, wlNano] -BandTabEdited = 'Yes' -rasterComboEdited = 'Yes' -tempDirName = 'semiautomaticclassification' -# USGS spectral library -usgs_C1 = 'Chapter 1: Minerals' -usgs_C2 = 'Chapter 2: Soils and Mixtures' -usgs_C3 = 'Chapter 3: Coatings' -usgs_C4 = 'Chapter 4: Liquids' -usgs_C5 = 'Chapter 5: Organics' -usgs_C6 = 'Chapter 6: Artificial' -usgs_C7 = 'Chapter 7: Vegetation and Mixtures' -usgs_lib_list = ['', usgs_C1,usgs_C2,usgs_C3,usgs_C4,usgs_C5,usgs_C6,usgs_C7] -usgs_C1p = '/spectralsignature/usgs_spectral_library/minerals.csv' -usgs_C2p = '/spectralsignature/usgs_spectral_library/soils.csv' -usgs_C3p = '/spectralsignature/usgs_spectral_library/coatings.csv' -usgs_C4p = '/spectralsignature/usgs_spectral_library/liquids.csv' -usgs_C5p = '/spectralsignature/usgs_spectral_library/organics.csv' -usgs_C6p = '/spectralsignature/usgs_spectral_library/artificial.csv' -usgs_C7p = '/spectralsignature/usgs_spectral_library/vegetation.csv' - -''' Batch ''' -workingDirNm = '!working_dir!' -tempRasterNm = '!temp_raster_' -tempDirNm = '!temp_dir!' -startForDirNm = '!for_directory_in!' -DirNm = '!directory!' -directoryName = '!directory_name!' -endForDirNm = '!end_for_directory!' -startForFileNm = '!for_file_in!' -FileNm = '!file!' -FileDirNm = '!file_directory!' -endForFileNm = '!end_for_file!' -startForBandSetNm = '!for_band_set!' -bandSetNm = '!bandset_number!' -endForBandSetNm = '!end_for_band_set!' -workingDir = None -functionNames = [] -functionNames.append([['Band set']]) -functionNames.append([[' add_new_bandset', 'cfg.batchT.performAddNewBandSet', 'cfg.bst.addBandSetTab', ['band_set : 1']]]) -functionNames.append([[' add_raster', 'cfg.batchT.performAddRaster', 'cfg.utls.addRasterOrBand', ['input_raster_path : \'\'', 'input_raster_name : \'\'', 'band_set : 1', 'center_wavelength : 1']]]) -functionNames.append([[' create_bandset', 'cfg.batchT.performBandSetCreation', 'cfg.bst.addFileToBandSet', ['raster_path_list : \'\'', 'center_wavelength : \'\'', 'wavelength_unit : 1', 'multiplicative_factor : \'\'', 'additive_factor : \'\'', 'date : \'\'']]]) -functionNames.append([[' open_training_input', 'cfg.batchT.performOpenTrainingInput', 'cfg.SCPD.openInput', ['training_file_path : \'\'']]]) -functionNames.append([[' remove_band_from_bandset', 'cfg.batchT.performRemoveBandFromBandSet', 'cfg.bst.removeBandsFromBandSet', ['band_set : 1', 'band_list : \'\'', 'unload_bands : 0']]]) -functionNames.append([[' remove_bandset', 'cfg.batchT.performRemoveBandSet', 'cfg.bst.removeBandSetTab', ['band_set : 1', 'unload_bands : 0']]]) -functionNames.append([[' select_bandset', 'cfg.batchT.performBandSetSelection', 'cfg.bst.selectBandSetTab', ['band_set : 1']]]) -functionNames.append([['Band calculation']]) -functionNames.append([[' band_calc', 'cfg.batchT.performBandCalc', 'cfg.bCalc.calculate', ['expression : \'\'', 'output_raster_path : \'\'', 'extent_same_as_raster_name : \'\'', 'align : 1', 'extent_intersection : 1', 'input_nodata_as_value : 0', 'use_value_nodata : 0', 'calculation_data_type : \'Float32\'', 'output_nodata_value : -32768', 'data_type : \'Float32\'', 'nodata_mask : 1', 'scale_value : 1', 'offset_value : 0', 'band_set : 1']]]) -functionNames.append([['Preprocessing']]) -functionNames.append([[' aster_conversion', 'cfg.batchT.performASTERConversion', 'cfg.ASTERT.ASTER', ['input_raster_path : \'\'', 'celsius_temperature : 0', 'apply_dos1 : 0', 'use_nodata : 1', 'nodata_value : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' clip_multiple_rasters', 'cfg.batchT.performClipRasters', 'cfg.clipMulti.clipRasters', ['band_set : 1', 'output_dir : \'\'', 'use_vector : 0', 'vector_path : \'\'', 'use_vector_field : 0', 'vector_field : \'\'', 'ul_x : \'\'', 'ul_y : \'\'', 'lr_x : \'\'', 'lr_y : \'\'', 'nodata_value : 0', 'output_name_prefix : \'clip\'']]]) -functionNames.append([[' cloud_masking', 'cfg.batchT.performCloudMasking', 'cfg.cloudMsk.cloudMaskingBandSet', ['band_set : 1', 'input_raster_path : \'\'', 'class_values : \'\'', 'use_buffer : 1', 'size_in_pixels : 1', 'nodata_value : 0', 'output_name_prefix : \'mask\'', 'output_dir : \'\'']]]) -functionNames.append([[' goes_conversion', 'cfg.batchT.performGOESConversion', 'cfg.goesT.GOES', ['input_dir : \'\'', 'use_nodata : 1', 'nodata_value : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' landsat_conversion', 'cfg.batchT.performLandsatConversion', 'cfg.landsatT.landsat', ['input_dir : \'\'', 'mtl_file_path : \'\'', 'celsius_temperature : 0', 'apply_dos1 : 0', 'use_nodata : 1', 'nodata_value : 0', 'pansharpening : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' modis_conversion', 'cfg.batchT.performMODISConversion', 'cfg.MODIST.MODIS', ['input_raster_path : \'\'', 'reproject_wgs84 : 1', 'use_nodata : 1', 'nodata_value : -999', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' mosaic_bandsets', 'cfg.batchT.performMosaicBandSets', 'cfg.mosaicBS.mosaicBandSets', ['band_set_list : \'\'', 'use_nodata : 1', 'nodata_value : 0', 'virtual_output : 0', 'output_dir : \'\'', 'output_name_prefix : \'mosaic\'']]]) -functionNames.append([[' neighbor_pixels', 'cfg.batchT.performNeighborPixels', 'cfg.clssNghbr.classNeighbor', ['band_set : 1', 'matrix_size : 1', 'circular : 0', 'matrix_file_path : \'\'', 'virtual_output : 0', 'output_name_prefix : \'neighbor\'', 'statistic : \'sum\'', 'stat_value : 50', 'output_dir : \'\'']]]) -functionNames.append([[' reproject_raster_bands', 'cfg.batchT.performReprojectRasters', 'cfg.rprjRstBndsT.reprojectRasters', ['band_set : 1', 'output_dir : \'\'', 'align_raster_path : \'\'', 'same_extent_reference : 0', 'epsg : \'\'','x_resolution : \'\'', 'y_resolution : \'\'', 'resample_pixel_factor : \'\'', 'resampling_method : \'near\'', 'output_nodata_value : -32768', 'data_type : \'auto\'', 'output_name_prefix : \'reproj\'']]]) -functionNames.append([[' sentinel1_conversion', 'cfg.batchT.performSentinel1Conversion', 'cfg.sentinel1T.sentinel1', ['input_raster_path : \'\'', 'xml_file_path : \'\'', 'vh : 1', 'vv : 1', 'raster_project : 0', 'raster_projections_band_set : 1', 'convert_to_db : 1', 'use_nodata : 1', 'nodata_value : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' sentinel2_conversion', 'cfg.batchT.performSentinel2Conversion', 'cfg.sentinel2T.sentinel2', ['input_dir : \'\'', 'mtd_safl1c_file_path : \'\'', 'apply_dos1 : 0', 'preprocess_bands_1_9_10 : 0', 'use_nodata : 1', 'nodata_value : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' sentinel3_conversion', 'cfg.batchT.performSentinel3Conversion', 'cfg.sentinel3T.sentinel3', ['input_dir : \'\'', 'apply_dos1 : 0', 'use_nodata : 1', 'nodata_value : 0', 'create_bandset : 1', 'output_dir : \'\'', 'band_set : 1']]]) -functionNames.append([[' vector_to_raster', 'cfg.batchT.performVectorToRaster', 'cfg.vctRstrT.convertToRaster', ['vector_file_path : \'\'', 'use_value_field : 1', 'vector_field_name : \'\'', 'constant_value : 1', 'reference_raster_path : \'\'', 'extent_same_as_reference : 0', 'type_of_conversion : \'Center of pixels\'', 'output_raster_path : \'\'']]]) -functionNames.append([[' split_raster_bands', 'cfg.batchT.performSplitRaster', 'cfg.splitT.splitRasterToBands', ['input_raster_path : \'\'', 'output_dir : \'\'', 'output_name_prefix : \'split\'']]]) -functionNames.append([[' stack_raster_bands', 'cfg.batchT.performStackRaster', 'cfg.stackRstr.stackRasters', ['band_set : 1', 'output_raster_path : \'\'']]]) -functionNames.append([['Band processing']]) -functionNames.append([[' band_combination', 'cfg.batchT.performBandCombination', 'cfg.bsComb.bandSetCombination', ['band_set : 1', 'output_raster_path : \'\'']]]) -functionNames.append([[' classification', 'cfg.batchT.performClassification', 'cfg.classTab.runClassification', ['band_set : 1', 'use_macroclass : 0', 'algorithm_name : \'Minimum Distance\'', 'use_lcs : 0', 'use_lcs_algorithm : 0', 'use_lcs_only_overlap : 0', 'apply_mask : 0', 'mask_file_path : \'\'', 'vector_output : 0', 'classification_report : 0', 'save_algorithm_files : 0', 'output_classification_path : \'\'']]]) -functionNames.append([[' clustering', 'cfg.batchT.performClustering', 'cfg.clusteringT.calculateClustering', ['band_set : 1','clustering_method : 1', 'use_distance_threshold : 1', 'threshold_value : 0.0001', 'number_of_classes : 10', 'max_iterations : 10', 'isodata_max_std_dev : 0.0001', 'isodata_min_class_size : 10', 'use_nodata : 0', 'nodata_value : 0', 'seed_signatures : 1', 'distance_algorithm : 1', 'save_signatures : 0', 'output_raster_path : \'\'']]]) -functionNames.append([[' pca', 'cfg.batchT.performPCA', 'cfg.pcaT.calculatePCA', ['band_set : 1', 'use_number_of_components : 0', 'number_of_components : 2', 'use_nodata : 1', 'nodata_value : 0', 'output_dir : \'\'']]]) -functionNames.append([[' random_forest', 'cfg.batchT.performRandomForest', 'cfg.rndmFrst.randomForestClassification', ['band_set : 1', 'use_macroclass : 1', 'number_training_samples : 5000', 'number_trees : 10', 'evaluate_classifier : 0', 'evaluate_feature_power_set : 0', 'min_power : 2', 'max_power : 7', 'save_classifier : 0', 'classifier_file_path : \'\'', 'output_classification_path : \'\'']]]) -functionNames.append([[' spectral_distance', 'cfg.batchT.performSpectralDistance', 'cfg.spclDstBS.spectralDistBandSets', ['first_band_set : 1', 'second_band_set : 2', 'distance_algorithm : 1', 'use_distance_threshold : 1', 'threshold_value : 0.1', 'output_raster_path : \'\'']]]) -functionNames.append([['Postprocessing']]) -functionNames.append([[' accuracy', 'cfg.batchT.performAccuracy', 'cfg.acc.errorMatrix', ['classification_file_path : \'\'', 'reference_file_path : \'\'', 'vector_field_name : \'\'', 'output_raster_path : \'\'', 'use_value_nodata : 0']]]) -functionNames.append([[' class_signature', 'cfg.batchT.performClassSignature', 'cfg.classSigT.calculateClassSignature', ['input_raster_path : \'\'', 'band_set : 1', 'save_signatures : 1', 'output_text_path : \'\'']]]) -functionNames.append([[' classification_dilation', 'cfg.batchT.performClassificationDilation', 'cfg.dltnRstr.dilationClassification', ['input_raster_path : \'\'', 'class_values : \'\'', 'size_in_pixels : 1', 'circular : 0', 'output_raster_path : \'\'']]]) -functionNames.append([[' classification_erosion', 'cfg.batchT.performClassificationErosion', 'cfg.ersnRstr.erosionClassification', ['input_raster_path : \'\'', 'class_values : \'\'', 'size_in_pixels : 1', 'circular : 0', 'output_raster_path : \'\'']]]) -functionNames.append([[' classification_report', 'cfg.batchT.performClassificationReport', 'cfg.classRep.calculateClassificationReport', ['input_raster_path : \'\'', 'use_nodata : 0', 'nodata_value : 0', 'output_report_path : \'\'']]]) -functionNames.append([[' classification_sieve', 'cfg.batchT.performClassificationSieve', 'cfg.sieveRstr.sieveClassification', ['input_raster_path : \'\'', 'size_threshold : 2', 'pixel_connection : 4', 'output_raster_path : \'\'']]]) -functionNames.append([[' classification_to_vector', 'cfg.batchT.performClassificationToVector', 'cfg.classVect.convertClassificationToVector', ['input_raster_path : \'\'', 'use_signature_list_code : 0', 'code_field : \'C_ID\'', 'dissolve_output : 0', 'output_vector_path : \'\'']]]) -functionNames.append([[' cross_classification', 'cfg.batchT.performCrossClassification', 'cfg.crossC.crossClassification', ['classification_file_path : \'\'', 'use_nodata : 0', 'nodata_value : 0', 'reference_file_path : \'\'', 'vector_field_name : \'\'', 'output_raster_path : \'\'', 'regression : 0']]]) -functionNames.append([[' edit_raster_using_vector', 'cfg.batchT.performEditRasterUsingVector', 'cfg.editRstr.setRasterValue', ['input_raster_path : \'\'', 'input_vector_path : \'\'', 'vector_field_name : \'\'', 'constant_value : 0', 'expression : \'where(raster == 1, 2, raster)\'']]]) -functionNames.append([[' land_cover_change', 'cfg.batchT.performLandCoverChange', 'cfg.landCC.landCoverChange', ['reference_raster_path : \'\'', 'new_raster_path : \'\'', 'output_raster_path : \'\'']]]) -functionNames.append([[' reclassification', 'cfg.batchT.performReclassification', 'cfg.reclassification.reclassify', ['input_raster_path : \'\'', 'value_list : \'oldVal_newVal,oldVal_newVal\'', 'use_signature_list_code : 1', 'code_field : \'MC_ID\'', 'output_raster_path : \'\'']]]) -functionNames.append([[' zonal_stat_raster', 'cfg.batchT.performZonalStatRaster', 'cfg.znlSttRstT.zonalStatRaster', ['input_raster_path : \'\'', 'reference_file_path : \'\'', 'use_nodata : 0', 'nodata_value : 0', 'vector_field_name : \'\'', 'statistic : \'sum\'', 'stat_value : 50', 'output_raster_path : \'\'']]]) -functionNames.append([['Variables']]) -functionNames.append([[' ' + workingDirNm, 'cfg.batchT.workingDirectory', '', ['\'\'']]]) -functionNames.append([[' ' + startForDirNm, '', '', ['\'\'']]]) -functionNames.append([[' ' + DirNm, '', '', []]]) -functionNames.append([[' ' + directoryName, '', '', []]]) -functionNames.append([[' ' + endForDirNm, '', '', []]]) -functionNames.append([[' ' + startForFileNm, '', '', ['\'\'']]]) -functionNames.append([[' ' + FileNm, '', '', []]]) -functionNames.append([[' ' + FileDirNm, '', '', []]]) -functionNames.append([[' ' + endForFileNm, '', '', []]]) -functionNames.append([[' ' + startForBandSetNm, '', '', ['\'\'']]]) -functionNames.append([[' ' + bandSetNm, '', '', []]]) -functionNames.append([[' ' + endForBandSetNm, '', '', []]]) -functionNames.append([[' ' + tempRasterNm + '1!', '', '', []]]) -functionNames.append([[' ' + tempDirNm, '', '', []]]) -functionNames.append([['Functions']]) -functionNames.append([[' process_settings', 'cfg.batchT.processSettings', 'cfg.sets.setProcessSetting', ['threads : 2', 'ram : 512']]]) -functionNames.append([[' send_notification', 'cfg.batchT.performSendNotification', 'cfg.utls.sendSMTPMessage', ['subject : \'\'', 'message : \'\'']]]) +reg_window_size_w = 'SemiAutomaticClassificationPlugin/window_size_width' +qgis_registry[reg_window_size_w] = 700 +reg_window_size_h = 'SemiAutomaticClassificationPlugin/window_size_height' +qgis_registry[reg_window_size_h] = 500 +reg_splitter_sizes = 'SemiAutomaticClassificationPlugin/splitter_sizes' +qgis_registry[reg_splitter_sizes] = [100, 100] -''' Scatter plot ''' -scatterColorMap = ['rainbow', 'gist_rainbow', 'jet', 'afmhot', 'bwr', 'gnuplot', 'gnuplot2', 'BrBG', 'coolwarm', 'PiYG', 'PRGn', 'PuOr', 'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'Spectral', 'seismic', 'ocean', 'terrain', 'Blues', 'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd', 'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu', 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd'] +""" band calc """ +map_extent = '\'Map extent\'' +union_extent = '\'Union\'' +intersection_extent = '\'Intersection\'' +custom_extent = '\'Custom\'' +default_align = '\'Default\'' +band_calc_functions = [ + ['+', ' + '], ['-', ' - '], ['/', ' / '], ['*', ' * '], ['==', ' == '], + ['!=', ' != '], ['<', ' < '], ['>', ' > '], ['(', '('], [')', ')'], + ['^', '^'], ['√', 'sqrt('], ['Conditional'], ['where', 'where('], + ['Logical'], ['AND', '&'], ['OR', '|'], ['XOR', '^'], ['NOT', '~'], + ['Statistics'], ['max', 'max('], ['min', 'min('], ['mean', 'mean('], + ['median', 'median('], ['percentile', 'percentile('], ['std', 'std('], + ['sum', 'sum('], ['Operations'], ['sin', 'sin('], ['cos', 'cos('], + ['tan', 'tan('], ['asin', 'asin('], ['acos', 'acos('], ['atan', 'atan('], + ['exp', 'exp('], ['ln', 'ln('], ['log10', 'log10('], ['Indices'], + ['NDVI', '( "#NIR#" - "#RED#" ) / ( "#NIR#" + "#RED#" ) @NDVI'], + ['EVI', '2.5# ( "#NIR#" - "#RED#" ) / ' + '( "#NIR#" + 6# "#RED#" - 7.5# "#BLUE#" + 1) @EVI' + ], ['NBR', '( "#NIR#" - "#SWIR2#" ) / ( "#NIR#" + "#SWIR2#" ) @NBR'], + ['Variables'], ['nodata', 'nodata('], + ['forbandsets', 'forbandsets[ ]'], + ['forbandsinbandset', 'forbandsinbandset[ ]'], + ['#BAND#', '#BAND#'], ['#BANDSET#', '#BANDSET#'], + ['#DATE#', '#DATE#'], ['@', '@'], ['Custom'] +] -''' Input toolbar ''' -toolButton_reload = None -main_toolButton = None -bandset_toolButton = None -ROItools_toolButton = None -preprocessing_toolButton = None -postprocessing_toolButton = None -settings_toolButton = None -settings_toolButton = None \ No newline at end of file +""" Scatter plot """ +# noinspection SpellCheckingInspection +scatter_color_map = [ + '', 'rainbow', 'gist_rainbow', 'jet', 'afmhot', 'bwr', 'gnuplot', + 'gnuplot2', 'BrBG', 'coolwarm', 'PiYG', 'PRGn', 'PuOr', 'RdBu', 'RdGy', + 'RdYlBu', 'RdYlGn', 'Spectral', 'seismic', 'ocean', 'terrain', 'Blues', + 'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd', 'PuBu', + 'PuBuGn', 'PuRd', 'Purples', 'RdPu', 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', + 'YlOrRd' +] diff --git a/core/input.py b/core/input.py deleted file mode 100644 index 123a0cc..0000000 --- a/core/input.py +++ /dev/null @@ -1,581 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) -try: - _fromUtf8 = cfg.QtCoreSCP.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s - -class Input: - -################################## - ''' Input functions ''' -################################## - - # check refresh raster and image list - def checkRefreshRasterLayer(self): - # check if other processes are active - if cfg.actionCheck == 'No': - self.refreshRasterLayer() - - def raster_layer_combo(self, layer): - cfg.ui.image_raster_name_combo.addItem(layer) - - # refresh raster and image list - def refreshRasterLayer(self): - cfg.ui.image_raster_name_combo.blockSignals(True) - cfg.rasterComboEdited = 'No' - lL = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.image_raster_name_combo.clear() - # empty item for new band set - self.raster_layer_combo('') - for l in sorted(lL, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() > 1 and cfg.bndSetVrtNm not in l.name(): - self.raster_layer_combo(l.name()) - cfg.rasterComboEdited = 'Yes' - cfg.ui.image_raster_name_combo.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster layers refreshed') - -################################## - ''' Interface functions ''' -################################## - - def loadInputToolbar(self): - cfg.toolBar2 = cfg.iface.addToolBar('SCP Working Toolbar') - cfg.toolBar2.setObjectName('SCP Working Toolbar') - cfg.toolBar3 = cfg.iface.addToolBar('SCP Edit Toolbar') - cfg.toolBar3.setObjectName('SCP Edit Toolbar') - self.loadToolbar2() - self.loadToolbarEditRaster() - self.setSCPDockTabs() - - # SCP Working Toolbar - def loadToolbar2(self): - cfg.main_toolButton = cfg.ipt.addToolbarAction(self.showPlugin, 'semiautomaticclassificationplugin.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Semi-Automatic Classification Plugin')) - # button zoom to image - cfg.zoomToImage = cfg.ipt.addToolbarAction(cfg.utls.zoomToBandset, 'semiautomaticclassificationplugin_zoom_to_Image.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zoom to input image extent')) - # radio button show hide input image - cfg.inputImageRadio = cfg.ipt.addToolbarRadio(cfg.utls.showHideInputImage, cfg.QtWidgetsSCP.QApplication.translate('SemiAutomaticClassificationPlugin', 'RGB = ', None), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Show/hide the input image')) - # combo RGB composite - cfg.rgb_combo = cfg.QtWidgetsSCP.QComboBox(cfg.iface.mainWindow()) - cfg.rgb_combo.setFixedWidth(80) - cfg.rgb_combo.setEditable(True) - rgb_comboAction = cfg.toolBar2.addWidget(cfg.rgb_combo) - cfg.rgb_combo.setToolTip(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a RGB color composite')) - cfg.rgb_combo.currentIndexChanged.connect(cfg.utls.setRGBColorComposite) - # local cumulative cut stretch button - cfg.local_cumulative_stretch_toolButton = cfg.ipt.addToolbarAction(cfg.utls.setRasterCumulativeStretch, 'semiautomaticclassificationplugin_bandset_cumulative_stretch_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Local cumulative cut stretch of band set')) - # local standard deviation stretch button - cfg.local_std_dev_stretch_toolButton = cfg.ipt.addToolbarAction(cfg.utls.setRasterStdDevStretch, 'semiautomaticclassificationplugin_bandset_std_dev_stretch_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Local standard deviation stretch of band set')) - # button zoom to ROI - cfg.zoomToTempROI = cfg.ipt.addToolbarAction(cfg.SCPD.zoomToTempROI, 'semiautomaticclassificationplugin_zoom_to_ROI.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zoom to temporary ROI')) - # radio button show hide ROI - cfg.show_ROI_radioButton = cfg.ipt.addToolbarRadio(cfg.SCPD.showHideROI, cfg.QtWidgetsSCP.QApplication.translate('SemiAutomaticClassificationPlugin', 'ROI ', None), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Show/hide the temporary ROI')) - # manual ROI pointer - cfg.polygonROI_Button = cfg.ipt.addToolbarAction(cfg.SCPD.pointerManualROIActive, 'semiautomaticclassificationplugin_manual_ROI.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Create a ROI polygon')) - # pointer button - cfg.pointerButton = cfg.ipt.addToolbarAction(cfg.SCPD.pointerROIActive, 'semiautomaticclassificationplugin_roi_single.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Activate ROI pointer')) - # redo button - cfg.redo_ROI_Button = cfg.ipt.addToolbarAction(cfg.SCPD.redoROI, 'semiautomaticclassificationplugin_roi_redo.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Redo the ROI at the same point')) - cfg.redo_ROI_Button.setEnabled(False) - # spinbox spectral distance - lblSpectralDistance = cfg.ipt.addToolbarLabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Dist'), 'Yes') - lblSpectralDistance.setStyleSheet(_fromUtf8('background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #535353, stop:1 #535353); color : white')) - cfg.Range_radius_spin = cfg.ipt.addToolbarSpin(cfg.SCPD.rangeRadius, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Similarity of pixels (distance in radiometry unit)'), 6, 1e-06, 10000.0, 0.001, 0.01) - # spinbox min size - lblmin= cfg.ipt.addToolbarLabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Min'), 'Yes') - lblmin.setStyleSheet(_fromUtf8('background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #535353, stop:1 #535353); color : white')) - cfg.Min_region_size_spin = cfg.ipt.addToolbarSpin(cfg.SCPD.minROISize, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Minimum area of ROI (in pixel unit)'), 0, 1, 10000, 1, 60, 60) - # spinbox max size - lblmax = cfg.ipt.addToolbarLabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Max'), 'Yes') - lblmax.setStyleSheet(_fromUtf8('background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #535353, stop:1 #535353); color : white')) - cfg.Max_ROI_width_spin = cfg.ipt.addToolbarSpin(cfg.SCPD.maxROIWidth, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit)'), 0, 1, 10000, 1, int(cfg.maxROIWdth), 60) - # button zoom to preview - cfg.zoomToTempPreview = cfg.ipt.addToolbarAction(cfg.SCPD.zoomToPreview, 'semiautomaticclassificationplugin_zoom_to_preview.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zoom to the classification preview')) - # radio button show hide preview - cfg.show_preview_radioButton2 = cfg.ipt.addToolbarRadio(cfg.SCPD.showHidePreview2, cfg.QtWidgetsSCP.QApplication.translate('SemiAutomaticClassificationPlugin', 'Preview ', None), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Show/hide the classification preview')) - # preview pointer button - cfg.pointerPreviewButton = cfg.ipt.addToolbarAction(cfg.SCPD.pointerPreviewActive, 'semiautomaticclassificationplugin_preview.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Activate classification preview pointer')) - cfg.redoPreviewButton = cfg.ipt.addToolbarAction(cfg.SCPD.redoPreview, 'semiautomaticclassificationplugin_preview_redo.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Redo the classification preview at the same point')) - cfg.redoPreviewButton.setEnabled(False) - # spinbox transparency - lblT = cfg.ipt.addToolbarLabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' T'), 'Yes') - lblT.setStyleSheet(_fromUtf8('background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #535353, stop:1 #535353); color : white')) - cfg.preview_transp_spin = cfg.ipt.addToolbarSpin(cfg.SCPD.changePreviewTransparency, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Set preview transparency'), 0, 0, 100, 10, 0, 50) - # spinbox size - lblS = cfg.ipt.addToolbarLabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' S'), 'Yes') - lblS.setStyleSheet(_fromUtf8('background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #535353, stop:1 #535353); color : white')) - cfg.preview_size_spinBox = cfg.ipt.addToolbarSpin(cfg.SCPD.previewSize, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Set the preview size (in pixel unit)'), 0, 1, 1000000, 100, float(cfg.prvwSz), 60) - cfg.removeTempFilesButton = cfg.ipt.addToolbarAction(cfg.utls.removeTempFiles, 'semiautomaticclassificationplugin_remove_temp.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Remove temporary files')) - cfg.createKMLButton = cfg.ipt.addToolbarAction(cfg.utls.createKMLFromMap, 'semiautomaticclassificationplugin_kml_add.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Create KML')) - - # add spinbox - def addToolbarSpin(self, function, tooltip, decimals, min, max, step, value, width = 100): - spin = cfg.QtWidgetsSCP.QDoubleSpinBox(cfg.iface.mainWindow()) - spin.setFixedWidth(width) - spin.setDecimals(decimals) - spin.setMinimum(min) - spin.setMaximum(max) - spin.setSingleStep(step) - spin.setProperty('value', value) - spin.setToolTip(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', tooltip)) - Range_radiusAction = cfg.toolBar2.addWidget(spin) - spin.valueChanged.connect(function) - return spin - - # add spinbox - def addEditToolbarSpin(self, function, tooltip, decimals, min, max, step, value, width = 100): - spin = cfg.QtWidgetsSCP.QDoubleSpinBox(cfg.iface.mainWindow()) - spin.setFixedWidth(width) - spin.setDecimals(decimals) - spin.setMinimum(min) - spin.setMaximum(max) - spin.setSingleStep(step) - spin.setProperty('value', value) - spin.setToolTip(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', tooltip)) - Range_radiusAction = cfg.toolBar3.addWidget(spin) - #spin.valueChanged.connect(function) - return spin - - # add radio button - def addToolbarRadio(self, function, text, tooltip): - radio = cfg.QtWidgetsSCP.QRadioButton(cfg.iface.mainWindow()) - inputImageRadio_comboAction = cfg.toolBar2.addWidget(radio) - radio.setToolTip(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', tooltip)) - radio.setStyleSheet(_fromUtf8('background-color : #656565; color : white')) - radio.setText(cfg.QtWidgetsSCP.QApplication.translate('SemiAutomaticClassificationPlugin', text, None)) - radio.setChecked(True) - radio.setAutoExclusive(False) - radio.clicked.connect(function) - return radio - - # add label to toolbar - def addToolbarLabel(self, text, black = None, width = None): - font = cfg.QtGuiSCP.QFont() - font.setFamily(_fromUtf8('FreeSans')) - font.setBold(True) - font.setWeight(75) - lbl = cfg.QtWidgetsSCP.QLabel(cfg.iface.mainWindow()) - lbl.setFont(font) - if black is None: - lbl.setStyleSheet(_fromUtf8('background-color : #656565; color : white')) - else: - lbl.setStyleSheet(_fromUtf8('color : black')) - lbl.setObjectName(_fromUtf8('lbl')) - if width is not None: - lbl.setFixedWidth(width) - lbl.setMaximumHeight(18) - lbl.setText(cfg.QtWidgetsSCP.QApplication.translate('SemiAutomaticClassificationPlugin', text, None)) - cfg.toolBar2.addWidget(lbl) - return lbl - - # SCP Edit raster - def loadToolbarEditRaster(self): - cfg.editRasterToolbar_toolButton = cfg.ipt.addToolbarEditAction(cfg.utls.editRasterTab, 'semiautomaticclassificationplugin_edit_raster.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Edit raster')) - # spinbox value 0 - cfg.val0_spin = cfg.ipt.addEditToolbarSpin(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Value 0'), 0, -10000, 10000, 1, 0, 60) - cfg.setVal0_toolButton = cfg.ipt.addToolbarEditAction(cfg.editRstr.toolbarValue0, 'semiautomaticclassificationplugin_enter.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Set value 0')) - # spinbox value 1 - cfg.val1_spin = cfg.ipt.addEditToolbarSpin(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Value 1'), 0, -10000, 10000, 1, 1, 60) - cfg.setVal1_toolButton = cfg.ipt.addToolbarEditAction(cfg.editRstr.toolbarValue1, 'semiautomaticclassificationplugin_enter.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Set value 1')) - # spinbox value 2 - cfg.val2_spin = cfg.ipt.addEditToolbarSpin(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Value 2'), 0, -10000, 10000, 1, 2, 60) - cfg.setVal2_toolButton = cfg.ipt.addToolbarEditAction(cfg.editRstr.toolbarValue2, 'semiautomaticclassificationplugin_enter.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Set value 2')) - cfg.undoEditRasterToolbar_toolButton = cfg.ipt.addToolbarEditAction(cfg.editRstr.undoEdit, 'semiautomaticclassificationplugin_undo_edit_raster.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Undo edit (only for ROI polygons)')) - cfg.undoEditRasterToolbar_toolButton.setEnabled(False) - - # Add toolbar action - def addToolbarAction(self, function, iconName, tooltip): - action = cfg.QtWidgetsSCP.QAction(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/' + iconName), tooltip, cfg.iface.mainWindow()) - action.setToolTip(tooltip) - action.triggered.connect(function) - cfg.toolBar2.addAction(action) - return action - - # Add toolbar button - def addToolbar2Button(self, function, iconName, tooltip): - toolButton = cfg.QtWidgetsSCP.QPushButton(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/' + iconName), '') - toolButton.setStyleSheet(' border: none;margin: 2px;icon-size: 24px; color: black') - toolButton.setToolTip(tooltip) - cfg.toolBar2.addWidget(toolButton) - toolButton.clicked.connect(function) - return toolButton - - # Add toolbar button - def addToolbarEditAction(self, function, iconName, tooltip): - action = cfg.QtWidgetsSCP.QAction(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/' + iconName), tooltip, cfg.iface.mainWindow()) - action.setToolTip(tooltip) - action.triggered.connect(function) - cfg.toolBar3.addAction(action) - return action - - # show plugin - def showPlugin(self): - # close the dialog - cfg.dlg.close() - self.activateDocks() - # show the dialog - cfg.dlg.show() - - # activate docks - def activateDocks(self): - cfg.dockclassdlg.show() - cfg.toolBar2.show() - cfg.toolBar3.show() - - # user manual - def quickGuide(self): - cfg.QtGuiSCP.QDesktopServices().openUrl(cfg.QtCoreSCP.QUrl('https://fromgistors.blogspot.com/p/user-manual.html?spref=scp')) - - # help - def askHelp(self): - cfg.QtGuiSCP.QDesktopServices().openUrl(cfg.QtCoreSCP.QUrl('https://fromgistors.blogspot.com/p/online-help.html?spref=scp')) - - # support SCP - def supportSCP(self): - cfg.QtGuiSCP.QDesktopServices().openUrl(cfg.QtCoreSCP.QUrl('https://fromgistors.blogspot.com/p/support-scp.html?spref=scp')) - - # add item to menu - def addMenuItem(self, menu, function, iconName, name): - try: - action = cfg.QtWidgetsSCP.QAction(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/' + iconName), name, cfg.iface.mainWindow()) - except: - action = cfg.QtWidgetsSCP.QAction(name, cfg.iface.mainWindow()) - action.setObjectName('action') - action.triggered.connect(function) - menu.addAction(action) - return action - - # load SCP menu - def loadMenu(self): - cfg.menu = cfg.QtWidgetsSCP.QMenu(cfg.iface.mainWindow()) - cfg.menu.setObjectName('semiautomaticclassificationplugin') - cfg.menu.setTitle(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SCP')) - menuBar = cfg.iface.mainWindow().menuBar() - menuBar.insertMenu(cfg.iface.firstRightStandardMenu().menuAction(), cfg.menu) - # Band set - bandset_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.bandSetTab, 'semiautomaticclassificationplugin_bandset_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set')) - # Band tools - cfg.basic_tools_menu = cfg.menu.addMenu(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Basic tools')) - # Algorithm band weight - algorithm_weight_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.algorithmBandWeightTab, 'semiautomaticclassificationplugin_weight_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Algorithm band weight')) - # Band set list - Band_set_list_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.BandSetListTab, 'semiautomaticclassificationplugin_bandset_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set list')) - # Export Spectral Library - export_spectral_library_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.exportSignaturesTab, 'semiautomaticclassificationplugin_export_spectral_library.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export signatures')) - # Import Spectral Library - import_spectral_library_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.importSignaturesTab, 'semiautomaticclassificationplugin_import_spectral_library.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import signatures')) - # LCS threshold - LCS_threshold_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.LCSThresholdTab, 'semiautomaticclassificationplugin_LCS_threshold_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'LCS threshold')) - # Multiple ROI creation - multiple_ROI_creation_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.multipleROICreationTab, 'semiautomaticclassificationplugin_roi_multiple.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Multiple ROI creation')) - # RGB list - RGB_list_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.RGBListTab, 'semiautomaticclassificationplugin_rgb_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'RGB list')) - # Signature threshold - signature_threshold_action = cfg.ipt.addMenuItem(cfg.basic_tools_menu, cfg.utls.signatureThresholdTab, 'semiautomaticclassificationplugin_threshold_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signature threshold')) - # Download - cfg.download_products_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.downloadProductsTab, 'semiautomaticclassificationplugin_download_arrow.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Download products')) - # Preprocessing - cfg.preprocessing_menu = cfg.menu.addMenu(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Preprocessing')) - # ASTER - aster_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.asterTab, 'semiautomaticclassificationplugin_aster_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ASTER')) - # GOES - GOES_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.GOESTab, 'semiautomaticclassificationplugin_goes_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'GOES')) - # Landsat - landsat_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.landsatTab, 'semiautomaticclassificationplugin_landsat8_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Landsat')) - # MODIS - modis_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.modisTab, 'semiautomaticclassificationplugin_modis_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'MODIS')) - # Sentinel-1 - sentinel1_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.sentinel1Tab, 'semiautomaticclassificationplugin_sentinel1_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-1')) - # Sentinel-2 - sentinel2_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.sentinel2Tab, 'semiautomaticclassificationplugin_sentinel_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-2')) - # Sentinel-3 - sentinel3_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.sentinel3Tab, 'semiautomaticclassificationplugin_sentinel3_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-3')) - # Clip multiple rasters - clip_multiple_rasters_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.clipMultipleRastersTab, 'semiautomaticclassificationplugin_clip_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clip multiple rasters')) - # Cloud masking - cloud_mask_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.cloudMaskingTab, 'semiautomaticclassificationplugin_cloud_masking_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cloud masking')) - # Mosaic bands - mosaic_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.mosaicBandSetsTab, 'semiautomaticclassificationplugin_mosaic_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Mosaic band sets')) - # Pixel neighbor bands - neighbor_pixels_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.neighborPixelsTab, 'semiautomaticclassificationplugin_neighbor_pixels.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Neighbor pixels')) - # reproject raster bands - reproject_raster_bands_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.reprojectrasterbandsTab, 'semiautomaticclassificationplugin_reproject_raster_bands.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reproject raster bands')) - # Split raster bands - split_raster_bands_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.splitrasterbandsTab, 'semiautomaticclassificationplugin_split_raster.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Split raster bands')) - # Stack raster bands - stack_raster_bands_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.stackrasterbandsTab, 'semiautomaticclassificationplugin_stack_raster.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Stack raster bands')) - # Vector to raster - vector_to_raster_action = cfg.ipt.addMenuItem(cfg.preprocessing_menu, cfg.utls.vectorToRasterTab, 'semiautomaticclassificationplugin_vector_to_raster_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Vector to raster')) - # Band processing - cfg.band_processing_menu = cfg.menu.addMenu(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band processing')) - # Band combination - band_combination_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.bandCombinationTab, 'semiautomaticclassificationplugin_band_combination_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band combination')) - # Classification - classification_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.classificationTab, 'semiautomaticclassificationplugin_classification.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification')) - # k-means - Kmeans_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.clusteringTab, 'semiautomaticclassificationplugin_kmeans_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clustering')) - # PCA - PCA_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.PCATab, 'semiautomaticclassificationplugin_pca_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PCA')) - # Random forest - randomForest_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.randomForestTab, 'semiautomaticclassificationplugin_random_forest.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Random forest')) - # spectral distance - spectral_distance_action = cfg.ipt.addMenuItem(cfg.band_processing_menu, cfg.utls.spectralDistanceTab, 'semiautomaticclassificationplugin_spectral_distance.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral distance')) - # Postprocessing - cfg.postprocessing_menu = cfg.menu.addMenu(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Postprocessing')) - # Accuracy - accuracy_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.accuracyTab, 'semiautomaticclassificationplugin_accuracy_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Accuracy')) - # Classification dilation - classification_dilation_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classificationDilationTab, 'semiautomaticclassificationplugin_classification_dilation.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification dilation')) - # Classification erosion - classification_erosion_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classificationErosionTab, 'semiautomaticclassificationplugin_classification_erosion.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification erosion')) - # Classification report - classification_report_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classificationReportTab, 'semiautomaticclassificationplugin_report_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification report')) - # Classification to vector - class_to_vector_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classificationToVectorTab, 'semiautomaticclassificationplugin_class_to_vector_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification to vector')) - # Classification sieve - classification_sieve_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classificationSieveTab, 'semiautomaticclassificationplugin_classification_sieve.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification sieve')) - # Class signature - class_signature = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.classSignatureTab, 'semiautomaticclassificationplugin_class_signature_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Class signature')) - # Cross classification - cross_classification_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.crossClassificationTab, 'semiautomaticclassificationplugin_cross_classification.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cross classification')) - # Edit raster - edit_raster_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.editRasterTab, 'semiautomaticclassificationplugin_edit_raster.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Edit raster')) - # Land cover change - land_cover_change_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.landCoverChangeTab, 'semiautomaticclassificationplugin_land_cover_change.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Land cover change')) - # Reclassification - reclassification_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.reclassificationTab, 'semiautomaticclassificationplugin_reclassification_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reclassification')) - # Zonal stat raster - zonal_stat_raster_action = cfg.ipt.addMenuItem(cfg.postprocessing_menu, cfg.utls.zonalStatRasterTab, 'semiautomaticclassificationplugin_zonal_stat_raster_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zonal stat raster')) - # Band calc - bandcalc_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.bandCalcTab, 'semiautomaticclassificationplugin_bandcalc_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band calc')) - # batch - batch_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.batchTab, 'semiautomaticclassificationplugin_batch.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Batch')) - # Settings - cfg.settings_menu = cfg.menu.addMenu(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_settings_tool.svg'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Settings')) - # Settings debug - settings_debug_action = cfg.ipt.addMenuItem(cfg.settings_menu, cfg.utls.debugTab, None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Debug')) - # Settings interface - settings_interface_action = cfg.ipt.addMenuItem(cfg.settings_menu, cfg.utls.interfaceTab, None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Interface')) - # Settings processing - settings_processing_action = cfg.ipt.addMenuItem(cfg.settings_menu, cfg.utls.processingSettingTab, None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing setting')) - # Spectral plot - spectral_plot_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.spectralPlotTab, 'semiautomaticclassificationplugin_sign_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral plot')) - # scatter plot - scatter_plot_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.scatterPlotTab, 'semiautomaticclassificationplugin_scatter_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Scatter plot')) - # User manual - userguide_action = cfg.ipt.addMenuItem(cfg.menu, cfg.ipt.quickGuide, 'guide.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'User manual')) - # help - help_action = cfg.ipt.addMenuItem(cfg.menu, cfg.ipt.askHelp, 'help.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Online help')) - # About - about_action = cfg.ipt.addMenuItem(cfg.menu, cfg.utls.aboutTab, 'fromGIStoRS.png', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'About')) - # show plugin - show_action = cfg.ipt.addMenuItem(cfg.menu, self.showPlugin, 'semiautomaticclassificationplugin_docks.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Show plugin')) - - # set SCP dock tabs buttons - def setSCPDockTabs(self): - icons = [':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process', ':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool'] - for i in range(3, 10): - lbl = cfg.QtWidgetsSCP.QLabel() - lbl.setStyleSheet(_fromUtf8('color : black')) - lbl.setObjectName(_fromUtf8('lbl')) - lbl.setPixmap(cfg.QtGuiSCP.QPixmap(icons[i-3]).scaled(24,24,cfg.QtSCP.KeepAspectRatio)) - lbl.setAlignment(cfg.QtSCP.AlignCenter) - cfg.uidc.tabWidget_dock.tabBar().setTabButton(i, cfg.QtWidgetsSCP.QTabBar.LeftSide, lbl) - - # dock tab index - def dockTabChanged(self, index): - if index > 2: - cfg.ui.SCP_tabs.setCurrentIndex(index - 3) - t = cfg.ui.menu_treeWidget - r = t.invisibleRootItem() - t.blockSignals(True) - # unselect all - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - c.setSelected(False) - for x in range(0, c.childCount()): - c.child(x).setHidden(False) - c.child(x).setSelected(False) - c = r.child(index - 3) - c.setSelected(True) - c.setExpanded(True) - t.blockSignals(False) - cfg.uidc.tabWidget_dock.blockSignals(True) - cfg.uidc.tabWidget_dock.setCurrentIndex(cfg.dockIndex) - cfg.uidc.tabWidget_dock.blockSignals(False) - cfg.dlg.close() - cfg.dlg.show() - else: - cfg.dockIndex = cfg.uidc.tabWidget_dock.currentIndex() - - # menu tab - def treeMenuTab(self): - t = cfg.ui.menu_treeWidget - r = t.invisibleRootItem() - t.blockSignals(True) - # unselect all - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - if c.text(0).lower().replace(' ', '').replace('-', '') == cfg.currentTab[0:-3].lower(): - c.setSelected(True) - c.setExpanded(True) - else: - c.setSelected(False) - for x in range(0, c.childCount()): - c.child(x).setHidden(False) - if c.child(x).text(0).lower().replace(' ', '').replace('-', '') == cfg.currentTab[0:-3].lower(): - c.child(x).setSelected(True) - c.setExpanded(True) - else: - c.child(x).setSelected(False) - t.blockSignals(False) - cfg.ui.main_tabWidget.setCurrentIndex(0) - cfg.dlg.show() - - # SCP tab index - def SCPTabChanged(self, index): - cfg.dlg.close() - cfg.dlg.show() - - # main tab index - def mainTabChanged(self, index): - if index == 1 and cfg.currentTab != 'aboutTab': - cfg.ui.help_textBrowser.clear() - cfg.ui.help_textBrowser.setPlainText('Loading ...') - baseUrl = 'https://semiautomaticclassificationmanual.readthedocs.io/en/latest/' + cfg.currentTab + '.html' - cfg.QtWidgetsSCP.qApp.processEvents() - if not cfg.osSCP.path.isfile(cfg.tmpDir + '/' + cfg.currentTab + '.html'): - r = cfg.requestsSCP.get(baseUrl) - with open(cfg.tmpDir + '/' + cfg.currentTab + '.html', 'wb') as f: - f.write(r.content) - with open(cfg.tmpDir + '/' + cfg.currentTab + '.html', 'r') as h: - html = h.read() - imgs = cfg.reSCP.findall('src="_images/(.+?)"', str(html)) - for i in imgs: - if not cfg.osSCP.path.isfile(cfg.tmpDir + '/_images/' + i): - try: - r = cfg.requestsSCP.get('https://semiautomaticclassificationmanual.readthedocs.io/en/latest/_images/' + i) - with open(cfg.tmpDir + '/_images/' + i, 'wb') as f: - f.write(r.content) - except: - pass - if len(html) > 0: - cfg.ui.help_textBrowser.clear() - cfg.ui.help_textBrowser.setHtml(html) - - # menu index - def menuIndex(self): - try: - nDict = {cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set'): cfg.utls.bandSetTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Basic tools'): self.topTree, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set list'): cfg.utls.BandSetListTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'RGB list'): cfg.utls.RGBListTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Algorithm band weight'): cfg.utls.algorithmBandWeightTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Multiple ROI creation'): cfg.utls.multipleROICreationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import signatures'): cfg.utls.importSignaturesTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export signatures'): cfg.utls.exportSignaturesTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signature threshold'): cfg.utls.signatureThresholdTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'LCS threshold'): cfg.utls.LCSThresholdTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Download products'): cfg.utls.downloadProductsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Preprocessing'): self.topTree, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Landsat'): cfg.utls.landsatTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-1'): cfg.utls.sentinel1Tab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-2'): cfg.utls.sentinel2Tab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sentinel-3'): cfg.utls.sentinel3Tab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ASTER'): cfg.utls.asterTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'MODIS'): cfg.utls.modisTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'GOES'): cfg.utls.GOESTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Vector to raster'): cfg.utls.vectorToRasterTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clip multiple rasters'): cfg.utls.clipMultipleRastersTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reproject raster bands'): cfg.utls.reprojectrasterbandsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Split raster bands'): cfg.utls.splitrasterbandsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Stack raster bands'): cfg.utls.stackrasterbandsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Mosaic band sets'): cfg.utls.mosaicBandSetsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Neighbor pixels'): cfg.utls.neighborPixelsTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cloud masking'): cfg.utls.cloudMaskingTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band processing'): self.topTree, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification'): cfg.utls.classificationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Random forest'): cfg.utls.randomForestTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PCA'): cfg.utls.PCATab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clustering'): cfg.utls.clusteringTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band combination'): cfg.utls.bandCombinationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral distance'): cfg.utls.spectralDistanceTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Postprocessing'): self.topTree, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Accuracy'): cfg.utls.accuracyTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Land cover change'): cfg.utls.landCoverChangeTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification report'): cfg.utls.classificationReportTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cross classification'): cfg.utls.crossClassificationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Class signature'): cfg.utls.classSignatureTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification to vector'): cfg.utls.classificationToVectorTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reclassification'): cfg.utls.reclassificationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Edit raster'): cfg.utls.editRasterTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification sieve'): cfg.utls.classificationSieveTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification erosion'): cfg.utls.classificationErosionTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification dilation'): cfg.utls.classificationDilationTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zonal stat raster'): cfg.utls.zonalStatRasterTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band calc'): cfg.utls.bandCalcTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Batch'): cfg.utls.batchTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Settings'): self.topTree, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing setting'): cfg.utls.processingSettingTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Interface'): cfg.utls.interfaceTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Debug'): cfg.utls.debugTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'User manual'): cfg.ipt.quickGuide, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Help'): cfg.ipt.askHelp, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'About'): cfg.utls.aboutTab, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Support the SCP'): cfg.ipt.supportSCP} - s = cfg.ui.menu_treeWidget.selectedItems() - n = s[0].text(0) - t = cfg.ui.menu_treeWidget - t.blockSignals(True) - cfg.ui.SCP_tabs.blockSignals(True) - nDict[n]() - s[0].setExpanded(True) - cfg.ui.SCP_tabs.blockSignals(False) - t.blockSignals(False) - except Exception as err: - cfg.ui.SCP_tabs.blockSignals(False) - t.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # top tree - def topTree(self): - pass - - def movedSplitter(self, index, pos): - cfg.utls.setQGISRegSetting(cfg.regSplitterSizeS, str(cfg.ui.splitter.sizes())) - - # filter tree - def filterTree(self): - try: - text = cfg.ui.f_filter_lineEdit.text() - t = cfg.ui.menu_treeWidget - r = t.invisibleRootItem() - t.blockSignals(True) - if len(text)>0: - t.expandAll() - items = t.findItems(text, cfg.QtSCP.MatchContains) - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - for x in range(0, c.childCount()): - if text.lower() in c.child(x).text(0).lower(): - c.child(x).setHidden(False) - else: - c.child(x).setHidden(True) - else: - t.collapseAll() - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - for x in range(0, c.childCount()): - if text in c.child(x).text(0): - c.child(x).setHidden(False) - t.blockSignals(False) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # welcome text - def welcomeText(self, inputUrl = None, inputUrl2 = None): - l = cfg.plgnDir + '/ui/welcome.html' - if inputUrl is None: - htmlTextF = open(l, 'r') - htmlText = htmlTextF.read() - else: - if cfg.downNewsVal == '2': - htmlText = cfg.utls.downloadHtmlFileQGIS(inputUrl, inputUrl2) - else: - htmlText = 'No' - if htmlText == 'No': - htmlTextF = open(l, 'r') - htmlText = htmlTextF.read() - cfg.uidc.main_textBrowser.clear() - cfg.uidc.main_textBrowser.setHtml(htmlText) - try: - htmlTextF.close() - except: - pass - \ No newline at end of file diff --git a/core/messages.py b/core/messages.py old mode 100644 new mode 100755 index 7bc5ee2..8b7ff23 --- a/core/messages.py +++ b/core/messages.py @@ -1,410 +1,218 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from PyQt5.QtWidgets import QMessageBox, QToolButton +from qgis.core import Qgis +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) +# message box information +def msg_box(title, message): + QMessageBox.information(cfg.iface.mainWindow(), str(title), str(message)) + + +# message box error +def msg_box_error(title, message): + QMessageBox.critical(cfg.iface.mainWindow(), title, message) + + +# message box warning +def msg_box_warning(title, message): + QMessageBox.warning(cfg.iface.mainWindow(), title, message) + + +# message bar information +def msg_bar(title, message): + cfg.iface.messageBar().pushMessage( + title, message, level=Qgis.Info, duration=7 + ) + cfg.iface.messageBar().findChildren(QToolButton)[0].setHidden(False) + + +# message bar information +def msg_bar_info(message): + msg_bar(cfg.translate('SCP information'), message) + + +# Message bar error +def msg_bar_critical(title, message): + cfg.iface.messageBar().pushMessage( + title, message, level=Qgis.Critical + ) + cfg.iface.messageBar().findChildren( + QToolButton + )[0].setHidden(False) + + +# Message bar error +def msg_bar_error(message): + msg_bar_critical(cfg.translate('Error'), message=message) + + +# message bar warning +def _msg_bar_warning(title, message): + cfg.iface.messageBar().pushMessage( + title, message, level=Qgis.Warning, duration=7 + ) + cfg.iface.messageBar().findChildren( + QToolButton + )[0].setHidden(False) + + +# message bar warning +def msg_bar_warning(message): + _msg_bar_warning(title=cfg.translate('Warning'), message=message) + + +''' Messages for callback ''' + + +def info(message): + msg_bar('SCP', message) + + +def warning(message): + if 'dependency error' in message: + if cfg.first_install == 1: + _msg_bar_warning('SCP', message) + else: + _msg_bar_warning('SCP', message) + + +def error(message): + msg_bar_critical('SCP', message) + + +''' Information ''' + + +def msg_test(message): + msg_box(cfg.translate('Test results'), message) + + +def msg_inf_1(): + msg_bar_info(cfg.translate('Training input cannot be edited')) + + +def msg_inf_2(): + msg_bar_info(cfg.translate('At least 3 points are required')) + + +def msg_inf_3(): + msg_bar_info(cfg.translate('Detailed log is active')) + + +def msg_inf_4(): + msg_bar_info(cfg.translate('Training vector exported')) + + +def msg_inf_5(): + msg_bar_info(cfg.translate('Enter class values')) + + +def msg_inf_6(): + msg_bar_info(cfg.translate('Process completed')) + + +""" Errors """ + + +def msg_err_1(): + msg_bar_error(cfg.translate('Process failed')) + + +def msg_err_2(): + msg_bar_error(cfg.translate('Bandset not found')) + + +def msg_err_3(): + msg_bar_error(cfg.translate('Area coordinates error')) + + +def msg_err_4(): + msg_bar_error(cfg.translate('Unable to create RGB color composite')) + + +def msg_err_5(): + msg_bar_error(cfg.translate('Unable to open file')) + + +def msg_err_6(): + msg_bar_error(cfg.translate('Unable to calculate')) + + +def msg_err_7(): + msg_bar_error(cfg.translate('Expression error')) + + +""" Warnings """ + + +def msg_war_1(): + msg_bar_warning(cfg.translate('Pixel resolution undefined')) + + +def msg_war_2(): + msg_bar_warning( + cfg.translate( + 'Unable to define hidden layer size, setting default 100' + ) + ) + + +def msg_war_3(): + msg_bar_warning( + cfg.translate( + 'Point outside band set or band set not defined' + ) + ) + + +def msg_war_4(): + msg_bar_warning(cfg.translate('ROI not found')) + + +def msg_war_5(): + msg_bar_warning( + cfg.translate( + 'Select a training input; input is not loaded' + ) + ) + + +def msg_war_6(bandset_number=None): + msg_bar_warning( + cfg.translate('Band set') + ' ' + str(bandset_number) + ' ' + + cfg.translate('is empty') + ) + + +def msg_war_7(): + msg_bar_warning(cfg.translate( + 'No band found. Check metadata inside the directory') + ) + -class Messages: - - def __init__(self, iface): - # reference to QGIS interface - cfg.iface = iface - - # Message box information - def msgBox(self, title, message): - cfg.QtWidgetsSCP.QMessageBox.information(cfg.iface.mainWindow(), str(title), str(message)) - - # Message box error - def msgBoxError(self, title, message): - cfg.QtWidgetsSCP.QMessageBox.critical(cfg.iface.mainWindow(), title, message) - - # Message box warning - def msgBoxWarning(self, title, message): - cfg.QtWidgetsSCP.QMessageBox.warning(cfg.iface.mainWindow(), title, message) - - # Message bar information - def msgBar(self, title, message): - cfg.iface.messageBar().pushMessage(title, message, level= cfg.qgisCoreSCP.Qgis.Info, duration=7) - cfg.iface.messageBar().findChildren(cfg.QtWidgetsSCP.QToolButton)[0].setHidden(False) - - # Message bar error - def msgBarError(self, title, message, SMTP = None): - cfg.iface.messageBar().pushMessage(title, message, level= cfg.qgisCoreSCP.Qgis.Critical) - cfg.iface.messageBar().findChildren(cfg.QtWidgetsSCP.QToolButton)[0].setHidden(False) - if SMTP is None: - cfg.utls.sendSMTPMessage('SCP: ' + title, message) - - # Message bar warning - def msgBarWarning(self, title, message): - cfg.iface.messageBar().pushMessage(title, message, level= cfg.qgisCoreSCP.Qgis.Warning, duration=7) - cfg.iface.messageBar().findChildren(cfg.QtWidgetsSCP.QToolButton)[0].setHidden(False) - - ''' Messages ''' - ''' Information ''' - def msgTest(self, message): - self.msgBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Test results'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', message)) - - def msg2(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [2]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'No log file found')) - - def msg3(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [3]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a SCP training input; input is not loaded')) - - def msg4(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [4]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a raster; raster is not loaded')) - - def msg6(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [6]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a point inside the image area')) - - def msg9(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [9]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Data projections do not match. Reproject data to the same projection')) - - def msg10(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [10]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Maximum Likelihood threshold must be less than 100')) - - def msg11(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [11]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral Angle Mapping threshold must be less than 90')) - - def msg14(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [14]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - - def msg16(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [16]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'At least 3 points are required')) - - def msg17(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [17]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Negative IDs are not allowed')) - - def msg18(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [18]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select at least one signature')) - - def msg19(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [19]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SCP is recording the Log file')) - - def msg20(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [20]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signature list file (.slf) created')) - - def msg21(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [21]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'No image found. Try with a larger area')) - - def msg22(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [22]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Create a ROI polygon or use a vector')) - - def msg23(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [23]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Define a search area')) - - def msg24(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [24]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'At least one band set is required')) - - def msg25(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [25]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to remove bands from a multiband image')) - - def msg26(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [26]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please select at least one tool. Band set definition does not require Run')) - - def msg27(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [27]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signatures exported')) - - def msg28(self): - self.msgBar(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Information') + ' [28]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signatures imported')) - - ''' Errors ''' - - def msgErr2(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [2]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData'), SMTP) - - def msgErr4(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [4]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signature calculation failed. Possible reason: the raster is not loaded'), SMTP) - - def msgErr5(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [5]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import failed. Possible reason: selected file is not a band set'), SMTP) - - def msgErr6(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [6]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification failed. It appears the one or more bands of the band set are missing'), SMTP) - - def msgErr7(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [7]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ROI creation failed. Possible reason: input is a virtual raster or band is not loaded'), SMTP) - - def msgErr8(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [8]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'No metadata found inside the input directory (a .txt file whose name contains MTL)'), SMTP) - - def msgErr9(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [9]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Raster not found'), SMTP) - - def msgErr11(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [11]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Vector or raster not found'), SMTP) - - def msgErr15(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [15]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error saving signatures'), SMTP) - - def msgErr16(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [16]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error opening signatures'), SMTP) - - def msgErr17(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [17]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error opening spectral library'), SMTP) - - def msgErr18(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [18]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error saving spectral library'), SMTP) - - def msgErr19(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [19]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import failed'), SMTP) - - def msgErr20(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [20]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ROI creation failed'), SMTP) - - def msgErr21(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [21]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Internet connection failed'), SMTP) - - def msgErr23(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [23]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error saving raster'), SMTP) - - def msgErr24(self, Macro_ID, Class_ID, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [24]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The following signature does not match the band set. MC_ID: ' + str(Macro_ID) + ' C_ID: ' + str(Class_ID)), SMTP) - - def msgErr25(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [25]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error reading raster. Possibly the raster path contains unicode characters'), SMTP) - - def msgErr26(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [26]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The version of Numpy is outdated'), SMTP) - - def msgErr27(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [27]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation'), SMTP) - - def msgErr28(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [28]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Memory error. Please, set a lower value of RAM in the tab Settings'), SMTP) - - def msgErr29(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [29]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Edge error. Reduce the ROI width or draw a ROI manually'), SMTP) - - def msgErr31(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [31]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error calculating signature. Possibly ROI is too small'), SMTP) - - def msgErr32(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [32]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to split bands'), SMTP) - - def msgErr33(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [33]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error reading band set. Possibly raster files are not loaded'), SMTP) - - def msgErr34(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [34]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clip area outside image. Check the raster projection'), SMTP) - - def msgErr35(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [35]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to merge. Signatures have different unit or wavelength'), SMTP) - - def msgErr36(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [36]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to calculate. Expression error'), SMTP) - - def msgErr37(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [37]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to calculate. Metadata error')) - - def msgErr38(self, path, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [38]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to load raster ' + path), SMTP) - - def msgErr39(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [39]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to find images'), SMTP) - - def msgErr40(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [40]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to connect'), SMTP) - - def msgErr40bis(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [40]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to connect, possibly archived image'), SMTP) - - def msgErr41(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [41]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to load image'), SMTP) - - def msgErr42(self, imageID, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [42]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to download image ' + imageID + ' . Please check the availability at http://earthexplorer.usgs.gov/'), SMTP) - - def msgErr43(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [43]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Attribute table error'), SMTP) - - def msgErr44(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [44]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to pansharpen: missing bands '), SMTP) - - def msgErr45(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [45]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to calculate'), SMTP) - - def msgErr46(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [46]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error reading raster. Possibly bands are not aligned'), SMTP) - - def msgErr47(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [47]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to get raster projection. Try to reproject the raster'), SMTP) - - def msgErr48(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [48]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error calculating accuracy. Possibly vector polygons are outside classification'), SMTP) - - def msgErr50(self, error, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [50]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Internet error:' + error), SMTP) - - def msgErr53(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [53]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Memory error. Please, decrease decimal precision'), SMTP) - - def msgErr54(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [54]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error calculating plot'), SMTP) - - def msgErr55(self, imageID, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [55]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to download image ' + imageID + ' . Check user name and password'), SMTP) - - def msgErr56(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [56]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SSL connection error. Please see the FAQ of the plugin user manual for solving this'), SMTP) - - def msgErr57(self, signature, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [57]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral signature ' + signature +' does not match Band set. Calculate the spectral signatures again'), SMTP) - - def msgErr58(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [58]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Directory error. Check write permission'), SMTP) - - def msgErr59(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [59]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error accessing training input'), SMTP) - - def msgErr60(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [60]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Rasters appear to be in different projections. Reproject rasters to the same CRS'), SMTP) - - def msgErr61(self, raster, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [61]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Projection error. Try to assign projection to raster ' + raster), SMTP) - - def msgErr62(self, index, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [62]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set ' + index + ' not available'), SMTP) - - def msgErr63(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [63]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Memory error, too many combinations. Try to reclassify the values'), SMTP) - - def msgErr64(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [64]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error, please change stratification parameters'), SMTP) - - def msgErr65(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [65]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error, extent of vector too large or attribute table error'), SMTP) - - def msgErr66(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [66]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error, select a stastistic'), SMTP) - - def msgErr67(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [67]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Projection error'), SMTP) - - def msgErr68(self, SMTP = None): - self.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ' [68]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sum method is available only with GDAL version >= 3.1 . Please update GDAL'), SMTP) - - ''' Warnings ''' - def msgWar2Windows(self): - self.msgBoxWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [2]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'It appears that SciPy is not correctly installed. Please, update QGIS ')) - - def msgWar2Linux(self): - self.msgBoxWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [2]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'It appears that SciPy is not correctly installed. Please, check the user manual')) - - def msgWar7(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [7]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Wavelength already present')) - - def msgWar8(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [8]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Wavelength unit not provided in band set')) - cfg.msgWar8check = 'Yes' - - def msgWar9(self, Macro_ID, Class_ID): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [9]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The following signature has wavelength different from band set. Macro: ' + str(Macro_ID) + ' ID: ' + str(Class_ID))) - - def msgWar10(self, Macro_ID, Class_ID): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [10]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The following signature has not a covariance matrix and is excluded. Macro: ' + str(Macro_ID) + ' ID: ' + str(Class_ID))) - - def msgWar11(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [11]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'RAM value was too high. Value has been decreased automatically')) - - def msgWar12(self, Macro_ID, Class_ID): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [12]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The following signature will be excluded if using Maximum Likelihood (singular covariance matrix). Macro: ' + str(Macro_ID) + ' ID: ' + str(Class_ID))) - - def msgWar13(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [13]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to load the virtual raster. Please create it manually')) - - def msgWar14(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [14]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to proceed. The raster must be in projected coordinates')) - - def msgWar15(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [15]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select at least one raster band')) - - def msgWar16(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [16]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Incorrect expression')) - - def msgWar17(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [17]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unable to access the temporary directory')) - - def msgWar18(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [18]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude')) - - def msgWar19(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [19]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Macroclass symbology is missing')) - - def msgWar20(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [20]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Missing bands')) - - def msgWar21(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [21]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'No metadata found inside the input directory. Default values will be used')) - - def msgWar22(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [22]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The coordinate system of training input is different from the input image. Please create a new training input')) - - def msgWar23(self, image): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [23]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Check integrity of image ' + image)) - - def msgWar24(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [24]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Search error HTTP Status 500, reduce the result number')) - - def msgWar25(self, band_set): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [25]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set ' + str(band_set) + ' is not correctly defined')) - - def msgWar26(self, band_set): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [26]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band set ' + str(band_set) + ' does not match training input. Create a new training input or change band set.')) - - def msgWar27(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [27]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Signature bands do not match band set. Calculate the spectral signature again')) - - def msgWar28(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [28]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please define band sets with matching number of bands')) - - def msgWar29(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [29]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please add single band rasters to the band set')) - - def msgWar30(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [30]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please lower the RAM value or thread number in Settings')) - - def msgWar31(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [31]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please set the path to ESA SNAP GPT executable in Settings')) - - def msgWar32(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [32]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Memory error. Please, decrease decimal precision of plot')) - - def msgWar33(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [33]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'The process could still be running in the background. Please terminate it manually')) - - def msgWar34(self): - self.msgBarWarning(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Warning') + ' [34]', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Please define a date range within the same year')) - \ No newline at end of file +def msg_war_8(): + msg_bar_warning(cfg.translate('No tool selected')) diff --git a/core/signature_importer.py b/core/signature_importer.py deleted file mode 100644 index fe714ff..0000000 --- a/core/signature_importer.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Signature_Importer: - def __init__(self): - pass - - # import USGS spectral library (https://www.usgs.gov/labs/spec-lab/capabilities/spectral-library) - def USGSLibrary(self, libraryReflectance, libraryWavelength, librarySD): - ref = libraryReflectance - wl = libraryWavelength - sD = librarySD - wavelength = cfg.np.array(wl) - a = list(cfg.bandSetsList[cfg.bndSetNumber][4]) - s = sorted(a, key=float) - if len(s) > 0: - b = 0 - cfg.tblOut = {} - for w in s: - i = (cfg.np.abs(wavelength - w)).argmin() - waveL = wl[i] - reflectance = ref[i] - standardDeviation = sD[i] - val = [] - val.append(reflectance-standardDeviation) - val.append(reflectance+standardDeviation) - val.append(reflectance) - val.append(standardDeviation) - cfg.tblOut['BAND_{0}'.format(b+1)] = val - cfg.tblOut['WAVELENGTH_{0}'.format(b + 1)] = w - b = b + 1 - self.addLibraryToSignatureList() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' spectral library imported') - - # import ASTER spectral library (http://speclib.jpl.nasa.gov/search-1) - def ASTERLibrary(self, libraryPath): - if cfg.osSCP.path.isfile(libraryPath): - f = open(libraryPath) - file = f.readlines() - if 'Name' in file[0]: - wl = [] - ref = [] - sD = [] - for b in range(26, len(file)): - v = file[b].split() - wl.append(float(v[0])) - ref.append(float(v[1]) / 100) - sD.append(float(0)) - wavelength = cfg.np.array(wl) - a = list(cfg.bandSetsList[cfg.bndSetNumber][4]) - s = sorted(a, key=float) - b = 0 - cfg.tblOut = {} - for w in s: - i = (cfg.np.abs(wavelength - w)).argmin() - waveL = wl[i] - reflectance = ref[i] - standardDeviation = sD[i] - val = [] - val.append(reflectance-standardDeviation) - val.append(reflectance+standardDeviation) - val.append(reflectance) - val.append(standardDeviation) - cfg.tblOut['BAND_{0}'.format(b+1)] = val - cfg.tblOut['WAVELENGTH_{0}'.format(b + 1)] = w - b = b + 1 - self.addLibraryToSignatureList() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' spectral library imported' + str(file[0])) - else: - cfg.mx.msgErr17() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' spectral library ' + str(file[0])) - - # import generic CSV spectral library (first line: wavelength, reflectance, standardDeviation, waveLengthUnit) - def CSVLibrary(self, libraryPath): - if cfg.osSCP.path.isfile(libraryPath): - f = open(libraryPath) - file = f.readlines() - wl = [] - ref = [] - sD = [] - for b in range(1, len(file)): - v = file[b].split(';') - if len(v) == 1: - v = file[b].split(',') - # check if wavelength is not in micrometers - vL = float(v[0]) - if v[3] != cfg.noUnit: - if vL > 30 and str(cfg.bandSetsList[cfg.bndSetNumber][5]) == cfg.unitMicro: - vL = vL / 1000 - elif vL < 30 and str(cfg.bandSetsList[cfg.bndSetNumber][5]) == cfg.wlNano: - vL = vL * 1000 - wl.append(vL) - ref.append(float(v[1])) - try: - sD.append(float(v[2])) - except: - sD.append(float(0)) - wavelength = cfg.np.array(wl) - a = list(cfg.bandSetsList[cfg.bndSetNumber][4]) - s = sorted(a, key=float) - b = 0 - cfg.tblOut = {} - for w in s: - i = (cfg.np.abs(wavelength - w)).argmin() - waveL = wl[i] - reflectance = ref[i] - standardDeviation = sD[i] - val = [] - val.append(reflectance-standardDeviation) - val.append(reflectance+standardDeviation) - val.append(reflectance) - val.append(standardDeviation) - cfg.tblOut['BAND_{0}'.format(b+1)] = val - cfg.tblOut['WAVELENGTH_{0}'.format(b + 1)] = w - b = b + 1 - unit = v[3].strip() - if str(unit) == cfg.noUnit or str(unit) == cfg.unitMicro or str(unit) == cfg.wlNano: - self.addLibraryToSignatureList(unit) - else: - self.addLibraryToSignatureList() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' spectral library imported ' + str(libraryPath)) - - # add library values to signature list - def addLibraryToSignatureList(self, unit = None): - macroclassID = cfg.ROIMacroID - macroclassInfo = cfg.ROIMacroClassInfo - classID = cfg.ROIID - classInfo = cfg.ROIInfo - cfg.tblOut['ROI_SIZE'] = 0 - cfg.utls.ROIStatisticsToSignature('No', macroclassID, macroclassInfo, classID, classInfo, cfg.bndSetNumber, unit) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - - # open a shapefile - def openShapefileI(self): - shpFile = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a shapefile'), '', 'Shapefile (*.shp);;GeoPackage (*.gpkg)') - if len(shpFile) > 0: - fields = cfg.utls.fieldsShapefile(shpFile) - cfg.ui.MC_ID_combo.clear() - cfg.ui.MC_ID_combo.addItems(fields) - cfg.ui.MC_Info_combo.clear() - cfg.ui.MC_Info_combo.addItems(fields) - cfg.ui.C_ID_combo.clear() - cfg.ui.C_ID_combo.addItems(fields) - cfg.ui.C_Info_combo.clear() - cfg.ui.C_Info_combo.addItems(fields) - cfg.ui.select_shapefile_label.setText(shpFile) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), ' open Shapefile') - \ No newline at end of file diff --git a/core/ui_utils.py b/core/ui_utils.py new file mode 100755 index 0000000..0bc640e --- /dev/null +++ b/core/ui_utils.py @@ -0,0 +1,303 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +import ssl +import smtplib + +import qgis.core as qgis_core +from PyQt5.QtCore import QSize +from PyQt5.QtGui import QFont, QPixmap +from PyQt5.QtWidgets import ( + qApp, QWidget, QSizePolicy, QLabel, QSpacerItem, QProgressBar, QPushButton, + QHBoxLayout, QVBoxLayout, QToolButton, QApplication +) + + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +class UiUtils: + progress_bar = None + widget_bar = None + msg_label_main = None + msg_label = None + remaining = '' + + def __init__(self): + pass + + # add a progress bar and a cancel button + def add_progress_bar(self, message='', main_message=None): + # remove if present + try: + UiUtils.progress_bar.setValue(0) + except Exception as err: + str(err) + self.create_progress_bar(main_message, message) + # disable map canvas render for speed + cfg.map_canvas.setRenderFlag(False) + qApp.processEvents() + + # Create a progress bar and a cancel button + # noinspection PyArgumentList + def create_progress_bar(self, main_message=None, message=''): + size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + icon_label = QLabel() + icon_label.setMinimumSize(QSize(20, 20)) + icon_label.setMaximumSize(QSize(50, 50)) + icon_label.setSizePolicy(size_policy) + icon_label.setPixmap( + QPixmap( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin.svg' + ) + ) + UiUtils.msg_label_main = QLabel() + size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + UiUtils.msg_label_main.setMinimumSize(QSize(50, 0)) + UiUtils.msg_label_main.setMaximumSize(QSize(800, 30)) + UiUtils.msg_label_main.setSizePolicy(size_policy) + font = QFont() + font.setBold(True) + UiUtils.msg_label_main.setFont(font) + UiUtils.msg_label_main.setText( + self.translate('Semi-Automatic Classification Plugin') + ) + spacer_item = QSpacerItem( + 40, 20, QSizePolicy.Expanding, + QSizePolicy.Minimum + ) + UiUtils.msg_label = QLabel() + UiUtils.msg_label.setMinimumSize(QSize(50, 0)) + UiUtils.msg_label.setMaximumSize(QSize(600, 80)) + UiUtils.msg_label.setSizePolicy(size_policy) + UiUtils.msg_label.setWordWrap(True) + UiUtils.progress_bar = QProgressBar() + UiUtils.progress_bar.setMinimum(0) + UiUtils.progress_bar.setMaximum(100) + UiUtils.progress_bar.setProperty('value', 0) + UiUtils.progress_bar.setTextVisible(True) + cancel_button = QPushButton() + cancel_button.setEnabled(True) + cancel_button.setText(self.translate('Cancel')) + q_widget = QWidget() + horizontal_layout = QHBoxLayout() + horizontal_layout2 = QHBoxLayout() + vertical_layout = QVBoxLayout(q_widget) + vertical_layout.addLayout(horizontal_layout) + vertical_layout.addLayout(horizontal_layout2) + horizontal_layout.addWidget(icon_label) + horizontal_layout.addWidget(UiUtils.msg_label_main) + horizontal_layout.addItem(spacer_item) + horizontal_layout2.addWidget(UiUtils.msg_label) + horizontal_layout2.addWidget(UiUtils.progress_bar) + horizontal_layout2.addWidget(cancel_button) + cancel_button.clicked.connect(self.cancel_action) + UiUtils.widget_bar = cfg.iface.messageBar().createMessage('', '') + cfg.iface.messageBar().findChildren(QToolButton)[0].setHidden(True) + UiUtils.widget_bar.layout().addWidget(q_widget) + self.update_bar(0, message, main_message) + cfg.rs.configurations.action = True + self.set_interface(False) + cfg.iface.messageBar().pushWidget( + UiUtils.widget_bar, + qgis_core.Qgis.Info + ) + + # cancel action + def cancel_action(self): + cfg.logger.log.debug('cancel_action') + self.remove_progress_bar() + cfg.rs.configurations.action = False + UiUtils.update_bar(100, ' Canceling ...') + qApp.processEvents() + self.set_interface(True) + cfg.map_canvas.setRenderFlag(True) + + # update bar value + @staticmethod + def update_bar( + step=None, message=None, process=None, percentage=None, + elapsed_time=None, previous_step=None, start=None, end=None, + ping=0 + ): + progress_symbols = ['○', '◔', '◑', '◕', '⬤', '⚙'] + colon = [' ◵ ', ' ◷ '] + if start: + text = '{} {} {}'.format( + message, progress_symbols[-1], colon[ping] + ) + try: + UiUtils.msg_label.setText(text) + UiUtils.progress_bar.setValue(step) + except Exception as err: + str(err) + if process is not None: + try: + UiUtils.msg_label_main.setText(str(process)) + except Exception as err: + str(err) + elif end: + if elapsed_time is not None: + e_time = ( + '(elapsed: {}min{}sec)'.format( + int(elapsed_time / 60), str( + int( + 60 * ((elapsed_time / 60) - int( + elapsed_time / 60 + )) + ) + ).rjust(2, '0') + ) + ) + else: + e_time = '' + text = '{} - {}'.format( + progress_symbols[-2], e_time + ) + try: + UiUtils.msg_label.setText(text) + UiUtils.progress_bar.setValue(step) + except Exception as err: + str(err) + try: + if process is not None: + UiUtils.msg_label_main.setText(str(process)) + except Exception as err: + str(err) + else: + if not percentage and percentage is not None: + percentage = -25 + if elapsed_time is not None: + e_time = ( + 'elapsed: {}min{}sec'.format( + int(elapsed_time / 60), str( + int( + 60 * ((elapsed_time / 60) - int( + elapsed_time / 60 + )) + ) + ).rjust(2, '0') + ) + ) + if previous_step < step: + try: + remaining_time = ( + (100 - int(step)) * elapsed_time / int(step) + ) + minutes = int(remaining_time / 60) + seconds = round( + 60 * ((remaining_time / 60) + - int(remaining_time / 60)) + ) + if seconds == 60: + seconds = 0 + minutes += 1 + remaining = '; remaining: {}min{}sec'.format( + minutes, str(seconds).rjust(2, '0') + ) + UiUtils.remaining = remaining + except Exception as err: + str(err) + remaining = '' + else: + remaining = UiUtils.remaining + else: + e_time = '' + remaining = '' + try: + text = '{} {} - {}{} {}'.format( + message, progress_symbols[int(percentage / 25)], e_time, + remaining, colon[ping] + ) + UiUtils.msg_label.setText(text) + UiUtils.progress_bar.setValue(step) + qApp.processEvents() + if process is not None: + UiUtils.msg_label_main.setText(str(process)) + except Exception as err: + str(err) + if process is not None: + try: + UiUtils.msg_label_main.setText(str(process)) + except Exception as err: + str(err) + + # remove progress bar and cancel button + def remove_progress_bar(self, smtp=None): + UiUtils.remaining = '' + try: + cfg.iface.messageBar().popWidget(UiUtils.widget_bar) + except Exception as err: + str(err) + UiUtils.progress_bar = None + self.set_interface(True) + cfg.iface.messageBar().findChildren(QToolButton)[0].setHidden(False) + cfg.map_canvas.setRenderFlag(True) + cfg.logger.log.debug('end progress: %s' % smtp) + if smtp is not None: + # send SMTP message + self.send_smtp_message( + subject=self.translate('Semi-Automatic Classification Plugin'), + message=self.translate('%s: process finished' % smtp) + ) + + # translate + @staticmethod + def translate(text): + # noinspection PyTypeChecker + return QApplication.translate( + 'semiautomaticclassificationplugin', text + ) + + # enable disable the interface to avoid errors + @staticmethod + def set_interface(state): + # classification dock + cfg.dock_class_dlg.setEnabled(state) + # main interface + cfg.dialog.setEnabled(state) + # toolbar + cfg.working_toolbar.setEnabled(state) + + # send SMTP message + @staticmethod + def send_smtp_message(subject: str = None, message: str = None): + if cfg.smtp_notification is True: + try: + if len(cfg.smtp_server) > 0: + server = smtplib.SMTP(cfg.smtp_server, 587) + context = ssl.create_default_context() + server.starttls(context=context) + server.login(cfg.smtp_user, cfg.smtp_password) + tolist = cfg.smtp_recipients.split(',') + if subject is None: + subject = 'completed process' + if message is None: + message = 'completed process' + msg = 'From: %s\nTo: \nSubject: %s\n\n%s' % ( + cfg.smtp_user, subject, message) + server.sendmail(cfg.smtp_user, tolist, msg) + server.quit() + except Exception as err: + str(err) diff --git a/core/util_gdal.py b/core/util_gdal.py new file mode 100644 index 0000000..b0c3e52 --- /dev/null +++ b/core/util_gdal.py @@ -0,0 +1,232 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +import numpy as np +from osgeo import gdal, ogr, osr + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + +""" GDAL functions """ + + +# read a block of band as array +def read_array_block( + gdal_band, start_column, start_row, block_columns, block_rows, + calc_data_type=None +): + if calc_data_type is None: + calc_data_type = np.float32 + try: + offset = gdal_band.GetOffset() + scale = gdal_band.GetScale() + if offset is None: + offset = 0.0 + if scale is None: + scale = 1.0 + except Exception as err: + str(err) + offset = 0.0 + scale = 1.0 + offset = np.asarray(offset).astype(calc_data_type) + scale = np.asarray(scale).astype(calc_data_type) + try: + array = np.asarray( + gdal_band.ReadAsArray( + start_column, start_row, block_columns, block_rows + ) * scale + offset + ).astype(calc_data_type) + except Exception as err: + str(err) + return None + return array + + +# read raster +def read_raster(raster_path): + _r_d = gdal.Open(raster_path, gdal.GA_ReadOnly) + if _r_d is None: + return False + x_count = _r_d.RasterXSize + y_count = _r_d.RasterYSize + band = _r_d.GetRasterBand(1) + data_type = gdal.GetDataTypeName(band.DataType) + calc_data_type = cfg.rs.shared_tools.data_type_conversion(data_type) + scale = band.GetScale() + if scale is not None: + if scale < 1 or scale > 1: + calc_data_type = np.float32 + r_array = read_array_block( + gdal_band=band, start_column=0, start_row=0, block_columns=x_count, + block_rows=y_count, calc_data_type=calc_data_type + ) + return r_array + + +# Get pixel size of a raster +def get_pixel_size(path): + # open input_raster + _input_raster = gdal.Open(path, gdal.GA_ReadOnly) + # get input_raster geotransformation + gt = _input_raster.GetGeoTransform() + p_x_size = abs(gt[1]) + p_y_size = abs(gt[5]) + _input_raster = None + return p_x_size, p_y_size + + +# Get CRS of a raster or vector +def get_crs_gdal(path): + # try vector + opened_vector = ogr.Open(path) + # if raster + if opened_vector is None: + opened_vector = gdal.Open(path, gdal.GA_ReadOnly) + if opened_vector is None: + crs = None + else: + try: + # check projections + crs = opened_vector.GetProjection() + crs = crs.replace(' ', '') + if len(crs) == 0: + crs = None + except Exception as err: + str(err) + crs = None + # if vector + else: + layer = opened_vector.GetLayer() + # check projection + proj = layer.GetSpatialRef() + try: + crs = proj.ExportToWkt() + crs = crs.replace(' ', '') + if len(crs) == 0: + crs = None + except Exception as err: + str(err) + crs = None + return crs + + +# compare two crs +def compare_crs(first_crs, second_crs): + try: + first_sr = osr.SpatialReference() + first_sr.ImportFromWkt(first_crs) + second_sr = osr.SpatialReference() + second_sr.ImportFromWkt(second_crs) + if first_sr.IsSame(second_sr) == 1: + same = True + else: + same = False + return same + except Exception as err: + str(err) + return False + + +# Get GDAL version +def get_gdal_version(): + v = gdal.VersionInfo('RELEASE_NAME').split('.') + return v + + +# create a polygon shapefile with OGR +def create_empty_shapefile_ogr( + crs_wkt, output_path, vector_format='ESRI Shapefile' +): + try: + crs_wkt = str(crs_wkt.toWkt()) + except Exception as err: + str(err) + driver = ogr.GetDriverByName(vector_format) + _source = driver.CreateDataSource(output_path) + spatial_reference = osr.SpatialReference() + spatial_reference.ImportFromWkt(crs_wkt) + name = cfg.rs.files_directories.file_name(output_path) + _layer = _source.CreateLayer( + name, spatial_reference, ogr.wkbMultiPolygon + ) + field = ogr.FieldDefn(cfg.empty_field_name, ogr.OFTInteger) + _layer.CreateField(field) + _layer = None + _source = None + cfg.logger.log.debug('create_vector_ogr: %s' % output_path) + + +# create a polygon gpkg with OGR +def create_vector_ogr(crs_wkt, output_path, vector_format='GPKG'): + try: + crs_wkt = str(crs_wkt.toWkt()) + except Exception as err: + str(err) + driver = ogr.GetDriverByName(vector_format) + _source = driver.CreateDataSource(output_path) + spatial_reference = osr.SpatialReference() + spatial_reference.ImportFromWkt(crs_wkt) + name = cfg.rs.files_directories.file_name(output_path) + _layer = _source.CreateLayer(name, spatial_reference, ogr.wkbMultiPolygon) + field = ogr.FieldDefn(cfg.empty_field_name, ogr.OFTInteger) + _layer.CreateField(field) + _layer = None + _source = None + cfg.logger.log.debug('create_vector_ogr: %s' % output_path) + + +# Get field names of a vector +def vector_fields(path): + _s = ogr.Open(path) + _layer = _s.GetLayer() + definition = _layer.GetLayerDefn() + fields = [definition.GetFieldDefn(i).GetName() for i in + range(definition.GetFieldCount())] + _layer = None + _s = None + return fields + + +# Open a vector +def open_vector(path): + _s = ogr.Open(path) + return _s + + +# get polygon from vector and return memory layer +def get_polygon_from_vector(vector_path, output, attribute_filter=None): + # open input vector + vector = ogr.Open(vector_path) + # get layer + try: + _v_layer = vector.GetLayer() + except Exception as err: + str(err) + return False + # attribute filter + _v_layer.SetAttributeFilter(attribute_filter) + d = ogr.GetDriverByName('GPKG') + _d_s = d.CreateDataSource(output) + _d_s.CopyLayer(_v_layer, _v_layer.GetName(), ['OVERWRITE=YES']) + _v_layer = None + _d_s = None + return output diff --git a/core/util_qgis.py b/core/util_qgis.py new file mode 100644 index 0000000..76eca92 --- /dev/null +++ b/core/util_qgis.py @@ -0,0 +1,599 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from qgis.core import ( + QgsProject, QgsVectorFileWriter, QgsLayerTreeNode, QgsMapLayer, + QgsRasterMinMaxOrigin, QgsContrastEnhancement, QgsRectangle, QgsPointXY, + QgsVectorLayer, QgsFillSymbol, QgsFeatureRequest, QgsWkbTypes, + QgsCoordinateReferenceSystem +) + +# sound for Windows +try: + import winsound +except Exception as error: + str(error) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# get QGIS project instance +def get_qgis_project(): + return QgsProject.instance() + + +# get QGIS map raster layer +def get_qgis_map_raster(): + return QgsMapLayer.RasterLayer + + +# get QGIS map vector layer +def get_qgis_map_vector(): + return QgsMapLayer.VectorLayer + + +# get QGIS wkb types +def get_qgis_wkb_types(): + return QgsWkbTypes + + +# get QGIS Proxy settings +def get_qgis_proxy_settings(): + cfg.proxy_enabled = cfg.util_qt.read_registry_keys( + 'proxy/proxyEnabled', '' + ) + cfg.proxy_type = cfg.util_qt.read_registry_keys('proxy/proxyType', '') + cfg.proxy_host = cfg.util_qt.read_registry_keys('proxy/proxyHost', '') + cfg.proxy_port = cfg.util_qt.read_registry_keys('proxy/proxyPort', '') + cfg.proxy_user = cfg.util_qt.read_registry_keys('proxy/proxyUser', '') + cfg.proxy_password = cfg.util_qt.read_registry_keys( + 'proxy/proxyPassword', '' + ) + + +# Get CRS of a layer by name thereof +def get_crs_qgis(layer): + if layer is None: + crs = None + else: + provider = layer.dataProvider() + crs = provider.crs() + return crs + + +# save memory layer to file +def save_memory_layer_to_geopackage(memory_layer, output): + try: + # QGIS > 3.20 + writer = QgsVectorFileWriter.writeAsVectorFormatV3 + except Exception as err: + str(err) + # QGIS < 3.20 + writer = QgsVectorFileWriter.writeAsVectorFormatV2 + save_vector_options = QgsVectorFileWriter.SaveVectorOptions() + save_vector_options.driverName = 'GPKG' + writer( + layer=memory_layer, fileName=output, + transformContext=get_qgis_project().transformContext(), + options=save_vector_options + ) + + +# save memory layer to file +def save_qgis_memory_layer_to_file( + memory_layer, output, name=None, file_format='ESRI Shapefile', + id_list=None, field_name_list=None +): + try: + cfg.util_gdal.create_vector_ogr( + memory_layer.crs(), output, vector_format=file_format + ) + if name is None: + name = cfg.rs.files_directories.file_name(output, suffix=True) + vector = add_vector_layer(output, name) + vector.updateFields() + vector.startEditing() + if id_list is None: + for feature in memory_layer.getFeatures(): + vector.addFeature(feature) + else: + for feature in memory_layer.getFeatures(): + field = str(feature[field_name_list]) + if field in id_list: + vector.addFeature(feature) + vector.commitChanges() + vector.updateExtents() + remove_layer_by_layer(vector) + cfg.logger.log.debug('save_qgis_memory_layer_to_file: %s' % output) + return True + except Exception as err: + cfg.logger.log.error(str(err)) + return False + + +# Find group by its name +def group_index(group_name): + root = get_qgis_project().layerTreeRoot() + group = root.findGroup(group_name) + return group + + +# Layer ID by name thereof +def get_layer_id_by_name(layer_name): + layers = get_qgis_project().mapLayers().values() + for layer in layers: + name = layer.name() + if name == layer_name: + return layer.id() + + +# read project variable +def read_project_variable(variable_name, value): + value = get_qgis_project().readEntry( + 'SemiAutomaticClassificationPlugin', + variable_name, str(value) + )[0] + cfg.util_qt.process_events() + try: + value = int(value) + except Exception as err: + str(err) + try: + value = eval(value) + except Exception as err: + str(err) + return value + + +# write project variable +def write_project_variable(variable_name, value): + get_qgis_project().writeEntry( + 'SemiAutomaticClassificationPlugin', + variable_name, str(value) + ) + cfg.util_qt.process_events() + return True + + +# Remove layer from map +def remove_layer_by_name(layer_name): + try: + get_qgis_project().removeMapLayer( + get_layer_id_by_name(layer_name) + ) + except Exception as err: + str(err) + + +# Remove layer from map +def remove_layer_by_layer(layer): + try: + get_qgis_project().removeMapLayer(layer.id()) + except Exception as err: + str(err) + + +# Create group +def create_group(group_name): + root = get_qgis_project().layerTreeRoot() + group = root.insertGroup(0, group_name) + return group + + +# Remove layer from map +def remove_group(group_name): + root = get_qgis_project().layerTreeRoot() + group = root.findGroup(group_name) + try: + if group is not None: + root.removeChildNode(group) + except Exception as err: + str(err) + + +# Set group visible +def set_group_visible(group_id, visible=False): + try: + QgsLayerTreeNode.setItemVisibilityChecked(group_id, visible) + except Exception as err: + str(err) + + +# Set group expanded +def set_group_expanded(group_id, expanded=False): + try: + QgsLayerTreeNode.setExpanded(group_id, expanded) + except Exception as err: + str(err) + + +# Move layer to top layers +def move_layer_to_top(layer): + try: + root = get_qgis_project().layerTreeRoot() + layer = root.findLayer(layer.id()) + layer_clone = layer.clone() + root.insertChildNode(0, layer_clone) + root.removeChildNode(layer) + except Exception as err: + str(err) + + +# Move layer in group +def move_layer(layer, group_name): + try: + root = get_qgis_project().layerTreeRoot() + layer_x = root.findLayer(layer.id()) + group = root.findGroup(group_name) + group.insertLayer(0, layer) + root.removeChildNode(layer_x) + except Exception as err: + str(err) + + +# Set layer visible +def set_layer_visible(layer, visible=True): + root = get_qgis_project().layerTreeRoot() + layer_x = root.findLayer(layer.id()) + QgsLayerTreeNode.setItemVisibilityChecked(layer_x, visible) + + +# Refresh layer symbology +def refresh_layer_symbology(layer): + root = get_qgis_project().layerTreeRoot() + model = cfg.iface.layerTreeView().model() + try: + layer_x = root.findLayer(layer.id()) + model.refreshLayerLegend(layer_x) + except Exception as err: + str(err) + cfg.iface.layerTreeView().refreshLayerSymbology(layer.id()) + + +# Select layer by name thereof +def select_layer_by_name(layer_name, filter_raster=None): + layers = get_qgis_project().mapLayers().values() + for layer in layers: + layer_x_name = layer.name() + if layer_x_name == layer_name: + if filter_raster is None: + return layer + else: + try: + if layer.type().value == 1: + return layer + except Exception as err: + str(err) + if layer.type() == QgsMapLayer.RasterLayer: + return layer + + +# file path +def get_file_path(layer_name): + try: + layer = select_layer_by_name(layer_name) + path = cfg.util_qgis.qgis_layer_source(layer) + return path + except Exception as err: + str(err) + + +# set map extent from layer +def set_map_extent_from_layer(layer): + ext = layer.extent() + upper_left_point = create_qgis_point(ext.xMinimum(), ext.yMaximum()) + lower_right_point = create_qgis_point(ext.xMaximum(), ext.yMinimum()) + point_1 = upper_left_point + point_2 = lower_right_point + # project extent + crs = get_crs_qgis(layer) + qgis_crs = get_qgis_crs() + if crs is None: + crs = qgis_crs + # projection of input point from raster's crs to project's crs + if qgis_crs != crs: + try: + point_1 = cfg.utils.project_qgis_point_coordinates( + upper_left_point, crs, qgis_crs + ) + point_2 = cfg.utils.project_qgis_point_coordinates( + lower_right_point, crs, qgis_crs + ) + if point_1 is False: + point_1 = upper_left_point + point_2 = lower_right_point + # Error latitude or longitude exceeded limits + except Exception as err: + str(err) + point_1 = upper_left_point + point_2 = lower_right_point + cfg.map_canvas.setExtent(QgsRectangle(point_1, point_2)) + + +# save a qml style +def save_qml_style(layer, style_path): + layer.saveNamedStyle(style_path) + + +# edit features of layer +def edit_layer_features(layer, expression, field_name, value): + if layer is not None: + layer.removeSelection() + layer.startEditing() + layer.selectByExpression(expression) + fields = layer.fields() + for feature in layer.selectedFeatures(): + layer.changeAttributeValue( + feature.id(), fields.indexFromName(field_name), value + ) + layer.commitChanges() + layer.removeSelection() + return True + else: + return False + + +# zoom to band set +def zoom_to_bandset(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + if band_count == 0: + return + try: + crs = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].crs + left = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].left + top = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].top + right = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].right + bottom = cfg.bandset_catalog.get_bandset(bandset_number).bands[ + 0].bottom + upper_left_point = create_qgis_point(left, top) + lower_right_point = create_qgis_point(right, bottom) + point_1 = upper_left_point + point_2 = lower_right_point + except Exception as err: + cfg.logger.log.error(str(err)) + return + qgis_crs = get_qgis_crs() + if crs is None: + crs = qgis_crs + # projection of input point from raster's crs to project's crs + if cfg.util_gdal.compare_crs(crs, qgis_crs) is False: + try: + point_1 = cfg.utils.project_qgis_point_coordinates( + upper_left_point, crs, qgis_crs + ) + point_2 = cfg.utils.project_qgis_point_coordinates( + lower_right_point, crs, qgis_crs + ) + if point_1 is False: + point_1 = upper_left_point + point_2 = lower_right_point + # Error latitude or longitude exceeded limits + except Exception as err: + str(err) + point_1 = upper_left_point + point_2 = lower_right_point + cfg.map_canvas.setExtent(QgsRectangle(point_1, point_2)) + + cfg.map_canvas.refresh() + + +# Add layer to map +def add_layer_to_map(layer): + get_qgis_project().addMapLayers([layer]) + + +# Add layer +def add_vector_layer(path, name=None, vector_format=None): + if name is None: + name = cfg.rs.files_directories.file_name(path) + if vector_format is None: + vector_format = 'ogr' + layer = QgsVectorLayer(path, name, vector_format) + return layer + + +# add raster layer +def add_raster_layer(path, name=None): + if cfg.utils.check_file(path): + if name is None: + name = cfg.rs.files_directories.file_name(path) + raster = cfg.iface.addRasterLayer(path, name) + raster.setName(name) + return raster + else: + return False + + +# Get QGIS project CRS +def get_qgis_crs(): + crs = cfg.map_canvas.mapSettings().destinationCrs() + return crs + + +# Set QGIS project CRS +def set_qgis_crs(crs): + cfg.map_canvas.setDestinationCrs(crs) + + +# create QGIS point +def create_qgis_point(x, y): + return QgsPointXY(x, y) + + +# create reference system from wkt string +def create_qgis_reference_system_from_wkt(wkt): + return QgsCoordinateReferenceSystem.fromWkt(wkt) + + +# layer source +def qgis_layer_source(layer): + source = layer.source().split("|layername=")[0] + return source + + +# set layer color for ROIs +def training_symbol(layer): + style = { + 'color': '0,0,0,230', 'color_border': '255,255,255,230', + 'style': 'solid', 'style_border': 'dash' + } + symbol = QgsFillSymbol.createSimple(style) + renderer = layer.renderer() + renderer.setSymbol(symbol) + refresh_layer_symbology(layer) + + +# get ID by attributes +def get_id_by_attributes(layer, field, attribute): + ids = [] + features = layer.getFeatures( + QgsFeatureRequest().setFilterExpression( + '"%s" = \'%s\'' % (str(field), str(attribute)) + ) + ) + for feature in features: + ids.append(feature.id()) + return ids + + +# Get last feature id +def get_last_feature_id(layer): + *_, last_feature = layer.getFeatures() + return last_feature.id() + + +# Get a feature from a shapefile by feature ID +def get_feature_by_id(layer, feature_id): + feature_filter = QgsFeatureRequest().setFilterFid(feature_id) + try: + feature = layer.getFeatures(feature_filter) + return next(feature) + except Exception as err: + str(err) + return False + + +# copy feature by ID to layer +def copy_feature_to_qgis_layer(source_layer, feature_id, target_layer): + feature = get_feature_by_id(source_layer, feature_id) + # get geometry + geometry = feature.geometry() + feature.setGeometry(geometry) + try: + fields = target_layer.fields() + feature.initAttributes(fields.count()) + if feature.hasGeometry() is not True: + pass + else: + # copy polygon to vector + target_layer.startEditing() + target_layer.addFeature(feature) + target_layer.commitChanges() + target_layer.dataProvider().createSpatialIndex() + target_layer.updateExtents() + except Exception as err: + str(err) + + +# set raster color composite +def set_raster_color_composite( + raster, red_band_number, green_band_number, blue_band_number +): + raster.renderer().setRedBand(red_band_number) + raster.renderer().setGreenBand(green_band_number) + raster.renderer().setBlueBand(blue_band_number) + set_raster_contrast_enhancement(raster, cfg.default_contrast) + + +# set raster enhancement +def set_raster_contrast_enhancement( + qgis_raster_layer, contrast_type=None +): + if contrast_type is None: + contrast_type = cfg.cumulative_cut_contrast + extent = cfg.map_canvas.extent() + top_left_point = create_qgis_point(extent.xMinimum(), extent.yMaximum()) + lower_right_point = create_qgis_point(extent.xMaximum(), extent.yMinimum()) + point_1 = top_left_point + point_2 = lower_right_point + # raster crs + raster_crs = get_crs_qgis(qgis_raster_layer) + # project crs + project_crs = get_qgis_crs() + if raster_crs is None: + raster_crs = project_crs + # projection of input point from project's crs to raster's crs + if project_crs != raster_crs: + try: + point_1 = cfg.utils.project_qgis_point_coordinates( + top_left_point, project_crs, raster_crs + ) + point_2 = cfg.utils.project_qgis_point_coordinates( + lower_right_point, project_crs, raster_crs + ) + if point_1 is False: + point_1 = top_left_point + point_2 = lower_right_point + # Error latitude or longitude exceeded limits + except Exception as err: + str(err) + point_1 = top_left_point + point_2 = lower_right_point + if contrast_type == cfg.std_dev_contrast: + contrast = QgsRasterMinMaxOrigin.StdDev + elif contrast_type == cfg.cumulative_cut_contrast: + contrast = QgsRasterMinMaxOrigin.CumulativeCut + else: + contrast = QgsRasterMinMaxOrigin.StdDev + try: + qgis_raster_layer.setContrastEnhancement( + QgsContrastEnhancement.StretchToMinimumMaximum, contrast, + QgsRectangle(point_1, point_2) + ) + qgis_raster_layer.triggerRepaint() + except Exception as err: + cfg.logger.log.error(str(err)) + + +# set local cumulative cut stretch +def set_raster_cumulative_stretch(): + if (cfg.project_registry[cfg.reg_active_bandset_number] + in cfg.virtual_bandset_dict): + layer = cfg.virtual_bandset_dict[ + cfg.project_registry[cfg.reg_active_bandset_number] + ] + set_raster_contrast_enhancement(layer, cfg.cumulative_cut_contrast) + cfg.default_contrast = cfg.cumulative_cut_contrast + + +# set local standard deviation stretch +def set_raster_std_dev_stretch(): + if (cfg.project_registry[cfg.reg_active_bandset_number] + in cfg.virtual_bandset_dict): + layer = cfg.virtual_bandset_dict[ + cfg.project_registry[cfg.reg_active_bandset_number] + ] + set_raster_contrast_enhancement(layer, cfg.std_dev_contrast) + cfg.default_contrast = cfg.std_dev_contrast diff --git a/core/util_qt.py b/core/util_qt.py new file mode 100644 index 0000000..5b7fc6a --- /dev/null +++ b/core/util_qt.py @@ -0,0 +1,293 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from os import path + +from PyQt5.QtCore import Qt, QSettings +from PyQt5.QtGui import QFont, QColor +from PyQt5.QtWidgets import ( + qApp, QWidget, QMessageBox, QColorDialog, QFileDialog, QTableWidgetItem, + QTableWidgetSelectionRange +) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# read registry keys +def read_registry_keys(key, default_value): + setting = QSettings() + value = setting.value(key, str(default_value)) + try: + value = int(value) + except Exception as err: + str(err) + try: + value = eval(value) + except Exception as err: + str(err) + return value + + +# write registry value +def write_registry_keys(key, value): + setting = QSettings() + setting.setValue(key, str(value)) + + +# process events +def process_events(): + qApp.processEvents() + + +# Question box +# noinspection PyArgumentList +def question_box(caption, message): + i = QWidget() + q = QMessageBox.question( + i, caption, message, QMessageBox.Yes, + QMessageBox.No + ) + if q == QMessageBox.Yes: + return True + elif q == QMessageBox.No: + return False + else: + return False + + +# select color +# noinspection PyArgumentList +def select_color(): + c = QColorDialog.getColor() + if c.isValid(): + return c + + +# get save file name +def get_save_file_name( + parent, text, directory=None, filter_text=None, extension=None +): + if directory is None: + directory = cfg.last_saved_dir + out = QFileDialog.getSaveFileName( + parent, text, directory, + filter_text + ) + if len(out[0]) > 0: + output = out[0].replace('\\', '/') + output = output.replace('//', '/') + cfg.last_saved_dir = path.dirname(output) + if extension is not None: + if output.lower().endswith(extension): + return output + else: + output = output + '.' + extension + return output + else: + return output + else: + return False + + +# get open file name +def get_open_file(parent, text, directory=None, filter_text=None): + if directory is None: + directory = cfg.last_saved_dir + out = QFileDialog.getOpenFileName( + parent, text, directory, + filter_text + ) + cfg.last_saved_dir = path.dirname(out[0]) + return out[0] + + +# get open file names +def get_open_files(parent, text, directory=None, filter_text=None): + if directory is None: + directory = cfg.last_saved_dir + out = QFileDialog.getOpenFileNames( + parent, text, directory, + filter_text + ) + if len(out) > 0: + if len(out[0]) > 0: + cfg.last_saved_dir = path.dirname(out[0][0]) + return out[0] + + +# get existing directory +def get_existing_directory(parent, text): + directory = cfg.last_saved_dir + out = QFileDialog.getExistingDirectory(parent, text, directory) + if len(out) > 0: + cfg.last_saved_dir = out + return out + else: + return False + + +# set combobox +def set_combobox_items(combobox, item_list): + combobox.clear() + for i in item_list: + if len(i) > 0: + combobox.addItem(i) + + +# get items in combobox +def get_all_items_in_combobox(combobox): + it = [combobox.itemText(i) for i in range(combobox.count())] + return it + + +""" table functions """ + + +# delete all items in a table +def clear_table(table): + table.clearContents() + for i in range(0, table.rowCount()): + table.removeRow(0) + + +# set all items to state 0 or 2 +def all_items_set_state(table, value): + table.blockSignals(True) + rows = table.rowCount() + for row in range(0, rows): + table.item(row, 0).setCheckState(value) + table.blockSignals(False) + + +# remove rows from table +def remove_rows_from_table(table): + answer = question_box( + cfg.translate('Remove rows'), + cfg.translate( + 'Are you sure you want to remove highlighted rows from the table?' + ) + ) + if answer is True: + table.blockSignals(True) + # list of item to remove + rows = [] + for index in table.selectedIndexes(): + rows.append(index.row()) + selected_rows = list(set(rows)) + # remove items + for row in reversed(list(range(0, len(selected_rows)))): + table.removeRow(selected_rows[row]) + table.blockSignals(False) + + +# select rows in table +def select_rows_in_table(table, row_list): + count = table.columnCount() + for row in row_list: + table.setRangeSelected( + QTableWidgetSelectionRange(row, 0, row, count - 1), True + ) + + +# add item to table +def add_table_item( + table, item, row, column, enabled=True, color=None, + checkbox_state=None, tooltip=None, foreground=None, bold=None +): + item_w = QTableWidgetItem() + if checkbox_state is not None: + item_w.setCheckState(checkbox_state) + if enabled is False: + item_w.setFlags(Qt.ItemIsEnabled) + item_w.setData(Qt.DisplayRole, item) + table.setItem(row, column, item_w) + if color is not None: + table.item(row, column).setBackground(color) + if foreground is not None: + table.item(row, column).setForeground(foreground) + if tooltip is not None: + item_w.setToolTip(tooltip) + if bold is not None: + font = QFont() + font.setBold(True) + table.item(row, column).setFont(font) + return item_w + + +# set table item +def set_table_item(table, row, column, value): + table.item(row, column).setText(value) + + +# insert table row +def insert_table_row(table, row, height=None): + table.insertRow(row) + if height is not None: + table.setRowHeight(row, height) + + +# insert table column +def insert_table_column(table, column, name, width=None, hide=False): + table.insertColumn(column) + table.setHorizontalHeaderItem(column, QTableWidgetItem(name)) + if width is not None: + table.setColumnWidth(column, width) + if hide is True: + table.hideColumn(column) + + +# sort table column +def sort_table_column(table, column, ascending=False): + table.sortItems(column, ascending) + + +# set table column width +def set_column_width_list(table, width_list): + for value in width_list: + table.setColumnWidth(value[0], value[1]) + + +# set tree column width +def set_tree_column_width_list(tree, width_list): + for value in width_list: + tree.header().resizeSection(value[0], value[1]) + + +def get_color_from_rgb(red, green, blue): + return QColor(red, green, blue) + + +def get_color_from_text(text): + return QColor(text) + + +def get_match_contains(): + return Qt.MatchContains + + +def get_unchecked(): + return Qt.Unchecked + + +def get_checked(): + return Qt.Checked diff --git a/core/utils.py b/core/utils.py old mode 100644 new mode 100755 index ae4987e..dc80f00 --- a/core/utils.py +++ b/core/utils.py @@ -1,9797 +1,928 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +import base64 +import ctypes +import datetime +import json +import os +import random +import subprocess +import time +from pathlib import Path +from packaging.version import parse +import numpy as np + +from PyQt5.QtCore import Qt, QUrl, QByteArray +from PyQt5.QtGui import QColor +from PyQt5.QtNetwork import QNetworkRequest +from PyQt5.QtWidgets import qApp +from osgeo import ogr, osr +from qgis.core import ( + QgsNetworkAccessManager, QgsSymbol, + QgsRendererCategory, QgsCategorizedSymbolRenderer, + QgsPalettedRasterRenderer, QgsCoordinateReferenceSystem +) +from scipy.spatial.distance import cdist cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) -# sound for Windows -try: - import winsound -except: - pass - -class Utils: - def __init__(self): - pass - -################################## - ''' Download functions ''' -################################## - - # download html file - def downloadHtmlFileQGIS(self, url, url2 = None, timeOutSec = 1): - cfg.htmlW = url2 - r = cfg.QNetworkRequestSCP(cfg.QtCoreSCP.QUrl(url)) - cfg.reply = cfg.qgisCoreSCP.QgsNetworkAccessManager.instance().get(r) - cfg.reply.finished.connect(self.replyInTextBrowser) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return 'No' - - # load reply in text browser - def replyInTextBrowser(self): - cfg.reply.deleteLater() - html2 = cfg.reply.readAll().data() - html = bytes.decode(html2) - # Github file not found - if '

404

' in html: - r = cfg.QNetworkRequestSCP(cfg.QtCoreSCP.QUrl(cfg.htmlW)) - cfg.reply2 = cfg.qgisCoreSCP.QgsNetworkAccessManager.instance().get(r) - cfg.reply2.finished.connect(self.replyInTextBrowser2) - if len(html) > 0: - cfg.uidc.main_textBrowser.clear() - cfg.uidc.main_textBrowser.setHtml(html) - cfg.reply.finished.disconnect() - cfg.reply.abort() - cfg.reply.close() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # load reply in text browser - def replyInTextBrowser2(self): - cfg.reply2.deleteLater() - html2 = cfg.reply2.readAll().data() - html = bytes.decode(html2) - if len(html) > 0: - cfg.uidc.main_textBrowser.clear() - cfg.uidc.main_textBrowser.setHtml(html) - cfg.reply2.finished.disconnect() - cfg.reply2.abort() - cfg.reply2.close() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # reply Finish - def replyFinish(self): - cfg.replyP.deleteLater() - cfg.fileP = cfg.replyP.readAll() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # replyText - def replyText(self): - cfg.replyP.deleteLater() - cfg.htmlP = cfg.replyP.readAll() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # progress - def downloadProgress(self, value, total): - cfg.uiUtls.updateBar(self.progressP, '(' + str(value/1048576) + '/' + str(total/1048576) + ' MB) ' + self.urlP, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading')) - if cfg.actionCheck == 'No': - cfg.replyP.finished.disconnect() - cfg.replyP.abort() - cfg.replyP.close() - - # reply redirect - def replyRedirect(self): - cfg.replyR.deleteLater() - rA = cfg.replyR.attribute(cfg.QNetworkRequestSCP.RedirectionTargetAttribute) - if rA is not None: - cfg.replyRURL = rA.toString() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # reply redirect - def replyRedirect2(self): - cfg.replyR2.deleteLater() - rA = cfg.replyR2.attribute(cfg.QNetworkRequestSCP.RedirectionTargetAttribute) - if rA is not None: - cfg.replyRURL2 = rA.toString() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # reply redirect - def replyRedirect3(self): - cfg.replyR3.deleteLater() - rA = cfg.replyR3.attribute(cfg.QNetworkRequestSCP.RedirectionTargetAttribute) - if rA is not None: - cfg.replyRURL3 = rA.toString() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # connect with password QT - def passwordConnect(self, user, password, url, topLevelUrl, outputPath = None, progress = None, quiet = 'No', redirect = 'No'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ' + url) - # auth - base64UP = cfg.base64SCP.encodestring(bytes(user + ':' + password, 'utf-8')[:-1]) - h = bytes('Basic ', 'utf-8') + base64UP - hKey = cfg.QtCoreSCP.QByteArray(bytes('Authorization', 'utf-8') ) - hValue = cfg.QtCoreSCP.QByteArray(h) - r = cfg.QNetworkRequestSCP(cfg.QtCoreSCP.QUrl(url)) - r.setRawHeader(hKey, hValue) - qnamI = cfg.qgisCoreSCP.QgsNetworkAccessManager.instance() - if redirect != 'No': - cfg.replyR = qnamI.get(r) - cfg.replyR.finished.connect(self.replyRedirect) - # loop - eL = cfg.QtCoreSCP.QEventLoop() - cfg.replyR.finished.connect(eL.quit) - eL.exec_() - cfg.replyR.finished.disconnect(eL.quit) - cfg.replyR.finished.disconnect() - cfg.replyR.abort() - cfg.replyR.close() - r2 = cfg.QNetworkRequestSCP(cfg.QtCoreSCP.QUrl(cfg.replyRURL)) - r2.setRawHeader(hKey, hValue) - cfg.replyR2 = qnamI.get(r2) - cfg.replyR2.finished.connect(self.replyRedirect2) - # loop - eL = cfg.QtCoreSCP.QEventLoop() - cfg.replyR2.finished.connect(eL.quit) - eL.exec_() - cfg.replyR2.finished.disconnect(eL.quit) - cfg.replyR2.finished.disconnect() - cfg.replyR2.abort() - cfg.replyR2.close() - r3 = cfg.QNetworkRequestSCP(cfg.QtCoreSCP.QUrl(cfg.replyRURL2)) - r3.setRawHeader(hKey, hValue) - cfg.replyR3 = qnamI.get(r3) - cfg.replyR3.finished.connect(self.replyRedirect3) - # loop - eL = cfg.QtCoreSCP.QEventLoop() - cfg.replyR3.finished.connect(eL.quit) - eL.exec_() - cfg.replyR3.finished.disconnect(eL.quit) - cfg.replyR3.finished.disconnect() - cfg.replyR3.abort() - cfg.replyR3.close() - try: - if outputPath is None: - cfg.replyP = qnamI.get(r) - cfg.replyP.finished.connect(self.replyText) - # loop - eL = cfg.QtCoreSCP.QEventLoop() - cfg.replyP.finished.connect(eL.quit) - eL.exec_() - cfg.replyP.finished.disconnect(eL.quit) - cfg.replyP.finished.disconnect() - cfg.replyP.abort() - cfg.replyP.close() - return cfg.htmlP - else: - self.urlP = url - self.progressP = progress - cfg.replyP = qnamI.get(r) - cfg.replyP.finished.connect(self.replyFinish) - cfg.replyP.downloadProgress.connect(self.downloadProgress) - # loop - eL = cfg.QtCoreSCP.QEventLoop() - cfg.replyP.finished.connect(eL.quit) - eL.exec_() - cfg.replyP.finished.disconnect(eL.quit) - cfg.replyP.finished.disconnect() - cfg.replyP.abort() - cfg.replyP.close() - with open(outputPath, 'wb') as file: - file.write(cfg.fileP) - if cfg.actionCheck == 'No': - raise ValueError('Cancel action') - if cfg.osSCP.path.getsize(outputPath) > 500: - cfg.fileP = None - return 'Yes' - else: - if 'problem' in cfg.fileP: - cfg.fileP = None - return 'No' - else: - cfg.fileP = None - return 'Yes' - except Exception as err: - if str(err) != 'Cancel action': - if quiet == 'No': - if 'ssl' in str(err): - cfg.mx.msgErr56() - else: - cfg.mx.msgErr50(str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # get password opener - def getPasswordHandler(self, user, password, topLevelUrl): - pswMng = cfg.urllibSCP.request.HTTPPasswordMgrWithDefaultRealm() - pswMng.add_password(None, topLevelUrl, user, password) - passwordHandler = cfg.urllibSCP.request.HTTPBasicAuthHandler(pswMng) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return passwordHandler - - # connect with password Python - def passwordConnectPython(self, user, password, url, topLevelUrl, outputPath = None, progress = None, quiet = 'No'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ' + url) - proxyHandler = cfg.utls.getProxyHandler() - passwordHandler = cfg.utls.getPasswordHandler(user, password, topLevelUrl) - cookieHandler = cfg.urllibSCP.request.HTTPCookieProcessor() - if proxyHandler is None: - if len(user) > 0: - opener = cfg.urllibSCP.request.build_opener(cookieHandler, passwordHandler) - else: - opener = cfg.urllibSCP.request.build_opener(cookieHandler) - else: - if len(user) > 0: - opener = cfg.urllibSCP.request.build_opener(proxyHandler, cookieHandler, passwordHandler) - else: - opener = cfg.urllibSCP.request.build_opener(proxyHandler, cookieHandler) - cfg.urllibSCP.request.install_opener(opener) - try: - if outputPath is None: - response = opener.open(url) - return response - else: - f = cfg.urllibSCP.request.urlopen(url) - total_size = int(f.headers['Content-Length']) - MB_size = round(total_size/1048576, 2) - block_size = 1024 * 1024 - ratio = 0 - tune = 'Yes' - with open(outputPath, 'wb') as file: - while True: - if tune == 'Yes': - start = cfg.datetimeSCP.datetime.now() - block = f.read(block_size) - dSize = round(int(cfg.osSCP.stat(outputPath).st_size)/1048576, 2) - cfg.uiUtls.updateBar(progress, '(' + str(dSize) + '/' + str(MB_size) + ' MB) ' + url, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading')) - cfg.QtWidgetsSCP.qApp.processEvents() - if not block: - break - file.write(block) - if tune == 'Yes': - end = cfg.datetimeSCP.datetime.now() - delta = end - start - newRatio = block_size / delta.microseconds - if newRatio > ratio: - block_size = block_size + 1024 * 1024 - elif newRatio < ratio: - block_size = block_size - 1024 * 1024 - tune = 'No' - ratio = newRatio - if cfg.actionCheck == 'No': - raise ValueError('Cancel action') - return 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if str(err) != 'Cancel action': - if quiet == 'No': - if 'ssl' in str(err): - cfg.mx.msgErr56() - elif 'Navigation failed' in str(err) or 'Internal Server Error' in str(err): - return 'Internal Server Error' - else: - cfg.mx.msgErr50(str(err)) - return 'No' - - # get proxy opener - def getProxyHandler(self): - cfg.utls.getQGISProxySettings() - if str(cfg.proxyEnabled) == 'true' and len(cfg.proxyHost) > 0: - if len(cfg.proxyUser) > 0: - proxyHandler = cfg.urllibSCP.ProxyHandler({'http': 'http://'+ cfg.proxyUser + ':' + cfg.proxyPassword + '@' + cfg.proxyHost + ':' + cfg.proxyPort}) - else: - proxyHandler = cfg.urllibSCP.ProxyHandler({'http': 'http://' + cfg.proxyHost + ':' + cfg.proxyPort}) - else: - proxyHandler = None - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return proxyHandler - - # connect to USGS - def generalOpener(self): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - proxyHandler = cfg.utls.getProxyHandler() - cfg.cookieJ = cfg.CookieJarSCP() - if proxyHandler is None: - cfg.openerGeneral = cfg.urllibSCP.request.build_opener(cfg.urllibSCP.request.HTTPCookieProcessor(cfg.cookieJ)) - else: - cfg.openerGeneral = cfg.urllibSCP.request.build_opener(proxyHandler, cfg.urllibSCP.request.HTTPCookieProcessor(cfg.cookieJ)) - - # NASA search - def NASASearch(self, url): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' url:' + str(url)) - cfg.utls.generalOpener() - request1 = cfg.urllibSCP.request.Request(url) - try: - response1 = cfg.openerGeneral.open(request1) - except Exception as err: - cfg.urllibSCP.request.install_opener(cfg.openerGeneral) - # certificate error - newContext = cfg.sslSCP.SSLContext(cfg.sslSCP.PROTOCOL_TLSv1_2) - response1 = cfg.urllibSCP.request.urlopen(request1, context=newContext) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return response1 - - # download file - def downloadFile(self, url, outputPath, fileName = None, progress = None): - try: - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' url:' + str(url)) - proxyHandler = cfg.utls.getProxyHandler() - if proxyHandler is not None: - opener = cfg.urllibSCP.request.build_opener(proxyHandler) - cfg.urllibSCP.request.install_opener(opener) - else: - opener = cfg.urllibSCP.request.build_opener() - f = cfg.urllibSCP.request.urlopen(url) - try: - total_size = int(f.headers['Content-Length']) - MB_size = round(total_size/1048576, 2) - except: - total_size = 1 - block_size = 1024 * 1024 - ratio = 0 - tune = 'Yes' - if block_size >= total_size: - response = f.read() - l = open(outputPath, 'wb') - l.write(response) - l.close() - else: - with open(outputPath, 'wb') as file: - while True: - if tune == 'Yes': - start = cfg.datetimeSCP.datetime.now() - block = f.read(block_size) - dSize = round(int(cfg.osSCP.stat(outputPath).st_size)/1048576, 2) - cfg.uiUtls.updateBar(progress, '(' + str(dSize) + '/' + str(MB_size) + ' MB) ' + url, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading')) - cfg.QtWidgetsSCP.qApp.processEvents() - if not block: - break - file.write(block) - if tune == 'Yes': - end = cfg.datetimeSCP.datetime.now() - delta = end - start - newRatio = block_size / delta.microseconds - if newRatio > ratio: - block_size = block_size + 1024 * 1024 - elif newRatio < ratio: - block_size = block_size - 1024 * 1024 - tune = 'No' - ratio = newRatio - if cfg.actionCheck == 'No': - raise ValueError('Cancel action') - return 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err) + ' url:' + str(url)) - return err - - # download virtual images - def downloadVirtualImages(self, url, outputPath, fileName = None, progress = None, extentList = None): - try: - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' url:' + str(url)) - cfg.uiUtls.updateBar(progress, url, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading')) - cfg.QtWidgetsSCP.qApp.processEvents() - output = cfg.utls.createVirtualRaster3(['/vsicurl/' + url], outputPath, None, 'Yes', 0, 'No', extentList) - return 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err) + ' url:' + str(url)) - return err - - # connect with password - def USGSLogin(self, user, password, topLevelUrl): - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - if len(user) > 0: - cfg.utls.generalOpener() - request1 = cfg.urllibSCP.request.Request(topLevelUrl) - response1 = cfg.openerGeneral.open(request1) - html1 = response1.read() - # required token - tok = cfg.reSCP.findall('', str(html1)) - tid = tok[0].replace('"', '').replace(' ', '') - # login - params = cfg.urllibSCP.parse.urlencode({'username': user, 'password': password, 'csrf_token': tid}) - params2 = params.encode() - request2 = cfg.urllibSCP.request.Request('https://ers.cr.usgs.gov/login', params2) - response2 = cfg.openerGeneral.open(request2) - for cookie in cfg.cookieJ: - if cookie.name == "EROS_SSO_production": - cookievalue = cookie.value - try: - cfg.openerGeneral.addheaders = [('Cookie', 'EROS_SSO_production=' + cookievalue)] - return cookievalue - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - raise ValueError('Login error') - - # download file - def downloadFileUSGS(self, user, password, topLevelUrl, url, outputPath, fileName = None, progress = None, quiet = 'No'): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' url:' + str(url)) - cookievalue = cfg.utls.USGSLogin(user, password, topLevelUrl) - cfg.urllibSCP.request.install_opener(cfg.openerGeneral) - cfg.timeSCP.sleep(0.5) - try: - request1 = cfg.urllibSCP.request.Request(url) - response1 = cfg.openerGeneral.open(request1) - cfg.timeSCP.sleep(0.5) - f = cfg.urllibSCP.request.urlopen(response1.url) - total_size = int(f.headers['Content-Length']) - MB_size = round(total_size/1048576, 2) - block_size = 1024 * 1024 - ratio = 0 - tune = 'Yes' - with open(outputPath, 'wb') as file: - while True: - if tune == 'Yes': - start = cfg.datetimeSCP.datetime.now() - block = f.read(block_size) - dSize = round(int(cfg.osSCP.stat(outputPath).st_size)/1048576, 2) - cfg.uiUtls.updateBar(progress, '(' + str(dSize) + '/' + str(MB_size) + ' MB) ' + url, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading')) - cfg.QtWidgetsSCP.qApp.processEvents() - if not block: - break - file.write(block) - if tune == 'Yes': - end = cfg.datetimeSCP.datetime.now() - delta = end - start - newRatio = block_size / delta.microseconds - if newRatio > ratio: - block_size = block_size + 1024 * 1024 - elif newRatio < ratio: - block_size = block_size - 1024 * 1024 - tune = 'No' - ratio = newRatio - if cfg.actionCheck == 'No': - raise ValueError('Cancel action') - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return 'Yes' - except Exception as err: - if str(err) != 'Cancel action': - if quiet == 'No': - cfg.mx.msgErr50(str(err)) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err) + " url:" + str(url)) - raise ValueError(str(err)) - - # encrypt password - def encryptPassword(self, password): - e = cfg.base64SCP.b64encode(bytes(password, 'utf-8')) - return str(e) - - # decrypt password - def decryptPassword(self, password): - if password is not None: - d = cfg.base64SCP.b64decode(password) - return d - else: - return '' - -################################## - ''' LOG functions ''' -################################## - - # Clear log file - def clearLogFile(self): - if cfg.osSCP.path.isfile(cfg.logFile): - try: - l = open(cfg.logFile, 'w') - except: - pass - try: - # logger - cfg.utls.logToFile(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "LOG ACTIVE" + cfg.sysSCPInfo) - cfg.ui.log_tableWidget.clearContents() - for i in range(0, cfg.ui.log_tableWidget.rowCount()): - cfg.ui.log_tableWidget.removeRow(0) - except: - cfg.mx.msg2() - - # Get the code line number for log file - def lineOfCode(self): - return str(cfg.inspectSCP.currentframe().f_back.f_lineno) - - # logger condition - def logCondition(self, function, message = ""): - if cfg.logSetVal == 'Yes': - cfg.utls.logToFile(function, message) - - # Logger of function - def logToFile(self, function, message): - # message string - m = cfg.datetimeSCP.datetime.now().strftime("%Y-%m-%d %H.%M.%S.%f") + " " + function + " " + message + "\n" - if cfg.osSCP.path.isfile(cfg.logFile): - try: - l = open(cfg.logFile, 'a') - except: - pass - else: - l = open(cfg.logFile, 'w') - try: - l.write("Date Function Message \n") - l.write(m) - l.close() - except: - pass - try: - l.write(m) - l.close() - # log table - mT = m.split("\t") - tW = cfg.ui.log_tableWidget - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - if "ERROR exception" in mT[2]: - cfg.utls.addTableItem(tW, mT[0], c, 0, 'No', cfg.QtGuiSCP.QColor(254, 137, 137)) - cfg.utls.addTableItem(tW, mT[1], c, 1, 'No', cfg.QtGuiSCP.QColor(254, 137, 137)) - cfg.utls.addTableItem(tW, mT[2], c, 2, 'No', cfg.QtGuiSCP.QColor(254, 137, 137)) - elif "error" in mT[2].lower(): - cfg.utls.addTableItem(tW, mT[0], c, 0, 'No', cfg.QtGuiSCP.QColor(30, 200, 200)) - cfg.utls.addTableItem(tW, mT[1], c, 1, 'No', cfg.QtGuiSCP.QColor(30, 200, 200)) - cfg.utls.addTableItem(tW, mT[2], c, 2, 'No', cfg.QtGuiSCP.QColor(30, 200, 200)) - else: - cfg.utls.addTableItem(tW, mT[0], c, 0, 'No') - cfg.utls.addTableItem(tW, mT[1], c, 1, 'No') - cfg.utls.addTableItem(tW, mT[2], c, 2, 'No') - cfg.ui.log_tableWidget.scrollToBottom() - except: - pass - -################################## - ''' Time functions ''' -################################## - - # get time - def getTime(self): - t = cfg.datetimeSCP.datetime.now().strftime("%Y%m%d_%H%M%S%f") - return t - - # convert seconds to H M S - def timeToHMS(self, time): - min, sec = divmod(time, 60) - hour, min = divmod(min, 60) - if hour > 0: - m = str("%.f" % round(hour)) + " H " + str("%.f" % round(min)) + " min" - else: - m = str("%.f" % round(min)) + " min " + str("%.f" % round(sec)) + " sec" - return m - -################################## - ''' Symbology functions ''' -################################## - - # set layer color for ROIs - def ROISymbol(self, layer): - st = { 'color': '0,0,0,230', 'color_border': '255,255,255,230', 'style': 'solid', 'style_border': 'dash' } - r = cfg.qgisCoreSCP.QgsFillSymbol.createSimple(st) - renderer = layer.renderer() - renderer.setSymbol(r) - - # Define vector symbology - def vectorSymbol(self, layer, signatureList, macroclassCheck): - c = [] - n = [] - # class count - mc = [] - v = signatureList - s = cfg.qgisCoreSCP.QgsSymbol.defaultSymbol(layer.geometryType()) - s.setColor(cfg.QtGuiSCP.QColor('#000000')) - c.append(cfg.qgisCoreSCP.QgsRendererCategory(0, s, '0 - ' + cfg.uncls)) - for i in range(0, len(v)): - if macroclassCheck == 'Yes': - if int(v[i][0]) not in mc: - mc.append(int(v[i][0])) - n.append([int(v[i][0]), cfg.QtGuiSCP.QColor(v[i][6]), str(v[i][1])]) - else: - n.append([int(v[i][2]), v[i][6], str(v[i][3])]) - for b in sorted(n, key=lambda c: c[0]): - s = cfg.qgisCoreSCP.QgsSymbol.defaultSymbol(layer.geometryType()) - s.setColor(b[1]) - ca = cfg.qgisCoreSCP.QgsRendererCategory(b[0], s, str(b[0]) + ' - ' + b[2]) - c.append(ca) - f = 'DN' - r = cfg.qgisCoreSCP.QgsCategorizedSymbolRenderer(f, c) - layer.setRenderer(r) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # Define class symbology - def rasterSymbol(self, classLayer, signatureList, macroclassCheck): - # The band of classLayer - cLB = 1 - # Color list for ramp - cL = [] - n = [] - # class count - mc = [] - v = signatureList - if cfg.unclassValue is not None: - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(cfg.unclassValue, cfg.QtGuiSCP.QColor("#4d4d4d"), cfg.overlap)) - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(0, cfg.QtGuiSCP.QColor("#000000"), "0 - " + cfg.uncls)) - for i in range(0, len(v)): - if macroclassCheck == 'Yes': - if int(v[i][0]) not in mc and int(v[i][0]) != 0: - mc.append(int(v[i][0])) - n.append([int(v[i][0]), cfg.QtGuiSCP.QColor(v[i][6]), str(v[i][1])]) - else: - if int(v[i][2]) != 0: - n.append([int(v[i][2]), v[i][6], str(v[i][3])]) - for b in sorted(n, key=lambda c: c[0]): - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(b[0], b[1], str(b[0]) + " - " + b[2])) - # Create the renderer - lR = cfg.qgisCoreSCP.QgsPalettedRasterRenderer(classLayer.dataProvider(), cLB, cL) - # Apply the renderer to classLayer - classLayer.setRenderer(lR) - # refresh legend - if hasattr(classLayer, "setCacheImage"): - classLayer.setCacheImage(None) - classLayer.triggerRepaint() - cfg.utls.refreshLayerSymbology(classLayer) - ql = cfg.utls.layerSource(classLayer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(ql)) - - # Define class symbology - def rasterSymbolLCSAlgorithmRaster(self, classLayer): - # The band of classLayer - cLB = 1 - # Color list for ramp - cL = [] - if cfg.unclassValue is not None: - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(cfg.unclassValue, cfg.QtGuiSCP.QColor("#4d4d4d"), cfg.overlap)) - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(0, cfg.QtGuiSCP.QColor("#000000"), "0 " + cfg.uncls)) - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(1, cfg.QtGuiSCP.QColor("#ffffff"), "1 " + cfg.clasfd)) - # Create the renderer - lR = cfg.qgisCoreSCP.QgsPalettedRasterRenderer(classLayer.dataProvider(), cLB, cL) - # Apply the renderer to classLayer - classLayer.setRenderer(lR) - # refresh legend - if hasattr(classLayer, "setCacheImage"): - classLayer.setCacheImage(None) - classLayer.triggerRepaint() - cfg.utls.refreshLayerSymbology(classLayer) - ql = cfg.utls.layerSource(classLayer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(ql)) - - # Define class symbology - def rasterPreviewSymbol(self, previewLayer, algorithmName): - if cfg.ui.LC_signature_checkBox.isChecked(): - cfg.utls.rasterSymbolLCSAlgorithmRaster(previewLayer) - elif algorithmName == cfg.algMinDist or algorithmName == cfg.algSAM: - cfg.utls.rasterSymbolPseudoColor(previewLayer) - elif algorithmName == cfg.algML: - cfg.utls.rasterSymbolSingleBandGray(previewLayer) - - # Define class symbology pseudo color - def rasterSymbolPseudoColor(self, layer): - # Band statistics - bndStat = layer.dataProvider().bandStatistics(1) - max = bndStat.maximumValue - min = bndStat.minimumValue - # The band of layer - cLB = 1 - # Color list for ramp - cL = [] - colorMin = cfg.QtGuiSCP.QColor("#ffffff") - colorMax = cfg.QtGuiSCP.QColor("#000000") - cL.append(cfg.qgisCoreSCP.QgsColorRampShader.ColorRampItem(min, colorMin, str(min))) - cL.append(cfg.qgisCoreSCP.QgsColorRampShader.ColorRampItem(max, colorMax, str(max))) - # Create the shader - lS = cfg.qgisCoreSCP.QgsRasterShader() - # Create the color ramp function - cR = cfg.qgisCoreSCP.QgsColorRampShader() - cR.setColorRampType(cfg.qgisCoreSCP.QgsColorRampShader.Interpolated) - cR.setColorRampItemList(cL) - # Set the raster shader function - lS.setRasterShaderFunction(cR) - # Create the renderer - lR = cfg.qgisCoreSCP.QgsSingleBandPseudoColorRenderer(layer.dataProvider(), cLB, lS) - # Apply the renderer to layer - layer.setRenderer(lR) - # refresh legend - if hasattr(layer, "setCacheImage"): - layer.setCacheImage(None) - layer.triggerRepaint() - cfg.utls.refreshLayerSymbology(layer) - ql = cfg.utls.layerSource(layer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(ql)) - - # Define class symbology single band grey - def rasterSymbolSingleBandGray(self, layer): - # QGIS3 - #layer.setDrawingStyle("SingleBandGray") - try: - layer.setContrastEnhancement(cfg.qgisCoreSCP.QgsContrastEnhancement.StretchToMinimumMaximum, cfg.qgisCoreSCP.QgsRasterMinMaxOrigin.CumulativeCut) - # refresh legend - if hasattr(layer, "setCacheImage"): - layer.setCacheImage(None) - layer.triggerRepaint() - cfg.utls.refreshLayerSymbology(layer) - ql = cfg.utls.layerSource(layer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(ql)) - except Exception as err: - list = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Define raster symbology - def rasterSymbolGeneric(self, rasterLayer, zeroValue = 'Unchanged', rasterUniqueValueList = None): - if rasterUniqueValueList is None: - ql = cfg.utls.layerSource(rasterLayer) - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = ql, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, progressMessage = 'UniqueVal ', deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - pass - rasterBandUniqueVal = cfg.np.unique(values).tolist() - refRasterBandUniqueVal = sorted(rasterBandUniqueVal) - else: - refRasterBandUniqueVal = rasterUniqueValueList - try: - maxV = max(refRasterBandUniqueVal) - except: - maxV = 1 - # Color list for ramp - cL = [ cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(0, cfg.QtGuiSCP.QColor(0,0,0), zeroValue)] - for i in refRasterBandUniqueVal: - if i > maxV/2: - c = cfg.QtGuiSCP.QColor(int(255 * (i/maxV)),int(255 * (1- (i/maxV))),int(255 * (1 - (i/maxV)))) - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(i, c, str(i))) - elif i > 0: - c = cfg.QtGuiSCP.QColor(int(255 * (i/maxV)),int(255 * (i/maxV)),int(255 * (1 - (i/maxV)))) - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(i, c, str(i))) - # The band of classLayer - classLyrBnd = 1 - # Create the renderer - try: - lyrRndr = cfg.qgisCoreSCP.QgsPalettedRasterRenderer(rasterLayer.dataProvider(), classLyrBnd, cL) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # Apply the renderer to rasterLayer - rasterLayer.setRenderer(lyrRndr) - # refresh legend - if hasattr(rasterLayer, 'setCacheImage'): - rasterLayer.setCacheImage(None) - rasterLayer.triggerRepaint() - cfg.utls.refreshLayerSymbology(rasterLayer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'symbology') - - # Define scatter raster symbology - def rasterScatterSymbol(self, valueColorList): - # Color list for ramp - cL = [] - for i in valueColorList: - cL.append(cfg.qgisCoreSCP.QgsPalettedRasterRenderer.Class(i[0], cfg.QtGuiSCP.QColor(i[1]), str(i[0]))) - return cL - - # set scatter raster symbology - def setRasterScatterSymbol(self, classLayer, shader): - # The band of classLayer - cLB = 1 - # Create the renderer - lR = cfg.qgisCoreSCP.QgsPalettedRasterRenderer(classLayer.dataProvider(), cLB, shader) - # Apply the renderer to classLayer - classLayer.setRenderer(lR) - # refresh legend - if hasattr(classLayer, "setCacheImage"): - classLayer.setCacheImage(None) - classLayer.triggerRepaint() - cfg.utls.refreshLayerSymbology(classLayer) - ql = cfg.utls.layerSource(classLayer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(ql)) - - # copy renderer - def copyRenderer(self, inputRaster, outputRaster): - try: - r = inputRaster.renderer().clone() - # Apply the renderer to rasterLayer - outputRaster.setRenderer(r) - outputRaster.triggerRepaint() - cfg.utls.refreshLayerSymbology(outputRaster) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - except Exception as err: - list = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -################################## - ''' Classification functions ''' -################################## - - # calculate covariance matrix from array list - def calculateCovMatrix(self, arrayList): - matrix = cfg.np.stack(arrayList) - # covariance matrix (degree of freedom = 1 for unbiased estimate) - CovMatrix = cfg.np.ma.cov(cfg.np.ma.masked_invalid(matrix), ddof=1) - try: - try: - inv = cfg.np.linalg.inv(CovMatrix) - if cfg.np.isnan(inv[0,0]): - CovMatrix = 'No' - except: - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'TEST matrix: ' + str(CovMatrix)) - CovMatrix = 'No' - except Exception as err: - CovMatrix = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cov matrix: ' + str(CovMatrix)) - return CovMatrix - - # convert list to covariance array - def listToCovarianceMatrix(self, list): - try: - covMat = cfg.np.zeros((len(list), len(list)), dtype=cfg.np.float32) - i = 0 - for x in list: - covMat[i, :] = x - i = i + 1 - return covMat - except Exception as err: - list = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # convert covariance array to list - def covarianceMatrixToList(self, covarianceArray): - try: - d = covarianceArray.shape - list = [] - for i in range(0, d[0]): - list.append(covarianceArray[i, :].tolist()) - except Exception as err: - list = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return list - - # create one raster for each signature class - def createSignatureClassRaster(self, signatureList, gdalRasterRef, outputDirectory, nodataValue = None, outputName = None, previewSize = 0, previewPoint = None, compress = 'No', compressFormat = 'DEFLATE21'): - dT = cfg.utls.getTime() - outputRasterList = [] - for s in range(0, len(signatureList)): - if outputName is None: - o = outputDirectory + '/' + cfg.sigRasterNm + '_' + str(signatureList[s][0]) + '_' + str(signatureList[s][2]) + '_' + dT + '.tif' - else: - o = outputDirectory + '/' + outputName + '_' + str(signatureList[s][0]) + '_' + str(signatureList[s][2]) + '.tif' - outputRasterList.append(o) - oRL = cfg.utls.createRasterFromReference(gdalRasterRef, 1, outputRasterList, nodataValue, 'GTiff', cfg.rasterDataType, previewSize, previewPoint, compress, compressFormat) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'end createSignatureClassRaster') - return oRL, outputRasterList - - # perform classification - def classificationMultiprocess(self, bandListNumber, signatureList, algorithmName, rasterArray, landCoverSignature, LCSClassAlgorithm,LCSLeaveUnclassified, algBandWeigths, outputGdalRasterList, outputAlgorithmRaster, outputClassificationRaster, nodataValue, macroclassCheck, algThrshld, nodataMask): - sigArrayList = self.createArrayFromSignature(bandListNumber, signatureList) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sigArrayList ' + str(sigArrayList)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputGdalRasterList ' + str(outputGdalRasterList)) - LCSminMaxL = cfg.utls.LCSminMaxList(signatureList) - minArray = None - maxArray = None - classArray = None - classArrayAlg = None - classArrayLCS = None - equalArray = None - cfg.unclassValue = None - cfg.algThrshld = algThrshld - n = 0 - # max and min values - tr = self.thresholdList(signatureList) - # if maximum likelihood - covMatrList = self.covarianceMatrixList(signatureList) - # open input with GDAL - rDC = cfg.gdalSCP.Open(outputClassificationRaster, cfg.gdalSCP.GA_Update) - rDA = cfg.gdalSCP.Open(outputAlgorithmRaster, cfg.gdalSCP.GA_Update) - if landCoverSignature == 'Yes': - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'landCoverSignature ' + str(landCoverSignature)) - for s in sigArrayList: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - # threshold - multFactor = float(1) - # second classification - if LCSClassAlgorithm == 'Yes': - secondClassification = algorithmName - else: - secondClassification = 'No' - if secondClassification == 'No': - dataValue = -100 - cfg.unclassValue = -1000 - elif secondClassification == cfg.algMinDist: - dataValue = -100 - cfg.unclassValue = -1000 - elif secondClassification == cfg.algSAM: - dataValue = -100 - cfg.unclassValue = -1000 - elif secondClassification == cfg.algML: - dataValue = cfg.maxValDt - cfg.unclassValue = -1000 - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'algBandWeigths' + str(algBandWeigths)) - # calculate LCS array - LCSarray = cfg.utls.algorithmLCS(rasterArrayx, s, LCSminMaxL[n][0], LCSminMaxL[n][1] , multFactor, algBandWeigths, dataValue, nodataValue) - if type(LCSarray) is not int: - # open input with GDAL - oR = cfg.gdalSCP.Open(outputGdalRasterList[n], cfg.gdalSCP.GA_Update) - # binary classification - LCSarrayWrite = cfg.np.where(LCSarray==dataValue,1,0) - # algorithm raster - cfg.utls.writeArrayBlock(oR, 1, LCSarrayWrite, 0, 0, nodataValue) - oR = None - LCSarrayWrite = None - # find equal array for overlapping classes - if equalArray is None: - equalArray = LCSarray - else: - equalArray = cfg.utls.findEqualArray(LCSarray, equalArray, dataValue, nodataValue, cfg.unclassValue) - if classArray is None: - classArray = nodataValue - if macroclassCheck == 'Yes': - classArray = cfg.utls.classifyClassesLCSSimple(LCSarray, equalArray, classArray, dataValue, cfg.unclassValue, nodataValue, signatureList[n][0]) - else: - classArray = cfg.utls.classifyClassesLCSSimple(LCSarray, equalArray, classArray, dataValue, cfg.unclassValue, nodataValue, signatureList[n][2]) - # in case of same class overlapping - equalArray = cfg.np.where( (equalArray ==cfg.unclassValue) & (classArray !=cfg.unclassValue), dataValue, equalArray) - # refine class output - classArrayLCS = cfg.np.where(classArray == nodataValue, 0, classArray) - algArrayWrite = cfg.np.where(classArrayLCS == 0, 0, cfg.np.where(classArrayLCS == cfg.unclassValue, cfg.unclassValue, 1)) - # algorithm raster - cfg.utls.writeArrayBlock(rDA, 1, algArrayWrite, 0, 0, nodataValue) - algArrayWrite = None - if secondClassification == 'No': - pass - elif secondClassification == cfg.algMinDist: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - c = cfg.utls.algorithmMinimumDistance(rasterArrayx, s, cfg.algBandWeigths) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 0: - c = cfg.utls.minimumDistanceThreshold(c, algThrshld, nodataValue) - if type(c) is not int: - if minArray is None: - minArray = c - else: - minArray = cfg.utls.findMinimumArray(c, minArray, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = cfg.utls.classifyClasses(c, minArray, signatureList[n][0]) - else: - clA = cfg.utls.classifyClasses(c, minArray, signatureList[n][2]) - # classification raster - if classArrayAlg is None: - classArrayAlg = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArrayAlg = e.mask * classArrayAlg + clA - e = None - clA = None - classArrayAlg[classArrayAlg == cfg.unclassifiedVal] = 0 - classArrayLCS = cfg.np.where(classArray == cfg.unclassValue, classArrayAlg, classArray) - if LCSLeaveUnclassified == 'Yes': - pass - else: - classArrayLCS = cfg.np.where(classArray == nodataValue, classArrayAlg, classArrayLCS) - else: - return 'No' - elif secondClassification == cfg.algSAM: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - c = cfg.utls.algorithmSAM(rasterArrayx, s, cfg.algBandWeigths) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 0: - if algThrshld > 90: - algThrshld = 90 - c = cfg.utls.minimumDistanceThreshold(c, algThrshld, nodataValue) - if type(c) is not int: - if minArray is None: - minArray = c - else: - minArray = cfg.utls.findMinimumArray(c, minArray, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = cfg.utls.classifyClasses(c, minArray, signatureList[n][0]) - else: - clA = cfg.utls.classifyClasses(c, minArray, signatureList[n][2]) - # classification raster - if classArrayAlg is None: - classArrayAlg = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArrayAlg = e.mask * classArrayAlg + clA - e = None - clA = None - classArrayAlg[classArrayAlg == cfg.unclassifiedVal] = 0 - classArrayLCS = cfg.np.where(classArray == cfg.unclassValue, classArrayAlg, classArray) - if LCSLeaveUnclassified == 'Yes': - pass - else: - classArrayLCS = cfg.np.where(classArray == nodataValue, classArrayAlg, classArrayLCS) - else: - return 'No' - elif secondClassification == cfg.algML: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 100: - algThrshld = 100 - c = cfg.utls.algorithmMaximumLikelihood(rasterArrayx, s, covMatrList[n], cfg.algBandWeigths, algThrshld, nodataValue) - if type(c) is not int: - if maxArray is None: - maxArray = c - else: - maxArray = cfg.utls.findMaximumArray(c, maxArray, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = cfg.utls.classifyClasses(c, maxArray, signatureList[n][0]) - else: - clA = cfg.utls.classifyClasses(c, maxArray, signatureList[n][2]) - # classification raster - if classArrayAlg is None: - classArrayAlg = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArrayAlg = e.mask * classArrayAlg + clA - e = None - clA = None - classArrayAlg[classArrayAlg == cfg.unclassifiedVal] = 0 - classArrayLCS = cfg.np.where(classArray == cfg.unclassValue, classArrayAlg, classArray) - if LCSLeaveUnclassified == 'Yes': - pass - else: - classArrayLCS = cfg.np.where(classArray == nodataValue, classArrayAlg, classArrayLCS) - else: - return 'No' - classArrayWrite = cfg.np.where(classArrayLCS == nodataValue, 0, classArrayLCS) - if nodataMask is not None: - classArray[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - # classification raster - cfg.utls.writeArrayBlock(rDC, 1, classArrayWrite, 0, 0, nodataValue) - n = n + 1 - else: - return 'No' - elif algorithmName == cfg.algMinDist: - for s in sigArrayList: - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'n ' + str(n)) - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - c = self.algorithmMinimumDistance(rasterArrayx, s, cfg.algBandWeigths) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'algorithmMinimumDistance signature' + str(c)) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 0: - c = self.minimumDistanceThreshold(c, algThrshld, nodataValue) - if type(c) is not int: - # open input with GDAL - oR = cfg.gdalSCP.Open(outputGdalRasterList[n], cfg.gdalSCP.GA_Update) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputGdalRasterList[n] ' + str(outputGdalRasterList[n])) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oR ' + str(oR)) - # algorithm raster - cfg.utls.writeArrayBlock(oR, 1, c, 0, 0, nodataValue) - oR = None - if minArray is None: - minArray = c - else: - minArray = self.findMinimumArray(c, minArray, nodataValue) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'findMinimumArray signature' + str(minArray[0,0])) - # minimum raster - self.writeArrayBlock(rDA, 1, minArray, 0, 0, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = self.classifyClasses(c, minArray, signatureList[n][0]) - else: - clA = self.classifyClasses(c, minArray, signatureList[n][2]) - # classification raster - if classArray is None: - classArray = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArray = e.mask * classArray + clA - e = None - clA = None - classArray[classArray == cfg.unclassifiedVal] = 0 - if nodataMask is not None: - classArray[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - # classification raster - self.writeArrayBlock(rDC, 1, classArray, 0, 0, nodataValue) - n = n + 1 - else: - return 'No' - elif algorithmName == cfg.algSAM: - for s in sigArrayList: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - c = self.algorithmSAM(rasterArrayx, s, cfg.algBandWeigths) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 0: - if algThrshld > 90: - algThrshld = 90 - c = self.minimumDistanceThreshold(c, algThrshld, nodataValue) - if type(c) is not int: - # open input with GDAL - oR = cfg.gdalSCP.Open(outputGdalRasterList[n], cfg.gdalSCP.GA_Update) - # algorithm raster - self.writeArrayBlock(oR, 1, c, 0, 0, nodataValue) - oR = None - if minArray is None: - minArray = c - else: - minArray = self.findMinimumArray(c, minArray, nodataValue) - # minimum raster - self.writeArrayBlock(rDA, 1, minArray, 0, 0, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = self.classifyClasses(c, minArray, signatureList[n][0]) - else: - clA = self.classifyClasses(c, minArray, signatureList[n][2]) - # classification raster - if classArray is None: - classArray = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArray = e.mask * classArray + clA - e = None - clA = None - classArray[classArray == cfg.unclassifiedVal] = 0 - if nodataMask is not None: - classArray[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - # classification raster - self.writeArrayBlock(rDC, 1, classArray, 0, 0, nodataValue) - n = n + 1 - else: - return 'No' - elif algorithmName == cfg.algML: - for s in sigArrayList: - # algorithm - rasterArrayx = cfg.np.copy(rasterArray) - # threshold - algThrshld = float(tr[n]) - if algThrshld > 100: - algThrshld = 100 - c = self.algorithmMaximumLikelihood(rasterArrayx, s, covMatrList[n], cfg.algBandWeigths, algThrshld, nodataValue) - if type(c) is not int: - # open input with GDAL - oR = cfg.gdalSCP.Open(outputGdalRasterList[n], cfg.gdalSCP.GA_Update) - # algorithm raster - self.writeArrayBlock(oR, 1, c, 0, 0, nodataValue) - oR = None - if maxArray is None: - maxArray = c - else: - maxArray = self.findMaximumArray(c, maxArray, nodataValue) - # maximum raster - self.writeArrayBlock(rDA, 1, maxArray, 0, 0, nodataValue) - # signature classification raster - if macroclassCheck == 'Yes': - clA = self.classifyClasses(c, maxArray, signatureList[n][0]) - else: - clA = self.classifyClasses(c, maxArray, signatureList[n][2]) - # classification raster - if classArray is None: - classArray = clA - else: - e = cfg.np.ma.masked_equal(clA, 0) - classArray = e.mask * classArray + clA - e = None - clA = None - classArray[classArray == cfg.unclassifiedVal] = 0 - if nodataMask is not None: - classArray[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - # classification raster - self.writeArrayBlock(rDC, 1, classArray, 0, 0, nodataValue) - n = n + 1 - else: - return 'No' - classArray = None - rasterArrayx = None - c = None - try: - minArray = None - except: - pass - try: - maxArray = None - except: - pass - rDC = None - rDA = None - - # classify classes - def classifyClasses(self, algorithmArray, minimumArray, classID, nodataValue = -999): - if int(classID) == 0: - classID = cfg.unclassifiedVal - cB = cfg.np.equal(algorithmArray, minimumArray) * int(classID) - cA = cfg.np.where(minimumArray != nodataValue, cB, cfg.unclassifiedVal) - return cA - - # classify classes - def classifyClassesLCSSimple(self, LCSarray, equalArray, classArrayLCS, dataValue, unclassValue, nodataValue, classID): - cA = cfg.np.where( (LCSarray == dataValue) & (equalArray == dataValue), int(classID), cfg.np.where( (equalArray == unclassValue) & (classArrayLCS != int(classID) ), unclassValue,classArrayLCS ) ) - return cA - - # find minimum array - def findMinimumArray(self, firstArray, secondArray, nodataValue = -999): - f = cfg.np.where(firstArray == nodataValue, cfg.maxValDt, firstArray) - s = cfg.np.where(secondArray == nodataValue, cfg.maxValDt, secondArray) - n = cfg.np.minimum(f, s) - m = cfg.np.where(n == cfg.maxValDt, nodataValue, n) - return m - - # find equal array - def findEqualArray(self, firstArray, secondArray, dataValue = -1, nodataValue = -999, unclassifiedValue = -1000): - f = cfg.np.where( (firstArray == dataValue) & (secondArray == dataValue), unclassifiedValue, cfg.np.where(firstArray == unclassifiedValue, unclassifiedValue, cfg.np.where(secondArray == unclassifiedValue, unclassifiedValue, cfg.np.where(firstArray == nodataValue, secondArray, firstArray) ) ) ) - return f - - # find maximum array - def findMaximumArray(self, firstArray, secondArray, nodataValue = -999): - m = cfg.np.maximum(firstArray, secondArray) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return m - - # set threshold - def maximumLikelihoodThreshold(self, array, nodataValue = 0): - outArray = cfg.np.where(array > cfg.maxLikeNoDataVal, array, nodataValue) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return outArray - - # set threshold - def minimumDistanceThreshold(self, array, threshold, nodataValue = 0): - outArray = cfg.np.where(array < threshold, array, nodataValue) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return outArray - - # create array from signature list - def createArrayFromSignature(self, bandListNumber, signatureList): - arrayList = [] - for s in signatureList: - val = s[4] - array = cfg.np.zeros((bandListNumber), dtype=cfg.np.float32) - max = bandListNumber * 2 - i = 0 - for b in range(0, max, 2): - array[i] = val[b] - i = i + 1 - arrayList.append(array) - return arrayList - - # minimum Euclidean distance algorithm [ sqrt( sum( (r_i - s_i)^2 ) ) ] - def algorithmMinimumDistance(self, rasterArray, signatureArray, weightList = None): - try: - if weightList is not None: - c = 0 - for w in weightList: - rasterArray[:,:,c] *= w - signatureArray[c] *= w - c = c + 1 - algArray = cfg.np.sqrt(((rasterArray - signatureArray)**2).sum(axis = 2)) - return algArray - except Exception as err: - return 0 - - # create covariance matrix list from signature list - def covarianceMatrixList(self, signatureList): - c = [] - for s in signatureList: - cov = s[7] - c.append(cov) - return c - - # create LCSmin LCSmax list from signature list - def LCSminMaxList(self, signatureList): - arrayList = [] - for s in signatureList: - arrayList.append([s[8], s[9]]) - return arrayList - - # create threshold list from signature list - def thresholdList(self, signatureList): - c = [] - if cfg.algThrshld > 0: - for s in signatureList: - c.append(cfg.algThrshld) - else: - for s in signatureList: - t = s[10] - c.append(t) - return c - - # calculate critical chi square and threshold - def chisquare(self, algThrshld, bands): - p = (algThrshld / 100) - chi = cfg.statdistrSCP.chi2.isf(p, bands) - return chi - - # Maximum Likelihood algorithm - def algorithmMaximumLikelihood(self, rasterArray, signatureArray, covarianceMatrix, weightList = None, algThrshld = 0, nodataValue = 0): - try: - if weightList is not None: - c = 0 - for w in weightList: - rasterArray[:,:,c] *= w - signatureArray[c] *= w - c = c + 1 - (sign, logdet) = cfg.np.linalg.slogdet(covarianceMatrix) - invC = cfg.np.linalg.inv(covarianceMatrix) - d = rasterArray - signatureArray - algArray = - logdet - (cfg.np.dot(d, invC) * d).sum(axis = 2) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' logdet: ' + str(logdet)) - if algThrshld > 0: - chi = self.chisquare(algThrshld, covarianceMatrix.shape[0]) - threshold = - 2 * chi - logdet - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' threshold: ' + str(threshold) + ' algThrshld: ' + str(algThrshld)) - algArray[algArray < threshold] = nodataValue - return algArray - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 0 - - # spectral angle mapping algorithm [ arccos( sum(r_i * s_i) / ( sum(r_i**2) * sum(s_i**2) ) ) ] - def algorithmSAM(self, rasterArray, signatureArray, weightList = None): - try: - if weightList is not None: - c = 0 - for w in weightList: - rasterArray[:,:,c] *= w - signatureArray[c] *= w - c = c + 1 - algArray = cfg.np.arccos((rasterArray * signatureArray).sum(axis = 2) / cfg.np.sqrt((rasterArray**2).sum(axis = 2) * (signatureArray**2).sum())) * 180 / cfg.np.pi - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return algArray - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 0 - - # land cover signature - def algorithmLCS(self, rasterArray, signatureArray, LCSmin, LCSmax, multFactor, weightList = None, dataValue = 0, nodataValue = -999): - try: - if weightList is not None: - c = 0 - for w in weightList: - rasterArray[:,:,c] *= w - signatureArray[c] *= w - LCSmin[c] *= w - LCSmax[c] *= w - c = c + 1 - condit1 = "cfg.np.where( " - for i in range(len(signatureArray)): - condit1 = condit1 + "(cfg.np.around(rasterArray[:,:," + str(i) + "], 11) >= cfg.np.around(" + repr(LCSmin[i] * multFactor) + ", 11)) & (cfg.np.around(rasterArray[:,:," + str(i) + "], 11) <= cfg.np.around(" + repr(LCSmax[i] * multFactor) + ", 11)) & " - condit1 = condit1[:-4] + "), " +repr(dataValue) +", " + repr(nodataValue) + ")" - algArray = eval(condit1) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return algArray - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 0 - -################################## - ''' Signature spectral distance functions ''' -################################## - - # calculate Jeffries-Matusita distance Jij = 2[1 − e^(−B)] from Richards, J. A. & Jia, X. 2006. Remote Sensing Digital Image Analysis: An Introduction, Springer. - def jeffriesMatusitaDistance(self, signatureArrayI, signatureArrayJ, covarianceMatrixI, covarianceMatrixJ, weightList = None): - try: - I = cfg.np.array(signatureArrayI) - J = cfg.np.array(signatureArrayJ) - cI = cfg.np.copy(covarianceMatrixI) - cJ = cfg.np.copy(covarianceMatrixJ) - if weightList is not None: - c = 0 - for w in weightList: - I[c] *= w - J[c] *= w - c = c + 1 - d = (I - J) - C = (cI + cJ)/2 - invC = cfg.np.linalg.inv(C) - dInvC = cfg.np.dot(d.T, invC) - f = cfg.np.dot(dInvC, d) / 8.0 - (signC, logdetC) = cfg.np.linalg.slogdet(C) - (signcI, logdetcI) = cfg.np.linalg.slogdet(cI) - (signcJ, logdetcJ) = cfg.np.linalg.slogdet(cJ) - s = cfg.np.log(signC * cfg.np.exp(logdetC) / (cfg.np.sqrt(signcI * cfg.np.exp(logdetcI)) * cfg.np.sqrt(signcJ * cfg.np.exp(logdetcJ)))) / 2.0 - B = f + s - JM = 2 * (1 - cfg.np.exp(-B)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - JM = cfg.notAvailable - return JM - - # calculate transformed divergence dij = 2[1 − e^(−dij/8)] from Richards, J. A. & Jia, X. 2006. Remote Sensing Digital Image Analysis: An Introduction, Springer. - def transformedDivergence(self, signatureArrayI, signatureArrayJ, covarianceMatrixI, covarianceMatrixJ): - try: - I = cfg.np.array(signatureArrayI) - J = cfg.np.array(signatureArrayJ) - d = (I - J) - cI = covarianceMatrixI - cJ = covarianceMatrixJ - invCI = cfg.np.linalg.inv(cI) - invCJ = cfg.np.linalg.inv(cJ) - p1 = (cI - cJ) * (invCI - invCJ) - t1 = 0.5 * cfg.np.trace(p1) - p2 = (invCI + invCJ) * d - p3 = p2 * d.T - t2 = 0.5 * cfg.np.trace(p3) - div = t1 + t2 - TD = 2 * (1 - cfg.np.exp(-div/8.0)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - TD = cfg.notAvailable - return TD - - # Bray-Curtis similarity (100 - 100 * sum(abs(x[ki]-x[kj]) / (sum(x[ki] + x[kj]))) - def brayCurtisSimilarity(self, signatureArrayI, signatureArrayJ): - try: - I = cfg.np.array(signatureArrayI) - J = cfg.np.array(signatureArrayJ) - sumIJ = I.sum() + J.sum() - d = cfg.np.sqrt((I - J)**2) - sim = 100 - d.sum() / sumIJ * 100 - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - sim = cfg.notAvailable - return sim - - # Euclidean distance sqrt(sum((x[ki] - x[kj])^2)) - def euclideanDistance(self, signatureArrayI, signatureArrayJ, weightList = None): - try: - I = cfg.np.array(signatureArrayI) - J = cfg.np.array(signatureArrayJ) - if weightList is not None: - c = 0 - for w in weightList: - I[c] *= w - J[c] *= w - c = c + 1 - d = (I - J)**2 - dist = cfg.np.sqrt(d.sum()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - dist = cfg.notAvailable - return dist - - # Spectral angle algorithm [ arccos( sum(r_i * s_i) / sqrt( sum(r_i**2) * sum(s_i**2) ) ) ] - def spectralAngle(self, signatureArrayI, signatureArrayJ, weightList = None): - try: - I = cfg.np.array(signatureArrayI) - J = cfg.np.array(signatureArrayJ) - if weightList is not None: - c = 0 - for w in weightList: - I[c] *= w - J[c] *= w - c = c + 1 - angle = cfg.np.arccos((I * J).sum() / cfg.np.sqrt((I**2).sum() * (J**2).sum())) * 180 / cfg.np.pi - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - angle = cfg.notAvailable - return angle - -################################## - ''' Signature functions ''' -################################## - - # calculate ROI signature (one signature for ROIs that have the same macroclass ID and class ID) - def calculateSignature(self, lyr, rasterName, featureIDList, macroclassID, macroclassInfo, classID, classInfo, progress = None, progresStep = None, plot = 'No', tempROI = 'No', SCP_UID = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if progress is not None: - cfg.uiUtls.updateBar(progress + int((1 / 4) * progresStep)) - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - # temporary layer - tSD = cfg.utls.createTempRasterPath('tif') - tLP = cfg.utls.createTempRasterPath('gpkg') - # get layer crs - crs = cfg.utls.getCrs(lyr) - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP, format = 'GPKG') - mL = cfg.utls.addVectorLayer(tLP) - rD = None - for x in featureIDList: - # copy ROI to temp shapefile - cfg.utls.copyFeatureToLayer(lyr, x, mL) - tRxs = cfg.utls.createTempRasterPath('tif') - if progress is not None: - cfg.uiUtls.updateBar(progress + int((2 / 4) * progresStep)) - cfg.tblOut = {} - cfg.parallelArrayDict = {} - ROIArray = [] - ROIsize = None - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - cfg.utls.checkBandSet(bandSetNumber) - check = cfg.utls.vectorToRaster(None, tLP, None, tRxs, cfg.bndSetLst[0], None, 'GTiff', 1) - if check == 'No': - return 'No' - outList = cfg.utls.clipRasterByRaster(cfg.bndSetLst, tRxs, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculating signature'), stats = 'Yes') - else: - rS = cfg.utls.selectLayerbyName(rasterName, 'Yes') - check = cfg.utls.vectorToRaster(None, tLP, None, tRxs, rS.source(), None, 'GTiff', 1) - if check == 'No': - return 'No' - # calculate ROI center, height and width - rCX, rCY, rW, rH = cfg.utls.getShapefileRectangleBox(tLP) - # subset - tLX, tLY, pS = cfg.utls.imageInformation(rasterName) - tS = cfg.utls.createTempRasterPath('tif') - # reduce band size - pr = cfg.utls.subsetImage(rasterName, rCX, rCY, int(round(rW/pS + 3)), int(round(rH/pS + 3)), str(tS), virtual = 'Yes') - if pr == 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error edge') - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return pr - oList = cfg.utls.rasterToBands(tS, cfg.tmpDir, None, 'No', cfg.bandSetsList[bandSetNumber][6]) - outList = cfg.utls.clipRasterByRaster(oList, tRxs, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculating signature'), stats = 'Yes') - # calculate signatures - b = 0 - ROIsizes = [] - for x in sorted(cfg.parallelArrayDict): - try: - for dic in cfg.parallelArrayDict[x]: - rStat, ar, ROIsize = dic[1] - ROIsizes.append(ROIsize) - except: - pass - rStatStr = str(rStat) - rStatStr = rStatStr.replace('nan', '0') - rStat = eval(rStatStr) - ROIArray.append(ar) - cfg.tblOut['BAND_' + str(b+1)] = rStat - cfg.tblOut['WAVELENGTH_' + str(b + 1)] = cfg.bandSetsList[bandSetNumber][4][b] - b = b + 1 - if progress is not None: - cfg.uiUtls.updateBar(progress + int((3 / 4) * progresStep)) - # if not temporary ROI min max - if tempROI != 'MinMax': - try: - covMat = cfg.utls.calculateCovMatrix(ROIArray) - if covMat == 'No': - cfg.mx.msgWar12(macroclassID, classID) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - covMat = 'No' - cfg.mx.msgWar12(macroclassID, classID) - # remove temp layers - cfg.utls.removeLayer(cfg.utls.fileName(tLP)) - try: - cfg.osSCP.remove(tRxs) - except: - pass - try: - cfg.tblOut['ROI_SIZE'] = min(ROIsizes) - except: - pass - # if not temporary ROI min max - if tempROI != 'MinMax': - cfg.utls.ROIStatisticsToSignature(covMat, macroclassID, macroclassInfo, classID, classInfo, bandSetNumber, cfg.bandSetsList[bandSetNumber][5], plot, tempROI, SCP_UID) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - if progress is not None: - cfg.uiUtls.updateBar(progress + int((4 / 4) * progresStep)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "roi signature calculated") - - # calculate pixel signature - def calculatePixelSignature(self, point, rasterName, bandSetNumber = None, plot = 'No', showPlot = 'Yes'): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - cfg.tblOut = {} - cfg.tblOut["ROI_SIZE"] = 1 - rStat = [] - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - for b in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - rast = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][b], 'Yes') - # open input with GDAL - try: - ql = cfg.utls.layerSource(rast) - Or = cfg.gdalSCP.Open(ql, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return 'No' - OrB = Or.GetRasterBand(1) - geoT = Or.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - try: - bVal = float(cfg.utls.readArrayBlock(OrB, pixelStartColumn, pixelStartRow, 1, 1)) * cfg.bandSetsList[bandSetNumber][6][0][b] + cfg.bandSetsList[bandSetNumber][6][1][b] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return 'No' - rStat = [bVal, bVal, bVal, 0] - cfg.tblOut["BAND_" + str(b + 1)] = rStat - cfg.tblOut["WAVELENGTH_" + str(b + 1)] = cfg.bandSetsList[bandSetNumber][4][b] - else: - rL = cfg.utls.selectLayerbyName(rasterName, 'Yes') - # open input with GDAL - try: - qll = cfg.utls.layerSource(rL) - Or = cfg.gdalSCP.Open(qll, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return 'No' - bCount = rL.bandCount() - for b in range(1, bCount + 1): - OrB = Or.GetRasterBand(b) - geoT = Or.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - try: - bVal = float(cfg.utls.readArrayBlock(OrB, pixelStartColumn, pixelStartRow, 1, 1)) * cfg.bandSetsList[bandSetNumber][6][0][b-1] + cfg.bandSetsList[bandSetNumber][6][1][b-1] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return 'No' - rStat = [bVal, bVal, bVal, 0] - cfg.tblOut["BAND_" + str(b)] = rStat - cfg.tblOut["WAVELENGTH_" + str(b)] = cfg.bandSetsList[bandSetNumber][4][b-1] - macroclassID = 0 - classID = 0 - macroclassInfo = cfg.pixelNm + " " + cfg.bandSetName + str(bandSetNumber + 1) - classInfo = cfg.pixelCoords + " " + str(point) - covMat = 'No' - val = cfg.utls.ROIStatisticsToSignature(covMat, macroclassID, macroclassInfo, classID, classInfo, bandSetNumber, cfg.bandSetsList[bandSetNumber][5], plot, 'No') - if showPlot == 'Yes': - cfg.spSigPlot.showSignaturePlotT() - return val - - # Get values for ROI signature - def ROIStatisticsToSignature(self, covarianceMatrix, macroclassID, macroclassInfo, classID, classInfo, bandSetNumber = None, unit = None, plot = 'No', tempROI = 'No', SCP_UID = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - iB = len(cfg.bandSetsList[bandSetNumber][3]) - else: - iR = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - iB = iR.bandCount() - wvl = [] - val = [] - valM = [] - min = [] - max = [] - vMin = [] - vMax = [] - try: - ROISize = cfg.tblOut['ROI_SIZE'] - for b in range(1, iB + 1): - stats = cfg.tblOut['BAND_' + str(b)] - w = cfg.tblOut['WAVELENGTH_' + str(b)] - wvl.append(w) - vMin.append(stats[0]) - vMax.append(stats[1]) - # values for mean and standard deviation - vM = stats[2] - vS = stats[3] - val.append(vM) - valM.append(vM) - val.append(vS) - #min.append(vM - vS) - #max.append(vM + vS) - min = vMin - max = vMax - c, cc = cfg.utls.randomColor() - if plot == 'No': - if SCP_UID is None: - i = cfg.utls.signatureID() - else: - i = SCP_UID - cfg.signList['CHECKBOX_' + str(i)] = cfg.QtSCP.Checked - cfg.signList['MACROCLASSID_' + str(i)] = macroclassID - cfg.signList['MACROCLASSINFO_' + str(i)] = macroclassInfo - cfg.signList['CLASSID_' + str(i)] = classID - cfg.signList['CLASSINFO_' + str(i)] = classInfo - cfg.signList['WAVELENGTH_' + str(i)] = wvl - cfg.signList['VALUES_' + str(i)] = val - cfg.signList['MIN_VALUE_' + str(i)] = vMin - cfg.signList['MAX_VALUE_' + str(i)] = vMax - cfg.signList['ROI_SIZE_' + str(i)] = ROISize - cfg.signList['LCS_MIN_' + str(i)] = min - cfg.signList['LCS_MAX_' + str(i)] = max - cfg.signList['COVMATRIX_' + str(i)] = covarianceMatrix - cfg.signList['MD_THRESHOLD_' + str(i)] = cfg.algThrshld - cfg.signList['ML_THRESHOLD_' + str(i)] = cfg.algThrshld - cfg.signList['SAM_THRESHOLD_' + str(i)] = cfg.algThrshld - # counter - n = 0 - m = [] - sdL = [] - for wi in wvl: - m.append(val[n * 2]) - sdL.append(val[n * 2 +1]) - n = n + 1 - cfg.signList['MEAN_VALUE_' + str(i)] = m - cfg.signList['SD_' + str(i)] = sdL - if unit is None: - unit = cfg.bandSetsList[bandSetNumber][5] - cfg.signList['UNIT_' + str(i)] = unit - cfg.signList['COLOR_' + str(i)] = c - #cfg.signList['COMPL_COLOR_' + str(i)] = cc - cfg.signIDs['ID_' + str(i)] = i - # calculation for plot - elif plot == 'Yes': - if SCP_UID is None: - i = cfg.utls.signatureID() - else: - i = SCP_UID - cfg.spectrPlotList['CHECKBOX_' + str(i)] = cfg.QtSCP.Checked - cfg.spectrPlotList['MACROCLASSID_' + str(i)] = macroclassID - cfg.spectrPlotList['MACROCLASSINFO_' + str(i)] = macroclassInfo - cfg.spectrPlotList['CLASSID_' + str(i)] = classID - cfg.spectrPlotList['CLASSINFO_' + str(i)] = classInfo - cfg.spectrPlotList['WAVELENGTH_' + str(i)] = wvl - cfg.spectrPlotList['VALUES_' + str(i)] = val - cfg.spectrPlotList['LCS_MIN_' + str(i)] = vMin - cfg.spectrPlotList['LCS_MAX_' + str(i)] = vMax - cfg.spectrPlotList['MIN_VALUE_' + str(i)] = vMin - cfg.spectrPlotList['MAX_VALUE_' + str(i)] = vMax - cfg.spectrPlotList['ROI_SIZE_' + str(i)] = ROISize - cfg.spectrPlotList['COVMATRIX_' + str(i)] = covarianceMatrix - cfg.spectrPlotList['MD_THRESHOLD_' + str(i)] = cfg.algThrshld - cfg.spectrPlotList['ML_THRESHOLD_' + str(i)] = cfg.algThrshld - cfg.spectrPlotList['SAM_THRESHOLD_' + str(i)] = cfg.algThrshld - # counter - n = 0 - m = [] - sdL = [] - for wi in wvl: - m.append(val[n * 2]) - sdL.append(val[n * 2 +1]) - n = n + 1 - cfg.spectrPlotList['MEAN_VALUE_' + str(i)] = m - cfg.spectrPlotList['SD_' + str(i)] = sdL - if unit is None: - unit = cfg.bandSetsList[bandSetNumber][5] - cfg.spectrPlotList['UNIT_' + str(i)] = unit - cfg.spectrPlotList['COLOR_' + str(i)] = c - #cfg.spectrPlotList['COMPL_COLOR_' + str(i)] = cc - cfg.signPlotIDs['ID_' + str(i)] = i - if tempROI == 'Yes': - try: - cfg.tmpROIColor = cfg.spectrPlotList['COLOR_' + str(cfg.tmpROIID)] - if cfg.spectrPlotList['MACROCLASSINFO_' + str(cfg.tmpROIID)] == cfg.tmpROINm: - cfg.spSigPlot.removeSignatureByID(cfg.tmpROIID) - cfg.tmpROIID = i - cfg.spectrPlotList['COLOR_' + str(i)] = cfg.tmpROIColor - else: - cfg.tmpROIID = i - cfg.spectrPlotList['COLOR_' + str(i)] = cfg.QtGuiSCP.QColor(cfg.ROIClrVal) - except: - cfg.tmpROIID = i - cfg.spectrPlotList['COLOR_' + str(i)] = cfg.QtGuiSCP.QColor(cfg.ROIClrVal) - #cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' values to shape concluded, plot: ' + str(plot)) - elif plot == 'Pixel': - return valM - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return [] - - # import a shapefile - def importShapefile(self): - shpFile = cfg.ui.select_shapefile_label.text() - if cfg.shpLay is None: - cfg.mx.msg3() - return 'No' - if len(shpFile) > 0: - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - shpName = cfg.utls.fileName(shpFile) - tSS = cfg.utls.addVectorLayer(shpFile, shpName, 'ogr') - # create memory layer - provider = tSS.dataProvider() - fields = provider.fields() - tCrs = cfg.utls.getCrs(cfg.shpLay) - pCrs = cfg.utls.getCrs(tSS) - f = cfg.qgisCoreSCP.QgsFeature() - mcIdF = self.fieldID(tSS, cfg.ui.MC_ID_combo.currentText()) - mcInfoF = self.fieldID(tSS, cfg.ui.MC_Info_combo.currentText()) - cIdF = self.fieldID(tSS, cfg.ui.C_ID_combo.currentText()) - cInfoF = self.fieldID(tSS, cfg.ui.C_Info_combo.currentText()) - for f in tSS.getFeatures(): - oFid = cfg.shpLay.fields().indexFromName('fid') - mFid = cfg.shpLay.maximumValue(oFid) + 1 - if mFid < 1: - mFid = 1 - cfg.shpLay.startEditing() - aF = f.geometry() - if pCrs != tCrs: - # transform coordinates - trs = cfg.qgisCoreSCP.QgsCoordinateTransform(pCrs, tCrs) - aF.transform(trs) - oF = cfg.qgisCoreSCP.QgsFeature() - oF.setGeometry(aF) - mcIdV = f.attributes()[mcIdF] - try: - mcId = int(mcIdV) - except: - mcId = cfg.ROIMacroID - mcInfo = f.attributes()[mcInfoF] - cIdV = f.attributes()[cIdF] - try: - cId = int(cIdV) - except: - cId = cfg.ROIID - cInfo = f.attributes()[cInfoF] - i = cfg.utls.signatureID() - attributeList = [mFid, mcId, mcInfo, cId, cInfo, i] - oF.setAttributes(attributeList) - cfg.shpLay.addFeature(oF) - cfg.shpLay.commitChanges() - cfg.shpLay.dataProvider().createSpatialIndex() - cfg.shpLay.updateExtents() - cfg.uiUtls.updateBar(40) - # calculate signature if checkbox is yes - if cfg.ui.signature_checkBox_2.isChecked() is True: - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(i)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, mcId, mcInfo, cId, cInfo, None, None, 'No', 'No', i) - cfg.uiUtls.updateBar(90) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - -################################## - ''' Process functions ''' -################################## - - # create value list from text - def textToValueList(self, text): - vList = [] - if "," in text: - c = text.split(",") - elif "-" in text: - v = text.split("-") - for z in range(int(v[0]), int(v[-1]) + 1): - vList.append(int(z)) - c = [] - else: - vList.append(int(text)) - c = [] - for b in c: - if "-" in b: - v = b.split("-") - for z in range(int(v[0]), int(v[-1]) + 1): - vList.append(int(z)) - else: - vList.append(int(b)) - uList = cfg.np.unique(vList).tolist() - return uList - - # create 3x3 window - def create3x3Window(self, connection = '8'): - size = 3 - B = cfg.np.ones((size,size)) - if connection != '8': - # 4 cells - B[0,0] = 0 - B[0,2] = 0 - B[2,0] = 0 - B[2,2] = 0 - return B - - # scatter plot raster - def createScatterPlotRasterCondition(self, rangeList, weightList = None, nodataValue = -999): - if weightList is not None: - c = 0 - for w in weightList: - #bandX *= w - #bandY *= w - c = c + 1 - condit1 = '' - condit2 = '' - bandX = cfg.np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - bandY = cfg.np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - for list in rangeList: - for range in list[0]: - Xmin = range[0][0] - Xmax = range[0][1] - Ymin = range[1][0] - Ymax = range[1][1] - condit1 = condit1 + 'cfg.np.where( (bandX >= ' + str(Xmin) + ') & (bandX <= ' + str(Xmax) + ') & (bandY >= ' + str(Ymin) + ') & (bandY <= ' + str(Ymax) + '), ' + str(list[1]) + ', ' - condit2 = condit2 + ')' - condit1 = condit1[:-2] + ', ' + str(nodataValue) + condit2 - try: - algArray = eval(condit1) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 0 - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return condit1 - - # scatter plot raster - def singleScatterPlotRasterCondition(self, rangeList, weightList = None, nodataValue = -999): - if weightList is not None: - c = 0 - for w in weightList: - #bandX *= w - #bandY *= w - c = c + 1 - conditions = [] - for list in rangeList: - for range in list[0]: - Xmin = range[0][0] - Xmax = range[0][1] - Ymin = range[1][0] - Ymax = range[1][1] - condit1 = 'cfg.np.where( (bandX >= ' + str(Xmin) + ') & (bandX <= ' + str(Xmax) + ') & (bandY >= ' + str(Ymin) + ') & (bandY <= ' + str(Ymax) + '), ' + str(list[1]) + ', ' + str(nodataValue) + ')' - conditions.append(condit1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return conditions - - # get UID - def signatureID(self): - dT = cfg.utls.getTime() - r = cfg.randomSCP.randint(100,999) - i = dT + "_" + str(r) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ID" + str(i)) - return i - - # calculate unique CID and MCID list - def calculateUnique_CID_MCID(self): - unique = [] - try: - if len(list(cfg.signIDs.values())) > 0: - for i in list(cfg.signIDs.values()): - unique.append(str(cfg.signList["CLASSID_" + str(i)]) + "-" + str(cfg.signList["MACROCLASSID_" + str(i)])) - l = set(unique) - listA = cfg.utls.uniqueToOrderedList(l) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " unique" + str(list)) - return listA - else: - return 'No' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # find DNmin in raster for DOS1 - def findDNmin(self, inputRaster, noDataVal = None): - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = noDataVal, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'DOS1 calculation'), deleteArray = 'No', parallel = cfg.parallelArray) - DNlist = [] - for x in sorted(cfg.parallelArrayDict): - rasterBandUniqueVal = {} - DNm = 0 - try: - for ar in cfg.parallelArrayDict[x]: - values = ar[0][0, ::] - count = ar[0][1, ::] - val = zip(values, count) - uniqueVal = cfg.counterSCP(dict(val)) - oldUniqueVal = cfg.counterSCP(rasterBandUniqueVal) - rasterBandUniqueVal = uniqueVal + oldUniqueVal - rasterBandUniqueVal.pop(noDataVal, None) - except: - return 'No' - sumTot = sum(rasterBandUniqueVal.values()) - mina = min(rasterBandUniqueVal.keys()) - pT1pc = sumTot * 0.0001 - newSum = 0 - for i in sorted(rasterBandUniqueVal): - DNm = i - newSum = newSum + rasterBandUniqueVal[i] - if newSum >= pT1pc: - DNm = i - break - DNlist.append(DNm) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' DNlist ' + str(DNlist)) - return DNlist - - # unique CID and MCID list to ordered list - def uniqueToOrderedList(self, uniqueList): - list = [] - for i in uniqueList: - v = i.split('-') - list.append([int(v[0]), int(v[1])]) - sortedList = sorted(list, key=lambda list: (list[0], list[1])) - return sortedList - - # check band set and create band set list - def checkBandSet(self, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - ck = 'Yes' - # list of bands for algorithm - cfg.bndSetLst = [] - for x in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][x], 'Yes') - if b is not None: - ql = cfg.utls.layerSource(b) - cfg.bndSetLst.append(ql) - else: - ck = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' raster is not loaded: ' + str(cfg.bandSetsList[bandSetNumber][3][x])) - return ck - return ck - - # check image Band set and create band set list - def checkImageBandSet(self, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - ck = 'Yes' - # list of bands for algorithm - cfg.bndSetLst = [] - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - for x in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - if b is not None: - ql = cfg.utls.layerSource(b) - cfg.bndSetLst.append(ql) - else: - ck = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " raster is not loaded: " + str(cfg.bandSetsList[bandSetNumber][3][x])) - return ck - return ck - - # check if the clicked point is inside the image - def checkPointImage(self, imageName, point, quiet = 'No', bandSetNumber = None, pointCoordinates = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - imageName = cfg.bandSetsList[bandSetNumber][3][0] - except: - cfg.mx.msgWar25(str(bandSetNumber + 1)) - return 'No' - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - iCrs = self.getCrs(bN0) - if iCrs is None: - if pointCoordinates is not None: - iCrs = pointCoordinates - pCrs = iCrs - else: - iCrs = cfg.utls.getQGISCrs() - pCrs = iCrs - else: - if pointCoordinates is not None: - pCrs = pointCoordinates - else: - # projection of input point from project's crs to raster's crs - pCrs = cfg.utls.getQGISCrs() - if pCrs != iCrs: - try: - point = cfg.utls.projectPointCoordinates(point, pCrs, iCrs) - if point is False: - cfg.pntCheck = 'No' - cfg.utls.setQGISCrs(iCrs) - return 'No' - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - crs = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ': latitude or longitude exceeded limits' + 'project crs: ' + str(pCrs.toProj4()) + ' - raster ' + str(imageName) + ' crs: ' + str(iCrs.toProj4())) - cfg.pntCheck = 'No' - return 'No' - # workaround coordinates issue - cfg.lstPnt = cfg.qgisCoreSCP.QgsPointXY(point.x() / float(1), point.y() / float(1)) - pX = point.x() - pY = point.y() - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - if i is not None: - # Point Check - cfg.pntCheck = None - if pX > i.extent().xMaximum() or pX < i.extent().xMinimum() or pY > i.extent().yMaximum() or pY < i.extent().yMinimum() : - if quiet == 'No': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'point outside the image area') - cfg.mx.msg6() - cfg.pntCheck = 'No' - else : - cfg.pntCheck = 'Yes' - return cfg.lstPnt - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image missing') - if quiet == 'No': - cfg.mx.msg4() - cfg.pntCheck = 'No' - else: - if cfg.utls.selectLayerbyName(imageName, 'Yes') is None: - if quiet == 'No': - cfg.mx.msg4() - self.pntROI = None - cfg.pntCheck = 'No' - else: - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - iCrs = self.getCrs(bN0) - if iCrs is None: - iCrs = None - else: - if pointCoordinates is not None: - pCrs = pointCoordinates - else: - # projection of input point from project's crs to raster's crs - pCrs = cfg.utls.getQGISCrs() - if pCrs != iCrs: - try: - point = cfg.utls.projectPointCoordinates(point, pCrs, iCrs) - if point is False: - cfg.pntCheck = 'No' - cfg.utls.setQGISCrs(iCrs) - return 'No' - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - crs = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error') + ': latitude or longitude exceeded limits') - cfg.pntCheck = 'No' - return 'No' - # workaround coordinates issue - if quiet == 'No': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'project crs: ' + str(pCrs.toProj4()) + ' - raster ' + str(imageName) + ' crs: ' + str(iCrs.toProj4())) - cfg.lstPnt = cfg.qgisCoreSCP.QgsPointXY(point.x() / float(1), point.y() / float(1)) - pX = point.x() - pY = point.y() - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - # Point Check - cfg.pntCheck = None - if pX > i.extent().xMaximum() or pX < i.extent().xMinimum() or pY > i.extent().yMaximum() or pY < i.extent().yMinimum() : - if quiet == 'No': - cfg.mx.msg6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "point outside the image area") - cfg.pntCheck = 'No' - else : - cfg.pntCheck = 'Yes' - return cfg.lstPnt - - # create temporary raster list - def createTempRasterList(self, rasterNumber): - oM = [] - dT = cfg.utls.getTime() - r = cfg.randomSCP.randint(0,1000) - for t in range(0, rasterNumber): - # date time for temp name - tPMD = cfg.osSCP.path.join(cfg.tmpDir, dT + str(r) + str(t) + '_temp.tif') - oM.append(tPMD) - return oM - - # create temporary raster path - def createTempRasterPath(self, extension, name = '_temp'): - r = cfg.randomSCP.randint(0,1000) - dT = cfg.utls.getTime() - tPMD = cfg.tmpDir + '/' + dT + str(r) + name + '.' + extension - return tPMD - - # create temporary raster path - def createTempRasterPathBatch(self, name, extension): - tPMD = cfg.tmpDir + '/' + name + '.' + extension - return tPMD - - # create temporary virtual raster - def createTempVirtualRaster(self, inputRasterList, bandNumberList = 'No', quiet = 'No', NoDataVal = 'No', relativeToVRT = 0, projection = 'No', intersection = 'Yes', boxCoordList = None, xyResList = None, aster = 'No'): - r = cfg.randomSCP.randint(0,1000) - # date time for temp name - dT = cfg.utls.getTime() - tPMN1 = cfg.tmpVrtNm + '.vrt' - tPMD1 = cfg.tmpDir + '/' + dT + str(r) + tPMN1 - # create virtual raster - output = cfg.utls.createVirtualRaster(inputRasterList, tPMD1, bandNumberList, quiet, NoDataVal, relativeToVRT, projection, intersection, boxCoordList, xyResList, aster) - return output - - # create virtual raster with Python - def createVirtualRaster(self, inputRasterList, output, bandNumberList = 'No', quiet = 'No', NoDataVal = 'No', relativeToVRT = 0, projection = 'No', intersection = 'Yes', boxCoordList = None, xyResList = None, aster = 'No', dataType = None): - # create virtual raster - drv = cfg.gdalSCP.GetDriverByName('vrt') - rXList = [] - rYList = [] - topList = [] - leftList = [] - rightList = [] - bottomList = [] - pXSizeList = [] - pYSizeList = [] - epsgList = [] - for b in inputRasterList: - gdalRaster = cfg.gdalSCP.Open(b, cfg.gdalSCP.GA_ReadOnly) - try: - gt = gdalRaster.GetGeoTransform() - if projection != 'No': - rP = projection - else: - rP = gdalRaster.GetProjection() - if rP == '': - cfg.mx.msgErr47() - return 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'Yes' - # check projections - try: - if rP is not None: - epsgList.append(rP) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rP is None ' + str(rP)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - pXSizeList.append(abs(gt[1])) - pYSizeList.append(abs(gt[5])) - leftList.append(gt[0]) - topList.append(gt[3]) - rightList.append(gt[0] + gt[1] * gdalRaster.RasterXSize) - bottomList.append(gt[3] + gt[5] * gdalRaster.RasterYSize) - # number of x pixels - rXList.append(float(gdalRaster.RasterXSize)) - # number of y pixels - rYList.append(float(gdalRaster.RasterYSize)) - gdalRaster = None - # check projections - epsgListI = list(set(epsgList)) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(epsgListI[0]) - for epsg in epsgListI: - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(epsg) - if vEPSG.IsSame(rEPSG) != 1: - cfg.mx.msgErr60() - # find raster box - iLeft = min(leftList) - iTop= max(topList) - iRight= max(rightList) - iBottom= min(bottomList) - # find intersection box - xLeft = max(leftList) - xTop= min(topList) - xRight= min(rightList) - xBottom= max(bottomList) - # highest resolution - pXSize = min(pXSizeList) - pYSize = min(pYSizeList) - if xyResList is not None: - pXSize = xyResList[0] - pYSize = xyResList[1] - if boxCoordList is not None: - try: - override = boxCoordList[4] - if override == 'Yes': - # find raster box - if iLeft < boxCoordList[0]: - iLeft = iLeft +abs(int(round((iLeft - boxCoordList[0]) / pXSize))) * pXSize - else: - iLeft = iLeft - abs(int(round((iLeft - boxCoordList[0]) / pXSize))) * pXSize - if iTop > boxCoordList[1]: - iTop= iTop - abs(int(round((iTop -boxCoordList[1]) / pYSize))) * pYSize - else: - iTop= iTop + abs(int(round((iTop -boxCoordList[1]) / pYSize))) * pYSize - if iRight > boxCoordList[2]: - iRight = iRight - abs(int(round((iRight - boxCoordList[2]) / pXSize))) * pXSize - else: - iRight = iRight + abs(int(round((iRight - boxCoordList[2]) / pXSize))) * pXSize - if iBottom < boxCoordList[3]: - iBottom = iBottom + abs(int(round((iBottom - boxCoordList[3]) / pYSize))) * pYSize - else: - iBottom = iBottom - abs(int(round((iBottom - boxCoordList[3]) / pYSize))) * pYSize - except: - # find raster box - if iLeft < boxCoordList[0]: - iLeft = iLeft +abs(int(round((iLeft - boxCoordList[0]) / pXSize))) * pXSize - if iTop > boxCoordList[1]: - iTop= iTop - abs(int(round((iTop -boxCoordList[1]) / pYSize))) * pYSize - if iRight > boxCoordList[2]: - iRight = iRight - abs(int(round((iRight - boxCoordList[2]) / pXSize))) * pXSize - if iBottom < boxCoordList[3]: - iBottom = iBottom + abs(int(round((iBottom - boxCoordList[3]) / pYSize))) * pYSize - # find intersection box - if xLeft < boxCoordList[0]: - xLeft = xLeft +abs(int(round((xLeft - boxCoordList[0]) / pXSize))) * pXSize - if xTop > boxCoordList[1]: - xTop= xTop - abs(int(round((xTop -boxCoordList[1]) / pYSize))) * pYSize - if xRight > boxCoordList[2]: - xRight= xRight - abs(int(round((xRight - boxCoordList[2]) / pXSize))) * pXSize - if xBottom < boxCoordList[3]: - xBottom = xBottom + abs(int(round((xBottom - boxCoordList[3]) / pYSize))) * pYSize - if xyResList is not None: - iLeft = xyResList[2] - iTop = xyResList[3] - iRight = xyResList[4] - iBottom = xyResList[5] - # number of x pixels - if intersection == 'Yes': - rX = abs(int(round((xRight - xLeft) / pXSize))) - rY = abs(int(round((xTop - xBottom) / pYSize))) - else: - rX = abs(int(round((iRight - iLeft) / pXSize))) - rY = abs(int(round((iTop - iBottom) / pYSize))) - # create virtual raster - vRast = drv.Create(output, rX, rY, 0) - # set raster projection from reference intersection - if intersection == 'Yes': - vRast.SetGeoTransform((xLeft, pXSize, 0, xTop, 0, -pYSize)) - else: - vRast.SetGeoTransform((iLeft, pXSize, 0, iTop, 0, -pYSize)) - vRast.SetProjection(rP) - if len(inputRasterList) == 1 and bandNumberList != 'No': - x = 0 - gdalRaster2 = cfg.gdalSCP.Open(b, cfg.gdalSCP.GA_ReadOnly) - try: - for b in bandNumberList: - gBand2 = gdalRaster2.GetRasterBand(int(b)) - offs = gBand2.GetOffset() - scl = gBand2.GetScale() - noData = gBand2.GetNoDataValue() - if noData is None or str(noData) == 'nan': - noData = cfg.NoDataVal - - gFormat = gBand2.DataType - if gFormat == cfg.gdalSCP.GDT_Float64: - gDataType = 'Float64' - elif gFormat == cfg.gdalSCP.GDT_Float32: - gDataType = 'Float32' - elif gFormat == cfg.gdalSCP.GDT_Int32: - gDataType = 'Int32' - elif gFormat == cfg.gdalSCP.GDT_UInt32: - gDataType = 'UInt32' - elif gFormat == cfg.gdalSCP.GDT_Int16: - gDataType = 'Int16' - elif gFormat == cfg.gdalSCP.GDT_UInt16: - gDataType = 'UInt16' - elif gFormat == cfg.gdalSCP.GDT_Byte: - gDataType = 'Byte' - if dataType is not None: - try: - format = eval('cfg.gdalSCP.GDT_' + dataType) - except: - format = gFormat - else: - format = gFormat - - gt = gdalRaster2.GetGeoTransform() - pX = abs(gt[1]) - pY = abs(gt[5]) - left = gt[0] - top = gt[3] - bsize2 = gBand2.GetBlockSize() - x_block = bsize2[0] - y_block = bsize2[1] - # number of x pixels - rX2 = int(round(gdalRaster2.RasterXSize * pX / pXSize)) - # number of y pixels - rY2 = int(round(gdalRaster2.RasterYSize * pY / pYSize)) - # offset - if intersection == 'Yes': - xoffX = abs(int(round((left - xLeft) / pX))) - xoffY = abs(int(round((xTop - top) / pY))) - offX = 0 - offY = 0 - else: - offX = abs(int(round((left - iLeft) / pXSize))) - offY = int(round((iTop - top) / pYSize)) - xoffX = 0 - xoffY = 0 - try: - override = boxCoordList[4] - if override == 'Yes': - if iLeft < left: - xoffX = 0 - offX = abs(int(round((left - iLeft) / pXSize))) - else: - xoffX = abs(int(round((left - iLeft) / pX))) - offX = 0 - if iTop > top: - xoffY = 0 - offY = abs(int(round((iTop - top) / pYSize))) - else: - xoffY = abs(int(round((iTop - top) / pY))) - offY = 0 - except: - pass - vRast.AddBand(gBand2.DataType) - bandNumber = bandNumberList[x] - band = vRast.GetRasterBand(x + 1) - bsize = band.GetBlockSize() - x_block = bsize[0] - y_block = bsize[1] - # check path - source_path = inputRasterList[0] - try: - source_path = source_path - except: - pass - if relativeToVRT == 1: - source_path = cfg.utls.fileName(source_path) - # set metadata xml - xml = ''' - - %s - %i - - - - %i - - ''' - source = xml % (relativeToVRT, source_path, bandNumber, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, format, x_block, y_block, xoffX, xoffY, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, offX, offY, rX2, rY2, noData) - band.SetMetadataItem('ComplexSource', source, 'new_vrt_sources') - if NoDataVal == 'Yes': - band.SetNoDataValue(noData) - elif NoDataVal != 'No': - band.SetNoDataValue(NoDataVal) - if offs is not None: - o = band.SetOffset(offs) - if scl is not None: - s = band.SetScale(scl) - band = None - gBand2 = None - x = x + 1 - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - gdalRaster2 = None - else: - x = 0 - for b in inputRasterList: - gdalRaster2 = cfg.gdalSCP.Open(b, cfg.gdalSCP.GA_ReadOnly) - gdalBandNumber = gdalRaster2.RasterCount - for bb in range(1, gdalBandNumber + 1): - gBand2 = gdalRaster2.GetRasterBand(bb) - offs = gBand2.GetOffset() - scl = gBand2.GetScale() - noData = gBand2.GetNoDataValue() - if noData is None: - noData = cfg.NoDataVal - - gFormat = gBand2.DataType - if gFormat == cfg.gdalSCP.GDT_Float64: - gDataType = 'Float64' - elif gFormat == cfg.gdalSCP.GDT_Float32: - gDataType = 'Float32' - elif gFormat == cfg.gdalSCP.GDT_Int32: - gDataType = 'Int32' - elif gFormat == cfg.gdalSCP.GDT_UInt32: - gDataType = 'UInt32' - elif gFormat == cfg.gdalSCP.GDT_Int16: - gDataType = 'Int16' - elif gFormat == cfg.gdalSCP.GDT_UInt16: - gDataType = 'UInt16' - elif gFormat == cfg.gdalSCP.GDT_Byte: - gDataType = 'Byte' - if dataType is not None: - try: - format = eval('cfg.gdalSCP.GDT_' + dataType) - except: - format = gFormat - else: - format = gFormat - - gt = gdalRaster2.GetGeoTransform() - pX = abs(gt[1]) - pY = abs(gt[5]) - left = gt[0] - top = gt[3] - bsize2 = gBand2.GetBlockSize() - x_block = bsize2[0] - y_block = bsize2[1] - # number of x pixels - rX2 = int(round(gdalRaster2.RasterXSize * pX / pXSize)) - # number of y pixels - rY2 = int(round(gdalRaster2.RasterYSize * pY / pYSize)) - # offset - if intersection == 'Yes': - xoffX = abs(int(round((left - xLeft) / pX))) - xoffY = abs(int(round((xTop - top) / pY))) - offX = 0 - offY = 0 - else: - offX = abs(int(round((left - iLeft) / pXSize))) - offY = int(round((iTop - top) / pYSize)) - xoffX = 0 - xoffY = 0 - try: - override = boxCoordList[4] - if override == 'Yes': - if iLeft < left: - xoffX = 0 - offX = abs(int(round((left - iLeft) / pXSize))) - else: - xoffX = abs(int(round((left - iLeft) / pX))) - offX = 0 - if iTop > top: - xoffY = 0 - offY = abs(int(round((iTop - top) / pYSize))) - else: - xoffY = abs(int(round((iTop - top) / pY))) - offY = 0 - except: - pass - vRast.AddBand(gBand2.DataType) - gBand2 = None - try: - errorCheck = 'Yes' - if bandNumberList == 'No': - bandNumber = 1 - else: - bandNumber = bandNumberList[x] - errorCheck = 'No' - band = vRast.GetRasterBand(x + 1) - bsize = band.GetBlockSize() - x_block = bsize[0] - y_block = bsize[1] - # check path - source_path = b.replace('//', '/') - try: - source_path = source_path - except: - pass - if relativeToVRT == 1: - source_path = cfg.utls.fileName(source_path) - # set metadata xml - xml = ''' - - %s - %i - - - - %i - - ''' - if aster == 'No': - source = xml % (relativeToVRT, source_path, bandNumber, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, format, x_block, y_block, xoffX, xoffY, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, offX, offY, rX2, rY2, noData) - else: - source = xml % (relativeToVRT, source_path, bandNumber, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, format, x_block, y_block, xoffX, xoffY, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, xoffX, xoffY, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, noData) - band.SetMetadataItem('ComplexSource', source, 'new_vrt_sources') - if NoDataVal == 'Yes': - band.SetNoDataValue(noData) - elif NoDataVal != 'No': - band.SetNoDataValue(NoDataVal) - if offs is not None: - o = band.SetOffset(offs) - if scl is not None: - s = band.SetScale(scl) - band = None - x = x + 1 - except Exception as err: - if errorCheck == 'No': - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - gdalRaster2 = None - vRast = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'virtual raster: ' + str(output)) - return str(output) - - # simplified virtual raster creation for mosaic - def createVirtualRaster2(self, inputRasterList, output, bandNumberList = None, NoDataValue = 'No', relativeToVRT = 0, intersection = 'No', extentList = None, dataType = None): - lefts = [] - rights = [] - tops = [] - bottoms = [] - pXSizes = [] - pYSizes = [] - for i in inputRasterList: - # raster extent and pixel size - left, right, top, bottom, pX, pY, rP, unit = cfg.utls.imageGeoTransform(i) - lefts.append(left) - rights.append(right) - tops.append(top) - bottoms.append(bottom) - pXSizes.append(pX) - pYSizes.append(pY) - try: - if intersection == 'No': - iLeft = min(lefts) - iTop = max(tops) - iRight = max(rights) - iBottom = min(bottoms) - else: - iLeft = max(lefts) - iTop = min(tops) - iRight = min(rights) - iBottom = max(bottoms) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None - pXSize = min(pXSizes) - pYSize = min(pYSizes) - # create virtual raster - drv = cfg.gdalSCP.GetDriverByName('vrt') - # number of x pixels - rX = abs(int(round((iRight - iLeft) / pXSize))) - rY = abs(int(round((iTop - iBottom) / pYSize))) - # create virtual raster - vRast = drv.Create(output, rX, rY, 0) - # set raster projection from reference intersection - vRast.SetGeoTransform((iLeft, pXSize, 0, iTop, 0, -pYSize)) - vRast.SetProjection(rP) - if dataType is not None: - try: - format = eval('cfg.gdalSCP.GDT_' + dataType) - except: - format = cfg.gdalSCP.GDT_Float32 - else: - dataType = 'Float32' - format = cfg.gdalSCP.GDT_Float32 - vRast.AddBand(format) - band = vRast.GetRasterBand(1) - bsize = band.GetBlockSize() - x_block = bsize[0] - y_block = bsize[1] - x = 0 - for b in range(0, len(inputRasterList)): - if bandNumberList is None: - bandNumber = 1 - else: - bandNumber = bandNumberList[b] - gdalRaster2 = cfg.gdalSCP.Open(inputRasterList[b], cfg.gdalSCP.GA_ReadOnly) - gBand2 = gdalRaster2.GetRasterBand(bandNumber) - offs = gBand2.GetOffset() - scl = gBand2.GetScale() - noData = gBand2.GetNoDataValue() - if NoDataValue != 'No' or noData is None: - try: - noData = int(NoDataValue) - except: - noData = cfg.NoDataVal - gt = gdalRaster2.GetGeoTransform() - pX = abs(gt[1]) - pY = abs(gt[5]) - left = gt[0] - top = gt[3] - bsize2 = gBand2.GetBlockSize() - x_block = bsize2[0] - y_block = bsize2[1] - # number of x pixels - rX2 = int(round(gdalRaster2.RasterXSize * pX / pXSize)) - # number of y pixels - rY2 = int(round(gdalRaster2.RasterYSize * pY / pYSize)) - # offset - offX = abs(int(round((left - iLeft) / pXSize))) - offY = abs(int(round((iTop - top) / pYSize))) - xoffX = 0 - xoffY = 0 - gBand2 = None - rX1 = gdalRaster2.RasterXSize - rY1 = gdalRaster2.RasterYSize - if extentList is not None: - offX, offY, rX2, rY2 = extentList - xoffX = offX - xoffY = offY - rX1 = rX2 - rY1 = rY2 - try: - # check path - if relativeToVRT == 1: - source_path = cfg.utls.fileName(inputRasterList[b]) - else: - source_path = inputRasterList[b].replace('//', '/') - # set metadata xml - xml = ''' - - %s - %i - - - - %i - - ''' - source = xml % (relativeToVRT, source_path, bandNumber, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, dataType, x_block, y_block, xoffX, xoffY, rX1, rY1, offX, offY, rX2, rY2, noData) - band.SetMetadataItem('ComplexSource', source, 'new_vrt_sources') - if NoDataValue == 'Yes': - band.SetNoDataValue(noData) - elif NoDataValue != 'No': - try: - band.SetNoDataValue(NoDataValue) - except: - band.SetNoDataValue(noData) - x = x + 1 - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - gdalRaster2 = None - if offs is not None: - o = band.SetOffset(offs) - if scl is not None: - s = band.SetScale(scl) - band = None - vRast = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'virtual raster: ' + str(output)) - return str(output) - - # simplified virtual raster creation - def createVirtualRaster3(self, inputRasterList, output, bandNumberList = None, NoDataValue = 'No', relativeToVRT = 0, intersection = 'No', extentList = None, dataType = None): - lefts = [] - rights = [] - tops = [] - bottoms = [] - pXSizes = [] - pYSizes = [] - for i in inputRasterList: - # raster extent and pixel size - left, right, top, bottom, pX, pY, rP, unit = cfg.utls.imageGeoTransform(i) - lefts.append(left) - rights.append(right) - tops.append(top) - bottoms.append(bottom) - pXSizes.append(pX) - pYSizes.append(pY) - if intersection == 'No': - iLeft = min(lefts) - iTop = max(tops) - iRight = max(rights) - iBottom = min(bottoms) - else: - iLeft = max(lefts) - iTop = min(tops) - iRight = min(rights) - iBottom = max(bottoms) - pXSize = min(pXSizes) - pYSize = min(pYSizes) - if extentList is not None: - eLeft, eRight, eTop, eBottom = extentList - rPSC = cfg.osrSCP.SpatialReference() - rPSC.ImportFromEPSG(4326) - rPS = cfg.osrSCP.SpatialReference(wkt=rP) - iLeft, iTop = cfg.utls.projectPointCoordinatesOGR(eLeft, eTop, rPSC, rPS) - iRight, iBottom = cfg.utls.projectPointCoordinatesOGR(eRight, eBottom, rPSC, rPS) - # create virtual raster - drv = cfg.gdalSCP.GetDriverByName('vrt') - # number of x pixels - rX = abs(int(round((iRight - iLeft) / pXSize))) - rY = abs(int(round((iTop - iBottom) / pYSize))) - # create virtual raster - vRast = drv.Create(output, rX, rY, 0) - # set raster projection from reference intersection - vRast.SetGeoTransform((iLeft, pXSize, 0, iTop, 0, -pYSize)) - vRast.SetProjection(rP) - x = 0 - for b in range(0, len(inputRasterList)): - if bandNumberList is None: - bandNumber = 1 - else: - bandNumber = bandNumberList[b] - gdalRaster2 = cfg.gdalSCP.Open(inputRasterList[b], cfg.gdalSCP.GA_ReadOnly) - gBand2 = gdalRaster2.GetRasterBand(bandNumber) - noData = gBand2.GetNoDataValue() - if noData is None: - if NoDataValue == 'Yes': - noData = 0 - else: - noData = NoDataValue - gt = gdalRaster2.GetGeoTransform() - pX = abs(gt[1]) - pY = abs(gt[5]) - left = gt[0] - top = gt[3] - bsize2 = gBand2.GetBlockSize() - x_block = bsize2[0] - y_block = bsize2[1] - # number of x pixels - rX2 = int(round(gdalRaster2.RasterXSize * pX / pXSize)) - # number of y pixels - rY2 = int(round(gdalRaster2.RasterYSize * pY / pYSize)) - # offset - offX = abs(int(round((left - iLeft) / pXSize))) - offY = abs(int(round((iTop - top) / pYSize))) - xoffX = 0 - xoffY = 0 - gFormat = gBand2.DataType - if gFormat == cfg.gdalSCP.GDT_Float64: - gDataType = 'Float64' - elif gFormat == cfg.gdalSCP.GDT_Float32: - gDataType = 'Float32' - elif gFormat == cfg.gdalSCP.GDT_Int32: - gDataType = 'Int32' - elif gFormat == cfg.gdalSCP.GDT_UInt32: - gDataType = 'UInt32' - elif gFormat == cfg.gdalSCP.GDT_Int16: - gDataType = 'Int16' - elif gFormat == cfg.gdalSCP.GDT_UInt16: - gDataType = 'UInt16' - elif gFormat == cfg.gdalSCP.GDT_Byte: - gDataType = 'Byte' - if dataType is not None: - try: - format = eval('cfg.gdalSCP.GDT_' + dataType) - except: - format = gFormat - else: - format = gFormat - vRast.AddBand(format) - gBand2 = None - try: - band = vRast.GetRasterBand(x + 1) - bsize = band.GetBlockSize() - x_block = bsize[0] - y_block = bsize[1] - # check path - source_path = inputRasterList[b] - # set metadata xml - xml = ''' - - %s - %i - - - - %i - - ''' - source = xml % (relativeToVRT, source_path, bandNumber, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, gDataType, x_block, y_block, offX, offY, gdalRaster2.RasterXSize, gdalRaster2.RasterYSize, xoffX, xoffY, rX2, rY2, noData) - band.SetMetadataItem('ComplexSource', source, 'new_vrt_sources') - if NoDataValue == 'Yes': - band.SetNoDataValue(noData) - elif NoDataValue != 'No': - band.SetNoDataValue(NoDataValue) - band = None - x = x + 1 - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - gdalRaster2 = None - vRast = None - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "virtual raster: " + str(output)) - return str(output) - - # create warped virtual raster - def createWarpedVrtGDAL(self, rasterPath, outputPath, outputWkt, maxError = 0.125): - rD = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - t = cfg.gdalSCP.AutoCreateWarpedVRT(rD, None, outputWkt, cfg.gdalSCP.GRA_NearestNeighbour, maxError) - rD = None - vrt = cfg.gdalSCP.GetDriverByName('VRT').CreateCopy(outputPath, t) - vrt = None - return outputPath - - # create warped virtual raster - def createWarpedVrt(self, rasterPath, outputPath, outputWkt = None, maxError = None, alignRasterPath = None, sameExtent = 'No'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters to be projected' + str(rasterPath)) - extra = None - # calculate minimal extent - if alignRasterPath is not None: - # raster extent and pixel size - try: - left, right, top, bottom, pX, pY, outputWkt, unit = cfg.utls.imageGeoTransform(alignRasterPath) - # check projections - rPSys =cfg.osrSCP.SpatialReference(wkt=outputWkt) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # raster extent and pixel size - try: - leftS, rightS, topS, bottomS, pXS, pYS, rPS, unitS = cfg.utls.imageGeoTransform(rasterPath) - rPSC =cfg.osrSCP.SpatialReference(wkt=rPS) - leftSP, topSP = cfg.utls.projectPointCoordinatesOGR(leftS, topS, rPSC, rPSys) - rightSP, bottomSP = cfg.utls.projectPointCoordinatesOGR(rightS, bottomS, rPSC, rPSys) - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if sameExtent == 'No': - # minimum extent - if leftSP < left: - leftR = left - int(2 + (left - leftSP) / pX) * pX - else: - leftR = left + int((leftSP- left) / pX - 2) * pX - if rightSP > right: - rightR = right + int(2 + (rightSP - right) / pX) * pX - else: - rightR = right - int((right - rightSP) / pX - 2) * pX - if topSP > top: - topR = top + int(2 + (topSP - top) / pY) * pY - else: - topR = top - int((top - topSP) / pY - 2) * pY - if bottomSP > bottom: - bottomR = bottom + int((bottomSP - bottom) / pY - 2) * pY - else: - bottomR = bottom - int(2 + (bottom - bottomSP) / pY) * pY - else: - leftR = left - rightR = right - topR = top - bottomR = bottom - extra = '-tr ' + str(pX) + ' ' + str(pY) + ' -te ' + str(leftR) + ' ' + str(bottomR) + ' ' + str(rightR) + ' ' + str(topR) - cfg.utls.GDALReprojectRaster(input = rasterPath, output = outputPath, outFormat = 'VRT', s_srs = None, t_srs = outputWkt, additionalParams = extra) - # workaround to gdalwarp issue ignoring scale and offset - try: - oR = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_Update) - iRB = oR.GetRasterBand(1) - offset = iRB.GetOffset() - scale = iRB.GetScale() - iRB = None - oR = None - if scale != 1 or offset != 0: - oR = cfg.gdalSCP.Open(outputPath, cfg.gdalSCP.GA_Update) - bO = oR.GetRasterBand(1) - try: - bO.SetScale(scale) - except: - pass - try: - bO.SetOffset(offset) - except: - pass - bO = None - oR = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' scale' + str(scale) + ' offset' + str(offset)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return outputPath - - # calculate raster block ranges - def rasterBlocks(self, gdalRaster, blockSizeX = 1, blockSizeY = 1, previewSize = 0, previewPoint = None): - # number of x pixels - rX = gdalRaster.RasterXSize - # number of y pixels - rY = gdalRaster.RasterYSize - # list of range pixels - lX = None - lY = None - if blockSizeX != 1 or blockSizeY !=1: - lX = list(range(0, rX, blockSizeX)) - lY = list(range(0, rY, blockSizeY)) - # classification preview - if previewPoint != None: - geoT = gdalRaster.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - sX = (int((previewPoint.x() - tLX) / pSX)) - int(previewSize / 2) - eX = (int((previewPoint.x() - tLX) / pSX)) + int(previewSize / 2) - sY = -(int((tLY - previewPoint.y()) / pSY)) - int(previewSize / 2) - eY = -(int((tLY - previewPoint.y()) / pSY)) + int(previewSize / 2) - # if start outside image - if sX < 0: - sX = 0 - if sY < 0: - sY = 0 - if eX > rX: - eX = rX - if eY > rY: - eY = rY - if blockSizeX > previewSize: - blockSizeX = previewSize - if blockSizeY > previewSize: - blockSizeY = previewSize - # raster range blocks - if previewSize > 1: - lX = list(range(sX, eX, blockSizeX)) - lY = list(range(sY, eY, blockSizeY)) - else: - lX = [sX] - lY = [sY] - # preview range blocks - pX = list(range(0, previewSize, blockSizeX)) - pY = list(range(0, previewSize, blockSizeY)) - # if not preview - else: - # set pX and pY if not preview - pX = lX - pY = lY - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return rX, rY, lX, lY, pX, pY - - - # read a block of band as array - def readArrayBlock(self, gdalBand, pixelStartColumn, pixelStartRow, blockColumns, blockRow, calcDataType = None): - if calcDataType is None: - calcDataType = cfg.np.float32 - try: - o = gdalBand.GetOffset() - s = gdalBand.GetScale() - if o is None: - o = 0.0 - if s is None: - s = 1.0 - except: - o = 0.0 - s = 1.0 - o = cfg.np.asarray(o).astype(calcDataType) - s = cfg.np.asarray(s).astype(calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 's ' + str(s)+ ' o ' + str(o)) - try: - a = cfg.np.asarray(gdalBand.ReadAsArray(pixelStartColumn, pixelStartRow, blockColumns, blockRow) * s + o).astype(calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a ' + str(a[0,0])) - except: - return None - return a - - # apply multiplicative and additivie factors to array - def arrayMultiplicativeAdditiveFactors(self, array, multiplicativeFactor, additiveFactor): - a = array * float(multiplicativeFactor) + float(additiveFactor) - return a - - # write an array to band - def writeArrayBlock(self, gdalRaster, bandNumber, dataArray, pixelStartColumn, pixelStartRow, nodataValue=None): - b = gdalRaster.GetRasterBand(bandNumber) - x = gdalRaster.RasterXSize - pixelStartColumn - y = gdalRaster.RasterYSize - pixelStartRow - dataArray = dataArray[:y, :x] - b.WriteArray(dataArray, pixelStartColumn, pixelStartRow) - if nodataValue is not None: - try: - b.SetNoDataValue(nodataValue) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error ' + str(err)) - b.FlushCache() - b = None - - # write an array to band - def writeRasterBlock(self, gdalRaster, bandNumber, dataArray, pixelStartColumn, pixelStartRow, nodataValue = None, scale = None, offset = None, outputNoData = None): - b = gdalRaster.GetRasterBand(bandNumber) - y, x = dataArray.shape - if scale is not None or offset is not None: - dataArray = cfg.np.subtract(dataArray/scale, offset/scale) - b.SetScale(scale) - b.SetOffset(offset) - #b.WriteRaster(pixelStartColumn, pixelStartRow, x, y, dataArray.tostring()) - b.WriteArray(dataArray, pixelStartColumn, pixelStartRow) - if nodataValue is not None: - b.SetNoDataValue(nodataValue) - b.FlushCache() - b = None - - # create raster from another raster - def createRasterFromReferenceMultiprocess(self, raster, bandNumber, outputRasterList, nodataValue = None, driver = 'GTiff', format = 'Float32', compress = 'No', compressFormat = 'DEFLATE21', projection = None, geotransform = None, constantValue = None, xSize = None, ySize = None): - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'format ' + str(format) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'compress ' + str(compress) ) - # open input with GDAL - gdalRasterRef = cfg.gdalSCP.Open(raster, cfg.gdalSCP.GA_ReadOnly) - if format == 'Float64': - format = cfg.gdalSCP.GDT_Float64 - elif format == 'Float32': - format = cfg.gdalSCP.GDT_Float32 - elif format == 'Int32': - format = cfg.gdalSCP.GDT_Int32 - elif format == 'UInt32': - format = cfg.gdalSCP.GDT_UInt32 - elif format == 'Int16': - format = cfg.gdalSCP.GDT_Int16 - elif format == 'UInt16': - format = cfg.gdalSCP.GDT_UInt16 - elif format == 'Byte': - format = cfg.gdalSCP.GDT_Byte - for o in outputRasterList: - if driver == 'GTiff': - if o.lower().endswith('.tif'): - pass - else: - o = o + '.tif' - # pixel size and origin from reference - if projection is None: - rP = gdalRasterRef.GetProjection() - else: - rP = projection - if geotransform is None: - rGT = gdalRasterRef.GetGeoTransform() - else: - rGT = geotransform - tD = cfg.gdalSCP.GetDriverByName(driver) - if xSize is None: - c = gdalRasterRef.RasterXSize - else: - c = xSize - if ySize is None: - r = gdalRasterRef.RasterYSize - else: - r = ySize - if compress == 'No': - oR = tD.Create(o, c, r, bandNumber, format) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'NO COMPRESS') - elif compress == 'DEFLATE21': - oR = tD.Create(o, c, r, bandNumber, format, options = ['COMPRESS=DEFLATE', 'PREDICTOR=2', 'ZLEVEL=1']) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'COMPRESS=DEFLATE') - else: - oR = tD.Create(o, c, r, bandNumber, format, ['COMPRESS=' + compressFormat]) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'COMPRESS ' + compressFormat) - if oR is None: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error GDAL raster') - # set raster projection from reference - oR.SetGeoTransform(rGT) - oR.SetProjection(rP) - if nodataValue is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.SetNoDataValue(nodataValue) - b.Fill(nodataValue) - b = None - if constantValue is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.Fill(constantValue) - b = None - oR = None - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster ' + str(outputRasterList)) - return outputRasterList - - # create raster from another raster - def createRasterFromReference(self, gdalRasterRef, bandNumber, outputRasterList, nodataValue = None, driver = 'GTiff', format = 'Float32', previewSize = 0, previewPoint = None, compress = 'No', compressFormat = 'DEFLATE21', projection = None, geotransform = None, constantValue = None, scale = None, offset = None): - oRL = [] - for o in outputRasterList: - if driver == 'GTiff': - if o.lower().endswith('.tif'): - pass - else: - o = o + '.tif' - # pixel size and origin from reference - if projection is None: - rP = gdalRasterRef.GetProjection() - else: - rP = projection - if geotransform is None: - rGT = gdalRasterRef.GetGeoTransform() - else: - rGT = geotransform - tD = cfg.gdalSCP.GetDriverByName(driver) - c = gdalRasterRef.RasterXSize - r = gdalRasterRef.RasterYSize - gBand2 = gdalRasterRef.GetRasterBand(1) - ndVal = gBand2.GetNoDataValue() - if format is None: - format_x = gBand2.DataType - elif format == 'Float64': - format_x = cfg.gdalSCP.GDT_Float64 - elif format == 'Float32': - format_x = cfg.gdalSCP.GDT_Float32 - elif format == 'Int32': - format_x = cfg.gdalSCP.GDT_Int32 - elif format == 'Int16': - format_x = cfg.gdalSCP.GDT_Int16 - elif format == 'UInt16': - format_x = cfg.gdalSCP.GDT_UInt16 - elif format == 'Byte': - format_x = cfg.gdalSCP.GDT_Byte - else: - format_x = cfg.gdalSCP.GDT_Float32 - if previewSize > 0: - tLX = rGT[0] - tLY = rGT[3] - pSX = rGT[1] - pSY = rGT[5] - sX = int((previewPoint.x() - tLX) / pSX) - int(previewSize / 2) - sY = int((tLY - previewPoint.y()) / cfg.np.sqrt(pSY ** 2)) - int(previewSize / 2) - lX = tLX + sX * pSX - tY = tLY + sY * pSY - if tY > tLY: - tY = tLY - if lX < tLX: - lX = tLX - if previewSize < c: - c = previewSize - if previewSize < r: - r = previewSize - rGT = (lX, rGT[1], rGT[2], tY, rGT[4], rGT[5]) - if compress == 'No': - oR = tD.Create(o, c, r, bandNumber, format_x) - elif compress == 'DEFLATE21': - oR = tD.Create(o, c, r, bandNumber, format_x, options = ['COMPRESS=DEFLATE', 'PREDICTOR=2', 'ZLEVEL=1']) - else: - oR = tD.Create(o, c, r, bandNumber, format_x, ['COMPRESS=' + compressFormat]) - if oR is None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error GDAL raster') - return 'No' - # set raster projection from reference - oR.SetGeoTransform(rGT) - oR.SetProjection(rP) - oRL.append(oR) - if nodataValue is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.SetNoDataValue(nodataValue) - b.Fill(nodataValue) - b = None - else: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.SetNoDataValue(ndVal) - b.Fill(ndVal) - b = None - if constantValue is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.Fill(constantValue) - b = None - if scale is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.SetScale(scale) - b = None - if offset is not None: - for x in range(1, bandNumber+1): - b = oR.GetRasterBand(x) - b.SetOffset(offset) - b = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster ' + str(outputRasterList)) - return oRL - - # clip a raster using a shapefile - def clipRasterByShapefile(self, shapefile, raster, outputRaster = None, outFormat = "GTiff"): - # convert polygon to raster - tRxs = cfg.utls.createTempRasterPath('tif') - burnValues = 1 - conversionType = None - bbList = [raster] - if cfg.osSCP.path.isfile(shapefile): - check = cfg.utls.vectorToRaster(cfg.emptyFN, shapefile, cfg.emptyFN, tRxs, raster, conversionType, "GTiff", burnValues) - else: - return 'No' - if check != 'No': - dirPath = cfg.osSCP.path.dirname(outputRaster) - outList = cfg.utls.clipRasterByRaster(bbList, tRxs, dirPath, outFormat, cfg.NoDataVal, progressMessage = None) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'shapefile ' + str(shapefile) + 'raster ' + str(raster) + 'outputRaster ' + str(outList[0])) - return outList[0] - else: - return 'No' - - # clip raster with another raster - def clipRasterByRaster(self, rasterClippedList, rasterClipping, outputRasterDir = None, outFormat = 'GTiff', nodataVal = None, progressMessage = 'Clip', stats = None, parallelWritingCheck = None, outputNameRoot = None, compress = 'No', compressFormat = 'LZW', dataType = None): - tPMD = cfg.utls.createTempRasterPath('vrt') - bList = rasterClippedList.copy() - bList.append(rasterClipping) - iBC = len(bList) - # create band list of clipped bands and clipping band - bandNumberList = [] - for cc in range(1, iBC + 1): - bandNumberList.append(1) - vrtCheck = cfg.utls.createVirtualRaster(bList, tPMD, bandNumberList, 'Yes', 'Yes', 0) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMD, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' None raster') - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - try: - # band list - bL = cfg.utls.readAllBandsFromRaster(rD) - bC = len(bL) - functionList = [] - variableList = [] - varList = [] - for t in range(0, bC): - varList.append('"im' + str(t)+ '"') - for t in range(0, bC - 1): - # output rasters - e = str('"im' + str(t) + '" * "im' + str(bC-1) + '"') - functionList.append(e) - variableList.append(varList) - oM = cfg.utls.createTempRasterList(bC-1) - oMR = cfg.utls.createRasterFromReference(rD, 1, oM, None, 'GTiff', dataType, compress = compress, compressFormat = compressFormat) - # close GDAL rasters - for b in range(0, len(oMR)): - oMR[b] = None - for b in range(0, len(bL)): - bL[b] = None - rD = None - if stats is None: - ffR = cfg.utls.calculateRaster - else: - ffR = cfg.utls.calculateRasterWithStats - o = cfg.utls.multiProcessRaster(rasterPath = tPMD, functionBand = 'No', functionRaster = ffR, outputRasterList = oM, nodataValue = nodataVal, functionBandArgument = functionList, functionVariable = variableList, progressMessage = progressMessage, parallel = cfg.parallelRaster, skipSingleBand = 'Yes', parallelWritingCheck = parallelWritingCheck) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outputRasterDir is None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster ' + str(oM)) - return oM - else: - outList = [] - for cc in range(0, len(oM)): - d = cfg.utls.fileNameNoExt(rasterClippedList[cc]) - if outputNameRoot is None: - t = '' - else: - t = outputNameRoot - e = outputRasterDir.rstrip('/') + '/' + t + d + '.tif' - outList.append(e) - if cfg.rasterCompression != 'No': - try: - cfg.utls.GDALCopyRaster(oM[cc], e, 'GTiff', cfg.rasterCompression, 'LZW') - cfg.osSCP.remove(oM[cc]) - except Exception as err: - cfg.shutilSCP.copy(oM[cc], e) - cfg.osSCP.remove(oM[cc]) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - cfg.shutilSCP.move(oM[cc], e) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster ' + str(outList)) - return outList - - # find nearest value in list - def findNearestValueinList(self, list, value, threshold): - if len(list) > 0: - arr = cfg.np.asarray(list) - v = (cfg.np.abs(arr - value)).argmin() - if cfg.np.abs(arr[v] - value) < threshold: - return arr[v] - else: - return None - else: - return None - - # find band set number used for vegetation index calculation - def findBandNumber(self, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - cfg.REDBand = None - cfg.NIRBand = None - cfg.BLUEBand = None - cfg.GREENBand = None - cfg.SWIR1Band = None - cfg.SWIR2Band = None - try: - cfg.bandSetsList[bandSetNumber][5] - except: - return 'No' - if cfg.bandSetsList[bandSetNumber][5] != cfg.noUnit: - if cfg.bandSetsList[bandSetNumber][5] == cfg.unitNano: - SWIR1 = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.SWIR1CenterBand*1000, cfg.SWIR1Threshold*1000) - SWIR2 = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.SWIR2CenterBand*1000, cfg.SWIR2Threshold*1000) - RED = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.REDCenterBand*1000, cfg.REDThreshold*1000) - NIR = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.NIRCenterBand*1000, cfg.NIRThreshold*1000) - BLUE = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.BLUECenterBand*1000, cfg.BLUEThreshold*1000) - GREEN = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.GREENCenterBand*1000, cfg.GREENThreshold*1000) - elif cfg.bandSetsList[bandSetNumber][5] == cfg.unitMicro: - SWIR1 = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.SWIR1CenterBand, cfg.SWIR1Threshold) - SWIR2 = self.findNearestValueinList(list(cfg.bandSetsList[bandSetNumber][4]), cfg.SWIR2CenterBand, cfg.SWIR2Threshold) - RED = self.findNearestValueinList(cfg.bandSetsList[bandSetNumber][4], cfg.REDCenterBand, cfg.REDThreshold) - NIR = self.findNearestValueinList(cfg.bandSetsList[bandSetNumber][4], cfg.NIRCenterBand, cfg.NIRThreshold) - BLUE = self.findNearestValueinList(cfg.bandSetsList[bandSetNumber][4], cfg.BLUECenterBand, cfg.BLUEThreshold) - GREEN = self.findNearestValueinList(cfg.bandSetsList[bandSetNumber][4], cfg.GREENCenterBand, cfg.GREENThreshold) - if RED is not None: - cfg.REDBand = cfg.bandSetsList[bandSetNumber][4].index(RED) + 1 - if NIR is not None: - cfg.NIRBand = cfg.bandSetsList[bandSetNumber][4].index(NIR) + 1 - if BLUE is not None: - cfg.BLUEBand = cfg.bandSetsList[bandSetNumber][4].index(BLUE) + 1 - if GREEN is not None: - cfg.GREENBand = cfg.bandSetsList[bandSetNumber][4].index(GREEN) + 1 - if SWIR1 is not None: - cfg.SWIR1Band = cfg.bandSetsList[bandSetNumber][4].index(SWIR1) + 1 - if SWIR2 is not None: - cfg.SWIR2Band = cfg.bandSetsList[bandSetNumber][4].index(SWIR2) + 1 - return 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "RED =" + str(cfg.REDBand) + ", NIR =" + str(cfg.NIRBand) + ", BLUE =" + str(cfg.BLUEBand) + ", GREEN =" + str(cfg.GREENBand) + ", SWIR1 =" + str(cfg.SWIR1Band) + ", SWIR2 =" + str(cfg.SWIR2Band)) - - # calculation of earth sun distance - def calculateEarthSunDistance(self, date, dateFormat): - dStr = cfg.datetimeSCP.datetime.strptime(date, dateFormat) - dStrT = dStr.timetuple() - # calculate julian day - day = dStrT.tm_yday - # Earth Sun distance from http://landsathandbook.gsfc.nasa.gov/excel_docs/d.xls - dL = [0.98331, 0.98330, 0.98330, 0.98330, 0.98330, 0.98332, 0.98333, 0.98335, 0.98338, 0.98341, 0.98345, 0.98349, 0.98354, 0.98359, 0.98365, 0.98371, 0.98378, 0.98385, - 0.98393, 0.98401, 0.98410, 0.98419, 0.98428, 0.98439, 0.98449, 0.98460, 0.98472, 0.98484, 0.98496, 0.98509, 0.98523, 0.98536, 0.98551, 0.98565, 0.98580, 0.98596, 0.98612, - 0.98628, 0.98645, 0.98662, 0.98680, 0.98698, 0.98717, 0.98735, 0.98755, 0.98774, 0.98794, 0.98814, 0.98835, 0.98856, 0.98877, 0.98899, 0.98921, 0.98944, 0.98966, 0.98989, - 0.99012, 0.99036, 0.99060, 0.99084, 0.99108, 0.99133, 0.99158, 0.99183, 0.99208, 0.99234, 0.99260, 0.99286, 0.99312, 0.99339, 0.99365, 0.99392, 0.99419, 0.99446, 0.99474, - 0.99501, 0.99529, 0.99556, 0.99584, 0.99612, 0.99640, 0.99669, 0.99697, 0.99725, 0.99754, 0.99782, 0.99811, 0.99840, 0.99868, 0.99897, 0.99926, 0.99954, 0.99983, 1.00012, - 1.00041, 1.00069, 1.00098, 1.00127, 1.00155, 1.00184, 1.00212, 1.00240, 1.00269, 1.00297, 1.00325, 1.00353, 1.00381, 1.00409, 1.00437, 1.00464, 1.00492, 1.00519, 1.00546, - 1.00573, 1.00600, 1.00626, 1.00653, 1.00679, 1.00705, 1.00731, 1.00756, 1.00781, 1.00806, 1.00831, 1.00856, 1.00880, 1.00904, 1.00928, 1.00952, 1.00975, 1.00998, 1.01020, - 1.01043, 1.01065, 1.01087, 1.01108, 1.01129, 1.01150, 1.01170, 1.01191, 1.01210, 1.01230, 1.01249, 1.01267, 1.01286, 1.01304, 1.01321, 1.01338, 1.01355, 1.01371, 1.01387, - 1.01403, 1.01418, 1.01433, 1.01447, 1.01461, 1.01475, 1.01488, 1.01500, 1.01513, 1.01524, 1.01536, 1.01547, 1.01557, 1.01567, 1.01577, 1.01586, 1.01595, 1.01603, 1.01610, - 1.01618, 1.01625, 1.01631, 1.01637, 1.01642, 1.01647, 1.01652, 1.01656, 1.01659, 1.01662, 1.01665, 1.01667, 1.01668, 1.01670, 1.01670, 1.01670, 1.01670, 1.01669, 1.01668, - 1.01666, 1.01664, 1.01661, 1.01658, 1.01655, 1.01650, 1.01646, 1.01641, 1.01635, 1.01629, 1.01623, 1.01616, 1.01609, 1.01601, 1.01592, 1.01584, 1.01575, 1.01565, 1.01555, - 1.01544, 1.01533, 1.01522, 1.01510, 1.01497, 1.01485, 1.01471, 1.01458, 1.01444, 1.01429, 1.01414, 1.01399, 1.01383, 1.01367, 1.01351, 1.01334, 1.01317, 1.01299, 1.01281, - 1.01263, 1.01244, 1.01225, 1.01205, 1.01186, 1.01165, 1.01145, 1.01124, 1.01103, 1.01081, 1.01060, 1.01037, 1.01015, 1.00992, 1.00969, 1.00946, 1.00922, 1.00898, 1.00874, - 1.00850, 1.00825, 1.00800, 1.00775, 1.00750, 1.00724, 1.00698, 1.00672, 1.00646, 1.00620, 1.00593, 1.00566, 1.00539, 1.00512, 1.00485, 1.00457, 1.00430, 1.00402, 1.00374, - 1.00346, 1.00318, 1.00290, 1.00262, 1.00234, 1.00205, 1.00177, 1.00148, 1.00119, 1.00091, 1.00062, 1.00033, 1.00005, 0.99976, 0.99947, 0.99918, 0.99890, 0.99861, 0.99832, - 0.99804, 0.99775, 0.99747, 0.99718, 0.99690, 0.99662, 0.99634, 0.99605, 0.99577, 0.99550, 0.99522, 0.99494, 0.99467, 0.99440, 0.99412, 0.99385, 0.99359, 0.99332, 0.99306, - 0.99279, 0.99253, 0.99228, 0.99202, 0.99177, 0.99152, 0.99127, 0.99102, 0.99078, 0.99054, 0.99030, 0.99007, 0.98983, 0.98961, 0.98938, 0.98916, 0.98894, 0.98872, 0.98851, - 0.98830, 0.98809, 0.98789, 0.98769, 0.98750, 0.98731, 0.98712, 0.98694, 0.98676, 0.98658, 0.98641, 0.98624, 0.98608, 0.98592, 0.98577, 0.98562, 0.98547, 0.98533, 0.98519, - 0.98506, 0.98493, 0.98481, 0.98469, 0.98457, 0.98446, 0.98436, 0.98426, 0.98416, 0.98407, 0.98399, 0.98391, 0.98383, 0.98376, 0.98370, 0.98363, 0.98358, 0.98353, 0.98348, - 0.98344, 0.98340, 0.98337, 0.98335, 0.98333, 0.98331] - eSD = dL[day - 1] - return eSD - - # calculate NDVI - def calculateNDVI(self, NIR, RED): - NDVI = (NIR - RED) / (NIR + RED) - if NDVI > 1: - NDVI = 1 - elif NDVI < -1: - NDVI = -1 - return NDVI - - # calculate EVI - def calculateEVI(self, NIR, RED, BLUE): - EVI = 2.5 * (NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1) - if EVI > 1: - EVI = 1 - elif EVI < -1: - EVI = -1 - return EVI - - # NDVI calculator from image - def NDVIcalculator(self, imageName, point): - NDVI = None - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - if cfg.NIRBand is None or cfg.REDBand is None: - return 'No' - else: - NIRRaster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(cfg.NIRBand) - 1], 'Yes') - REDRaster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(cfg.REDBand) - 1], 'Yes') - # open input with GDAL - try: - NIRr = cfg.gdalSCP.Open(cfg.utls.layerSource(NIRRaster), cfg.gdalSCP.GA_ReadOnly) - REDr = cfg.gdalSCP.Open(cfg.utls.layerSource(REDRaster), cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - NIRB = NIRr.GetRasterBand(1) - REDB = REDr.GetRasterBand(1) - geoT = NIRr.GetGeoTransform() - else: - inputRaster = cfg.utls.selectLayerbyName(imageName, 'Yes') - # open input with GDAL - try: - ql = cfg.utls.layerSource(inputRaster) - rD = cfg.gdalSCP.Open(ql, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if rD is None or cfg.NIRBand is None or cfg.REDBand is None: - return 'No' - else: - NIRB = rD.GetRasterBand(int(cfg.NIRBand)) - REDB = rD.GetRasterBand(int(cfg.REDBand)) - geoT = rD.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - try: - NIR = self.readArrayBlock(NIRB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(cfg.NIRBand) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(cfg.NIRBand) - 1] - RED = self.readArrayBlock(REDB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(cfg.REDBand) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(cfg.REDBand) - 1] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # close bands - NIRB = None - REDB = None - # close raster - rD = None - return 'No' - if NIR is not None and RED is not None: - try: - NDVI = self.calculateNDVI(float(NIR), float(RED)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # close bands - NIRB = None - REDB = None - # close raster - rD = None - return 'No' - # close bands - NIRB = None - REDB = None - # close raster - rD = None - NIRr = None - REDr = None - try: - return round(NDVI, 3) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # EVI calculator from image - def EVIcalculator(self, imageName, point): - EVI = None - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - if cfg.NIRBand is None or cfg.REDBand is None or cfg.BLUEBand is None: - return 'No' - else: - NIRRaster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(cfg.NIRBand) - 1], 'Yes') - REDRaster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(cfg.REDBand) - 1], 'Yes') - BLUERaster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(cfg.BLUEBand) - 1], 'Yes') - # open input with GDAL - try: - NIRr = cfg.gdalSCP.Open(cfg.utls.layerSource(NIRRaster), cfg.gdalSCP.GA_ReadOnly) - REDr = cfg.gdalSCP.Open(cfg.utls.layerSource(REDRaster), cfg.gdalSCP.GA_ReadOnly) - BLUEr = cfg.gdalSCP.Open(cfg.utls.layerSource(BLUERaster), cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - NIRB = NIRr.GetRasterBand(1) - REDB = REDr.GetRasterBand(1) - BLUEB = REDr.GetRasterBand(1) - geoT = NIRr.GetGeoTransform() - else: - inputRaster = cfg.utls.selectLayerbyName(imageName, 'Yes') - # open input with GDAL - try: - ql = cfg.utls.layerSource(inputRaster) - rD = cfg.gdalSCP.Open(ql, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if rD is None or cfg.NIRBand is None or cfg.REDBand is None or cfg.BLUEBand is None: - return 'No' - else: - NIRB = rD.GetRasterBand(int(cfg.NIRBand)) - REDB = rD.GetRasterBand(int(cfg.REDBand)) - BLUEB = rD.GetRasterBand(int(cfg.BLUEBand)) - geoT = rD.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - NIR = self.readArrayBlock(NIRB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(cfg.NIRBand) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(cfg.NIRBand) - 1] - RED = self.readArrayBlock(REDB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(cfg.REDBand) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(cfg.REDBand) - 1] - BLUE = self.readArrayBlock(BLUEB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(cfg.BLUEBand) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(cfg.BLUEBand) - 1] - if NIR is not None and RED is not None and BLUE is not None: - if NIR <= 1 and RED <= 1 and BLUE <= 1: - try: - EVI = self.calculateEVI(float(NIR), float(RED), float(BLUE)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # close bands - NIRB = None - REDB = None - BLUEB = None - # close raster - rD = None - return 'No' - # close bands - NIRB = None - REDB = None - BLUEB = None - # close raster - rD = None - NIRr = None - REDr = None - BLUEr = None - try: - return round(EVI, 3) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # custom index calculator from image - def customIndexCalculator(self, imageName, point): - customIndex = None - geoT = None - e = " " + cfg.uidc.custom_index_lineEdit.text() + " " - dExpr = e - for b in range(1, len(cfg.bandSetsList[cfg.bndSetNumber][3])+1): - if "bandset#b" + str(b) in e: - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - raster = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][int(b) - 1], 'Yes') - ql = cfg.utls.layerSource(raster) - rRaster = cfg.gdalSCP.Open(ql, cfg.gdalSCP.GA_ReadOnly) - rasterB = rRaster.GetRasterBand(1) - if geoT is None: - geoT = rRaster.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - val = self.readArrayBlock(rasterB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(b) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(b) - 1] - dExpr = dExpr.replace("bandset#b" + str(b), str(val[0,0])) - # close bands - rasterB = None - # close raster - rD = None - else: - inputRaster = cfg.utls.selectLayerbyName(imageName, 'Yes') - # open input with GDAL - try: - qll = cfg.utls.layerSource(inputRaster) - rD = cfg.gdalSCP.Open(qll, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if rD is None or cfg.NIRBand is None or cfg.REDBand is None or cfg.BLUEBand is None or cfg.GREENBand is None: - return 'No' - else: - rasterB = rD.GetRasterBand(int(b)) - if geoT is None: - geoT = rD.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - val = self.readArrayBlock(rasterB, pixelStartColumn, pixelStartRow, 1, 1) * cfg.bandSetsList[cfg.bndSetNumber][6][0][int(b) - 1] + cfg.bandSetsList[cfg.bndSetNumber][6][1][int(b) - 1] - dExpr = dExpr.replace("bandset#b" + str(b), str(val[0,0])) - # close bands - rasterB = None - # close raster - rD = None - try: - f = cfg.utls.replaceNumpyOperators(dExpr) - customIndex = eval(f) - return round(customIndex, 3) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # copy a raster band from a multi band raster - def getRasterBandByBandNumber(self, inputRaster, band, outputRaster, virtualRaster = 'No', GDALFormat = None, multiAddList = None): - if virtualRaster == 'No': - # open input with GDAL - rD = cfg.gdalSCP.Open(inputRaster, cfg.gdalSCP.GA_ReadOnly) - # number of x pixels - rC = rD.RasterXSize - # number of y pixels - rR = rD.RasterYSize - # check projections - rP = rD.GetProjection() - # pixel size and origin - rGT = rD.GetGeoTransform() - tD = cfg.gdalSCP.GetDriverByName('GTiff') - iRB = rD.GetRasterBand(int(band)) - if GDALFormat is None: - bDT = iRB.DataType - else: - if GDALFormat == 'Float64': - bDT = cfg.gdalSCP.GDT_Float64 - elif GDALFormat == 'Float32': - bDT = cfg.gdalSCP.GDT_Float32 - try: - o = iRB.GetOffset() - s = iRB.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - a = iRB.ReadAsArray()*s+o - if multiAddList is not None: - a = cfg.utls.arrayMultiplicativeAdditiveFactors(a, multiAddList[0], multiAddList[1]) - oR = tD.Create(outputRaster, rC, rR, 1, bDT) - oR.SetGeoTransform( [ rGT[0] , rGT[1] , 0 , rGT[3] , 0 , rGT[5] ] ) - oR.SetProjection(rP) - oRB = oR.GetRasterBand(1) - oRB.WriteArray(a) - # close bands - oRB = None - iRB = None - # close rasters - oR = None - rD = None - else: - vrtCheck = cfg.utls.createVirtualRaster2([inputRaster], outputRaster, [band]) - cfg.timeSCP.sleep(0.1) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "get band: " + str(band)) - - # Split raster into single bands, and return a list of images - def rasterToBands(self, rasterPath, outputFolder, outputName = None, progressBar = 'No', multiAddList = None, virtual = 'No'): - try: - dT = self.getTime() - iBC = cfg.utls.getNumberBandRaster(rasterPath) - iL = [] - if outputName is None: - name = cfg.splitBndNm + dT - else: - name = outputName - progresStep = int(100 / iBC) - i = 1 - for x in range(1, iBC+1): - if cfg.actionCheck == 'Yes': - if virtual == 'No': - xB = outputFolder + '/' + name + '_B' + str(x) + '.tif' - else: - xB = outputFolder + '/' + name + '_B' + str(x) + '.vrt' - if multiAddList is not None: - self.getRasterBandByBandNumber(rasterPath, x, xB, 'No', None, [multiAddList[0][x - 1], multiAddList[1][x - 1]]) - else: - self.getRasterBandByBandNumber(rasterPath, x, xB, virtual, None) - iL.append(xB) - if progressBar == 'Yes': - cfg.uiUtls.updateBar(progresStep * i) - i = i + 1 - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster: ' + str(rasterPath) + ' split to bands') - return iL - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - -################################## - ''' Multiprocess functions ''' -################################## - - # calculate raster - def calculateRaster(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputRaster, functionBandArgument, functionVariableList, outputBandNumber): - # create function - b = 0 - f = functionBandArgument - for i in functionVariableList: - f = f.replace(i , ' rasterSCPArrayfunctionBand[::, ::,' + str(b) + '] ') - b = b + 1 - # replace numpy operators - f = cfg.utls.replaceNumpyOperators(f) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand shape' + str(rasterSCPArrayfunctionBand.shape)) - try: - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand ' + str(rasterSCPArrayfunctionBand[0, 0, 0])) - except: - pass - # perform operation - try: - o = eval(f) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # output raster - oR = cfg.gdalSCP.Open(outputRaster, cfg.gdalSCP.GA_Update) - scale = gdalBandList[0] - offset = gdalBandList[1] - outputNoData = gdalBandList[2] - cfg.utls.writeRasterBlock(oR, int(outputBandNumber), o, pixelStartColumn, pixelStartRow, scale = scale, offset = offset, outputNoData = outputNoData) - o = None - oR = None - return outputRaster - - # calculate raster with stats - def calculateRasterWithStats(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputRaster, functionBandArgument, functionVariableList, outputBandNumber): - # create function - b = 0 - f = functionBandArgument - for i in functionVariableList: - f = f.replace(i , ' rasterSCPArrayfunctionBand[::, ::,' + str(b) + '] ') - b = b + 1 - # replace numpy operators - f = cfg.utls.replaceNumpyOperators(f) - # perform operation - o = eval(f) - # output raster - oR = cfg.gdalSCP.Open(outputRaster, cfg.gdalSCP.GA_Update) - cfg.utls.writeArrayBlock(oR, int(outputBandNumber), o, pixelStartColumn, pixelStartRow) - min = cfg.np.nanmin(o) - max = cfg.np.nanmax(o) - mean = cfg.np.nanmean(o) - stdDev = cfg.np.nanstd(o) - array = o.flatten() - count = cfg.np.count_nonzero(~cfg.np.isnan(o)) - o = None - oR = None - return [outputRaster, [[min, max, mean, stdDev], array, count]] - - # calculate raster unique values with sum - def rasterUniqueValuesWithSum(self, gdalBandList, rasterSCPArrayfunctionBand, nodataMask, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - try: - outputNoData = gdalBandList[2] - b = rasterSCPArrayfunctionBand[nodataMask != outputNoData] - o = cfg.np.array(cfg.np.unique(b[~cfg.np.isnan(b)], return_counts=True)) - except: - o = cfg.np.array(cfg.np.unique(rasterSCPArrayfunctionBand[~cfg.np.isnan(rasterSCPArrayfunctionBand)], return_counts=True)) - return o - - # calculate raster unique values - def rasterUniqueValues(self, gdalBandList, rasterSCPArrayfunctionBand, nodataMask, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - outputNoData = gdalBandList[2] - try: - a = rasterSCPArrayfunctionBand[:,:,0][nodataMask != outputNoData].ravel() - for i in range(1, rasterSCPArrayfunctionBand.shape[2]): - a = cfg.np.vstack((a,rasterSCPArrayfunctionBand[:,:,i][nodataMask != outputNoData].ravel())) - except: - a = rasterSCPArrayfunctionBand[:,:,0].ravel() - for i in range(1, rasterSCPArrayfunctionBand.shape[2]): - a = cfg.np.vstack((a,rasterSCPArrayfunctionBand[:,:,i].ravel())) - a = a.T - a = a[~cfg.np.isnan(a).any(axis=1)] - # adapted from Jaime answer at https://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array - b = a.view(cfg.np.dtype((cfg.np.void, a.dtype.itemsize * a.shape[1]))) - ff, indexA = cfg.np.unique(b, return_index=True, return_counts=False) - #o = cfg.np.column_stack((a[indexA], cc)) - return a[indexA] - - # reclassify raster - def reclassifyRaster(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - try: - old, new = cfg.np.array(functionBandArgument).T - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'old ' + str(old)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'new ' + str(new)) - raster = cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]) - if cfg.np.all(raster.astype(int) == raster) and cfg.np.all(old.astype(int) == old): - reclass = cfg.np.zeros(max(old.astype(int).max(), rasterSCPArrayfunctionBand.astype(int).max())+1) * cfg.np.nan - reclass[old.astype(int)] = new - o = reclass[raster.astype(int)].astype(cfg.np.float32) - o[cfg.np.isnan(o)] = raster[cfg.np.isnan(o)] - o[cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0])] = cfg.np.nan - else: - # cause exception - int('x') - except: - # raster array - o = cfg.np.copy(rasterSCPArrayfunctionBand[:,:,0]) - a = rasterSCPArrayfunctionBand[:,:,0] - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reclassifyRaster ') - for i in functionBandArgument: - # create condition - try: - o[a==int(i[0])] = float(i[1]) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '(i[1]) ' + str(i[1])) - except Exception as err: - try: - exp = 'o[' + i[0].replace(functionVariableList, 'a') + '] = float(i[1])' - exec(exp) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'error ' + str(err)) - return 'No' - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o.dtype ' + str(o.dtype)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o.shape ' + str(o.shape)) - return o - - # cross raster - def crossRasters(self, gdalBandList, rasterSCPArrayfunctionBand, nodataMask, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBandArgument ' + str(functionBandArgument) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'nodataMask ' + str(nodataMask) ) - a = eval(functionVariableList) - o = cfg.np.searchsorted(functionBandArgument, a.ravel(), side = 'right').reshape(rasterSCPArrayfunctionBand.shape[0], rasterSCPArrayfunctionBand.shape[1]) - if nodataMask is not None: - o[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - stats = cfg.np.array(cfg.np.unique(o[nodataMask[::, ::] == 0], return_counts=True)) - else: - try: - o[cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0])] = cfg.np.nan - stats = cfg.np.array(cfg.np.unique(o[~cfg.np.isnan(o)], return_counts=True)) - except: - stats = None - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o) ) - return [o, stats] - - # band calculation - def bandCalculation(self, gdalBandList, rasterSCPArrayfunctionBand, nodataMask, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - f = functionBandArgument - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand type ' + str(rasterSCPArrayfunctionBand.dtype) ) - # create function - b = 0 - for i in functionVariableList: - f = f.replace(i[0], ' rasterSCPArrayfunctionBand[::, ::,' + str(b) + '] ') - f = f.replace(i[1], ' rasterSCPArrayfunctionBand[::, ::,' + str(b) + '] ') - b = b + 1 - # replace numpy operators - f = cfg.utls.replaceNumpyOperators(f) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - # perform operation - try: - o = eval(f) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'error ' + str(err) ) - return err - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o) ) - # create array if not - if not isinstance(o, cfg.np.ndarray): - return 'No' - # check nan - if nodataMask is not None: - o[::, ::][nodataMask[::, ::] != 0] = nodataMask[::, ::][nodataMask[::, ::] != 0] - return o - - # multiple where scatter raster calculation - def scatterRasterMultipleWhere(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - for f in functionBandArgument: - # create function - f = f.replace('bandX', ' rasterSCPArrayfunctionBand[::, ::, 0] ') - f = f.replace('bandY', ' rasterSCPArrayfunctionBand[::, ::, 1] ') - # perform operation - try: - u = eval(f) - o = cfg.np.where(u == -999, o, u) - # first iteration - except: - try: - o = eval(f) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'error ' + str(err) ) - return 'No' - return o - - # band calculation scatter raster - def scatterRasterBandCalculation(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - f = functionBandArgument - # create function - f = f.replace('bandX', ' rasterSCPArrayfunctionBand[::, ::, 0] ') - f = f.replace('bandY', ' rasterSCPArrayfunctionBand[::, ::, 1] ') - # perform operation - o = eval(f) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), f) - return o - - # raster neighbor - def rasterNeighbor(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - structure = functionBandArgument - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'structure ' + str(structure)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList[0])) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand' + str(rasterSCPArrayfunctionBand[0,0,0])) - # calculate - if 'nansum' in functionVariableList[0]: - try: - o = cfg.np.round(cfg.signalSCP.oaconvolve(cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - except: - # if scipy version < 1.4 - o = cfg.np.round(cfg.signalSCP.fftconvolve(cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - o[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.np.nan - elif 'nanmean' in functionVariableList[0]: - try: - o = cfg.np.round(cfg.signalSCP.oaconvolve(cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same') / cfg.signalSCP.oaconvolve(~cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - except: - # if scipy version < 1.4 - o = cfg.np.round(cfg.signalSCP.fftconvolve(cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same') / cfg.signalSCP.fftconvolve(~cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - o[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.np.nan - elif 'nanmax' in functionVariableList[0]: - o = cfg.maximum_filterSCP(rasterSCPArrayfunctionBand[:,:,0], footprint=structure, mode='constant', cval=cfg.np.nan) - elif 'nanmin' in functionVariableList[0]: - o = cfg.minimum_filterSCP(rasterSCPArrayfunctionBand[:,:,0], footprint=structure, mode='constant', cval=cfg.np.nan) - elif 'median' in functionVariableList[0]: - o = cfg.median_filterSCP(rasterSCPArrayfunctionBand[:,:,0], footprint=structure, mode='constant', cval=cfg.np.nan) - elif 'count' in functionVariableList[0]: - try: - o = cfg.np.round(cfg.signalSCP.oaconvolve(~cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - except: - # if scipy version < 1.4 - o = cfg.np.round(cfg.signalSCP.fftconvolve(~cfg.np.isnan(rasterSCPArrayfunctionBand[:,:,0]), structure, mode='same'), 6) - o[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.np.nan - elif 'std' in functionVariableList[0]: - o = cfg.generic_filterSCP(rasterSCPArrayfunctionBand[:,:,0], cfg.np.std, footprint=structure, mode='constant', cval=cfg.np.nan) - elif 'percentile' in functionVariableList[0]: - o = cfg.percentile_filterSCP(rasterSCPArrayfunctionBand[:,:,0], percentile = int(functionVariableList[0].split(',')[1].strip(')')), footprint=structure, mode='constant', cval=cfg.np.nan) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o[0,0]) ) - return o - - # raster erosion - def rasterErosion(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - A = cfg.np.copy(rasterSCPArrayfunctionBand[::, ::, 0]) - A[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.NoDataVal - structure = functionBandArgument - # unique value list - uniqueVal = cfg.np.unique(A) - aUniqueVal = list(uniqueVal.astype(int)) - try: - aUniqueVal.remove(cfg.NoDataVal) - except: - pass - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'aUniqueVal ' + str(aUniqueVal) ) - # empty array - erosion = cfg.np.zeros(A.shape) - try: - sumAll = cfg.signalSCP.oaconvolve(cfg.np.ones(A.shape), structure, mode='same') - except: - # if scipy version < 1.4 - sumAll = cfg.signalSCP.fftconvolve(cfg.np.ones(A.shape), structure, mode='same') - # calculate sum - for i in aUniqueVal: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'i ' + str(i) ) - try: - sumA = cfg.signalSCP.oaconvolve(A==i, structure, mode='same') - except: - # if scipy version < 1.4 - sumA = cfg.signalSCP.fftconvolve(A==i, structure, mode='same') - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sumA ' + str(sumA) ) - if i not in functionVariableList: - try: - Amax[sumA > oldSumA] = float(i) - except: - Amax = cfg.np.ones(A.shape) * float(i) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Amax ' + str(Amax) ) - try: - oldSumA[sumA > oldSumA] = sumA[sumA > oldSumA] - except: - oldSumA = cfg.np.copy(sumA) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oldSumA ' + str(oldSumA) ) - else: - # erosion values - erosion[((sumAll - sumA) > 0.01 ) & (A==i) ] = 1 - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'erosion ' + str(erosion) ) - try: - AmaxCopy = Amax - except: - Amax = cfg.np.ones(A.shape) * float(cfg.NoDataVal) - oldSumA = cfg.np.zeros(A.shape) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Amax ' + str(Amax) ) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oldSumA ' + str(oldSumA) ) - o = cfg.np.where(erosion == 1, cfg.np.where(Amax == cfg.NoDataVal, cfg.np.nan, Amax), A) - o[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.np.nan - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o[0,0]) ) - return o - - # raster dilation - def rasterDilation(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - structure = functionBandArgument - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'structure ' + str(structure)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList[0])) - A = cfg.np.nan_to_num(rasterSCPArrayfunctionBand[:,:,0]) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'A' + str(A)) - # calculate - # value dictionary - C={} - for i in functionVariableList: - try: - C['arr_'+ str(i)] = (cfg.signalSCP.oaconvolve(A==i, structure, mode='same') > 0.999) - except: - # if scipy version < 1.4 - C['arr_'+ str(i)] = (cfg.signalSCP.fftconvolve(A==i, structure, mode='same') > 0.999) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'C[arr_' + str(C['arr_'+ str(i)])) - # core - D = cfg.np.ones(A.shape) - for v in functionVariableList: - D[A == v] = 0 - # dilation - o = cfg.np.copy(A) - try: - for v in functionVariableList: - o[(D * C['arr_'+ str(v)]) > 0] = v - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o) ) - o[::, ::][cfg.np.isnan(rasterSCPArrayfunctionBand[:, :, 0])] = cfg.np.nan - return o - - # calculate raster with stats - def regionGrowingAlgMultiprocess(self, rasterSCPArrayfunctionBand, functionBandArgument, functionVariableList, outputArrayFile, outputBandNumber): - # create function - f = ' rasterSCPArrayfunctionBand[::, ::,' + str(functionBandArgument) + '] ' - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand ' + str(rasterSCPArrayfunctionBand.shape) ) - # perform operation - array = eval(f) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'array ' + str(array) ) - seedX = functionVariableList[0] - seedY = functionVariableList[1] - spectralRange = functionVariableList[2] - minimumSize = functionVariableList[3] - sA = cfg.np.zeros(array.shape) - seedV = array[seedY, seedX] - # if nodata - if cfg.np.sum(cfg.np.isnan(seedV)) > 0: - return sA - sA.fill(seedV) - # difference array - dA = abs(array - sA) - # calculate minimum difference - uDA = cfg.np.unique(dA) - uDB = uDA[uDA > float(spectralRange)] - uDA = cfg.np.insert(uDB, 0, float(spectralRange)) - rr = None - for i in uDA: - rL, num_features = cfg.labelSCP(dA <= i) - # value of ROI seed - rV = rL[seedY,seedX] - rV_mask =(rL == rV) - if rV != 0 and cfg.np.count_nonzero(rV_mask) >= minimumSize: - rr = cfg.np.copy(rV_mask) - break - if rr is None and rV != 0 : - rr = cfg.np.copy(rV_mask) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rr.shape ' + str(rr.shape) ) - return [rr] - - # replace numpy operators for expressions in Band calc - def replaceOperatorNames(self, expression, nameList, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # variable bandset#b* - if '"' + cfg.variableBandsetName + '#b*"' in expression: - bandList = '[' - for b in range(1, len(cfg.bandSetsList[bandSetNumber][3])+1): - bandList = bandList + '"' + cfg.variableBandsetName + '#b' + str(b) + '", ' - # if percentile - perc = cfg.reSCP.findall(r'percentile\(#?(.*?)#?\)',expression.replace(' ', '')) - for percX in perc: - if '"' + cfg.variableBandsetName + '#b*"' in percX: - percXS = percX.split(',') - try: - expression = expression.replace(percX, bandList[:-2] + '],' + percXS[1] + ', axis = 0') - except: - pass - bandList = bandList[:-2] + '], axis = 0' - expression = expression.replace('"' + cfg.variableBandsetName + '#b*"', bandList) - # variable bandset*b1 - elif '"' + cfg.variableBandsetName + '*b' in expression: - bandNums = cfg.reSCP.findall(cfg.variableBandsetName + r'\*b#?(.*?)#?"', expression) - for parts in bandNums: - try: - numB = int(parts) - except: - return expression - bandList = '[' - for c in range(1, len(cfg.bandSetsList) + 1): - try: - # check band - cfg.bandSetsList[c-1][3][numB-1] - bandList = bandList + '"' + cfg.variableBandsetName + str(c) + 'b' + str(numB) + '", ' - except: - pass - # if percentile - perc = cfg.reSCP.findall(r'percentile\(#?(.*?)#?\)',expression) - for percX in perc: - if '"' + cfg.variableBandsetName + '*b' in percX: - percXS = percX.split(',') - try: - expression = expression.replace(percX, bandList[:-2] + '],' + percXS[1] + ', axis = 0') - except: - pass - bandList = bandList[:-2] + '], axis = 0' - expression = expression.replace('"' + cfg.variableBandsetName + '*b' + str(numB) + '"', bandList) - # variable bandset{1,2,3}b1 - elif '"' + cfg.variableBandsetName + '{' in expression: - bandNums = cfg.reSCP.findall(cfg.variableBandsetName + '{(.*?)\"', expression) - bsetList = [] - checkO = 'Yes' - for parts in bandNums: - partSplit = parts.split('}b') - try: - numB = int(partSplit[1]) - except: - return expression - foB = partSplit[0] - dtList = [] - dtRList = [] - nBList = [] - if ':' in foB and ',' in foB: - # list of ranges of dates - try: - lrg = foB.split(',') - for lrgL in lrg: - try: - # range of numbers - rg = lrgL.split(':') - for nbRg in range(int(rg[0].strip()), int(rg[1].strip())+1): - nBList.append(nbRg) - except: - try: - # range of dates - rg = lrgL.split(':') - dtRList.append([cfg.datetimeSCP.datetime.strptime(rg[0].strip(), '%Y-%m-%d'), cfg.datetimeSCP.datetime.strptime(rg[1].strip(), '%Y-%m-%d')]) - except: - pass - except: - checkO = 'No' - else: - try: - try: - # range of numbers - rg = foB.split(':') - for nbRg in range(int(rg[0].strip()), int(rg[1].strip())+1): - nBList.append(nbRg) - except: - # range of dates - rg = foB.split(':') - dtRList.append([cfg.datetimeSCP.datetime.strptime(rg[0].strip(), '%Y-%m-%d'), cfg.datetimeSCP.datetime.strptime(rg[1].strip(), '%Y-%m-%d')]) - except: - # list of dates - try: - rg = foB.split(',') - for rgL in rg: - try: - # number of band set - nBList.append(int(rgL.strip())) - except: - # date of band sets - dtList.append(rgL.strip()) - except: - checkO = 'No' - if checkO == 'Yes': - # number of band set - if len(nBList) > 0: - for j in nBList: - bsetList.append(j) - # date of band set - elif len(dtList) > 0: - for j in range(0, len(cfg.bandSetsList)): - if cfg.bandSetsList[j][9] in dtList: - bsetList.append(j+1) - # range of dates of band set - else: - for j in range(0, len(cfg.bandSetsList)): - try: - bD = cfg.datetimeSCP.datetime.strptime(cfg.bandSetsList[j][9], '%Y-%m-%d') - for dStr in dtRList: - if (bD >= dStr[0]) & (bD <= dStr[1]) is True: - bsetList.append(j+1) - break - except: - pass - bandList = '[' - for c in bsetList: - try: - # check band - cfg.bandSetsList[c-1][3][numB-1] - bandList = bandList + '"' + cfg.variableBandsetName + str(c) + 'b' + str(numB) + '", ' - except: - pass - # if percentile - perc = cfg.reSCP.findall(r'percentile\((.*?)\)',expression) - for percX in perc: - if '"' + cfg.variableBandsetName + '{' + parts in percX: - percXS = percX.split('",') - try: - expression = expression.replace(percX, bandList[:-2] + '],' + percXS[1] + ', axis = 0') - except: - pass - bandList = bandList[:-2] + '], axis = 0' - expression = expression.replace('"' + cfg.variableBandsetName + '{' + parts + '"', bandList) - # variable bandset1b* - elif cfg.variableBandsetName in expression and 'b*"' in expression: - for c in range(0, len(cfg.bandSetsList)): - bandList = '[' - if '"' + cfg.variableBandsetName + str(c + 1) + 'b*"' in expression: - for b in range(1, len(cfg.bandSetsList[c][3])+1): - bandList = bandList + '"' + cfg.variableBandsetName + str(c + 1) + 'b' + str(b) + '", ' - # if percentile - perc = cfg.reSCP.findall(r'percentile\(#?(.*?)#?\)',expression) - for percX in perc: - if '"' + cfg.variableBandsetName in percX and 'b*"' in percX: - percXS = percX.split(',') - try: - expression = expression.replace(percX, bandList[:-2] + "]," + percXS[1] + ", axis = 0") - except: - pass - bandList = bandList[:-2] + '], axis = 0' - expression = expression.replace('"' + cfg.variableBandsetName + str(c + 1) + 'b*"', bandList) - if "nodata" in expression: - # find all non-greedy expression - g = cfg.reSCP.findall(r'nodata\(\"#?(.*?)#?\"\)',expression) - else: - return expression - for l in g: - name = l - for i in nameList: - if l == i[0].replace('"', ''): - l = i[1].replace('"', '') - if l in cfg.variableBlueName or l in cfg.variableRedName or l in cfg.variableNIRName or l in cfg.variableGreenName or l in cfg.variableSWIR1Name or l in cfg.variableSWIR2Name : - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - name = '#' + name - if '#' + l == cfg.variableRedName : - bandNumber = ['', cfg.REDBand] - elif '#' + l == cfg.variableGreenName : - bandNumber = ['', cfg.GREENBand] - elif '#' + l == cfg.variableNIRName : - bandNumber = ['', cfg.NIRBand] - elif '#' + l == cfg.variableBlueName : - bandNumber = ['', cfg.BLUEBand] - elif '#' + l == cfg.variableSWIR1Name : - bandNumber = ['', cfg.SWIR1Band] - elif '#' + l == cfg.variableSWIR2Name : - bandNumber = ['', cfg.SWIR2Band] - l = cfg.bandSetsList[bandSetNumber][3][int(bandNumber[1]) - 1] - else: - l = cfg.bandSetsList[bandSetNumber][8] - # in case of bandset name - for b in range(1, len(cfg.bandSetsList[bandSetNumber][3])+1): - if cfg.variableBandsetName + '#b' + str(b) == l: - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - l = cfg.bandSetsList[bandSetNumber][3][int(b) - 1] - else: - l = cfg.bandSetsList[bandSetNumber][8] - break - for c in range(0, len(cfg.bandSetsList)): - for b in range(0, len(cfg.bandSetsList[c][3])): - if cfg.variableBandsetName + str(c + 1) + 'b' + str(b + 1) == l: - # band set - if cfg.bandSetsList[c][0] == 'Yes': - l = cfg.bandSetsList[c][3][int(b)] - else: - l = cfg.bandSetsList[c][8] - break - name = '"' + name + '"' - r = cfg.utls.selectLayerbyName(l, 'Yes') - if r is not None: - ql = cfg.utls.layerSource(r) - nd = cfg.utls.imageNoDataValue(ql) - expression = expression.replace('nodata(' + name + ')', str(nd)) - # find Nodata values - return expression - - # replace numpy operators for expressions in Band calc - def replaceNumpyOperators(self, expression): - f = ' ' + expression.replace(',', ', ') + ' ' - f = f.replace(' np.', ' ' + cfg.numpyn) - f = f.replace('~np.', ' ~' + cfg.numpyn) - f = f.replace(' ln(', ' ' + cfg.logn + '(') - f = f.replace(' ln (', ' ' + cfg.logn + '(') - f = f.replace(' log10(', ' ' + cfg.log10 + '(') - f = f.replace(' log10 (', ' ' + cfg.log10 + '(') - f = f.replace(' sqrt(', ' ' + cfg.numpySqrt + '(') - f = f.replace(' sqrt (', ' ' + cfg.numpySqrt + '(') - f = f.replace(' cos(', ' ' + cfg.numpyCos+ '(') - f = f.replace(' cos (', ' ' + cfg.numpyCos + '(') - f = f.replace(' acos(', ' ' + cfg.numpyArcCos + '(') - f = f.replace(' acos (', ' ' + cfg.numpyArcCos + '(') - f = f.replace(' sin(', ' ' + cfg.numpySin + '(') - f = f.replace(' sin (', ' ' + cfg.numpySin + '(') - f = f.replace(' asin(', ' ' + cfg.numpyArcSin + '(') - f = f.replace(' asin (', ' ' + cfg.numpyArcSin + '(') - f = f.replace(' tan(', ' ' + cfg.numpyTan + '(') - f = f.replace(' tan (', ' ' + cfg.numpyTan + '(') - f = f.replace(' atan(', ' ' + cfg.numpyArcTan + '(') - f = f.replace(' atan (', ' ' + cfg.numpyArcTan + '(') - f = f.replace(' exp(', ' ' + cfg.numpyExp + '(') - f = f.replace(' exp (', ' ' + cfg.numpyExp + '(') - f = f.replace(' min(', ' ' + cfg.numpyAMin + '(') - f = f.replace(' min (', ' ' + cfg.numpyAMin + '(') - f = f.replace(' max(', ' ' + cfg.numpyAMax + '(') - f = f.replace(' max (', ' ' + cfg.numpyAMax + '(') - f = f.replace(' percentile(', ' ' + cfg.numpyPercentile + '(') - f = f.replace(' percentile (', ' ' + cfg.numpyPercentile + '(') - f = f.replace(' median(', ' ' + cfg.numpyMedian + '(') - f = f.replace(' median (', ' ' + cfg.numpyMedian + '(') - f = f.replace(' mean(', ' ' + cfg.numpyMean + '(') - f = f.replace(' mean (', ' ' + cfg.numpyMean + '(') - f = f.replace(' sum(', ' ' + cfg.numpySum + '(') - f = f.replace(' sum (', ' ' + cfg.numpySum + '(') - f = f.replace(' std(', ' ' + cfg.numpyStd + '(') - f = f.replace(' std (', ' ' + cfg.numpyStd + '(') - f = f.replace('^', '**') - f = f.replace(' where(', ' ' + cfg.numpyWhere + '(') - f = f.replace(' where (', ' ' + cfg.numpyWhere + '(') - return f - - # raster calculation - def noBlocksCalculation(self, rasterSCPArrayfunctionBand, functionBandArgument, functionVariableList, outputArrayFile, outputBandNumber): - f = functionBandArgument - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - # replace numpy operators - f = cfg.utls.replaceNumpyOperators(f) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - # perform operation - o = eval(f) - if outputArrayFile is None: - return o - else: - cfg.np.save(outputArrayFile, o) - return outputArrayFile - - # interprocess - def multiProcessNoBlocksDev(self, raster = None, signatureList = None, bandNumberList = None, functionRaster = None, algorithmName = None, outputArrayFile = None, outputAlgorithmRaster = None, outputClassificationRaster = None, previewSize = None, previewPoint = None, nodataValue = None, macroclassCheck = None, functionBandArgument = None, functionVariable = None, progressMessage = None, skipReplaceNoData = None, outputBandNumber = None, writerLog = None): - from . import config as cfg - import os - import sys - import inspect - import time - import datetime - import random - cfg.osSCP = os - cfg.sysSCP = sys - cfg.inspectSCP = inspect - cfg.datetimeSCP = datetime - cfg.randomSCP = random - wrtProc = str(writerLog[0]) - cfg.tmpDir = writerLog[1] - memory = writerLog[2] - compress = writerLog[3] - compressFormat = writerLog[4] - GDALDLLPath = writerLog[5] - from .utils import Utils - cfg.utls = Utils() - cfg.logFile = cfg.tmpDir + '/log_' + wrtProc - for d in GDALDLLPath.split(';'): - try: - os.add_dll_directory(d) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'error ' + str(err) ) - import numpy as np - try: - from scipy.ndimage import label - cfg.labelSCP = label - except: - pass - try: - from scipy.ndimage.filters import maximum_filter - from scipy.ndimage.filters import minimum_filter - from scipy.ndimage.filters import percentile_filter - from scipy.ndimage.filters import generic_filter - from scipy.ndimage.filters import median_filter - cfg.maximum_filterSCP = maximum_filter - cfg.minimum_filterSCP = minimum_filter - cfg.percentile_filterSCP = percentile_filter - cfg.generic_filterSCP = generic_filter - cfg.median_filterSCP = median_filter - except: - pass - from osgeo import gdal - from osgeo import ogr - from osgeo import osr - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - cfg.np = np - # GDAL config - try: - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', memory) - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass - # open input with GDAL - rD = cfg.gdalSCP.Open(raster, cfg.gdalSCP.GA_ReadOnly) - bandNumber = rD.RasterCount - # number of x pixels - rX = rD.RasterXSize - # number of y pixels - rY = rD.RasterYSize - gdalBandList = [] - for b in range(1, bandNumber + 1): - rB = rD.GetRasterBand(b) - gdalBandList.append(rB) - if outputBandNumber is None: - outputBandNumber = 1 - # numpy data - array = cfg.np.zeros((rY, rX, len(gdalBandList)), dtype=cfg.np.float32) - for b in bandNumberList: - if nodataValue is None: - ndv = cfg.NoDataVal - else: - ndv = nodataValue - # multiband - try: - b0 = gdalBandList[b].GetRasterBand(b+1) - except: - b0 = gdalBandList[b] - try: - of = b0.GetOffset() - s = b0.GetScale() - if of is None: - of = 0 - if s is None: - s = 1 - except: - of = 0 - s = 1 - a = b0.ReadAsArray()*s+of - try: - ndvBand = b0.GetNoDataValue() * s + of - except: - ndvBand = None - if a is not None: - if functionBandArgument == cfg.multiAddFactorsVar: - multiAdd = functionVariable - a = cfg.utls.arrayMultiplicativeAdditiveFactors(a, multiAdd[0][b], multiAdd[1][b]) - array[::, ::, b] = a - else: - return 'No' - a = None - # set nodata value - if ndvBand is not None: - try: - array[::, ::, b][array[::, ::, b] == ndvBand] = cfg.np.nan - except: - pass - if skipReplaceNoData is not None: - try: - array[::, ::, b][cfg.np.isnan(array[::, ::, b])] = ndvBand - except: - pass - if ndv is not None: - try: - array[::, ::, b][array[::, ::, b] == ndv] = cfg.np.nan - except: - pass - for b in range(0, len(gdalBandList)): - gdalBandList[b] = None - rD = None - o = functionRaster(array, functionBandArgument, functionVariable, outputArrayFile, outputBandNumber) - # close GDAL rasters - array = None - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o ' + str(o) ) - return o - - # process a raster entirely - def multiProcessNoBlocks(self, rasterPath, signatureList = None, bandNumberList = None, functionRaster = None, algorithmName = None, outputRasterList = None, outputAlgorithmRaster = None, outputClassificationRaster = None, previewSize = 0, previewPoint = None, nodataValue = None, macroclassCheck = 'No', functionBandArgument = None, functionVariable = None, progressMessage = '', skipReplaceNoData = None, threadNumber = None, parallel = None, outputBandNumber = None, compress = 'No', compressFormat = 'LZW'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'start processRaster no boundaries') - if threadNumber is None: - threadNumber = cfg.threads - memVal = str(int( cfg.RAMValue / threadNumber)*1000000) - # multiple calculations - sez = list(range(0, len(functionBandArgument), threadNumber)) - sez.append(len(functionBandArgument)) - totBlocks = len(functionBandArgument) - # calculation multiprocess - output = {} - completedBlocks = 0 - for s in range(0, len(sez)-1): - cfg.subprocRes = {} - cfg.pool = cfg.poolSCP(processes=threadNumber) - results = [] - for p in range(sez[s], sez[s+1]): - if cfg.actionCheck == 'Yes': - try: - pOut = outputRasterList[p] - except: - pOut = None - fArg = functionBandArgument[p] - fVar = functionVariable[p] - bList = bandNumberList[p] - wrtP = [p, cfg.tmpDir, memVal, compress, compressFormat, cfg.gdalDLLPath] - c = cfg.pool.apply_async(cfg.utls.multiProcessNoBlocksDev, args=(rasterPath, signatureList, bList, functionRaster, algorithmName, pOut, outputAlgorithmRaster, outputClassificationRaster, previewSize, previewPoint, nodataValue, macroclassCheck, fArg, fVar, progressMessage, skipReplaceNoData, outputBandNumber, wrtP)) - results.append([c, p]) - # update progress - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - try: - if progressMessage is not None: - cfg.uiUtls.updateBar(int(100 * (completedBlocks + sum(pR)) / totBlocks), progressMessage) - except: - pass - cfg.QtWidgetsSCP.qApp.processEvents() - completedBlocks = completedBlocks + sum(pR) - if cfg.actionCheck == 'Yes': - for r in results: - cfg.subprocRes[r[1]] = r[0].get() - cfg.pool.close() - cfg.pool.terminate() - for p in range(sez[s], sez[s+1]): - if cfg.actionCheck == 'Yes': - try: - output[functionBandArgument[p]] = cfg.subprocRes[p] - except: - output[functionBandArgument[p]] = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "end processRaster no boundaries") - return output - -# interprocess - def processRasterDev(self, raster = None, signatureList = None, functionBand = None, functionRaster = None, algorithmName = None, outputArrayFile = None, outputAlgorithmRaster = None, outputClassificationRaster = None, section = None, classificationOptions = None, nodataValue = None, macroclassCheck = None, functionBandArgument = None, functionVariable = None, progressMessage = None, skipReplaceNoData = None, singleBandNumber = None, outputBandNumber = None, outputNoData = None, scale = None, offset = None, writerLog = None): - from . import config as cfg - import os - import sys - import inspect - import time - import datetime - import random - wrtProc = str(writerLog[0]) - wrtOut = writerLog[1] - cfg.tmpDir = writerLog[2] - parallelWritingCheck = writerLog[3] - progressQueue = writerLog[4] - memory = writerLog[5] - compress = writerLog[6] - compressFormat = writerLog[7] - dataType = writerLog[8] - boundarySize = writerLog[9] - roX = writerLog[10] - roY = writerLog[11] - vBX = writerLog[12] - vBY = writerLog[13] - calcDataType = writerLog[14] - GDALDLLPath = writerLog[15] - useNoDataMask = writerLog[16] - for d in GDALDLLPath.split(';'): - try: - os.add_dll_directory(d) - except: - pass - import numpy as np - # garbage collector for memory issue - import gc - try: - import scipy.stats.distributions as statdistr - cfg.statdistrSCP = statdistr - except: - pass - try: - from scipy import signal - cfg.signalSCP = signal - except: - pass - try: - from scipy.ndimage.filters import maximum_filter - from scipy.ndimage.filters import minimum_filter - from scipy.ndimage.filters import percentile_filter - from scipy.ndimage.filters import generic_filter - from scipy.ndimage.filters import median_filter - cfg.maximum_filterSCP = maximum_filter - cfg.minimum_filterSCP = minimum_filter - cfg.percentile_filterSCP = percentile_filter - cfg.generic_filterSCP = generic_filter - cfg.median_filterSCP = median_filter - except: - pass - from osgeo import gdal - from osgeo import ogr - from osgeo import osr - cfg.osSCP = os - cfg.sysSCP = sys - cfg.inspectSCP = inspect - cfg.datetimeSCP = datetime - cfg.np = np - cfg.randomSCP = random - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - from .utils import Utils - cfg.utls = Utils() - cfg.logFile = cfg.tmpDir + '/log_' + wrtProc - # GDAL config - try: - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', memory) - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass - if scale is not None: - scl = float(scale) - else: - scl = 1.0 - if offset is not None: - offs = float(offset) - else: - offs = 0.0 - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster ' + str(raster)) - # for raster creation - format = cfg.gdalSCP.GDT_Float32 - # open input with GDAL - rD = cfg.gdalSCP.Open(raster, cfg.gdalSCP.GA_ReadOnly) - # pixel size and origin from reference - rP = rD.GetProjection() - rGT = rD.GetGeoTransform() - tD = cfg.gdalSCP.GetDriverByName('GTiff') - xSize = rD.RasterXSize - ySize = rD.RasterYSize - tLX = rGT[0] - tLY = rGT[3] - pSX = rGT[1] - pSY = rGT[5] - bandNumber = rD.RasterCount - rD = None - # if classification - if functionRaster is not None and functionBand == 'Yes': - # classification rasters - outClasses = [] - # algorithm rasters - outAlgs = [] - # signature dictionary rasters - outSigDict = {} - # create raster - uLX = tLX + roX * pSX - uLY = tLY + roY * pSY - geotransform = (uLX, pSX, rGT[2], uLY, rGT[4], pSY) - wrtFile = cfg.utls.createTempRasterPath('tif', wrtProc) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'wrtFile, compress, roX, roY, vBX, vBY ' + str([wrtFile, compress, roX, roY, vBX, vBY]) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'dataType ' + str(dataType) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'calcDataType ' + str(calcDataType) ) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' nodataValue ' + str(nodataValue) ) - # output - o = [] - ooS = None - if wrtOut is not None: - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'compress ' + str(compress) ) - cfg.utls.createRasterFromReferenceMultiprocess(raster, 1, [wrtFile], nodataValue, 'GTiff', dataType, compress, compressFormat, geotransform = geotransform, xSize = vBX, ySize = vBY) - process = 0 - while process < 2: - procError = 'No' - process = process + 1 - countPerc = 0 - for sec in section: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sec ' + str(sec) ) - check = 0 - # open input with GDAL - rD = cfg.gdalSCP.Open(raster, cfg.gdalSCP.GA_ReadOnly) - gdalBandList = [] - if singleBandNumber is None: - for b in range(1, bandNumber + 1): - rB = rD.GetRasterBand(b) - gdalBandList.append(rB) - else: - rB = rD.GetRasterBand(singleBandNumber+1) - gdalBandList.append(rB) - # perform the process twice in case of error - while check < 2: - if boundarySize is None: - x, y, bSX, bSY = sec - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'x, y, bSX, bSY ' + str([x, y, bSX, bSY]) ) - else: - x, y, bSX, bSY, oX, oXX, oY, oYY = sec - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'x, y, bSX, bSY, oX, oXX, oY, oYY ' + str([x, y, bSX, bSY, oX, oXX, oY, oYY]) ) - # if classification - if functionRaster is not None and functionBand == 'Yes': - dT = cfg.datetimeSCP.datetime.now().strftime('%Y%m%d_%H%M%S%f') - # signature raster list - outputSigRasterList = [] - # list of rasters to be created - outputReferenceRasterList = [] - # create tif paths - for s in range(0, len(signatureList)): - sLR = str(signatureList[s][0]) + '_' + str(signatureList[s][2]) - sTR = cfg.tmpDir + '/' + cfg.sigRasterNm + '_' + sLR + '_' + dT + str(wrtProc) + '.tif' - try: - outSigDict[sLR].append(sTR) - except Exception as err: - outSigDict[sLR] = [sTR] - outputSigRasterList.append(sTR) - outputReferenceRasterList.append(sTR) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outSigDict ' + str(outSigDict) ) - outClass = cfg.tmpDir + '/' + 'c_' + dT + str(wrtProc) + '.tif' - outAlg = cfg.tmpDir + '/' + 'a_' + dT + str(wrtProc) + '.tif' - outputReferenceRasterList.append(outClass) - outputReferenceRasterList.append(outAlg) - outClasses.append(outClass) - outAlgs.append(outAlg) - uLX = tLX + x * pSX - uLY = tLY + y * pSY - geotransform = (uLX, pSX, rGT[2], uLY, rGT[4], pSY) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'compress ' + str(compress) ) - cfg.utls.createRasterFromReferenceMultiprocess(raster, 1, outputReferenceRasterList, nodataValue, 'GTiff', cfg.rasterDataType, compress, compressFormat, geotransform = geotransform, xSize = bSX, ySize = bSY) - array = cfg.np.zeros((bSY, bSX, len(gdalBandList)), dtype=calcDataType) - nodataMask = None - for b in range(0, len(gdalBandList)): - sclB = 1 - offsB = 0 - ndvBand = None - ''' - if nodataValue is None: - ndv = None - else: - ndv = nodataValue - ''' - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'read band ' + str(b) ) - # read - if parallelWritingCheck == 'Yes': - pCount = 0 - while True: - pCount = pCount + 1 - a = cfg.utls.readArrayBlock(gdalBandList[b], x, y, bSX, bSY, calcDataType) - time.sleep(0.1) - a2 = cfg.utls.readArrayBlock(gdalBandList[b], x, y, bSX, bSY, calcDataType) - checkA = cfg.np.allclose(a, a2, equal_nan=True) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'checkA ' + str(checkA) ) - if checkA is True: - break - if pCount > 3: - a = None - break - a2 = None - else: - a = cfg.utls.readArrayBlock(gdalBandList[b], x, y, bSX, bSY, calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a[0, 0] ' + str(a[0, 0] ) ) - try: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a ' + str(a[0,0]) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a.dtype ' + str(a.dtype) ) - except: - pass - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'read band' + str(b) ) - try: - b0 = gdalBandList[b].GetRasterBand(1) - offsB = b0.GetOffset() - sclB = b0.GetScale() - if sclB is not None: - sclB = sclB - if offsB is not None: - offsB = offsB - offsB = cfg.np.asarray(offsB).astype(a.dtype) - sclB = cfg.np.asarray(sclB).astype(a.dtype) - ndvBand = b0.GetNoDataValue() - ndvBand = cfg.np.asarray(ndvBand * sclB + offsB).astype(a.dtype) - except: - try: - offsB = gdalBandList[b].GetOffset() - sclB = gdalBandList[b].GetScale() - if sclB is not None: - sclB = sclB - else: - sclB = 1 - if offsB is not None: - offsB = offsB - else: - offsB = 0 - offsB = cfg.np.asarray(offsB).astype(a.dtype) - sclB = cfg.np.asarray(sclB).astype(a.dtype) - ndvBand = gdalBandList[b].GetNoDataValue() - ndvBand = cfg.np.asarray(ndvBand * sclB + offsB).astype(a.dtype) - except: - ndvBand = None - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ndvBand ' + str(ndvBand)) - if ndvBand is not None: - # adapt NoData to dtype - ndvBand = cfg.np.asarray(ndvBand).astype(calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ndvBand ' + str(ndvBand) + ' sclB ' + str(sclB)+ ' offsB ' + str(offsB)) - if a is not None: - if functionBandArgument == cfg.multiAddFactorsVar: - multiAdd = functionVariable - a = cfg.utls.arrayMultiplicativeAdditiveFactors(a, multiAdd[0][b], multiAdd[1][b]) - array[::, ::, b] = a.astype(calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a[0, 0] ' + str(a[0, 0] ) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'array[0, 0, b] ' + str(array[0, 0, b] ) ) - else: - procError = 'Error array none' - # set nodata value - if calcDataType == np.float32 or calcDataType == np.float64: - if ndvBand is not None: - try: - array[::, ::, b][array[::, ::, b] == ndvBand] = cfg.np.nan - except: - pass - if skipReplaceNoData is not None: - try: - array[::, ::, b][cfg.np.isnan(array[::, ::, b])] = ndvBand - except: - pass - if useNoDataMask == 'Yes': - try: - nodataMask[0, 0] - except: - nodataMask = cfg.np.zeros((bSY, bSX), dtype=calcDataType) - if skipReplaceNoData is not None: - pass - elif ndvBand is not None: - try: - nodataMask[::, ::][array[::, ::, b] == ndvBand] = outputNoData - except: - pass - if skipReplaceNoData is not None: - pass - else: - try: - nodataMask[::, ::][cfg.np.isnan(array[::, ::, b])] = outputNoData - except: - pass - if skipReplaceNoData is not None: - pass - elif nodataValue is not None: - nodataValue = cfg.np.asarray(nodataValue).astype(a.dtype).astype(calcDataType) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'nodataValue ' + str(nodataValue)) - try: - nodataMask[::, ::][array[::, ::, b] == nodataValue] = outputNoData - except: - pass - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputNoData ' + str(outputNoData)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'a[0,0] ' + str(a[0, 0])) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'nodataMask[0, 0] ' + str(nodataMask)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'array ' + str(array[::, ::, 0])) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'skipReplaceNoData ' + str(skipReplaceNoData)) - #if functionBand is not None and functionBand != 'No': - # functionBand(b+1, array[::, ::, b].reshape(bSY, bSX), bSX, bSY, x, y, outputArrayFile, functionBandArgument, functionVariable) - # logger - # cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBand ' + str(functionBand)) - a = None - # logger - try: - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'array ' + str(array)) - except: - pass - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'wrtOut ' + str(wrtOut)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBand ' + str(functionBand)) - if functionRaster is not None: - if functionBand == 'No': - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputBandNumber ' + str(outputBandNumber)) - oo = functionRaster([scl, offs, outputNoData], array, nodataMask, bSY, x, y, outputArrayFile, functionBandArgument, functionVariable, outputBandNumber) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oo ' + str(oo)) - if isinstance(oo, list): - ooS = oo[1] - oo = oo[0] - if wrtOut is None: - o.append([oo, ooS]) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBand No functionRaster ' + str(functionRaster)) - if type(oo) is not cfg.np.ndarray: - if oo == 'No': - procError = 'Error function raster' - # classification - else: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputSigRasterList ' + str(outputSigRasterList)) - landCoverSignature, LCSClassAlgorithm, LCSLeaveUnclassified, algBandWeigths, algThrshld = classificationOptions - oo = functionRaster(len(gdalBandList), signatureList, algorithmName, array, landCoverSignature, LCSClassAlgorithm,LCSLeaveUnclassified, algBandWeigths, outputSigRasterList, outAlg, outClass, outputNoData, macroclassCheck, algThrshld, nodataMask) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oo ' + str(oo)) - o = [outClasses, outAlgs, outSigDict] - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionRaster ' + str(functionRaster)) - if type(oo) is not cfg.np.ndarray: - if oo == 'No': - procError = 'Error function band' - # output - if wrtOut is not None: - try: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'scale ' + str(scale)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'offset ' + str(offset)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oo dtype ' + str(oo.dtype)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputNoData ' + str(outputNoData)) - # write array - oo[cfg.np.isnan(oo)] = outputNoData - if boundarySize is not None: - oo = oo[oY:(bSY-oYY), oX:(bSX-oXX)] - x = x + oX - y = y + oY - bSX = bSX - oX - oXX - bSY = bSY - oY - oYY - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'x ' + str(x)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oXX ' + str(oXX)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'bSX ' + str(bSX)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oo1 ' + str(oo.shape)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oo2 ' + str(oo.shape)) - if parallelWritingCheck == 'Yes': - pCount = 0 - while True: - pCount = pCount + 1 - writeOut = cfg.utls.writeRasterNew(wrtFile, x-roX, y-roY, bSX, bSY, oo, outputNoData, scl, offs, dataType) - oR = cfg.gdalSCP.Open(wrtFile, cfg.gdalSCP.GA_ReadOnly) - bO = oR.GetRasterBand(1) - oo2 = cfg.utls.readArrayBlock(bO, x-roX, y-roY, bSX, bSY, calcDataType) - bO = None - oR = None - checkOO = cfg.np.allclose(oo, oo2, equal_nan=True) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'checkOO ' + str(checkOO)) - if checkOO is True: - break - if pCount > 3: - break - else: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'writeRasterNew compress ' + str(compress)) - writeOut = cfg.utls.writeRasterNew(wrtFile, x-roX, y-roY, bSX, bSY, oo, outputNoData, scl, offs, dataType) - check = 2 - array = None - oo = None - oo2 = None - o.append([wrtFile, ooS]) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'wrtFile ' + str(wrtFile) + ' writeOut' + str(writeOut)) - except Exception as err: - procError = err - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error ' + str(err)) - check = check + 1 - else: - check = 2 - if wrtProc == '0': - perc = str(int(100 * countPerc / len(section))) - progressQueue.put([perc], False) - # close GDAL rasters - for b in range(0, len(gdalBandList)): - gdalBandList[b].FlushCache() - gdalBandList[b] = None - gdalBandList = None - rD = None - gc.collect() - countPerc = countPerc + 1 - if procError == 'No': - process = 2 - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'end for') - if procError != 'No': - return o, procError - return o, '' - - # process a raster with block size - def multiProcessRaster(self, rasterPath, signatureList = None, functionBand = None, functionRaster = None, algorithmName = None, outputRasterList = None, outputAlgorithmRaster = None, outputClassificationRaster = None, classificationOptions = None, nodataValue = None, macroclassCheck = 'No', functionBandArgument = None, functionVariable = None, progressMessage = "", skipReplaceNoData = None, threadNumber = None, parallel = None, deleteArray = None, skipSingleBand = None, outputBandNumber = None, virtualRaster = 'No', compress = 'No', compressFormat = 'LZW', outputNoDataValue = None, dataType = None, scale = None, offset = None, parallelWritingCheck = None, boundarySize = None, additionalLayer = None, calcDataType = None, nodataMask = None): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'start processRaster') - if outputNoDataValue is None: - outputNoDataValue = cfg.NoDataVal - if dataType is None: - dataType = cfg.rasterDataType - unitMemory = cfg.arrayUnitMemory - # nodata mask - if nodataMask is None: - nodataMask = 'Yes' - # calculation data type - if calcDataType is None: - calcDataType = cfg.np.float32 - if calcDataType == cfg.np.uint32 or calcDataType == cfg.np.int32: - unitMemory = cfg.arrayUnitMemory8 - elif calcDataType == cfg.np.uint16 or calcDataType == cfg.np.int16: - unitMemory = cfg.arrayUnitMemory4 - gdalRaster = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - if additionalLayer is None: - additionalLayer = 1 - elif algorithmName == 'PCA': - additionalLayer = 10 - if outputBandNumber is None: - outputBandNumber = 1 - if parallelWritingCheck is None: - parallelWritingCheck = cfg.parallelWritingCheck - if virtualRaster == 'Yes': - parallelWritingCheck = 'No' - try: - bandNumber = gdalRaster.RasterCount - except: - return 'No' - if threadNumber is None: - threadNumber = cfg.threads - # number of x pixels - rX = gdalRaster.RasterXSize - # number of y pixels - rY = gdalRaster.RasterYSize - block = gdalRaster.GetRasterBand(1).GetBlockSize() - # list of range pixels - yBlock = block[1] - if yBlock == rY: - yBlock = block[0] - singleBlockSize = rX * yBlock * unitMemory * (bandNumber + additionalLayer) - RAMBlocks = int(cfg.RAMValue/(singleBlockSize * threadNumber)) - if RAMBlocks == 0: - RAMBlocks = 1 - blockSizeX = rX - blockSizeY = RAMBlocks * yBlock - if blockSizeX > rX: - blockSizeX = rX - lX = list(range(0, rX, blockSizeX)) - if blockSizeY > rY: - blockSizeY = int(rY/float(threadNumber))+1 - lY = list(range(0, rY, blockSizeY)) - if len(lY) < threadNumber: - blockSizeY = int(rY/float(threadNumber))+1 - lY = list(range(0, rY, blockSizeY)) - gdalRaster = None - # set initial value for progress bar - try: - progresStep = 60 / (len(lX) * len(lY)) - except: - progresStep = 60 - progressStart = 20 - progresStep - singleBandNumber = None - cfg.remainingTime = 0 - totBlocks = len(lX) * len(lY) - try: - manager = cfg.MultiManagerSCP() - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # progress queue - pMQ = manager.Queue() - results = [] - pR = [] - # temporary raster output - tmpRastList = [] - cfg.subprocRes = {} - # calculate raster ranges - ranges = [] - bSX = blockSizeX - x = 0 - try: - lYt = list(range(0, len(lY), round(len(lY)/threadNumber))) - except: - lYt = [0] - lYt.append(len(lY)) - for lYp in range(1, len(lYt)): - secs = [] - for lYs in range(lYt[lYp-1], lYt[lYp]): - y = lY[lYs] - bSY = blockSizeY - if y + bSY > rY: - bSY = rY - y - # single parallel process - if parallel is None: - if boundarySize is None: - secs.append([x, y, bSX, bSY]) - else: - # left x position plus boundary - boundX = x - boundarySize - # right x position plus boundary - boundSX = bSX + boundarySize * 2 - # left pixels - oX = boundarySize - # right pixels - oXX = boundarySize - if boundX <= 0: - boundX = 0 - boundSX = bSX + boundarySize - oX = 0 - if boundX + boundSX >= rX: - boundSX = rX - boundX - oXX = 0 - # upper position plus boundary - boundY = y - boundarySize - # lower y position plus boundary - boundSY = bSY + boundarySize * 2 - # upper pixels - oY = boundarySize - # lower pixels - oYY = boundarySize - if boundY <= 0: - boundY = 0 - boundSY = bSY + boundarySize - oY = 0 - if boundY + boundSY >= rY: - boundSY = rY - boundY - oYY = 0 - secs.append([boundX, boundY, boundSX, boundSY, oX, oXX, oY, oYY]) - # multiple parallel processes - else: - ranges.append([x, y, bSX, bSY]) - # single parallel process - if parallel is None: - ranges.append(secs) - if skipSingleBand is not None: - ranges.append([0, 0, rX, rY]) - # single parallel process - if parallel is None: - # pool - cfg.pool = cfg.poolSCP(processes=threadNumber) - memVal = '100000000' - if progressMessage is not None: - cfg.uiUtls.updateBar(0, progressMessage) - for p in range(0, len(ranges)): - sections = ranges[p] - vY = [] - vBY = 0 - for sec in sections: - if boundarySize is not None: - x, y, bSX, bSY, oX, oXX, oY, oYY = sec - x = x + oX - bSX = bSX - oX - oXX - y = y + oY - bSY = bSY - oY - oYY - else: - x, y, bSX, bSY = sec - vY.append(y) - vBY = vBY + bSY - # minimum origin - roY = min(vY) - if cfg.actionCheck == 'Yes': - pOut = '' - wrtP = [p, outputRasterList, cfg.tmpDir, parallelWritingCheck, pMQ, memVal, compress, compressFormat, dataType, boundarySize, x, roY, bSX, vBY, calcDataType, cfg.gdalDLLPath, nodataMask] - c = cfg.pool.apply_async(self.processRasterDev, args=(rasterPath, signatureList, functionBand, functionRaster, algorithmName, pOut, outputAlgorithmRaster, outputClassificationRaster, sections, classificationOptions, nodataValue, macroclassCheck, functionBandArgument, functionVariable, progressMessage, skipReplaceNoData, singleBandNumber, outputBandNumber, outputNoDataValue, scale, offset, wrtP)) - results.append([c, p]) - cfg.QtWidgetsSCP.qApp.processEvents() - # update progress - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - cfg.timeSCP.sleep(1) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - try: - pMQp = pMQ.get(False) - pgQ = int(pMQp[0]) - try: - # update progress and message - cfg.uiUtls.updateBar(pgQ, pMQp[1] + dots) - except: - cfg.uiUtls.updateBar(pgQ) - except: - if progressMessage is not None: - cfg.uiUtls.updateBar(message = progressMessage + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck == 'Yes': - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - cfg.subprocRes[r[1]] = res[0] - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - cfg.gcSCP.collect() - return 'No' - else: - cfg.pool.close() - cfg.pool.terminate() - cfg.gcSCP.collect() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - # multiple parallel processes - else: - if progressMessage is not None: - cfg.uiUtls.updateBar(0, progressMessage) - # set initial value for progress bar - progressStart = progressStart + progresStep - # for band number - if functionBandArgument is None: - sez = list(range(0, bandNumber, threadNumber)) - sez.append(bandNumber) - totBlocks = bandNumber - # for function number - else: - sez = list(range(0, len(functionBandArgument), threadNumber)) - sez.append(len(functionBandArgument)) - totBlocks = len(functionBandArgument) - completedBlocks = 0 - for s in range(0, len(sez)-1): - # pool - cfg.pool = cfg.poolSCP(processes=len(list(range(sez[s], sez[s+1])))) - memVal = str(int( cfg.RAMValue / len(list(range(sez[s], sez[s+1]))))*1000000) - results = [] - roX = 0 - for p in range(sez[s], sez[s+1]): - if cfg.actionCheck == 'Yes': - sections= ranges - if parallel == cfg.parallelArray: - pOut = '' - try: - fArg = functionBandArgument[p] - except: - fArg = None - try: - fVar = functionVariable[p] - except: - fVar = None - otpLst = outputRasterList - # cfg.parallelRaster - else: - pOut = outputRasterList[p] - fArg = functionBandArgument[p] - fVar = functionVariable[p] - otpLst = None - wrtP = [p, otpLst, cfg.tmpDir, parallelWritingCheck, pMQ, memVal, compress, compressFormat, dataType, boundarySize, 0, 0, rX, rY, calcDataType, cfg.gdalDLLPath, nodataMask] - if skipSingleBand is None: - singleBand = p - else: - singleBand = None - c = cfg.pool.apply_async(self.processRasterDev, args=(rasterPath, signatureList, functionBand, functionRaster, algorithmName, pOut, outputAlgorithmRaster, outputClassificationRaster, sections, classificationOptions, nodataValue, macroclassCheck, fArg, fVar, progressMessage, skipReplaceNoData, singleBand, outputBandNumber, outputNoDataValue, scale, offset, wrtP)) - results.append([c, p]) - # update progress - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - try: - if progressMessage is not None: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progressStart + int((100 - progressStart) * (completedBlocks + sum(pR)) / totBlocks), progressMessage + dots) - except: - pass - cfg.timeSCP.sleep(1) - cfg.QtWidgetsSCP.qApp.processEvents() - completedBlocks = completedBlocks + sum(pR) - if cfg.actionCheck == 'Yes': - for r in results: - res = r[0].get() - cfg.subprocRes[r[1]] = res[0] - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - cfg.pool.close() - cfg.pool.terminate() - cfg.gcSCP.collect() - return 'No' - cfg.QtWidgetsSCP.qApp.processEvents() - cfg.pool.close() - cfg.pool.terminate() - # get parallel dictionary result - for p in sorted(cfg.subprocRes): - try: - cfg.parallelArrayDict[p].extend(cfg.subprocRes[p]) - except: - cfg.parallelArrayDict[p] = cfg.subprocRes[p] - # output - if outputRasterList is not None and parallel is None: - try: - parts = len(cfg.subprocRes[p]) * len(cfg.subprocRes) - except: - cfg.gcSCP.collect() - return 'No' - for p in cfg.subprocRes: - for op in cfg.subprocRes[p]: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(0, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Writing file') + dots) - tmpRastList.append(op[0]) - tmpRastList = list(set(tmpRastList)) - if scale is not None: - scl = scale - else: - scl = 1 - if offset is not None: - offs = offset - else: - offs = 0 - gdalV = cfg.utls.getGDALVersion() - if float(gdalV[0] + '.' + gdalV[1]) >= 2.3: - if scale is not None or offset is not None: - parScaleOffset = ' -a_scale ' + str(scl) + ' -a_offset ' + str(offs) - else: - parScaleOffset = '' - else: - parScaleOffset = '' - if virtualRaster == 'Yes': - cfg.tmpList = [] - dirPath = cfg.osSCP.path.dirname(outputRasterList[0]) - fCount = 1 - for tR in tmpRastList: - oTR = dirPath + '/' + cfg.utls.fileNameNoExt(outputRasterList[0]) + '_%02d' % (fCount,) + '.tif' - fCount = fCount + 1 - cfg.tmpList.append(oTR) - cfg.shutilSCP.move(tR, oTR) - cfg.utls.createVirtualRaster2(inputRasterList = cfg.tmpList, output = outputRasterList[0], NoDataValue = outputNoDataValue, relativeToVRT = 1, dataType = dataType) - else: - vrtFile = cfg.utls.createTempRasterPath('vrt') - try: - cfg.utls.createVirtualRaster2(inputRasterList = tmpRastList, output = vrtFile, NoDataValue = outputNoDataValue, dataType = dataType) - gcopy = cfg.utls.GDALCopyRaster(vrtFile, outputRasterList[0], 'GTiff', compress, compressFormat, additionalParams = '-ot ' + str(dataType) + parScaleOffset) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'gcopy ' + gcopy) - except: - try: - cfg.utls.createVirtualRaster2(inputRasterList = tmpRastList, output = vrtFile, NoDataValue = outputNoDataValue, dataType = dataType) - gcopy = cfg.utls.GDALCopyRaster(vrtFile, outputRasterList[0], 'GTiff', compress, compressFormat, additionalParams = '-ot ' + str(dataType) + parScaleOffset) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'gcopy ' + gcopy) - except: - cfg.gcSCP.collect() - return 'No' - if functionBand == 'Yes': - outputClasses = [] - outputAlgs = [] - outSigDict = {} - for p in cfg.subprocRes: - for s in range(0, len(signatureList)): - sLR = str(signatureList[s][0]) + '_' + str(signatureList[s][2]) - try: - nSLR = list(cfg.subprocRes[p][2][sLR]) - nSLR.extend(outSigDict[sLR]) - outSigDict[sLR] = nSLR - except: - outSigDict[sLR] = cfg.subprocRes[p][2][sLR] - for oC in cfg.subprocRes[p][0]: - outputClasses.append(oC) - for oA in cfg.subprocRes[p][1]: - outputAlgs.append(oA) - cfg.gcSCP.collect() - return [outputClasses, outputAlgs, outSigDict] - # delete temp array - if deleteArray is None and virtualRaster != 'Yes': - for n in tmpRastList: - try: - cfg.osSCP.remove(n) - except: - pass - tmpRastList = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'end processRaster') - cfg.gcSCP.collect() - return 'Yes' - - # convert raster to shapefile - def multiProcessRasterToVector(self, rasterPath, outputVectorPath, fieldName = 'No', threadNumber = None, dissolveOutput = 'Yes'): - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'start raster to vector') - if threadNumber is None: - threadNumber = cfg.threads - gdalRaster = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - xSize = gdalRaster.RasterXSize - ySize = gdalRaster.RasterYSize - blockSizeX = xSize - blockSizeY = int(ySize/float(threadNumber))+1 - # raster blocks - rX, rY, lX, lY, pX, pY = self.rasterBlocks(gdalRaster, blockSizeX, blockSizeY) - rGT = gdalRaster.GetGeoTransform() - tLX = rGT[0] - tLY = rGT[3] - pSX = rGT[1] - pSY = rGT[5] - gdalRaster = None - if blockSizeX > rX: - blockSizeX = rX - if blockSizeY > rY: - blockSizeY = rY - # pool - cfg.pool = cfg.poolSCP(processes=threadNumber) - # temporary raster output - tmpRastList = [] - subprocRes = [] - # calculate raster ranges - nn = 0 - for x in lX: - bSX = blockSizeX - if x + bSX > rX: - bSX = rX - x - for y in lY: - bSY = blockSizeY - if y + bSY > rY: - bSY = rY - y - tPMD = cfg.utls.createTempRasterPath('vrt', name = str(nn)) - tmpRastList.append(tPMD) - cfg.utls.createVirtualRaster2(inputRasterList = [rasterPath], output = tPMD, NoDataValue = 'Yes', extentList = [x, y, bSX, bSY]) - nn = nn + 1 - # multiple parallel processes - results = [] - field = 'DN' - for p in range(0, len(tmpRastList)): - if cfg.actionCheck == 'Yes': - vRasterPath = tmpRastList[p] - tVect = cfg.utls.createTempRasterPath('gpkg', name = str(p)) - wrtP = [p, cfg.tmpDir, cfg.gdalDLLPath] - c = cfg.pool.apply_async(cfg.utls.rasterToVectorMulti, args=(vRasterPath, tVect, field, wrtP)) - results.append([c, p]) - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(int(100 * sum(pR) / len(pR)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion to vector') + dots) - if all(pR): - break - cfg.timeSCP.sleep(1) - cfg.QtWidgetsSCP.qApp.processEvents() - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - subprocRes.append(res[0]) - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - return 'No' - cfg.QtWidgetsSCP.qApp.processEvents() - else: - cfg.pool.close() - cfg.pool.terminate() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - cfg.uiUtls.updateBar(50) - # merge vectors - merged = cfg.utls.createTempRasterPath('gpkg') - if len(subprocRes) > 1: - merge = cfg.utls.mergeLayersToNewLayer(subprocRes, outputVectorPath, field, dissolveOutput) - else: - merge = subprocRes[0] - cfg.uiUtls.updateBar(60) - # copy merge - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' merged') - return merge - - # convert raster to shapefile - def rasterToVectorMulti(self, rasterPath, outputVectorPath, fieldName = 'No', writerLog = None): - from . import config as cfg - import os - import sys - import inspect - import time - import datetime - import random - wrtProc = str(writerLog[0]) - cfg.tmpDir = writerLog[1] - GDALDLLPath = writerLog[2] - for d in GDALDLLPath.split(';'): - try: - os.add_dll_directory(d) - except: - pass - import numpy as np - from osgeo import gdal - from osgeo import ogr - from osgeo import osr - cfg.osSCP = os - cfg.sysSCP = sys - cfg.inspectSCP = inspect - cfg.datetimeSCP = datetime - cfg.randomSCP = random - cfg.np = np - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - from .utils import Utils - cfg.utls = Utils() - # GDAL config - try: - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', '4') - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass - cfg.logFile = cfg.tmpDir + '/log_' + wrtProc - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " process: " + str(wrtProc)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " rasterPath: " + str(rasterPath)) - # open input with GDAL - try: - rD = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - # number of x pixels - rC = rD.RasterXSize - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return '', 'No' - # create a shapefile - d = cfg.ogrSCP.GetDriverByName('GPKG') - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " outputVectorPath: " + str(outputVectorPath)) - dS = d.CreateDataSource(outputVectorPath) - if dS is None: - # close rasters - rD = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " error: " + str(outputVectorPath)) - else: - # shapefile - sR = cfg.osrSCP.SpatialReference() - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " sR: " + str(sR)) - sR.ImportFromWkt(rD.GetProjectionRef()) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " sR: " + str(sR)) - rL = dS.CreateLayer(cfg.utls.fileName(rasterPath), sR, cfg.ogrSCP.wkbMultiPolygon) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " rL: " + str(rL)) - if fieldName == 'No': - fN = str(cfg.fldID_class) - else: - fN = fieldName - fd = cfg.ogrSCP.FieldDefn(fN, cfg.ogrSCP.OFTInteger) - try: - rL.CreateField(fd) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # close rasters - rD = None - return '', 'No' - fld = rL.GetLayerDefn().GetFieldIndex(fN) - rRB = rD.GetRasterBand(1) - # raster to polygon - cfg.gdalSCP.Polygonize(rRB, rRB.GetMaskBand(), rL, fld) - # close rasters and shapefile - rRB = None - rD = None - dS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' vector output performed') - # open layer - input0 = cfg.ogrSCP.Open(outputVectorPath) - iL0 = input0.GetLayer() - iNm0 = iL0.GetName() - sql = 'SELECT MIN(miny) FROM "rtree_' + iNm0 + '_geom"' - uV = input0.ExecuteSQL(sql, dialect = 'SQLITE') - uVF = uV.GetNextFeature() - minY = uVF.GetField(0) - sql = 'SELECT MAX(maxy) FROM "rtree_' + iNm0 + '_geom"' - uV = input0.ExecuteSQL(sql, dialect = 'SQLITE') - uVF = uV.GetNextFeature() - maxY = uVF.GetField(0) - return [outputVectorPath, minY, maxY], '' - - # write raster - def writeArrayRaster(self, rasterPath, arrayFile, section): - if cfg.actionCheck == 'Yes': - r = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_Update) - try: - arrayFile = arrayFile[::, ::, 0] - except: - pass - cfg.utls.writeArrayBlock(r, 1, arrayFile, section[0], section[1]) - r = None - - # write raster - def writeRasterNew(self, rasterPath, x, y, bSX, bSY, dataArray, nodataValue = None, scale = None, offset = None, dataType = None): - ''' - if dataType is not None: - if dataType == 'Float64': - oType = cfg.np.float64 - elif dataType == 'Float32': - oType = cfg.np.float32 - elif dataType == 'Int32': - oType = cfg.np.int32 - elif dataType == 'UInt32': - oType = cfg.np.uint32 - elif dataType == 'Int16': - oType = cfg.np.int16 - elif dataType == 'UInt16': - oType = cfg.np.uint16 - elif dataType == 'Byte': - oType = cfg.np.byte - else: - oType = cfg.np.float32 - else: - oType = cfg.np.float32 - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'oType ' + str(oType)) - ''' - oR = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_Update) - bO = oR.GetRasterBand(1) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'write bO ' + str(bO)) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'dataArray shape write ' + str(dataArray.shape) + ' type ' + str(dataArray.dtype) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' scale ' + str(scale) ) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' nodataValue ' + str(nodataValue) ) - try: - # it seems a GDAL issue that if scale is float the datatype is converted to Float32 - if scale is not None or offset is not None: - dataArray = cfg.np.subtract(dataArray/scale, offset/scale) - bO.SetScale(scale) - bO.SetOffset(offset) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if nodataValue is not None: - bO.SetNoDataValue(int(nodataValue)) - try: - dataArray = dataArray[::, ::, 0] - except: - pass - r = bO.WriteArray(dataArray, x, y) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'output r ' + str(r)) - bO.FlushCache() - bO = None - oR = None - return rasterPath - - # calculate random points - def randomPoints(self, pointNumber, Xmin, Xmax, Ymin, Ymax, minDistance = None, rasterName = None, NoDataValue = None, stratified = None, stratifiedExpression = None, bandSetNumber = None): - points = [] - counter = 0 - while len(points) < pointNumber: - counter = counter + 1 - XCoords = cfg.np.random.uniform(Xmin,Xmax,1) - YCoords = cfg.np.random.uniform(Ymin,Ymax,1) - point = cfg.qgisCoreSCP.QgsPointXY(XCoords, YCoords) - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - rast = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][0], 'Yes') - # open input with GDAL - try: - ql = cfg.utls.layerSource(rast) - Or = cfg.gdalSCP.Open(ql, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return points - else: - rL = cfg.utls.selectLayerbyName(rasterName, 'Yes') - # open input with GDAL - try: - qll = cfg.utls.layerSource(rL) - Or = cfg.gdalSCP.Open(qll, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr4() - return points - OrB = Or.GetRasterBand(1) - geoT = Or.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - pixelStartColumn = (int((point.x() - tLX) / pSX)) - pixelStartRow = -(int((tLY - point.y()) / pSY)) - bVal = None - try: - bVal = float(cfg.utls.readArrayBlock(OrB, pixelStartColumn, pixelStartRow, 1, 1)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if bVal is not None: - try: - if str(bVal).lstrip('[').rstrip(']') == 'nan': - pass - elif NoDataValue is not None and float(bVal) == float(NoDataValue): - pass - elif stratified is not None: - try: - if eval(stratifiedExpression.replace(cfg.variableName, 'bVal')) is True: - points.append([XCoords[0], YCoords[0]]) - except: - pass - if counter == pointNumber*100 and len(points) == 0: - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR : maximum number of iterations" ) - cfg.mx.msgErr64() - return points - else: - points.append([XCoords[0], YCoords[0]]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return points - - # count pixels in a raster lower than value - def rasterValueCount(self, gdalBand, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputGdalRasterList, functionBandArgumentNoData, functionVariable): - if cfg.actionCheck == 'Yes': - sum = ((rasterArray <= functionVariable) & (rasterArray != functionBandArgumentNoData)).sum() - cfg.rasterBandPixelCount = cfg.rasterBandPixelCount + sum - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return cfg.rasterBandPixelCount - - # count pixels in a raster equal to value - def rasterEqualValueCount(self, gdalBand, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputGdalRasterList, functionBandArgumentNoData, functionVariable): - if cfg.actionCheck == 'Yes': - sum = (rasterArray == functionVariable).sum() - cfg.rasterBandPixelCount = cfg.rasterBandPixelCount + sum - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return cfg.rasterBandPixelCount - - # calculate sum raster unique values - def rasterSumUniqueValues(self, gdalBand, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputGdalRasterList, functionBandArgumentNoData, functionVariable): - if cfg.actionCheck == 'Yes': - val = cfg.np.unique(rasterArray).tolist() - for i in val: - try: - oldV = cfg.uVal[str(i)] - except: - oldV = 0 - sum = oldV + (rasterArray == i).sum() - cfg.uVal[str(i)] = sum - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return cfg.uVal - - # count pixels in a raster - def rasterPixelCount(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - try: - bool(cfg.rasterClassSignature) - except: - cfg.rasterClassSignature = {} - i = functionBandArgument - a = rasterSCPArrayfunctionBand.ravel() - rasterSCPArrayfunctionBand = None - a = a[~cfg.np.isnan(a)] - count = a.shape[0] - try: - cfg.rasterClassSignature['COUNT_BAND_' + str(i)] = cfg.rasterClassSignature['COUNT_BAND_' + str(i)] + count - except: - cfg.rasterClassSignature['COUNT_BAND_' + str(i)] = count - sum = a.sum() - try: - cfg.rasterClassSignature['SUM_BAND_' + str(i)] = cfg.rasterClassSignature['SUM_BAND_' + str(i)] + sum - except: - cfg.rasterClassSignature['SUM_BAND_' + str(i)] = sum - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cfg.rasterClassSignature ' + str(cfg.rasterClassSignature)) - return cfg.rasterClassSignature - - # covariance in a raster - def rasterCovariance(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - try: - bool(cfg.rasterClassSignature) - except: - cfg.rasterClassSignature = {} - preClassSignature = functionVariableList - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBandArgument ' + str(functionBandArgument)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'preClassSignature ' + str(preClassSignature)) - # covariance - for i in functionBandArgument: - xx = rasterSCPArrayfunctionBand[::, ::, int(i[0])].ravel() - yy = rasterSCPArrayfunctionBand[::, ::, int(i[1])].ravel() - x = xx[~cfg.np.isnan(xx)&~cfg.np.isnan(yy)] - y = yy[~cfg.np.isnan(xx)&~cfg.np.isnan(yy)] - xx = None - yy = None - cov = ( (x - preClassSignature['MEAN_BAND_' + str(i[0])]) * (y - preClassSignature['MEAN_BAND_' + str(i[1])]) ).sum() / (preClassSignature['COUNT_BAND_' + str(i[0])] - 1) - try: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] + cov - except: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] = cov - # variance - for f in range(0, rasterSCPArrayfunctionBand.shape[2]): - x = rasterSCPArrayfunctionBand[::, ::, int(f)].ravel() - x = x[~cfg.np.isnan(x)] - # (x - M) * (x - M) - cov = ( (x - preClassSignature['MEAN_BAND_' + str(f)]) * (x - preClassSignature['MEAN_BAND_' + str(f)]) ).sum() / (preClassSignature['COUNT_BAND_' + str(f)] - 1) - try: - cfg.rasterClassSignature['COV_BAND_' + str(f) + '-' + str(f)] = cfg.rasterClassSignature['COV_BAND_' + str(f) + '-' + str(f)] + cov - except: - cfg.rasterClassSignature['COV_BAND_' + str(f) + '-' + str(f)] = cov - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cfg.rasterClassSignature ' + str(cfg.rasterClassSignature)) - return cfg.rasterClassSignature - - # count pixels in a raster - def rasterPixelCountClassSignature(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgument, functionVariableList, outputBandNumber): - try: - bool(cfg.rasterClassSignature) - except: - cfg.rasterClassSignature = {} - preClassSignature = functionVariableList - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBandArgument ' + str(functionBandArgument)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterSCPArrayfunctionBand shape ' + str(rasterSCPArrayfunctionBand.shape)) - b = rasterSCPArrayfunctionBand[::, ::, 0].ravel() - for i in functionBandArgument[0]: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'i ' + str(i)) - for c in functionBandArgument[1]: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'c ' + str(c)) - a = rasterSCPArrayfunctionBand[::, ::, i+1].ravel() - a = a[b == c] - a = a[~cfg.np.isnan(a)] - count = a.shape[0] - if count > 0: - try: - cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] = cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] + count - except: - cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] = count - amin = cfg.np.nanmin(a) - amax = cfg.np.nanmax(a) - try: - cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)] = min(amin, cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)]) - except: - cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)] = amin - try: - cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)] = max(amax, cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)]) - except: - cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)] = amax - sum = a.sum() - try: - cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] = cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] + sum - except: - cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] = sum - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cfg.rasterClassSignature ' + str(cfg.rasterClassSignature)) - return cfg.rasterClassSignature - - # count for standard deviation in a raster - def rasterStandardDeviationClassSignature(self, gdalBand, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputGdalRasterList, functionBandArgument, functionVariableList, outputBandNumber): - try: - bool(cfg.rasterClassSignature) - except: - cfg.rasterClassSignature = {} - cl = rasterArray[::, ::, 0].ravel() - i = functionBandArgument - preClassSignature = functionVariableList - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBandArgument ' + str(functionBandArgument)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'preClassSignature ' + str(preClassSignature)) - for i in functionBandArgument[0]: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'i ' + str(i)) - for c in functionBandArgument[1]: - xx = rasterArray[::, ::, int(i[0]+1)].ravel() - xx = xx[cl == c] - yy = rasterArray[::, ::, int(i[1]+1)].ravel() - yy = yy[cl == c] - x = xx[~cfg.np.isnan(xx)&~cfg.np.isnan(yy)] - y = yy[~cfg.np.isnan(xx)&~cfg.np.isnan(yy)] - xx = None - yy = None - a = x - preClassSignature['MEAN_BAND_' + str(i[0]) + '_c_' + str(c)] - b = y - preClassSignature['MEAN_BAND_' + str(i[1]) + '_c_' + str(c)] - d = a * b - cov = d.sum() / (preClassSignature['COUNT_BAND_' + str(i[0]) + '_c_' + str(c)] - 1) - try: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] + cov - except: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] = cov - # variance - for f in functionBandArgument[2]: - for c in functionBandArgument[1]: - x = rasterArray[::, ::, int(f+1)].ravel() - x = x[cl == c] - x = x[~cfg.np.isnan(x)] - a = x - preClassSignature['MEAN_BAND_' + str(f) + '_c_' + str(c)] - d = a * a - var = d.sum() / (preClassSignature['COUNT_BAND_' + str(f) + '_c_' + str(c)] - 1) - try: - cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] = cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] + var - except: - cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] = var - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cfg.rasterClassSignature ' + str(cfg.rasterClassSignature)) - return cfg.rasterClassSignature - - # calculate minimum and maximum values in a raster - def rasterMinimumMaximum(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - rasterDict = {} - for i in range(0, rasterSCPArrayfunctionBand.shape[2]): - try: - a = rasterSCPArrayfunctionBand[::, ::, i].ravel() - amin = cfg.np.nanmin(a) - amax = cfg.np.nanmax(a) - rasterDict['MINIMUM_BAND_' + str(i)] = amin - rasterDict['MAXIMUM_BAND_' + str(i)] = amax - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterDict ' + str(rasterDict) ) - except Exception as err: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return rasterDict - - # count pixels in a raster - def rasterPixelCountKmeans(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - rasterDict = {} - b = rasterSCPArrayfunctionBand[::, ::, rasterSCPArrayfunctionBand.shape[2] - 1].ravel() - for i in range(0, rasterSCPArrayfunctionBand.shape[2] - 1): - for c in functionVariableList: - a = rasterSCPArrayfunctionBand[::, ::, i].ravel() - a = a[b == c[0]] - a = a[~cfg.np.isnan(a)] - count = a.shape[0] - rasterDict['COUNT_BAND_' + str(i) + '_c_' + str(c[0])] = count - sum = a.sum() - rasterDict['SUM_BAND_' + str(i) + '_c_' + str(c[0])] = sum - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterDict ' + str(rasterDict) ) - return rasterDict - - # count for standard deviation in a raster - def rasterStandardDeviationISODATA(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - rasterDict = {} - b = rasterSCPArrayfunctionBand[::, ::, rasterSCPArrayfunctionBand.shape[2] - 2].ravel() - # variance - for i in range(0, rasterSCPArrayfunctionBand.shape[2] - 2): - for c in functionVariableList[0]: - x = rasterSCPArrayfunctionBand[::, ::, int(i)].ravel() - x = x[b == c[0]] - # find No data - NoDtX = cfg.np.where(cfg.np.isnan(x)) - # delete No data - x = cfg.np.delete(x, NoDtX) - NoDtX = None - x = x[~cfg.np.isnan(x)] - a = x - functionVariableList[1]['MEAN_BAND_' + str(i) + '_c_' + str(c[0])] - d = a * a - var = d.sum() / (functionVariableList[1]['COUNT_BAND_' + str(i) + '_c_' + str(c[0])] - 1) - rasterDict['VAR_BAND_' + str(i) + '_c_' + str(c[0])] = var - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterDict ' + str(rasterDict) ) - return rasterDict - - # count pixels in a raster - def rasterPixelCountISODATA(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariableList, outputBandNumber): - rasterDict = {} - b = rasterSCPArrayfunctionBand[::, ::, rasterSCPArrayfunctionBand.shape[2] - 2].ravel() - for i in range(0, rasterSCPArrayfunctionBand.shape[2] - 2): - for c in functionVariableList: - a = rasterSCPArrayfunctionBand[::, ::, i].ravel() - a = a[b == c[0]] - a = a[~cfg.np.isnan(a)] - count = a.shape[0] - rasterDict['COUNT_BAND_' + str(i) + '_c_' + str(c[0])] = count - sum = a.sum() - rasterDict['SUM_BAND_' + str(i) + '_c_' + str(c[0])] = sum - g = rasterSCPArrayfunctionBand[::, ::, rasterSCPArrayfunctionBand.shape[2] - 1].ravel() - for c in functionVariableList: - d = g[b == c[0]] - d = d[~cfg.np.isnan(d)] - sum = d.sum() - rasterDict['SUM_DIST_' + str(c[0])] = sum - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterDict ' + str(rasterDict)) - return rasterDict - - # calculate PCA bands - def calculatePCABands(self, gdalBandList, rasterSCPArrayfunctionBand, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputRaster, functionBandArgument, functionVariableList, outputBandNumber): - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionVariableList ' + str(functionVariableList)) - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'functionBandArgument ' + str(functionBandArgument)) - n = 0 - for i in functionBandArgument: - try: - o = (cfg.np.array(i) * rasterSCPArrayfunctionBand).sum(axis=2, dtype=cfg.np.float32) - except Exception as err: - return 'No' - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o shape ' + str(o.shape)) - # output raster - oR = cfg.gdalSCP.Open(functionVariableList[n], cfg.gdalSCP.GA_Update) - cfg.utls.writeRasterBlock(oR, int(outputBandNumber), o, pixelStartColumn, pixelStartRow) - o = None - oR = None - n = n + 1 - return functionVariableList - - # mask process - def maskProcess(self, gdalBandList, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputGdalRasterList, functionBandArgumentNoData, functionVariable): - # mask - a = rasterArray[::, ::, 0] - # raster - b = rasterArray[::, ::, 1] - b[b==functionBandArgumentNoData] = cfg.np.nan - for v in functionVariable: - o = cfg.np.where(a == v, cfg.np.nan,b) - b = cfg.np.copy(o) - a = None - # create array if not - if not isinstance(o, cfg.np.ndarray): - a = cfg.np.zeros((rasterArray.shape[0], rasterArray.shape[1]), dtype=cfg.np.float32) - try: - a.fill(o) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - o = a - a = cfg.np.nan_to_num(o) * 1.0 - a[cfg.np.isnan(o)] = cfg.np.nan - o = a - return o - - # spectral distance process - def spectralDistanceProcess(self, gdalBandList, rasterArray, columnNumber, rowNumber, pixelStartColumn, pixelStartRow, outputArrayFile, functionBandArgumentNoData, functionVariable, outputBandNumber): - f = functionBandArgumentNoData - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'f ' + str(f) ) - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'rasterArray type ' + str(rasterArray.dtype) ) - rasterArray[rasterArray==functionBandArgumentNoData] = cfg.np.nan - firstArray = rasterArray[::, ::, :rasterArray.shape[2]//2] - secondArray = rasterArray[::, ::, rasterArray.shape[2]//2:] - rasterArray = None - if functionVariable[0] == cfg.algMinDist: - o = cfg.np.sqrt(((firstArray - secondArray)**2).sum(axis = 2)) - else: - o = cfg.np.arccos((firstArray * secondArray).sum(axis = 2) / cfg.np.sqrt((firstArray**2).sum(axis = 2) * (secondArray**2).sum(axis = 2))) * 180 / cfg.np.pi - secondArray = None - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'o type ' + str(o.dtype) ) - # create array if not - if not isinstance(o, cfg.np.ndarray): - return 'No' - return o - - # calculate histogram 2d - def calculateHistogram2d(self, xVal, yVal, binVal, normedVal = False): - try: - h, xE, yE = cfg.np.histogram2d(xVal, yVal, bins=binVal, normed=normedVal) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return [h, xE, yE ] - except Exception as err: - cfg.mx.msgErr53() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # calculate scatter plot - def calculateScatterPlot(self, vector, field, id, tempROI = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - # crs of loaded raster - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][0], 'Yes') - filePath = cfg.utls.layerSource(b) - crs = cfg.utls.getCrsGDAL(filePath) - else: - # crs of loaded raster - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8]) - filePath = cfg.utls.layerSource(b) - crs = cfg.utls.getCrsGDAL(filePath) - tLP = cfg.utls.createTempRasterPath('gpkg') - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP, format = 'GPKG') - mL = cfg.utls.addVectorLayer(tLP) - try: - if tempROI == 'No': - rId = cfg.utls.getIDByAttributes(vector, field, str(id)) - else: - rId = [] - f = cfg.qgisCoreSCP.QgsFeature() - for f in vector.getFeatures(): - rId.append(f.id()) - except Exception as err: - cfg.mx.msgErr54() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # copy ROI to temp shapefile - for pI in rId: - cfg.utls.copyFeatureToLayer(vector, pI, mL) - # clip by ROI - tRxs = cfg.utls.createTempRasterPath('tif') - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - cfg.utls.checkBandSet(bandSetNumber) - bandX = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][cfg.scatterBandX - 1], 'Yes') - bandY = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][cfg.scatterBandY - 1], 'Yes') - bandList = [bandX.source(), bandY.source()] - check = cfg.utls.vectorToRaster(cfg.emptyFN, tLP, cfg.emptyFN, tRxs, bandList[0], None, 'GTiff', 1) - if check == 'No': - return 'No' - bX = cfg.utls.clipRasterByRaster(bandList, tRxs, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculating signature'), stats = 'Yes', dataType = 'Float32') - else: - rS = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - check = cfg.utls.vectorToRaster(cfg.emptyFN, tLP, cfg.emptyFN, tRxs, rS.source(), None, 'GTiff', 1) - if check == 'No': - return 'No' - # calculate ROI center, height and width - rCX, rCY, rW, rH = cfg.utls.getShapefileRectangleBox(tLP) - # subset - tLX, tLY, pS = cfg.utls.imageInformation(cfg.bandSetsList[bandSetNumber][8]) - tS = cfg.utls.createTempRasterPath('tif') - # reduce band size - pr = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][8], rCX, rCY, int(round(rW/pS + 3)), int(round(rH/pS + 3)), str(tS), virtual = 'Yes') - if pr == 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error edge') - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return pr - oList = cfg.utls.rasterToBands(tS, cfg.tmpDir, None, 'No', cfg.bandSetsList[cfg.bndSetNumber][6]) - bandList = [oList[cfg.scatterBandX - 1], oList[cfg.scatterBandY - 1]] - bX = cfg.utls.clipRasterByRaster(bandList, tRxs, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculating signature'), stats = 'Yes') - # band X - rD = cfg.gdalSCP.Open(bX[0], cfg.gdalSCP.GA_ReadOnly) - iRB = rD.GetRasterBand(1) - try: - o = iRB.GetOffset() - s = iRB.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - xVal = iRB.ReadAsArray()*s+o - # close bands - iRB = None - # close rasters - rD = None - # band Y - rD = cfg.gdalSCP.Open(bX[1], cfg.gdalSCP.GA_ReadOnly) - iRB = rD.GetRasterBand(1) - try: - o = iRB.GetOffset() - s = iRB.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - yVal = iRB.ReadAsArray()*s+o - # close bands - iRB = None - # close rasters - rD = None - # calculate histogram - try: - xVal2 = xVal[~cfg.np.isnan(xVal)] - yVal2 = yVal[~cfg.np.isnan(xVal)] - xVal = xVal2[~cfg.np.isnan(yVal2)] - yVal = yVal2[~cfg.np.isnan(yVal2)] - del xVal2 - del yVal2 - xMax = cfg.np.amax(xVal) - yMax = cfg.np.amax(yVal) - except Exception as err: - cfg.mx.msgErr54() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if cfg.uiscp.precision_checkBox.isChecked(): - rou = int(cfg.uiscp.precision_comboBox.currentText()) - elif xMax <= 1.1: - rou = 3 - else: - rou = -1 - prc = cfg.np.power(10, -float(rou)) - xMin = cfg.np.amin(xVal) - xMin = cfg.np.around(xMin, rou) - prc - xMax = cfg.np.around(xMax, rou) + prc - xSteps = self.calculateSteps(xMin, xMax, prc) - yMin = cfg.np.amin(yVal) - yMin = cfg.np.around(yMin, rou) - prc - yMax = cfg.np.around(yMax, rou) + prc - ySteps = self.calculateSteps(yMin, yMax, prc) - binVal = (xSteps, ySteps) - h = cfg.utls.calculateHistogram2d(xVal, yVal, binVal) - return h - - # calculate step list - def calculateSteps(self, minValue, maxValue, step): - steps = [] - val = minValue - steps.append(val) - while val < maxValue: - val = val + step - steps.append(val) - return steps - - # subset image by rectangle - def subsetImageByRectangle(self, rectangle, rasterName, bandList, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # calculate ROI center, height and width - xMin = rectangle[0] - xMax = rectangle[1] - yMin = rectangle[2] - yMax = rectangle[3] - rCX = (xMax + xMin) / 2 - rW = (xMax - xMin) - rCY = (yMax + yMin) / 2 - rH = (yMax - yMin) - bands = [] - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - tLX, tLY, pS = cfg.utls.imageInformation(cfg.bandSetsList[bandSetNumber][3][0]) - # subset - for b in bandList: - tS = cfg.utls.createTempRasterPath('tif') - pr = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][3][b], rCX, rCY, int(round(rW/pS + 3)), int(round(rH/pS + 3)), tS) - if pr == 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error edge') - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return pr - bands.append(tS) - else: - # subset - tLX, tLY, pS = cfg.utls.imageInformation(rasterName) - tS = cfg.utls.createTempRasterPath('tif') - pr = cfg.utls.subsetImage(rasterName, rCX, rCY, int(round(rW/pS + 3)), int(round(rH/pS + 3)), str(tS)) - if pr == 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error edge') - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return pr - oList = cfg.utls.rasterToBands(tS, cfg.tmpDir, None, 'No', cfg.bandSetsList[bandSetNumber][6]) - n = 0 - for b in oList: - if n in bandList: - bands.append(b) - n = n + 1 - return bands - -################################## - ''' Interface functions ''' -################################## - - # Question box - def questionBox(self, caption, message): - i = cfg.QtWidgetsSCP.QWidget() - q = cfg.QtWidgetsSCP.QMessageBox.question(i, caption, message, cfg.QtWidgetsSCP.QMessageBox.Yes, cfg.QtWidgetsSCP.QMessageBox.No) - if q == cfg.QtWidgetsSCP.QMessageBox.Yes: - return 'Yes' - if q == cfg.QtWidgetsSCP.QMessageBox.No: - return 'No' - - # show hide input image - def showHideInputImage(self): - try: - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - i = cfg.tmpVrtDict[cfg.bndSetNumber] - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - except: - pass - try: - if i is not None: - if cfg.inputImageRadio.isChecked(): - cfg.utls.setLayerVisible(i, True) - cfg.utls.moveLayerTop(i) - else: - cfg.utls.setLayerVisible(i, False) - except: - pass - - # refresh classification combo - def refreshRasterExtent(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.raster_extent_combo.clear() - cfg.dlg.raster_extent_combo(cfg.mapExtent) - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - cfg.dlg.raster_extent_combo(l.name()) - - # refresh classification combo - def refreshClassificationLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.classification_name_combo.clear() - cfg.ui.classification_name_combo_2.clear() - cfg.ui.classification_name_combo_3.clear() - cfg.ui.classification_name_combo_5.clear() - cfg.ui.classification_report_name_combo.clear() - cfg.ui.classification_vector_name_combo.clear() - cfg.ui.reclassification_name_combo.clear() - cfg.ui.edit_raster_name_combo.clear() - cfg.ui.sieve_raster_name_combo.clear() - cfg.ui.erosion_raster_name_combo.clear() - cfg.ui.dilation_raster_name_combo.clear() - cfg.ui.classification_name_combo_4.clear() - cfg.ui.reference_raster_name_combo.clear() - cfg.ui.raster_align_comboBox.clear() - # classification name - self.clssfctnNm = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.classification_layer_combo(l.name()) - cfg.dlg.classification_layer_combo_2(l.name()) - cfg.dlg.classification_layer_combo_3(l.name()) - cfg.dlg.classification_layer_combo_5(l.name()) - cfg.dlg.classification_report_combo(l.name()) - cfg.dlg.classification_to_vector_combo(l.name()) - cfg.dlg.reclassification_combo(l.name()) - cfg.dlg.edit_raster_combo(l.name()) - cfg.dlg.sieve_raster_combo(l.name()) - cfg.dlg.erosion_raster_combo(l.name()) - cfg.dlg.dilation_raster_combo(l.name()) - cfg.dlg.cloud_mask_raster_combo(l.name()) - cfg.dlg.reference_raster_combo(l.name()) - cfg.dlg.project_raster_combo(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification layers refreshed') - - # refresh vector combo - def refreshVectorLayer(self): - cfg.ui.vector_name_combo.blockSignals(True) - cfg.ui.vector_name_combo_2.blockSignals(True) - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.shapefile_comboBox.clear() - cfg.ui.vector_name_combo.clear() - cfg.ui.vector_name_combo_2.clear() - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer): - if (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.Polygon) or (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon): - cfg.dlg.shape_clip_combo(l.name()) - cfg.dlg.vector_to_raster_combo(l.name()) - cfg.dlg.vector_edit_raster_combo(l.name()) - cfg.ui.vector_name_combo.blockSignals(False) - cfg.ui.vector_name_combo_2.blockSignals(False) - cfg.utls.refreshVectorFields() - cfg.utls.refreshVectorFields2() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'vector layers refreshed') - - # reference layer name - def refreshVectorFields(self): - referenceLayer = cfg.ui.vector_name_combo.currentText() - cfg.ui.field_comboBox.clear() - l = cfg.utls.selectLayerbyName(referenceLayer) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != 'string': - cfg.dlg.reference_field_combo(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # reference layer name - def refreshVectorFields2(self): - referenceLayer = cfg.ui.vector_name_combo_2.currentText() - cfg.ui.field_comboBox_2.clear() - l = cfg.utls.selectLayerbyName(referenceLayer) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != 'string': - cfg.dlg.reference_field_combo2(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # get random color and complementary color - def randomColor(self): - r = cfg.randomSCP.randint(0,255) - g = cfg.randomSCP.randint(0,255) - b = cfg.randomSCP.randint(0,255) - c = cfg.QtGuiSCP.QColor(r, g, b) - cc = cfg.QtGuiSCP.QColor(255 - r, 255 - r, 225 - r) - return c, cc - - # select color - def selectColor(self): - c = cfg.QtWidgetsSCP.QColorDialog.getColor() - if c.isValid(): - # logger - #cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'color') - return c - - # get save file name - def getSaveFileName(self, parent, text, directory, filterText, extension = None): - directory = cfg.lastSaveDir - out = cfg.QtWidgetsSCP.QFileDialog.getSaveFileName(None, text, directory, filterText) - if len(out[0]) > 0: - output = out[0].replace('\\', '/') - output = output.replace('//', '/') - cfg.lastSaveDir = cfg.osSCP.path.dirname(output) - if extension is not None: - if output.lower().endswith(extension): - return output - else: - output = output + '.' + extension - return output - else: - return output - else: - return False - - # get open file name - def getOpenFileName(self, parent, text, directory, filterText): - directory = cfg.lastSaveDir - out = cfg.QtWidgetsSCP.QFileDialog.getOpenFileName(None, text, directory, filterText) - cfg.lastSaveDir = cfg.osSCP.path.dirname(out[0]) - return out[0] - - # get open file names - def getOpenFileNames(self, parent, text, directory, filterText): - directory = cfg.lastSaveDir - out = cfg.QtWidgetsSCP.QFileDialog.getOpenFileNames(None, text, directory, filterText) - if len(out) > 0: - if len(out[0]) > 0: - cfg.lastSaveDir = cfg.osSCP.path.dirname(out[0][0]) - return out[0] - - # get existing directory - def getExistingDirectory(self, parent, text): - directory = cfg.lastSaveDir - out = cfg.QtWidgetsSCP.QFileDialog.getExistingDirectory(None, text, directory) - cfg.lastSaveDir = out - return out - -################################## - ''' QGIS functions ''' -################################## - - # get QGIS Proxy settings - def getQGISProxySettings(self): - cfg.proxyEnabled = cfg.utls.readRegistryKeys('proxy/proxyEnabled', '') - cfg.proxyType = cfg.utls.readRegistryKeys('proxy/proxyType', '') - cfg.proxyHost = cfg.utls.readRegistryKeys('proxy/proxyHost', '') - cfg.proxyPort = cfg.utls.readRegistryKeys('proxy/proxyPort', '') - cfg.proxyUser = cfg.utls.readRegistryKeys('proxy/proxyUser', '') - cfg.proxyPassword = cfg.utls.readRegistryKeys('proxy/proxyPassword', '') - - # read registry keys - def readRegistryKeys(self, key, value): - rK = cfg.QSettingsSCP() - val = rK.value(key, value) - return val - - # set QGIS registry value - def setQGISRegSetting(self, key, value): - q = cfg.QSettingsSCP() - q.setValue(key, value) - - # Raster top left origin and pixel size - def imageInformation(self, imageName): - try: - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - # TopLeft X coord - tLX = i.extent().xMinimum() - # TopLeft Y coord - tLY = i.extent().yMaximum() - # pixel size - pS = i.rasterUnitsPerPixelX() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'image: ' + str(imageName) + ' topleft: (' + str(tLX) + ','+ str(tLY) + ')') - # return a tuple TopLeft X, TopLeft Y, and Pixel size - return tLX, tLY, pS - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None, None, None - - # Raster size - def imageInformationSize(self, imageName): - try: - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - # TopLeft X coord - tLX = i.extent().xMinimum() - # TopLeft Y coord - tLY = i.extent().yMaximum() - # LowRight X coord - lRY = i.extent().yMinimum() - # LowRight Y coord - lRX = i.extent().xMaximum() - # pixel size - pSX = i.rasterUnitsPerPixelX() - pSY = i.rasterUnitsPerPixelX() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'image: ' + str(imageName) + ' topleft: (' + str(tLX) + ','+ str(tLY) + ')') - # return a tuple TopLeft X, TopLeft Y, and Pixel size - return tLX, tLY, lRX, lRY, pSX, pSY - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None, None, None, None, None, None - - # Get CRS of a layer by name thereof - def getCrs(self, layer): - if layer is None: - crs = None - else: - rP = layer.dataProvider() - crs = rP.crs() - return crs - - # Pan action - def pan(self): - cfg.toolPan = cfg.qgisGuiSCP.QgsMapToolPan(cfg.cnvs) - cfg.cnvs.setMapTool(cfg.toolPan) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'pan action') - - # Project point coordinates - def projectPointCoordinates(self, point, inputCoordinates, outputCoordinates): - try: - # spatial reference - iSR = cfg.osrSCP.SpatialReference() - iSR.ImportFromWkt(inputCoordinates.toWkt()) - oSR = cfg.osrSCP.SpatialReference() - oSR.ImportFromWkt(outputCoordinates.toWkt()) - # required by GDAL 3 coordinate order - try: - iSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - oSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - except: - pass - # Coordinate Transformation - cT = cfg.osrSCP.CoordinateTransformation(iSR, oSR) - pointT = cfg.ogrSCP.Geometry(cfg.ogrSCP.wkbPoint) - pointT.AddPoint(point.x(), point.y()) - pointT.Transform(cT) - pointTQ = cfg.qgisCoreSCP.QgsPointXY(pointT.GetX(), pointT.GetY()) - return pointTQ - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return False - - # Project point coordinates - def projectPointCoordinatesOGR(self, pointX, pointY, inputCoordinates, outputCoordinates): - try: - # spatial reference - iSR = inputCoordinates - oSR = outputCoordinates - # required by GDAL 3 coordinate order - try: - iSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - oSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - except: - pass - # Coordinate Transformation - cT = cfg.osrSCP.CoordinateTransformation(iSR, oSR) - pointT = cfg.ogrSCP.Geometry(cfg.ogrSCP.wkbPoint) - pointT.AddPoint(pointX, pointY) - pointT.Transform(cT) - return [pointT.GetX(), pointT.GetY()] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return False - - # Find group by its name - def groupIndex(self, groupName): - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - p = root.findGroup(groupName) - return p - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'group ' + str(groupName) + ' Position: ' + str(p)) - - # Layer ID by its name - def layerID(self, layerName, trainingID = None): - lsx = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - for lx in lsx: - lN = lx.name() - if lN == layerName: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'layer: ' + str(layerName) + ' ID: ' + str(lx.id())) - if lx.id() != trainingID: - return lx.id() - - # read project variable - def readProjectVariable(self, variableName, value): - p = cfg.qgisCoreSCP.QgsProject.instance() - v = p.readEntry('SemiAutomaticClassificationPlugin', variableName, value)[0] - cfg.QtWidgetsSCP.qApp.processEvents() - return v - - # read QGIS path project variable - def readQGISVariablePath(self): - cfg.projPath = cfg.qgisCoreSCP.QgsProject.instance().fileName() - p = cfg.qgisCoreSCP.QgsProject.instance() - v = p.readEntry('Paths', 'Absolute', '')[0] - cfg.absolutePath = v - - # read QGIS font project variable - def readQGISVariableFont(self): - s = cfg.qgisCoreSCP.QgsSettings() - f = s.value('qgis/stylesheet/fontFamily') - size = s.value('qgis/stylesheet/fontPointSize') - i = s.value('qgis/stylesheet/iconSize') - return [f, size, i] - - # write project variable - def writeProjectVariable(self, variableName, value): - if cfg.skipRegistry is False: - p = cfg.qgisCoreSCP.QgsProject.instance() - p.writeEntry('SemiAutomaticClassificationPlugin', variableName, value) - cfg.QtWidgetsSCP.qApp.processEvents() - # logger - #cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'variable: ' + str(variableName) + ' - value: ' + str(value)) - - # absolute to relative path - def qgisAbsolutePathToRelativePath(self, absolutePath, relativePath): - p = cfg.qgisCoreSCP.QgsApplication.absolutePathToRelativePath(absolutePath, relativePath) - return p - - # relative to absolute path - def qgisRelativePathToAbsolutePath(self, relativePath, absolutePath): - p = cfg.qgisCoreSCP.QgsApplication.relativePathToAbsolutePath(relativePath, absolutePath) - return p - - # Remove layer from map - def removeLayer(self, layerName): - try: - cfg.qgisCoreSCP.QgsProject.instance().removeMapLayer(self.layerID(layerName)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'layer: ' + str(layerName)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Remove layer from map - def removeLayerByLayer(self, layer): - try: - cfg.qgisCoreSCP.QgsProject.instance().removeMapLayer(layer.id()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Remove layer from map - def removeGroup(self, groupName): - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.findGroup(groupName) - try: - if g is not None: - root.removeChildNode(g) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'group: ' + str(groupName)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # remove temporary files from project - def removeTempFiles(self): - # disable map canvas render - cfg.cnvs.setRenderFlag(False) - try: - for p in cfg.prevList: - pp = cfg.utls.selectLayerbyName(p.name()) - if pp is not None: - cfg.utls.removeLayerByLayer(p) - for i in range(0, len(cfg.bandSetsList)): - vrt = cfg.utls.selectLayerbyName(cfg.bndSetVrtNm + str(i + 1)) - if vrt is not None: - cfg.utls.removeLayerByLayer(vrt) - cfg.utls.removeGroup(cfg.grpNm) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.prevList = [] - cfg.tmpVrtDict[cfg.bndSetNumber] = None - # remove layers with the same name as training input - try: - scpPath = cfg.utls.readProjectVariable('trainingLayer', '') - name = cfg.utls.fileNameNoExt(scpPath) - duplicateID = cfg.utls.layerID(name, cfg.shpLay.id()) - cfg.qgisCoreSCP.QgsProject.instance().removeMapLayer(duplicateID) - except: - pass - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - - # create KML from map - def createKMLFromMap(self): - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - ext1 = cfg.cnvs.extent() - pCrs = cfg.utls.getQGISCrs() - crswgs84 = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem(4326) - cfg.utls.setQGISCrs(crswgs84) - cfg.cnvs.refreshAllLayers() - cfg.QtWidgetsSCP.qApp.processEvents() - cfg.uiUtls.updateBar(30) - cfg.timeSCP.sleep(1) - cfg.QtWidgetsSCP.qApp.processEvents() - ext = cfg.cnvs.extent() - # date time for temp name - dT = cfg.utls.getTime() - tPMN = cfg.kmlNm - tPMD = cfg.tmpDir + "/" + dT + tPMN + ".png" - tPMD2 = cfg.tmpDir + "/" + tPMN + ".kml" - cfg.cnvs.setCanvasColor(cfg.QtSCP.transparent) - cfg.cnvs.saveAsImage(tPMD) - xml = ''' - - - %s - - %s - - - %.10f - %.10f - %.10f - %.10f - - - %.10f - %.10f - 5000 - - - - ''' - source = xml % (tPMN, dT + tPMN + ".png", ext.yMaximum(), ext.yMinimum(), ext.xMaximum(), ext.xMinimum(), (ext.xMaximum() + ext.xMinimum())/2, (ext.yMinimum() + ext.yMaximum())/2) - l = open(tPMD2, 'w') - try: - l.write(source) - l.close() - except: - pass - if cfg.osSCP.path.isfile(tPMD2): - if cfg.sysSCPNm == 'Darwin': - sP = cfg.subprocessSCP.call(('open', tPMD2)) - elif cfg.sysSCPNm == 'Windows': - cfg.osSCP.startfile(tPMD2) - else: - sP = cfg.subprocessSCP.call(('xdg-open', tPMD2)) - cfg.utls.setQGISCrs(pCrs) - cfg.cnvs.setExtent(ext1) - cfg.cnvs.refreshAllLayers() - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - - # Create group - def createGroup(self, groupName): - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.insertGroup(0, groupName) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "group: " + str(groupName)) - return g - - # Move group to top layers - def moveGroup(self, groupName): - try: - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.findGroup(groupName) - cG = g.clone() - root.insertChildNode(0, cG) - root.removeChildNode(g) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "group: " + str(groupName)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Set group visibile - def setGroupVisible(self, groupIndex, visible = False): - try: - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - cfg.qgisCoreSCP.QgsLayerTreeNode.setItemVisibilityChecked(groupIndex, visible) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "group: " + str(groupIndex)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Set group expanded - def setGroupExpanded(self, groupIndex, expanded = False): - try: - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - cfg.qgisCoreSCP.QgsLayerTreeNode.setExpanded(groupIndex, expanded) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "group: " + str(groupIndex)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Move layer to top layers - def moveLayerTop(self, layer): - try: - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.findLayer(layer.id()) - cG = g.clone() - root.insertChildNode(0, cG) - root.removeChildNode(g) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "layer: " + str(layer.name())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Move layer in group - def moveLayer(self, layer, groupName): - try: - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.findLayer(layer.id()) - a = root.findGroup(groupName) - a.insertLayer(0, layer) - root.removeChildNode(g) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "layer: " + str(layer.name())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Set layer visible - def setLayerVisible(self, layer, visible = True): - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - g = root.findLayer(layer.id()) - cfg.qgisCoreSCP.QgsLayerTreeNode.setItemVisibilityChecked(g, visible) - - # Refresh layer Symbology - def refreshLayerSymbology(self, layer): - root = cfg.qgisCoreSCP.QgsProject.instance().layerTreeRoot() - model = cfg.iface.layerTreeView().model() - try: - g = root.findLayer(layer.id()) - model.refreshLayerLegend(g) - except: - cfg.iface.layerTreeView().refreshLayerSymbology(layer.id()) - - # Select layer by name thereof - def selectLayerbyName(self, layerName, filterRaster=None): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - for l in ls: - lN = l.name() - if lN == layerName: - if filterRaster is None: - return l - else: - try: - if l.type().value == 1: - return l - except: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer: - return l - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "layer selected: " + str(layerName)) - - # file path - def getFilePath(self, layerName): - try: - l = cfg.utls.selectLayerbyName(layerName) - filePath = cfg.utls.layerSource(l) - return filePath - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # set map extent from layer - def setMapExtentFromLayer(self, layer): - ext = layer.extent() - tLPoint = cfg.qgisCoreSCP.QgsPointXY(ext.xMinimum(), ext.yMaximum()) - lRPoint = cfg.qgisCoreSCP.QgsPointXY(ext.xMaximum(), ext.yMinimum()) - point1 = tLPoint - point2 = lRPoint - # project extent - iCrs = cfg.utls.getCrs(layer) - pCrs = cfg.utls.getQGISCrs() - if iCrs is None: - iCrs = pCrs - # projection of input point from raster's crs to project's crs - if pCrs != iCrs: - try: - point1 = cfg.utls.projectPointCoordinates(tLPoint, iCrs, pCrs) - point2 = cfg.utls.projectPointCoordinates(lRPoint, iCrs, pCrs) - if point1 is False: - point1 = tLPoint - point2 = lRPoint - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - point1 = tLPoint - point2 = lRPoint - cfg.cnvs.setExtent(cfg.qgisCoreSCP.QgsRectangle(point1, point2)) - - # save a qml style - def saveQmlStyle(self, layer, stylePath): - layer.saveNamedStyle(stylePath) - - # Zoom to selected feature of layer - def zoomToSelected(self, layer, featureIDList): - layer.removeSelection() - for featureID in featureIDList: - layer.select(featureID) - cfg.cnvs.zoomToSelected(layer) - layer.removeSelection() - - # Zoom to band set - def zoomToBandset(self): - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - try: - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][0], 'Yes') - except: - b = None - else: - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - if b is not None: - cfg.utls.setMapExtentFromLayer(b) - cfg.cnvs.refresh() - - # Add layer to map - def addLayerToMap(self, layer): - cfg.qgisCoreSCP.QgsProject.instance().addMapLayers([layer]) - - # Add layer - def addVectorLayer(self, path, name = None, format = None): - if name is None: - name = cfg.utls.fileNameNoExt(path) - if format is None: - format = 'ogr' - l = cfg.qgisCoreSCP.QgsVectorLayer(path, name, format) - return l - - # Add raster layer or band to band set - def addRasterOrBand(self, path = None, name = None, bandSetNumber = None, wavelengthString = None): - if path is None: - image = cfg.utls.selectLayerbyName(name, 'Yes') - if image is not None and bandSetNumber is not None: - cfg.bst.addBandToBandSet(name, bandSetNumber, wavelengthString) - return 'Yes' - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error not raster: ' + str(name) ) - return 'No' - else: - cfg.utls.addRasterLayer(path, name, bandSetNumber, wavelengthString) - - # Add raster layer - def addRasterLayer(self, path, name = None, bandSetNumber = None, wavelengthString = None): - if cfg.osSCP.path.isfile(path): - if name is None: - name = cfg.utls.fileNameNoExt(path) - r = cfg.iface.addRasterLayer(path, name) - r.setName(name) - if bandSetNumber is not None: - cfg.bst.addBandToBandSet(name, bandSetNumber, wavelengthString) - return r - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " not file: " + str(path) ) - return 'No' - - # Get QGIS project CRS - def getQGISCrs(self): - pCrs = cfg.cnvs.mapSettings().destinationCrs() - return pCrs - - # Set QGIS project CRS - def setQGISCrs(self, crs): - cfg.cnvs.setDestinationCrs(crs) - - # layer source - def layerSource(self, layer): - s = layer.source().split("|layername=")[0] - return s - - # save memory layer to shapefile - def saveMemoryLayerToShapefile(self, memoryLayer, output, name = None, format = 'ESRI Shapefile', IDList = None, listFieldName = None): - shpF = output - try: - if format == 'ESRI Shapefile': - cfg.utls.createSCPShapefile(memoryLayer.crs(), shpF) - else: - cfg.utls.createSCPVector(memoryLayer.crs(), shpF, format = format) - if name is None: - name = cfg.utls.fileName(shpF) - tSS = cfg.utls.addVectorLayer(shpF, name, 'ogr') - tSS.updateFields() - f = cfg.qgisCoreSCP.QgsFeature() - tSS.startEditing() - if IDList is None: - for f in memoryLayer.getFeatures(): - tSS.addFeature(f) - else: - for f in memoryLayer.getFeatures(): - UID = str(f[listFieldName]) - if UID in IDList: - tSS.addFeature(f) - tSS.commitChanges() - tSS.dataProvider().createSpatialIndex() - tSS.updateExtents() - return tSS - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None - - # duplicate memory layer - def duplicateMemoryLayer(self, layer): - # create memory layer - provider = layer.dataProvider() - fields = provider.fields().toList() - pCrs = cfg.utls.getCrs(layer) - dT = cfg.utls.getTime() - mL2 = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), dT, 'memory') - mL2.setCrs(pCrs) - pr2 = mL2.dataProvider() - pr2.addAttributes(fields) - mL2.updateFields() - f = cfg.qgisCoreSCP.QgsFeature() - mL2.startEditing() - for f in layer.getFeatures(): - mL2.addFeature(f) - mL2.commitChanges() - mL2.dataProvider().createSpatialIndex() - mL2.updateExtents() - return mL2 - - # save features to shapefile - def featuresToShapefile(self, idList): - # create shapefile - crs = cfg.utls.getCrs(cfg.shpLay) - f = cfg.qgisCoreSCP.QgsFields() - # add Class ID, macroclass ID and Info fields - f.append(cfg.qgisCoreSCP.QgsField('fid', cfg.QVariantSCP.Int)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldMacroID_class, cfg.QVariantSCP.Int)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROIMC_info, cfg.QVariantSCP.String)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldID_class, cfg.QVariantSCP.Int)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROI_info, cfg.QVariantSCP.String)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldSCP_UID, cfg.QVariantSCP.String)) - # shapefile - shpF = cfg.utls.createTempRasterPath('shp') - try: - cfg.qgisCoreSCP.QgsVectorFileWriter(shpF, 'CP1250', f, cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon , crs, 'ESRI Shapefile') - tSS = cfg.utls.addVectorLayer(shpF) - f = cfg.qgisCoreSCP.QgsFeature() - tSS.startEditing() - count = 0 - for f in cfg.shpLay.getFeatures(): - SCP_UID = str(f[cfg.fldSCP_UID]) - if SCP_UID in idList: - a = tSS.addFeature(f) - count = count + 1 - if count == 0: - tSS.commitChanges() - cfg.utls.removeLayerByLayer(tSS) - return None - tSS.commitChanges() - tSS.dataProvider().createSpatialIndex() - tSS.updateExtents() - cfg.utls.removeLayerByLayer(tSS) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' vector exported ') - return shpF - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None - -################################## - ''' raster GDAL functions ''' -################################## - - # Get the number of bands of a raster - def getNumberBandRaster(self, raster): - rD = cfg.gdalSCP.Open(raster, cfg.gdalSCP.GA_ReadOnly) - number = rD.RasterCount - rD = None - return number - - # Raster no data value - def imageNoDataValue(self, rasterPath): - rD = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - gBand = rD.GetRasterBand(1) - nd = gBand.GetNoDataValue() - gBand = None - rD = None - return nd - - # Get CRS of a layer raster or vector - def getCrsGDAL(self, layerPath): - l = cfg.ogrSCP.Open(layerPath) - if l is None: - l = cfg.gdalSCP.Open(layerPath, cfg.gdalSCP.GA_ReadOnly) - if l is None: - crs = None - else: - try: - # check projections - crs = l.GetProjection() - if len(crs) == 0: - crs = None - # in case of errors - except Exception as err: - crs = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - gL = l.GetLayer() - # check projection - lP = gL.GetSpatialRef() - try: - crs = lP.ExportToWkt() - if len(crs) == 0: - crs = None - # in case of errors - except Exception as err: - crs = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' lyr ' + str(layerPath) + ' crs: ' + str(crs)) - return crs.replace(' ', '') - - # raster sieve with GDAL - def rasterSieve(self, inputRaster, outputRaster, pixelThreshold, connect = 4, outFormat = 'GTiff', quiet = 'No'): - if cfg.sysSCPNm == 'Windows': - gD = 'gdal_sieve.bat' - else: - gD = 'gdal_sieve.py' - st = 'No' - cfg.utls.getGDALForMac() - # copy input to temp to prevent path issue - dT = cfg.utls.getTime() - tempRaster = cfg.osSCP.path.join(cfg.tmpDir, dT + cfg.osSCP.path.splitext(inputRaster)[1]) - cfg.shutilSCP.copy(inputRaster, tempRaster) - tempOut = cfg.utls.createTempRasterPath('tif') - a = cfg.gdalPath + gD + ' -st ' + str(pixelThreshold) + ' -' + str(connect) + ' ' + tempRaster + ' -of '+ outFormat + ' ' + tempOut - if cfg.sysSCPNm != 'Windows': - a = cfg.shlexSCP.split(a) - tPMD = cfg.utls.createTempRasterPath('txt') - stF = open(tPMD, 'a') - sPL = len(cfg.subprocDictProc) - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(a, shell=False, startupinfo = startupinfo, stdout=stF, stderr=cfg.subprocessSCP.PIPE, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(a, shell=False, stdout=stF, stderr=cfg.subprocessSCP.PIPE) - while True: - line = '' - with open(tPMD, 'r') as rStF: - for line in rStF: - pass - poll = cfg.subprocDictProc['proc_'+ str(sPL)].poll() - if poll != None: - break - else: - try: - progress = int(line.split('...')[-1].strip('.')) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Sieve') + dots) - except: - pass - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - break - cfg.timeSCP.sleep(1) - stF.close() - try: - # get error - out, err = cfg.subprocDictProc['proc_'+ str(sPL)].communicate() - if len(err) > 0: - st = 'Yes' - if quiet == 'No': - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " GDAL error: " + str(err) ) - return 'No' - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # copy output - try: - cfg.shutilSCP.move(tempOut, outputRaster) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # remove temp layers - try: - cfg.osSCP.remove(tempRaster) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "sieve: " + str(outputRaster)) - return st - - # build band overviews - def buildOverviewsBandSet(self, directory = 'Yes', quiet = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0: - if directory == 'Yes': - a = 'Yes' - else: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Build overviews'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Do you want to build the external overviews of bands?')) - if a == 'Yes': - if quiet == 'No': - cfg.uiUtls.addProgressBar() - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - cfg.uiUtls.updateBar(20, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Building overviews')) - b = 1 - for i in cfg.bndSetLst: - # pool - cfg.pool = cfg.poolSCP(processes=1) - p = 0 - memVal = str(int(cfg.RAMValue * 0.8)*1000000) - wrtP = [p, cfg.tmpDir, memVal, cfg.gdalDLLPath] - results = [] - c = cfg.pool.apply_async(self.buildOverviewsGDAL, args=(i, wrtP)) - results.append([c, p]) - cfg.QtWidgetsSCP.qApp.processEvents() - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - cfg.timeSCP.sleep(1) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar('', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Building overviews') + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - return 'No' - else: - cfg.pool.close() - cfg.pool.terminate() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - b = b + 1 - cfg.uiUtls.updateBar(20 + b * 80 / (len(cfg.bndSetLst)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Building overviews')) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " image: " + str(i)) - else: - image = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - i = cfg.utls.layerSource(image) - cfg.uiUtls.updateBar(50, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Building overviews')) - # pool - cfg.pool = cfg.poolSCP(processes=1) - p = 0 - memVal = str(int(cfg.RAMValue * 0.8)*1000000) - wrtP = [p, cfg.tmpDir, memVal, cfg.gdalDLLPath] - results = [] - c = cfg.pool.apply_async(self.buildOverviewsGDAL, args=(i, wrtP)) - results.append([c, p]) - cfg.QtWidgetsSCP.qApp.processEvents() - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - cfg.timeSCP.sleep(1) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar('', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Building overviews') + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - return 'No' - else: - cfg.pool.close() - cfg.pool.terminate() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - cfg.uiUtls.updateBar(100) - if quiet == 'No': - cfg.utls.finishSound() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " all bands clicked") - - # build GDAL overviews - def buildOverviewsGDAL(self, inputRaster, writerLog): - from . import config as cfg - import os - import sys - import inspect - import time - import datetime - wrtProc = str(writerLog[0]) - cfg.tmpDir = writerLog[1] - memory = writerLog[2] - GDALDLLPath = writerLog[3] - for d in GDALDLLPath.split(';'): - try: - os.add_dll_directory(d) - except: - pass - import numpy as np - from osgeo import gdal - from osgeo import ogr - from osgeo import osr - cfg.osSCP = os - cfg.sysSCP = sys - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - from .utils import Utils - cfg.utls = Utils() - # GDAL config - try: - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', memory) - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass - try: - rD = cfg.gdalSCP.Open(inputRaster, cfg.gdalSCP.GA_ReadOnly) - rD.BuildOverviews('NEAREST', [8,16,32,64]) - rD = None - return inputRaster, '' - # in case of errors - except Exception as err: - # logger - return inputRaster, err - - # Try to get GDAL for Mac - def getGDALForMac(self): - if cfg.sysSCPNm == 'Darwin': - gdalLine = cfg.gdalPath - if len(gdalLine) > 0: - cfg.gdalPath = gdalLine.rstrip('/') + '/' - if cfg.osSCP.path.isfile(cfg.gdalPath + 'gdal_translate'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' getGDALForMac: ' + str(cfg.gdalPath)) - else: - cfg.gdalPath = '' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' getGDALForMac: ERROR') - else: - v = cfg.utls.getGDALVersion() - cfg.gdalPath = '/Library/Frameworks/GDAL.framework/Versions/' + v[0] + '.' + v[1] + '/Programs/' - if cfg.osSCP.path.isfile(cfg.gdalPath + 'gdal_translate'): - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' getGDALForMac: ' + str(cfg.gdalPath)) - else: - cfg.gdalPath = '' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' getGDALForMac: ERROR') - - # Get GDAL version - def getGDALVersion(self): - v = cfg.gdalSCP.VersionInfo('RELEASE_NAME').split('.') - return v - - # Get raster data type name - def getRasterDataTypeName(self, inputRaster): - rD = cfg.gdalSCP.Open(inputRaster, cfg.gdalSCP.GA_ReadOnly) - b = rD.GetRasterBand(1) - dType = cfg.gdalSCP.GetDataTypeName(b.DataType) - b.FlushCache() - b = None - rD = None - return dType - - # create GDAL raster table - def createRasterTable(self, rasterPath, bandNumber, signatureList): - r = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_Update) - b = r.GetRasterBand(bandNumber) - at = cfg.gdalSCP.RasterAttributeTable() - at.CreateColumn(str(cfg.fldID_class), cfg.gdalSCP.GFT_Integer, cfg.gdalSCP.GFU_Generic ) - at.CreateColumn(str(cfg.fldROI_info), cfg.gdalSCP.GFT_String, cfg.gdalSCP.GFU_Generic ) - v = signatureList - if cfg.macroclassCheck == 'Yes': - mc = [] - for c in range(len(v)): - mc.append(int(v[c][0])) - mcList = list(set(mc)) - for i in range(len(mcList)): - at.SetValueAsInt(i, 0, mcList[i]) - ind = mc.index(mcList[i]) - at.SetValueAsString(i, 1, v[ind][1]) - else: - for i in range(len(v)): - at.SetValueAsInt(i, 0, int(v[i][2])) - at.SetValueAsString(i, 1, v[i][3]) - b.SetDefaultRAT(at) - b = None - r = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "" + str(rasterPath)) - - # read all raster from band - def readAllBandsFromRaster(self, gdalRaster): - bandNumber = gdalRaster.RasterCount - bandList = [] - for b in range(1, bandNumber + 1): - rB = gdalRaster.GetRasterBand(b) - bandList.append(rB) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - return bandList - - # copy raster with GDAL - def GDALCopyRaster(self, input, output, outFormat = 'GTiff', compress = 'No', compressFormat = 'DEFLATE', additionalParams = ''): - outDir = cfg.osSCP.path.dirname(output) - cfg.utls.makeDirectory(outDir) - op = ' -co BIGTIFF=YES -co NUM_THREADS=' + str(cfg.threads) - if compress == 'No': - op = op + ' -of ' + outFormat - else: - op = op + ' -co COMPRESS=' + compressFormat + ' -of ' + outFormat - a = additionalParams + ' ' + op - # pool - cfg.pool = cfg.poolSCP(processes=1) - p = 0 - manager = cfg.MultiManagerSCP() - # progress queue - pMQ = manager.Queue() - memVal = str(int(cfg.RAMValue)*1000000) - wrtP = [p, cfg.tmpDir, memVal, pMQ, cfg.gdalDLLPath] - results = [] - c = cfg.pool.apply_async(self.gdalTranslate, args=(input, output, a, wrtP)) - results.append([c, p]) - cfg.QtWidgetsSCP.qApp.processEvents() - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - try: - pMQp = pMQ.get(False) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(int(pMQp[0]), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Writing file') + dots) - except: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(message = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Writing file') + dots) - cfg.timeSCP.sleep(1) - cfg.QtWidgetsSCP.qApp.processEvents() - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - return 'No' - else: - cfg.pool.close() - cfg.pool.terminate() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " image: " + str(output)) - return output - - # interprocess - def gdalTranslate(self, input = None, output = None, optionString = None, writerLog = None): - from . import config as cfg - import os - import sys - import inspect - import time - import datetime - wrtProc = str(writerLog[0]) - cfg.tmpDir = writerLog[1] - memory = writerLog[2] - global progressQueue - progressQueue = writerLog[3] - GDALDLLPath = writerLog[4] - for d in GDALDLLPath.split(';'): - try: - os.add_dll_directory(d) - except: - pass - from osgeo import gdal - from osgeo import ogr - from osgeo import osr - cfg.osSCP = os - cfg.sysSCP = sys - cfg.inspectSCP = inspect - cfg.datetimeSCP = datetime - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - from .utils import Utils - cfg.utls = Utils() - # GDAL config - try: - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', memory) - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass - cfg.logFile = cfg.tmpDir + '/log_' + 'gdal' - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' process: ' + str(wrtProc)) - try: - progressG = (lambda perc, m, d: progressQueue.put([perc * 100, m], False)) - to = gdal.TranslateOptions(gdal.ParseCommandLine(optionString), callback = progressG) - gdal.Translate(output, input, options = to) - return output, '' - # in case of errors - except Exception as err: - # logger - return output, err - - # interprocess - def subprocessStdout(self, input = None, progressQueue = None): - line = input.readline() - return line - - # reproject raster with GDAL - def GDALReprojectRaster(self, input, output, outFormat = 'GTiff', s_srs = None, t_srs = None, additionalParams = None, resampleMethod = None, rasterDataType = None, noDataVal = None, compression = None): - outDir = cfg.osSCP.path.dirname(output) - cfg.utls.makeDirectory(outDir) - if resampleMethod is None: - resampleMethod = 'near' - elif resampleMethod == 'sum': - gdalV = cfg.utls.getGDALVersion() - if float(gdalV[0] + '.' + gdalV[1]) < 3.1: - cfg.mx.msgErr68() - return 'No' - op = ' --config GDAL_DISABLE_READDIR_ON_OPEN TRUE' + ' --config GDAL_CACHEMAX ' + str(int(cfg.RAMValue * 0.3)*1000000) + ' -co BIGTIFF=YES -co NUM_THREADS=' + str(cfg.threads) + ' -r ' + resampleMethod + ' -multi -wo NUM_THREADS=' + str(cfg.threads) - if compression is None: - if cfg.rasterCompression == 'Yes': - op = op + ' -co COMPRESS=LZW' - elif compression == 'Yes': - op = op + ' -co COMPRESS=LZW' - if s_srs is not None: - op = op + ' -s_srs ' + s_srs - if t_srs is not None: - op = op + ' -t_srs ' + t_srs - if rasterDataType is not None: - op = op + ' -ot ' + rasterDataType - if noDataVal is not None: - op = op + ' -dstnodata ' + str(noDataVal) - op = op + ' -of ' + outFormat - if additionalParams is None: - pass - else: - op = ' ' + additionalParams + ' ' + op - gD = 'gdalwarp' - cfg.utls.getGDALForMac() - a = cfg.gdalPath + gD + op - if '"' in input: - b = input - else: - b = '"' + input + '" ' - c = '"' + output + '" ' - d = a + ' ' + b + ' ' + c - if cfg.sysSCPNm != 'Windows': - d = cfg.shlexSCP.split(d) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' GDAL: ' + str(d)) - tPMD = cfg.utls.createTempRasterPath('txt') - stF = open(tPMD, 'a') - sPL = len(cfg.subprocDictProc) - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False,startupinfo = startupinfo, stdout=stF, stderr=cfg.subprocessSCP.PIPE, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, stdout=stF, stderr=cfg.subprocessSCP.PIPE) - while True: - line = '' - with open(tPMD, 'r') as rStF: - for line in rStF: - pass - poll = cfg.subprocDictProc['proc_'+ str(sPL)].poll() - if poll != None: - break - else: - try: - progress = int(line.split('...')[-1].strip('.')) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reprojecting') + dots) - except: - pass - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - break - cfg.timeSCP.sleep(1) - stF.close() - try: - # get error - out, err = cfg.subprocDictProc['proc_'+ str(sPL)].communicate() - if len(err) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' GDAL error: ' + str(err) ) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image: ' + str(output)) - - # Merge raster bands - def mergeRasterBands(self, bandList, output, outFormat = 'GTiff', compress = 'No', compressFormat = 'DEFLATE', additionalParams = ''): - rCrs = cfg.utls.getCrsGDAL(bandList[0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - for b in range(0, len(bandList)): - eCrs = cfg.utls.getCrsGDAL(bandList[b]) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - nD = cfg.utls.imageNoDataValue(bandList[b]) - if nD is None: - nD = cfg.NoDataVal - #tPMD = cfg.utls.createTempRasterPath('tif', name = str(b)) - #cfg.utls.GDALReprojectRaster(bandList[b], tPMD, 'GTiff', None, 'EPSG:' + str(rEPSG), '-ot Float32 -dstnodata ' + str(nD)) - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(bandList[b], tPMD, str(rCrs)) - cfg.mx.msg9() - if cfg.osSCP.path.isfile(tPMD): - bandList[b] = tPMD - else: - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if outFormat == 'vrt': - # create virtual raster - vrtCheck = cfg.utls.createVirtualRaster(bandList, output, 'No', 'Yes', 'Yes', 0) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image: ' + str(output)) - else: - tPMD1 = cfg.utls.createTempRasterPath('vrt') - # create virtual raster - vrtCheck = cfg.utls.createVirtualRaster(bandList, tPMD1, 'No', 'Yes', 'Yes', 0) - if cfg.osSCP.path.isfile(tPMD1): - if compress == 'No': - cfg.utls.GDALCopyRaster(tPMD1, output, 'GTiff', compress) - else: - cfg.utls.GDALCopyRaster(tPMD1, output, 'GTiff', compress, compressFormat, additionalParams) - cfg.osSCP.remove(tPMD1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image: ' + str(output)) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error no image ') - - # Subset an image, given an origin point and a subset width - def subsetImage(self, imageName, XCoord, YCoord, Width, Height, output = None, outFormat = 'GTiff', virtual = 'No'): - if output is None: - if virtual == 'No': - output = cfg.utls.createTempRasterPath('tif') - else: - output = cfg.utls.createTempRasterPath('vrt') - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - # output variable - st = 'Yes' - if i is not None: - bandNumberList = [] - for bb in range(1, i.bandCount()+1): - bandNumberList.append(bb) - i = cfg.utls.layerSource(i) - st = 'No' - # raster top left origin and pixel size - tLX, tLY, lRX, lRY, pSX, pSY = self.imageInformationSize(imageName) - if pSX is None: - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " image none or missing") - else: - try: - dType = self.getRasterDataTypeName(i) - # subset origin - UX = tLX + abs(int((tLX - XCoord) / pSX )) * pSX - (Width -1 )/ 2 * pSX - UY = tLY - abs(int((tLY - YCoord) / pSY )) * pSY + (Height -1 )/ 2 * pSY - LX = UX + Width * pSX - LY = UY - Height * pSY - tPMD = cfg.utls.createTempRasterPath('vrt') - bList = [i] - if virtual == 'No': - st = cfg.utls.createVirtualRaster(bList, tPMD, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes', [float(UX), float(UY), float(LX), float(LY)]) - cfg.utls.GDALCopyRaster(tPMD, output, 'GTiff', cfg.rasterCompression, 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1' + ' -a_nodata ' + str(cfg.NoDataVal)) - st = output - else: - st = cfg.utls.createVirtualRaster(bList, output, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes', [float(UX), float(UY), float(LX), float(LY)]) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - st = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "image: " + str(imageName) + " subset origin: (" + str(XCoord) + ","+ str(YCoord) + ") width: " + str(Width)) - return st - - # get values for vector field - def getVectorFieldfValues(self, layerPath, fieldName): - d = cfg.gdalSCP.OpenEx(layerPath, cfg.gdalSCP.OF_VECTOR | cfg.gdalSCP.OF_READONLY) - if d is None: - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "Error layer " + layerPath) - return 'No' - l = d.GetLayerByName(cfg.utls.fileNameNoExt(layerPath)) - l.ResetReading() - fieldValues =[] - try: - for f in l: - fieldValues.append(f.GetField(str(fieldName))) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - l.ResetReading() - l = None - dr = None - values = cfg.np.unique(fieldValues).tolist() - return values - - # convert reference layer to raster based on the resolution of a raster - def vectorToRaster(self, fieldName, layerPath, referenceRasterName, outputRaster, referenceRasterPath=None, ALL_TOUCHED=None, outFormat = 'GTiff', burnValues = None, filter = None, extent = None, noDataValue = 0, backgroundValue = 0, compress = 'No', compressFormat = 'DEFLATE21'): - if referenceRasterPath is None: - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - referenceRasterName = cfg.bandSetsList[cfg.bndSetNumber][3][0] - # input - r = cfg.utls.selectLayerbyName(referenceRasterName, 'Yes') - else: - if cfg.utls.selectLayerbyName(referenceRasterName, 'Yes') is None: - cfg.mx.msg4() - cfg.ipt.refreshRasterLayer() - else: - # input - r = cfg.utls.selectLayerbyName(referenceRasterName, 'Yes') - try: - rS = cfg.utls.layerSource(r) - ck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - ck = 'No' - cfg.mx.msg4() - return ck - else: - rS = referenceRasterPath - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(rS, cfg.gdalSCP.GA_ReadOnly) - # number of x pixels - rC = rD.RasterXSize - # number of y pixels - rR = rD.RasterYSize - # check projections - rP = rD.GetProjection() - # pixel size and origin - rGT = rD.GetGeoTransform() - origX = rGT[0] - origY = rGT[3] - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg4() - return 'No' - if not layerPath.lower().endswith('.gpkg'): - tVect = cfg.utls.createTempRasterPath('gpkg') - v = cfg.utls.mergeAllLayers([layerPath], tVect) - layerPath = tVect - l = cfg.ogrSCP.Open(layerPath) - try: - gL = l.GetLayer() - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr34() - return 'No' - # check projection - vCrs = cfg.utls.getCrsGDAL(layerPath) - lPRS = cfg.osrSCP.SpatialReference() - lPRS.ImportFromWkt(vCrs) - rPRS = cfg.osrSCP.SpatialReference() - rPRS.ImportFromWkt(rP) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rP: ' + str(rP)) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' vCrs: ' + str(vCrs)) - if lPRS is not None: - # date time for temp name - dT = cfg.utls.getTime() - if lPRS.IsSame(rPRS) != 1: - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileName(layerPath) - try: - cfg.utls.repojectShapefile(layerPath, lPRS, reprjShapefile, rPRS) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg9() - return 'No' - l.Destroy() - l = cfg.ogrSCP.Open(reprjShapefile) - gL = l.GetLayer() - if filter is not None: - gL.SetAttributeFilter(filter) - d = cfg.ogrSCP.GetDriverByName('MEMORY') - dS = d.CreateDataSource('memData') - ou = dS.CopyLayer(gL,dS.GetName(),['OVERWRITE=YES']) - minX, maxX, minY, maxY = ou.GetExtent() - else: - minX, maxX, minY, maxY = gL.GetExtent() - if extent is None: - origX = rGT[0] + rGT[1] * int(round((minX - rGT[0]) / rGT[1])) - origY = rGT[3] + rGT[5] * int(round((maxY - rGT[3]) / rGT[5])) - rC = abs(int(round((maxX - minX) / rGT[1]))) - rR = abs(int(round((maxY - minY) / rGT[5]))) - tD = cfg.gdalSCP.GetDriverByName(outFormat) - tPMD2 = cfg.utls.createTempRasterPath('tif') - oR = tD.Create(tPMD2, rC, rR, 1, cfg.gdalSCP.GDT_Float32) - if oR is None: - oR = tD.Create(tPMD2, rC, rR, 1, cfg.gdalSCP.GDT_Int16) - if oR is None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: raster size') - cfg.mx.msgErr65() - return 'No' - try: - oRB = oR.GetRasterBand(1) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr34() - return 'No' - # set raster projection from reference - oR.SetGeoTransform( [ origX , rGT[1] , 0 , origY , 0 , rGT[5] ] ) - oR.SetProjection(rP) - # output rasters - oM = [] - oM.append(outputRaster) - oMR = cfg.utls.createRasterFromReference(oR, 1, oM, noDataValue, 'GTiff', cfg.rasterDataType, 0, None, compress = compress, compressFormat = compressFormat, constantValue = backgroundValue) - # close bands - oRB = None - # close rasters - oR = None - oMR = None - oR2 = cfg.gdalSCP.Open(outputRaster, cfg.gdalSCP.GA_Update) - # convert reference layer to raster - if ALL_TOUCHED is None: - if burnValues is None: - oC = cfg.gdalSCP.RasterizeLayer(oR2, [1], gL, options = ['ATTRIBUTE=' + str(fieldName)]) - else: - oC = cfg.gdalSCP.RasterizeLayer(oR2, [1], gL, burn_values=[burnValues]) - else: - if burnValues is None: - oC = cfg.gdalSCP.RasterizeLayer(oR2, [1], gL, options = ['ATTRIBUTE=' + str(fieldName), 'ALL_TOUCHED=TRUE']) - else: - oC = cfg.gdalSCP.RasterizeLayer(oR2, [1], gL, burn_values=[burnValues], options = ['ALL_TOUCHED=TRUE']) - # close rasters - oR2 = None - rD = None - l.Destroy() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'vector to raster check: ' + str(oC)) - return outputRaster - else: - cfg.mx.msg9() - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error None lPRS: ' + str(lPRS) + 'rPRS: ' + str(rPRS)) - return 'No' - - # merge dissolve two layers to new layer - def createVirtualLayer(self, inputLayerList, targetLayer = None): - # create virtual layer - source = ''' - - ''' - for layer in inputLayerList: - i = cfg.ogrSCP.Open(layer) - iL = i.GetLayer() - iN = iL.GetName() - xml = ''' - - %s - %s - - ''' - source = source + xml % (iN, layer, iN) - source = source + ''' - - ''' - if targetLayer is None: - targetLayer = cfg.utls.createTempRasterPath('vrt') - with open(targetLayer, 'w') as file: - file.write(source) - return targetLayer - - # merge dissolve layer to new layer - def mergeDissolveLayer(self, inputLayer, targetLayer, column, yListCoordinates): - # open virtual layer - inputM = cfg.ogrSCP.Open(inputLayer) - iL0 = inputM.GetLayer() - iNm0 = iL0.GetName() - iSR = iL0.GetSpatialRef() - iLDefn = iL0.GetLayerDefn() - # column fid - fld = iLDefn.GetFieldIndex(column) - iD = cfg.ogrSCP.GetDriverByName('GPKG') - oS = iD.CreateDataSource(targetLayer) - nm = cfg.utls.fileNameNoExt(targetLayer) - oL = oS.CreateLayer(str(nm), iSR, cfg.ogrSCP.wkbMultiPolygon) - # fields - for f in range(0, iLDefn.GetFieldCount()): - fDefn = iLDefn.GetFieldDefn(f) - oL.CreateField(fDefn) - oLDefn = oL.GetLayerDefn() - # get unique values - sql = 'SELECT DISTINCT "' + column +'" FROM "' + iNm0 + '"' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sql ' + sql) - uniqueValues = inputM.ExecuteSQL(sql, dialect = 'SQLITE') - uniqueValues - values = [] - idList = [] - for i, f in enumerate(uniqueValues): - values.append(f.GetField(0)) - sqlList = str(yListCoordinates)[1:-1].replace("'", '') - # for each value - for v in values: - uVFL = None - # to be replaced by cascaded ST_UNION when performance issues are solved, see https://groups.google.com/g/spatialite-users/c/FTO_cmLCfpE/ - sql = 'SELECT DISTINCT(ST_unaryunion(ST_COLLECT(geom))), GROUP_CONCAT(DISTINCT id) FROM (SELECT fid as id, geom FROM "' + iNm0 + '" WHERE ' + column + ' = ' + str(v) + ') INNER JOIN (SELECT DISTINCT id FROM "rtree_' + iNm0 + '_geom" WHERE miny IN (' + sqlList + ') OR maxy IN (' + sqlList + ') ) USING (id)' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sql ' + sql) - uV = inputM.ExecuteSQL(sql, dialect = 'SQLITE') - if uV is not None: - uVF = uV.GetNextFeature() - uVFL = uVF.GetField(0) - geometryRef = uVF.GetGeometryRef() - if geometryRef is not None: - # geometry count - cUG = geometryRef.GetGeometryCount() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' count geometries ' + str(cUG)) - if cUG > 1: - for j in range(0, cUG): - oL.StartTransaction() - jg = geometryRef.GetGeometryRef(int(j)) - try: - if jg is not None: - if jg.IsValid() is False: - jg = jg.Buffer(0.0) - if jg.IsValid() is True: - oF = cfg.ogrSCP.Feature(oLDefn) - oFO = oF.SetGeometry(jg) - oF.SetField(column, v) - oLO = oL.CreateFeature(oF) - oL.CommitTransaction() - else: - oL.RollbackTransaction() - oL.CommitTransaction() - oL.StartTransaction() - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(geometryRef) - oF.SetField(column, v) - oL.CreateFeature(oF) - oL.CommitTransaction() - break - except: - oL.RollbackTransaction() - oL.CommitTransaction() - oL.StartTransaction() - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(geometryRef) - oF.SetField(column, v) - oL.CreateFeature(oF) - oL.CommitTransaction() - break - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' added union cascade geometries ') - else: - oL.StartTransaction() - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(geometryRef) - oF.SetField(column, v) - oL.CreateFeature(oF) - oL.CommitTransaction() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' added union geometries ') - if uVFL is not None: - idList1 = uVFL.split(',') - idList.extend(idList1) - iF = iL0.GetNextFeature() - oL.StartTransaction() - while iF: - iFID = str(iF.GetFID()) - vF = iF.GetField(column) - if str(iFID) not in idList: - g = iF.GetGeometryRef() - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(g) - oF.SetField(column, vF) - oL.CreateFeature(oF) - iF = iL0.GetNextFeature() - oL.CommitTransaction() - inputM.Destroy() - iL0 = None - inputM = None - oS.Destroy() - oL = None - oS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'merged: ' + str(targetLayer)) - return targetLayer - - # merge all layers to new layer - def mergeAllLayers(self, inputLayersList, targetLayer): - tL = cfg.utls.createVirtualLayer(inputLayersList) - # open virtual layer - input = cfg.ogrSCP.Open(tL) - iL0 = input.GetLayer() - iNm0 = iL0.GetName() - iSR = iL0.GetSpatialRef() - iLDefn = iL0.GetLayerDefn() - iLFcount = iLDefn.GetFieldCount() - iD = cfg.ogrSCP.GetDriverByName('GPKG') - oS = iD.CreateDataSource(targetLayer) - nm = cfg.utls.fileNameNoExt(targetLayer) - oL = oS.CreateLayer(str(nm), iSR, cfg.ogrSCP.wkbMultiPolygon) - # fields - for f in range(0, iLFcount): - fDefn = iLDefn.GetFieldDefn(f) - oL.CreateField(fDefn) - oLDefn = oL.GetLayerDefn() - oLFcount = oLDefn.GetFieldCount() - oL.StartTransaction() - for i in input: - iNm = i.GetName() - iL0 = input.GetLayer(iNm) - iF = iL0.GetNextFeature() - while iF: - g = iF.GetGeometryRef() - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(g) - for i in range(0, iLFcount): - try: - nmRef = iLDefn.GetFieldDefn(i).GetNameRef() - field = iF.GetField(i) - oF.SetField(nmRef, field) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - oL.CreateFeature(oF) - iF = iL0.GetNextFeature() - oL.CommitTransaction() - input.Destroy() - oS.Destroy() - oS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'merged: ' + str(targetLayer)) - return targetLayer - - # merge layers to new layer - def mergeLayersToNewLayer(self, inputList, targetLayer, column = None, dissolveOutputOption = None): - # input layers - inputLayersList = [] - # y coordinates of polygons on borders - yList = [] - for i in range(0, len(inputList)): - vectorPath, minY, maxY = inputList[i] - inputLayersList.append(vectorPath) - if i > 0: - if maxY is not None: - yList.append(str(maxY)) - if i < len(inputList) - 1: - if minY is not None: - yList.append(str(minY)) - if dissolveOutputOption == 'Yes': - tVect = cfg.utls.createTempRasterPath('gpkg') - else: - tVect = targetLayer - v = cfg.utls.mergeAllLayers(inputLayersList, tVect) - if dissolveOutputOption == 'Yes': - r = cfg.utls.mergeDissolveLayer(v, targetLayer, column, yList) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'merged: ' + str(targetLayer)) - return targetLayer - - # get image Geo Transform - def imageGeoTransform(self, rasterPath): - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(rasterPath, cfg.gdalSCP.GA_ReadOnly) - # number of x pixels - rC = rD.RasterXSize - # number of y pixels - rR = rD.RasterYSize - # check projections - rP = rD.GetProjection() - # pixel size and origin - rGT = rD.GetGeoTransform() - left = rGT[0] - top = rGT[3] - pX = rGT[1] - pY = abs(rGT[5]) - right = rGT[0] + rGT[1] * rD.RasterXSize - bottom = rGT[3] + rGT[5] * rD.RasterYSize - cRSR = cfg.osrSCP.SpatialReference(wkt=rP) - un = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unknown') - if cRSR.IsProjected: - un = cRSR.GetAttrValue('unit') - rD = None - return left, right, top, bottom, pX, pY, rP.replace(' ', ''), un - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err) + ' rasterPath: ' + str(rasterPath)) - return 'No', 'No', 'No', 'No', 'No', 'No', 'No', 'No' - -################################## - ''' vector functions ''' -################################## - - # zip a directory - def zipDirectoryInFile(self, zipPath, fileDirectory): - try: - zip = cfg.zipfileSCP.ZipFile(zipPath, 'w') - for f in cfg.osSCP.listdir(fileDirectory): - zip.write(fileDirectory + "/" + f) - zip.close() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # create backup file - def createBackupFile(self, filePath): - try: - cfg.shutilSCP.copy(filePath, filePath + "." + cfg.backupNm) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # create a polygon shapefile with OGR - def createEmptyShapefile(self, crsWkt, outputVector, format = 'ESRI Shapefile'): - try: - crsWkt = str(crsWkt.toWkt()) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'crsWkt: ' + str(crsWkt)) - d = cfg.ogrSCP.GetDriverByName(format) - dS = d.CreateDataSource(outputVector) - # shapefile - sR = cfg.osrSCP.SpatialReference() - sR.ImportFromWkt(crsWkt) - rL = dS.CreateLayer('NewLayer', sR, cfg.ogrSCP.wkbMultiPolygon) - fN = cfg.emptyFN - fd = cfg.ogrSCP.FieldDefn(fN, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd) - rL = None - dS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputVector: ' + str(outputVector)) - - # create a polygon shapefile with OGR - def createSCPShapefile(self, crsWkt, outputVector): - try: - crsWkt = str(crsWkt.toWkt()) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'crsWkt: ' + str(crsWkt)) - d = cfg.ogrSCP.GetDriverByName('ESRI Shapefile') - dS = d.CreateDataSource(outputVector) - # shapefile - sR = cfg.osrSCP.SpatialReference() - sR.ImportFromWkt(crsWkt) - nm = cfg.utls.fileNameNoExt(outputVector) - rL = dS.CreateLayer(nm, sR, cfg.ogrSCP.wkbMultiPolygon) - fd0 = cfg.ogrSCP.FieldDefn('fid', cfg.ogrSCP.OFTInteger) - rL.CreateField(fd0) - fd1 = cfg.ogrSCP.FieldDefn(cfg.fldMacroID_class, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd1) - fd2 = cfg.ogrSCP.FieldDefn(cfg.fldROIMC_info, cfg.ogrSCP.OFTString) - rL.CreateField(fd2) - fd3 = cfg.ogrSCP.FieldDefn(cfg.fldID_class, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd3) - fd4 = cfg.ogrSCP.FieldDefn(cfg.fldROI_info, cfg.ogrSCP.OFTString) - rL.CreateField(fd4) - fd5 = cfg.ogrSCP.FieldDefn(cfg.fldSCP_UID, cfg.ogrSCP.OFTString) - rL.CreateField(fd5) - rL = None - dS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputVector: ' + str(outputVector)) - - # create a polygon gpkg with OGR - def createSCPVector(self, crsWkt, outputVector, format = 'GPKG'): - try: - crsWkt = str(crsWkt.toWkt()) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'crsWkt: ' + str(crsWkt)) - d = cfg.ogrSCP.GetDriverByName(format) - dS = d.CreateDataSource(outputVector) - # shapefile - sR = cfg.osrSCP.SpatialReference() - sR.ImportFromWkt(crsWkt) - nm = cfg.utls.fileNameNoExt(outputVector) - rL = dS.CreateLayer(nm, sR, cfg.ogrSCP.wkbMultiPolygon) - fd1 = cfg.ogrSCP.FieldDefn(cfg.fldMacroID_class, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd1) - fd2 = cfg.ogrSCP.FieldDefn(cfg.fldROIMC_info, cfg.ogrSCP.OFTString) - rL.CreateField(fd2) - fd3 = cfg.ogrSCP.FieldDefn(cfg.fldID_class, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd3) - fd4 = cfg.ogrSCP.FieldDefn(cfg.fldROI_info, cfg.ogrSCP.OFTString) - rL.CreateField(fd4) - fd5 = cfg.ogrSCP.FieldDefn(cfg.fldSCP_UID, cfg.ogrSCP.OFTString) - rL.CreateField(fd5) - rL = None - dS = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'outputVector: ' + str(outputVector)) - - # Get extent of a shapefile - def getShapefileRectangleBox(self, layerPath): - try: - dr = cfg.ogrSCP.Open(layerPath, 1) - l = dr.GetLayer() - e = l.GetExtent() - minX = e[0] - minY = e[2] - maxX = e[1] - maxY = e[3] - centerX = (maxX + minX) / 2 - centerY = (maxY + minY) / 2 - width = maxX - minX - heigth = maxY - minY - l = None - return centerX, centerY, width, heigth - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "roi bounding box: center " + str(r.center()) + " width: " + str(r.width())+ " height: " + str(r.height())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # get ID by attributes - def getIDByAttributes(self, layer, field, attribute): - IDs = [] - fR = layer.getFeatures(cfg.qgisCoreSCP.QgsFeatureRequest().setFilterExpression('"' + str(field) + '" = \'' + str(attribute) + '\'')) - for f in fR: - IDs.append(f.id()) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ID: " + str(IDs)) - return IDs - - # Get last feauture id - def getLastFeatureID(self, layer): - f = cfg.qgisCoreSCP.QgsFeature() - try: - for f in layer.getFeatures(): - ID = f.id() - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ID: " + str(ID)) - return ID - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return False - - # Get a feature from a shapefile by feature ID - def getFeaturebyID(self, layer, ID): - f = cfg.qgisCoreSCP.QgsFeature() - # feature request - fR = cfg.qgisCoreSCP.QgsFeatureRequest().setFilterFid(ID) - try: - f = layer.getFeatures(fR) - f = next(f) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'get feature ' + str(ID) + ' from shapefile: ' + str(layer.name())) - return f - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return False - - # Get a feature box by feature ID - def getFeatureRectangleBoxbyID(self, layer, ID): - try: - d = cfg.ogrSCP.GetDriverByName('ESRI Shapefile') - ql = cfg.utls.layerSource(layer) - dr = d.Open(ql, 1) - l = dr.GetLayer() - f = l.GetFeature(ID) - # bounding box rectangle - e = f.GetGeometryRef().GetEnvelope() - minX = e[0] - minY = e[2] - maxX = e[1] - maxY = e[3] - centerX = (maxX + minX) / 2 - centerY = (maxY + minY) / 2 - width = maxX - minX - heigth = maxY - minY - l = None - dr = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi bounding box: center ' + str(r.center()) + ' width: ' + str(r.width())+ ' height: ' + str(r.height())) - return centerX, centerY, width, heigth - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Delete a feauture from a shapefile by its Id - def deleteFeatureShapefile(self, layer, feautureIds): - layer.startEditing() - res = layer.dataProvider().deleteFeatures(feautureIds) - layer.commitChanges() - res2 = layer.dataProvider().createSpatialIndex() - layer.updateExtents() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'feauture deleted: ' + str(layer) + ' ' + str(feautureIds) ) - - # Edit a feauture in a shapefile by its Id - def editFeatureShapefile(self, layer, feautureId, fieldName, value): - id = self.fieldID(layer, fieldName) - layer.startEditing() - res = layer.changeAttributeValue(feautureId, id, value) - layer.commitChanges() - res2 = layer.dataProvider().createSpatialIndex() - layer.updateExtents() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'feauture edited: ' + str(layer) + ' ' + str(feautureId) ) - -### Copy feature by ID to layer - def copyFeatureToLayer(self, sourceLayer, ID, targetLayer): - f = self.getFeaturebyID(sourceLayer, ID) - # get geometry - fG = f.geometry() - f.setGeometry(fG) - try: - sF = targetLayer.fields() - f.initAttributes(sF.count()) - if f.hasGeometry() is not True: - cfg.mx.msg6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'feature geometry is none') - else: - # copy polygon to shapefile - targetLayer.startEditing() - targetLayer.addFeature(f) - targetLayer.commitChanges() - targetLayer.dataProvider().createSpatialIndex() - targetLayer.updateExtents() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'feature copied') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # merge polygons - def mergePolygons(self, targetLayer, idList, attributeList): - f = cfg.utls.getFeaturebyID(targetLayer, idList[0]) - sg = cfg.qgisCoreSCP.QgsGeometry(f.geometry()) - for i in idList: - if i != idList[0]: - f = cfg.utls.getFeaturebyID(targetLayer, i) - g = cfg.qgisCoreSCP.QgsGeometry(f.geometry()) - g.convertToMultiType() - sg.addPartGeometry(g) - pr = targetLayer.dataProvider() - fields = pr.fields().toList() - targetLayer.startEditing() - f = cfg.qgisCoreSCP.QgsFeature() - f.setGeometry(sg) - f.setAttributes(attributeList) - pr.addFeatures([f]) - targetLayer.commitChanges() - targetLayer.dataProvider().createSpatialIndex() - targetLayer.updateExtents() - fs = cfg.qgisCoreSCP.QgsFeature() - for fs in targetLayer.getFeatures(): - ID = fs.id() - return targetLayer - - # merge polygons to new layer - def mergePolygonsToNewLayer(self, targetLayer, idList, attributeList): - # create memory layer - provider = targetLayer.dataProvider() - fields = provider.fields() - pCrs = cfg.utls.getCrs(targetLayer) - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), 'memoryLayer', 'memory') - mL.setCrs(pCrs) - pr = mL.dataProvider() - for fld in fields: - pr.addAttributes([fld]) - mL.updateFields() - f = cfg.utls.getFeaturebyID(targetLayer, idList[0]) - sg = cfg.qgisCoreSCP.QgsGeometry(f.geometry()) - for i in idList: - if i != idList[0]: - f = cfg.utls.getFeaturebyID(targetLayer, i) - g = cfg.qgisCoreSCP.QgsGeometry(f.geometry()) - g.convertToMultiType() - sg.addPartGeometry(g) - mL.startEditing() - f.setGeometry(sg) - f.setAttributes(attributeList) - pr.addFeatures([f]) - mL.commitChanges() - mL.dataProvider().createSpatialIndex() - mL.updateExtents() - return mL - -### Delete a field from a shapefile by its name - def deleteFieldShapefile(self, layerPath, fieldName): - fds = self.fieldsShapefile(layerPath) - s = cfg.ogrSCP.Open(layerPath, 1) - l = s.GetLayer() - i = fds.index(fieldName) - l.DeleteField(i) - s = None - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "deleted field: " + str(fieldName) + " for layer: " + str(l.name())) - -### Find field ID by name - def fieldID(self, layer, fieldName): - try: - fID = layer.fields().lookupField(fieldName) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ID: ' + str(fID) + ' for layer: ' + str(layer.name())) - return fID - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -### Get field names of a shapefile - def fieldsShapefile(self, layerPath): - s = cfg.ogrSCP.Open(layerPath) - l = s.GetLayer() - lD = l.GetLayerDefn() - fN = [lD.GetFieldDefn(i).GetName() for i in range(lD.GetFieldCount())] - s = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'shapefile field ' + str(layerPath)) - return fN - - # get field attribute list - def getFieldAttributeList(self, layer, field): - fID = self.fieldID(layer, field) - f = cfg.qgisCoreSCP.QgsFeature() - l = [] - for f in layer.getFeatures(): - a = f.attributes()[fID] - l.append(a) - x = list(set(l)) - return x - - # reproject shapefile - def repojectShapefile(self, inputShapefilePath, inputEPSG, outputShapefilePath, outputEPSG, type = 'wkbMultiPolygon'): - # spatial reference - iSR = cfg.osrSCP.SpatialReference() - # EPSG or projection - try: - iSR.ImportFromEPSG(inputEPSG) - except: - iSR = inputEPSG - oSR = cfg.osrSCP.SpatialReference() - try: - oSR.ImportFromEPSG(outputEPSG) - except: - oSR = outputEPSG - # required by GDAL 3 coordinate order - try: - iSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - oSR.SetAxisMappingStrategy(cfg.osrSCP.OAMS_TRADITIONAL_GIS_ORDER) - except: - pass - # Coordinate Transformation - cT = cfg.osrSCP.CoordinateTransformation(iSR, oSR) - # input shapefile - iS = cfg.ogrSCP.Open(inputShapefilePath) - iL = iS.GetLayer() - # output shapefile - iD = cfg.ogrSCP.GetDriverByName('ESRI Shapefile') - oS = iD.CreateDataSource(outputShapefilePath) - nm = cfg.utls.fileName(outputShapefilePath) - if type == 'wkbMultiPolygon': - oL = oS.CreateLayer(str(nm), oSR, cfg.ogrSCP.wkbMultiPolygon) - elif type == 'wkbPoint': - oL = oS.CreateLayer(str(nm), oSR, cfg.ogrSCP.wkbPoint) - iLDefn = iL.GetLayerDefn() - # fields - for i in range(0, iLDefn.GetFieldCount()): - fDefn = iLDefn.GetFieldDefn(i) - oL.CreateField(fDefn) - oLDefn = oL.GetLayerDefn() - oLFcount = oLDefn.GetFieldCount() - iF = iL.GetNextFeature() - while iF: - g = iF.GetGeometryRef() - g.Transform(cT) - oF = cfg.ogrSCP.Feature(oLDefn) - oF.SetGeometry(g) - for i in range(0, oLFcount): - nmRef = oLDefn.GetFieldDefn(i).GetNameRef() - field = iF.GetField(i) - oF.SetField(nmRef, field) - oL.CreateFeature(oF) - oF.Destroy() - iF.Destroy() - iF = iL.GetNextFeature() - iS.Destroy() - oS.Destroy() - -################################## - ''' raster color composite functions ''' -################################## - - # get items in combobox - def getAllItemsInCombobox(self, combobox): - it = [combobox.itemText(i) for i in range(combobox.count())] - return it - - # set RGB Combobox - def setComboboxItems(self, combobox, itemList): - combobox.clear() - for i in itemList: - if len(i) > 0: - combobox.addItem(i) - - # set RGB color composite - def setRGBColorComposite(self): - if cfg.rgb_combo.currentText() != "-": - try: - rgb = cfg.rgb_combo.currentText() - check = self.createRGBColorComposite(rgb) - if check == 'Yes': - listA = cfg.utls.getAllItemsInCombobox(cfg.rgb_combo) - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.RGBLT.RGBListTable(cfg.RGBList) - return 'Yes' - else: - int(check) - except Exception as err: - if "string index" not in str(err): - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # create RGB color composite - def createRGBColorComposite(self, colorComposite, bandSetNumber = None): - if bandSetNumber is None or bandSetNumber is False: - bandSetNumber = cfg.bndSetNumber - try: - a = cfg.tmpVrtDict[bandSetNumber] - except: - cfg.tmpVrtDict[bandSetNumber] = None - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - # if bandset create temporary virtual raster - tPMN = cfg.bndSetVrtNm + str(bandSetNumber + 1) - if cfg.tmpVrtDict[bandSetNumber] is None: - try: - self.removeLayer(tPMN) - except: - pass - tPMD = cfg.utls.createTempRasterPath('vrt') - ckB = cfg.utls.checkBandSet(bandSetNumber) - vrtCheck = cfg.utls.createVirtualRaster(cfg.bndSetLst, tPMD, 'No', 'Yes', 'Yes', 0) - cfg.timeSCP.sleep(1) - i = self.addRasterLayer(tPMD, tPMN) - cfg.utls.setRasterColorComposite(i, 3, 2, 1) - cfg.tmpVrtDict[bandSetNumber] = i - else: - i = cfg.utls.selectLayerbyName(tPMN, 'Yes') - c = str(colorComposite).split(',') - if len(c) == 1: - c = str(colorComposite).split('-') - if len(c) == 1: - c = str(colorComposite).split(';') - if len(c) == 1: - c = str(colorComposite) - if i is not None: - b = len(cfg.bandSetsList[bandSetNumber][3]) - if int(c[0]) <= b and int(c[1]) <= b and int(c[2]) <= b: - cfg.utls.setRasterColorComposite(i, int(c[0]), int(c[1]), int(c[2])) - return 'Yes' - else: - return 'No' - else: - cfg.tmpVrtDict[bandSetNumber] = None - else: - c = str(colorComposite).split(',') - if len(c) == 1: - c = str(colorComposite).split('-') - if len(c) == 1: - c = str(colorComposite).split(';') - if len(c) == 1: - c = str(colorComposite) - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - if i is not None: - b = len(cfg.bandSetsList[bandSetNumber][3]) - if int(c[0]) <= b and int(c[1]) <= b and int(c[2]) <= b: - self.setRasterColorComposite(i, int(c[0]), int(c[1]), int(c[2])) - return 'Yes' - else: - return 'No' - - # set raster color composite - def setRasterColorComposite(self, raster, RedBandNumber, GreenBandNumber, BlueBandNumber): - # QGIS3 - #raster.setDrawingStyle('MultiBandColor') - raster.renderer().setRedBand(RedBandNumber) - raster.renderer().setGreenBand(GreenBandNumber) - raster.renderer().setBlueBand(BlueBandNumber) - cfg.utls.setRasterContrastEnhancement(raster, cfg.defaultContrast ) - - # set local cumulative cut stretch - def setRasterCumulativeStretch(self): - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - i = cfg.tmpVrtDict[cfg.bndSetNumber] - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - cfg.utls.setRasterContrastEnhancement(i, cfg.cumulativeCutContrast) - cfg.defaultContrast = cfg.cumulativeCutContrast - - # set local standard deviation stretch - def setRasterStdDevStretch(self): - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - i = cfg.tmpVrtDict[cfg.bndSetNumber] - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - cfg.utls.setRasterContrastEnhancement(i, cfg.stdDevContrast) - cfg.defaultContrast = cfg.stdDevContrast - - # set raster enhancement - def setRasterContrastEnhancement(self, QGISraster, contrastType = cfg.cumulativeCutContrast): - ext = cfg.cnvs.extent( ) - tLPoint = cfg.qgisCoreSCP.QgsPointXY(ext.xMinimum(), ext.yMaximum()) - lRPoint = cfg.qgisCoreSCP.QgsPointXY(ext.xMaximum(), ext.yMinimum()) - point1 = tLPoint - point2 = lRPoint - # project extent - iCrs = cfg.utls.getCrs(QGISraster) - pCrs = cfg.utls.getQGISCrs() - if iCrs is None: - iCrs = pCrs - # projection of input point from project's crs to raster's crs - if pCrs != iCrs: - try: - point1 = cfg.utls.projectPointCoordinates(tLPoint, pCrs, iCrs) - point2 = cfg.utls.projectPointCoordinates(lRPoint, pCrs, iCrs) - if point1 is False: - point1 = tLPoint - point2 = lRPoint - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - point1 = tLPoint - point2 = lRPoint - if contrastType == cfg.stdDevContrast: - contrast = cfg.qgisCoreSCP.QgsRasterMinMaxOrigin.StdDev - elif contrastType == cfg.cumulativeCutContrast: - contrast = cfg.qgisCoreSCP.QgsRasterMinMaxOrigin.CumulativeCut - try: - QGISraster.setContrastEnhancement(cfg.qgisCoreSCP.QgsContrastEnhancement.StretchToMinimumMaximum, contrast, cfg.qgisCoreSCP.QgsRectangle(point1, point2)) - QGISraster.triggerRepaint() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -################################## - ''' table functions ''' -################################## - - # delete all items in a table - def clearTable(self, table): - table.clearContents() - for i in range(0, table.rowCount()): - table.removeRow(0) - - # set all items to state 0 or 2 - def allItemsSetState(self, tableWidget, value): - tW = tableWidget - tW.blockSignals(True) - r = tW.rowCount() - for b in range(0, r): - if cfg.actionCheck == 'Yes': - tW.item(b, 0).setCheckState(value) - #cfg.uiUtls.updateBar((b+1) * 100 / r) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' cancelled') - tW.blockSignals(False) - tW.blockSignals(False) - - # highlight row in table - def highlightRowInTable(self, table, value, columnIndex): - tW = table - v = tW.rowCount() - for x in range(0, v): - id = tW.item(x, columnIndex).text() - if str(id) == str(value): - return x - - # remove rows from table - def removeRowsFromTable(self, table): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Remove rows'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to remove highlighted rows from the table?')) - if a == 'Yes': - tW = table - tW.blockSignals(True) - c = tW.rowCount() - # list of item to remove - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - # remove items - for i in reversed(list(range(0, len(v)))): - tW.removeRow(v[i]) - c = tW.rowCount() - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' row removed') - - # select rows in table - def selectRowsInTable(self, table, rowList): - c = table.columnCount() - for row in rowList: - table.setRangeSelected(cfg.QtWidgetsSCP.QTableWidgetSelectionRange(row, 0, row, c-1), True) - - # table content to text - def tableToText(self, table): - try: - tW = table - r = tW.rowCount() - c = tW.columnCount() - text = '' - for x in range(0, r): - row = '' - for y in range(0, c): - it = tW.item(x, y).text() - row = row + it - if y < (c - 1): - row = row + '\t' - text = text + row - if x < (r - 1): - text = text + '\n' - return text - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # text to table content - def textToTable(self, table, text): - try: - tW = table - c = tW.columnCount() - nSplit = text.split('\n') - for n in nSplit: - # add item to table - r = tW.rowCount() - # add list items to table - tW.setRowCount(r + 1) - tSplit = n.split('\t') - for t in range(0, c): - cfg.utls.addTableItem(tW, str(tSplit[t]), r, t) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # add item to table - def addTableItem(self, table, item, row, column, enabled = 'Yes', color = None, checkboxState = None, tooltip = None, foreground = None, bold = None): - itMID = cfg.QtWidgetsSCP.QTableWidgetItem() - if checkboxState != None: - itMID.setCheckState(checkboxState) - if enabled == 'No': - itMID.setFlags(cfg.QtSCP.ItemIsEnabled) - itMID.setData(cfg.QtSCP.DisplayRole, item) - table.setItem(row, column, itMID) - if color is not None: - table.item(row, column).setBackground(color) - if foreground is not None: - table.item(row, column).setForeground(foreground) - if tooltip is not None: - itMID.setToolTip(tooltip) - if bold is not None: - font = cfg.QtGuiSCP.QFont() - font.setBold(True) - table.item(row, column).setFont(font) - - # set table item - def setTableItem(self, table, row, column, value): - table.item(row, column).setText(value) - - # insert table row - def insertTableRow(self, table, row, height = None): - table.insertRow(row) - if height is not None: - table.setRowHeight(row, height) - - # insert table column - def insertTableColumn(self, table, column, name, width = None, hide = 'No'): - table.insertColumn(column) - table.setHorizontalHeaderItem(column, cfg.QtWidgetsSCP.QTableWidgetItem(name)) - if width is not None: - table.setColumnWidth(column, width) - if hide == 'Yes': - table.hideColumn(column) - - # sort table column - def sortTableColumn(self, table, column, ascending = False): - table.sortItems(column, ascending) - - # set table column width - def setColumnWidthList(self, table, list): - for c in list: - table.setColumnWidth(c[0], c[1]) - - # set tree column width - def setTreeColumnWidthList(self, tree, list): - for c in list: - tree.header().resizeSection(c[0], c[1]) - -################################## - ''' tab selection functions ''' -################################## - -### tab 0 - # select band set tab - def bandSetTab(self): - cfg.ui.SCP_tabs.setCurrentIndex(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 1 - # select tab 1 from Main Interface - def selectTab2MainInterface(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(1) - if secondTab is not None: - cfg.ui.tabWidget_5.setCurrentIndex(secondTab) - - # select basic tools tab - def basicToolsTab(self): - cfg.utls.selectTab2MainInterface() - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # RGB List tab - def RGBListTab(self): - cfg.utls.selectTab2MainInterface(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # Band Set List tab - def BandSetListTab(self): - cfg.utls.selectTab2MainInterface(1) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # algorithm weight tab - def algorithmBandWeightTab(self): - cfg.utls.selectTab2MainInterface(2) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select multiple roi tab - def multipleROICreationTab(self): - cfg.utls.selectTab2MainInterface(3) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # import library signatures tab - def importSignaturesTab(self): - cfg.utls.selectTab2MainInterface(4) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # export library signatures tab - def exportSignaturesTab(self): - cfg.utls.selectTab2MainInterface(5) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # signature threshold tab - def signatureThresholdTab(self): - cfg.utls.selectTab2MainInterface(6) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # LCS threshold tab - def LCSThresholdTab(self): - cfg.utls.selectTab2MainInterface(7) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 2 - # select tab 2 - def selectTabDownloadImages(self): - cfg.ui.SCP_tabs.setCurrentIndex(2) - cfg.ipt.dockTabChanged(5) - - # select pre processing tab - def downloadProductsTab(self): - cfg.utls.selectTabDownloadImages() - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 4 - # select tab 4 from Main Interface - def selectTab4MainInterface(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(3) - if secondTab is not None: - cfg.ui.tabWidget_preprocessing.setCurrentIndex(secondTab) - - # select pre processing tab - def preProcessingTab(self): - cfg.utls.selectTab4MainInterface() - cfg.ipt.dockTabChanged(6) - - # select Landsat tab - def landsatTab(self): - cfg.utls.selectTab4MainInterface(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Sentinel-1 tab - def sentinel1Tab(self): - cfg.utls.selectTab4MainInterface(1) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Sentinel-2 tab - def sentinel2Tab(self): - cfg.utls.selectTab4MainInterface(2) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Sentinel-3 tab - def sentinel3Tab(self): - cfg.utls.selectTab4MainInterface(3) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select ASTER tab - def asterTab(self): - cfg.utls.selectTab4MainInterface(4) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select MODIS tab - def modisTab(self): - cfg.utls.selectTab4MainInterface(5) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # Vector to raster tab - def vectorToRasterTab(self): - cfg.utls.selectTab4MainInterface(6) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Clip multiple rasters tab - def clipMultipleRastersTab(self): - cfg.utls.selectTab4MainInterface(7) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Reproject raster bands tab - def reprojectrasterbandsTab(self): - cfg.utls.selectTab4MainInterface(8) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Split raster bands tab - def splitrasterbandsTab(self): - cfg.utls.selectTab4MainInterface(9) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Stack raster bands tab - def stackrasterbandsTab(self): - cfg.utls.selectTab4MainInterface(10) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # Mosaic tab - def mosaicBandSetsTab(self): - cfg.utls.selectTab4MainInterface(11) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # cloud masking tab - def cloudMaskingTab(self): - cfg.utls.selectTab4MainInterface(12) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select GOES tab - def GOESTab(self): - cfg.utls.selectTab4MainInterface(13) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select neighbor pixels tab - def neighborPixelsTab(self): - cfg.utls.selectTab4MainInterface(14) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 5 - # select tab 5 from Main Interface - def selectTab5MainInterface(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(4) - if secondTab is not None: - cfg.ui.tabWidget_4.setCurrentIndex(secondTab) - - # select bandrefRstrDt processing tab - def bandProcessingTab(self): - cfg.utls.selectTab5MainInterface() - cfg.ipt.dockTabChanged(7) - - # select Band combination tab - def bandCombinationTab(self): - cfg.utls.selectTab5MainInterface(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # PCA tab - def PCATab(self): - cfg.utls.selectTab5MainInterface(1) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # Clustering tab - def clusteringTab(self): - cfg.utls.selectTab5MainInterface(2) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # Spectral distance tab - def spectralDistanceTab(self): - cfg.utls.selectTab5MainInterface(3) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification tab - def classificationTab(self): - cfg.utls.selectTab5MainInterface(4) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Random forest tab - def randomForestTab(self): - cfg.utls.selectTab5MainInterface(5) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 5 - # select tab 5 from Main Interface - def selectTab6MainInterface(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(5) - if secondTab is not None: - cfg.ui.tabWidget_2.setCurrentIndex(secondTab) - - # select post processing tab - def postProcessingTab(self): - cfg.utls.selectTab6MainInterface() - cfg.ipt.dockTabChanged(8) - - # select Accuracy tab - def accuracyTab(self): - cfg.utls.selectTab6MainInterface(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Land cover change tab - def landCoverChangeTab(self): - cfg.utls.selectTab6MainInterface(1) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification report tab - def classificationReportTab(self): - cfg.utls.selectTab6MainInterface(2) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Cross classification tab - def crossClassificationTab(self): - cfg.utls.selectTab6MainInterface(3) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification to vector tab - def classSignatureTab(self): - cfg.utls.selectTab6MainInterface(4) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification to vector tab - def classificationToVectorTab(self): - cfg.utls.selectTab6MainInterface(5) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Reclassification tab - def reclassificationTab(self): - cfg.utls.selectTab6MainInterface(6) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Edit raster tab - def editRasterTab(self): - cfg.utls.selectTab6MainInterface(7) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification sieve tab - def classificationSieveTab(self): - cfg.utls.selectTab6MainInterface(8) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification erosion tab - def classificationErosionTab(self): - cfg.utls.selectTab6MainInterface(9) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select Classification dilation tab - def classificationDilationTab(self): - cfg.utls.selectTab6MainInterface(10) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select zonal stat raster tab - def zonalStatRasterTab(self): - cfg.utls.selectTab6MainInterface(11) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 6 - # select Band calc tab - def bandCalcTab(self): - cfg.ui.SCP_tabs.setCurrentIndex(6) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 7 - # select tab 7 from Main Interface - def selectTabBatch(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(7) - if secondTab is not None: - cfg.ui.toolBox.setCurrentIndex(secondTab) - - # select batch tab - def batchTab(self): - cfg.utls.selectTabBatch() - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 8 - # select tab 8 from Main Interface - def selectTabSettings(self, secondTab = None): - cfg.ui.SCP_tabs.setCurrentIndex(8) - if secondTab is not None: - cfg.ui.settings_tabWidget.setCurrentIndex(secondTab) - - # select settings tab - def settingsTab(self): - cfg.utls.selectTabSettings() - - # select settings Processing tab - def processingSettingTab(self): - cfg.utls.selectTabSettings(0) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select settings interface tab - def interfaceTab(self): - cfg.utls.selectTabSettings(1) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - - # select settings debug tab - def debugTab(self): - cfg.utls.selectTabSettings(2) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### tab 9 - # select about tab - def aboutTab(self): - cfg.ui.SCP_tabs.setCurrentIndex(9) - cfg.currentTab = str(cfg.inspectSCP.stack()[0][3]) - cfg.ipt.treeMenuTab() - -### spectral signature plot tab - def spectralPlotTab(self): - cfg.spectralplotdlg.close() - cfg.spectralplotdlg.show() - - # select tab in signature plot tab - def selectSpectralPlotTabSettings(self, secondTab = None): - if secondTab is not None: - cfg.uisp.tabWidget.setCurrentIndex(secondTab) - -### scatter plot tab - def scatterPlotTab(self): - cfg.scatterplotdlg.close() - cfg.scatterplotdlg.show() - - # first install welcome tab - def welcomeTab(self): - cfg.welcomedlg.close() - cfg.welcomedlg.show() - -################################## - ''' notification functions ''' -################################## - - # beep sound - def beepSound(self, frequency, duration): - if cfg.sysSCP.platform.startswith('win'): - winsound.Beep(frequency, int(duration * 1000)) - elif cfg.sysSCP.platform.startswith('linux'): - cfg.osSCP.system('play --no-show-progress --null --channels 1 synth ' + str(duration) + ' sine ' + str(frequency)) - else: - cfg.sysSCP.stdout.write('\a') - cfg.sysSCP.stdout.flush() - - # finish sound - def finishSound(self): - if cfg.soundVal == '2': - try: - self.beepSound(800, 0.2) - self.beepSound(600, 0.3) - self.beepSound(700, 0.5) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # send SMTP message - def sendSMTPMessage(self, subject = None, message = None): - if cfg.SMTPCheck == '2': - try: - if len(cfg.SMTPServer) > 0: - s = cfg.smtplibSCP.SMTP(cfg.SMTPServer, 587) - c = cfg.sslSCP.create_default_context() - s.starttls(context = c) - s.login(cfg.SMTPUser, cfg.SMTPPassword) - tolist = cfg.SMTPtoEmails.split(',') - if subject is None: - subject = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SCP: completed process') - if message is None: - message = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SCP: completed process') - msg = 'From: SCP\nTo: \nSubject: ' + subject + '\n\n' + message + '\n\n---\nSemi-Automatic Classification Plugin\nhttps://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html' - s.sendmail(cfg.SMTPUser, tolist, msg) - s.quit() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' subject:' + str(subject) + ' message:' + str(message)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -################################## - ''' clean functions ''' -################################## - - # clean old temporary directory - def cleanOldTempDirectory(self): - t = cfg.datetimeSCP.datetime.now() - inputDir = str(cfg.QDirSCP.tempPath() + '/' + cfg.tempDirName) - try: - for name in cfg.osSCP.listdir(inputDir): - dStr = cfg.datetimeSCP.datetime.strptime(name, '%Y%m%d_%H%M%S%f') - diff = (t - dStr) - if diff.days > 3: - cfg.shutilSCP.rmtree(inputDir + '/' + name, True) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -################################## - ''' general functions ''' -################################## - - # 32bit or 64bit - def findSystemSpecs(self): - if cfg.sysSCP.maxsize > 2**32: - cfg.sysSCP64bit = 'Yes' - else: - cfg.sysSCP64bit = 'No' - # file system encoding - cfg.fSEnc = cfg.sysSCP.getfilesystemencoding() - # system information - cfg.sysSCPNm = cfg.platformSCP.system() - # QGIS version - cfg.QGISVer = cfg.qgisCoreSCP.Qgis.QGIS_VERSION_INT - - # read variables from project instance - def readVariables(self): - # read qml path from project instance - cfg.qmlFl = cfg.utls.readProjectVariable('qmlfile', '') - # set qml line content - cfg.ui.qml_lineEdit.setText(cfg.qmlFl) - # read signature checkbox from project instance - cfg.sigClcCheck = cfg.utls.readProjectVariable('calculateSignature', '2') - # read save input checkbox from project instance - cfg.saveInputCheck = cfg.utls.readProjectVariable('saveInput', '2') - # read rapid ROI checkbox from project instance - cfg.rpdROICheck = cfg.utls.readProjectVariable('rapidROI', '2') - cfg.vegIndexCheck = cfg.utls.readProjectVariable('vegetationIndex', '2') - cfg.ROIband = cfg.utls.readProjectVariable('rapidROIBand', str(cfg.ROIband)) - cfg.prvwSz = cfg.utls.readProjectVariable('previewSize', str(cfg.prvwSz)) - cfg.minROISz = cfg.utls.readProjectVariable('minROISize', str(cfg.minROISz)) - cfg.maxROIWdth = cfg.utls.readProjectVariable('maxROIWidth', str(cfg.maxROIWdth)) - cfg.rngRad = cfg.utls.readProjectVariable('rangeRadius', str(cfg.rngRad)) - cfg.ROIID = cfg.utls.readProjectVariable('ROIIDField', str(cfg.ROIID)) - cfg.ROIInfo = cfg.utls.readProjectVariable('ROIInfoField', str(cfg.ROIInfo)) - cfg.ROIMacroClassInfo = cfg.utls.readProjectVariable('ROIMacroclassInfoField', str(cfg.ROIMacroClassInfo)) - cfg.customExpression = cfg.utls.readProjectVariable('customExpression', str(cfg.customExpression)) - cfg.ROIMacroID = cfg.utls.readProjectVariable('ROIMacroIDField', str(cfg.ROIMacroID)) - # mask option - cfg.mskFlPath = cfg.utls.readProjectVariable('maskFilePath', str(cfg.mskFlPath)) - cfg.mskFlState = cfg.utls.readProjectVariable('maskFileState', str(cfg.mskFlState)) - cfg.ui.mask_lineEdit.setText(str(cfg.mskFlPath)) - cfg.classTab.setMaskCheckbox() - # band set - bandSetsList = cfg.utls.readProjectVariable('bandSetsList', '[]') - bndSetNumber = cfg.utls.readProjectVariable('bndSetNumber', str(cfg.bndSetNumber)) - cfg.bandSetsList = eval(bandSetsList) - bndSetMaxNumber = len(cfg.bandSetsList) - if bndSetMaxNumber > 0: - t = cfg.ui.Band_set_tabWidget.count() - for index in reversed(list(range(0, t))): - cfg.BandTabEdited = 'No' - cfg.bst.deleteBandSetTab(index) - cfg.BandTabEdited = 'Yes' - # add band set tab - for i in range(0, bndSetMaxNumber): - cfg.BandTabEdited = 'No' - cfg.bst.addBandSetTab('No') - cfg.BandTabEdited = 'Yes' - bndSetList = cfg.bandSetsList[i] - # add band set to table - bs = bndSetList[3] - wlg = bndSetList[4] - t = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[i]) - it = 0 - cfg.BandTabEdited = 'No' - t.blockSignals(True) - for x in sorted(wlg): - # add item to table - c = t.rowCount() - # name of item of list - iN = bs[it] - # add list items to table - t.setRowCount(c + 1) - cfg.utls.addTableItem(t, iN, c, 0) - cfg.utls.addTableItem(t, str(x), c, 1) - try: - cfg.utls.addTableItem(t, str(bndSetList[6][0][it]), c, 2) - except: - cfg.utls.addTableItem(t, '1', c, 2) - try: - cfg.utls.addTableItem(t, str(bndSetList[6][1][it]), c, 3) - except: - cfg.utls.addTableItem(t, '0', c, 3) - cfg.utls.addTableItem(t, str(cfg.bst.unitNameConversion(bndSetList[5], 'Yes')), c, 4) - try: - cfg.utls.addTableItem(t, bndSetList[8], c, 5) - except: - cfg.utls.addTableItem(t, '', c, 5) - try: - cfg.utls.addTableItem(t, bndSetList[9], c, 6) - except: - cfg.utls.addTableItem(t, '', c, 6) - it = it + 1 - t.blockSignals(False) - cfg.BandTabEdited = 'Yes' - else: - t = cfg.ui.Band_set_tabWidget.count() - for index in reversed(list(range(0, t))): - cfg.bst.deleteBandSetTab(index) - cfg.bst.addBandSetTab('No') - cfg.bst.readBandSet('Yes') - cfg.bndSetNumber = int(bndSetNumber) - if cfg.bndSetNumber < 0: - cfg.bndSetNumber = 0 - cfg.utls.checkBandSet(cfg.bndSetNumber) - cfg.BandTabEdited = 'No' - cfg.ui.Band_set_tabWidget.setCurrentIndex(cfg.bndSetNumber) - cfg.BandTabEdited = 'Yes' - # read RGB list - rgbList = cfg.utls.readProjectVariable('SCP_RGBList', str(cfg.RGBList)) - cfg.RGBList = eval(rgbList) - try: - if cfg.vrtRstProjVal == '0': - cfg.rgb_combo.blockSignals(True) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - cfg.rgb_combo.blockSignals(False) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' readVariables') - - # get temporary directory - def getTempDirectory(self): - # temp directory - if cfg.tmpDir is None: - tmpDir0 = str(cfg.QDirSCP.tempPath() + '/' + cfg.tempDirName) - else: - tmpDir0 = cfg.tmpDir - if not cfg.QDirSCP(tmpDir0).exists(): - try: - cfg.osSCP.makedirs(tmpDir0) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.utls.setQGISRegSetting(cfg.regTmpDir, tmpDir0) - cfg.mx.msgWar17() - cfg.tmpDir = str(cfg.QDirSCP.tempPath() + '/' + cfg.tempDirName) - tmpDir0 = cfg.tmpDir - if not cfg.QDirSCP(tmpDir0).exists(): - cfg.osSCP.makedirs(tmpDir0) - try: - dT = cfg.utls.getTime() - cfg.osSCP.makedirs(tmpDir0 + '/' + dT) - cfg.tmpDir = str(tmpDir0 + '/' + dT) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgWar17() - if not cfg.QDirSCP(cfg.tmpDir).exists(): - cfg.osSCP.makedirs(cfg.tmpDir) - return tmpDir0 - # check and create directory - def makeDirectory(self, path): - if not cfg.QDirSCP(path).exists(): - try: - cfg.osSCP.makedirs(path) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None - return path - - # find available RAM - def findAvailableRAM(self): - try: - if cfg.sysSCP64bit == 'Yes': - if cfg.sysSCPNm == 'Windows': - class GlobalMemoryStatus(cfg.ctypesSCP.Structure): - _fields_ = [('length', cfg.ctypesSCP.c_ulong), - ('memoryLoad', cfg.ctypesSCP.c_ulong), - ('totalRam', cfg.ctypesSCP.c_ulong), - ('availPhys', cfg.ctypesSCP.c_ulonglong), - ('totalPageFile', cfg.ctypesSCP.c_ulonglong), - ('availPageFile', cfg.ctypesSCP.c_ulonglong), - ('totalVirt', cfg.ctypesSCP.c_ulonglong), - ('availVirt', cfg.ctypesSCP.c_ulonglong), - ('availExVirt', cfg.ctypesSCP.c_ulonglong), - ] - - GMS = GlobalMemoryStatus() - cfg.ctypesSCP.windll.kernel32.GlobalMemoryStatus(cfg.ctypesSCP.byref(GMS)) - tRam = GMS.totalRam - ram = int((tRam / 1048576) / 2) - cfg.ui.RAM_spinBox.setValue(ram) - elif cfg.sysSCPNm == 'Darwin': - cfg.ui.RAM_spinBox.setValue(1024) - else: - with open('/proc/meminfo') as t: - for b in t: - if b.startswith('MemTotal'): - tRam = b.split()[1] - break - ram = int((int(tRam) / 1000) / 2) - cfg.ui.RAM_spinBox.setValue(ram) - except: - pass - - # find file name without extension - def fileNameNoExt(self, path): - n = cfg.osSCP.path.basename(cfg.osSCP.path.splitext(path)[0]) - return n - - # find file name with extension - def fileName(self, path): - n = cfg.osSCP.path.basename(path) - return n - - # find available processors - def findAvailableProcessors(self): - try: - if cfg.sysSCP64bit == 'Yes': - threads = cfg.osSCP.cpu_count() - cfg.ui.CPU_spinBox.setValue(int((threads+1)/2)) - except: - cfg.ui.CPU_spinBox.setValue(1) - - # create a circular structure - def createCircularStructure(self, radius): - circle = cfg.np.zeros([radius*2+1, radius*2+1]) - for x in range(0, radius*2+1): - for y in range(0, radius*2+1): - if (x - radius)**2 + (y - radius)**2 <= radius**2: - circle[x,y] = 1 - return circle +""" download functions """ + + +# check Remotior Sensus version +def check_remotior_sensus_version(): + request = QNetworkRequest( + QUrl('https://pypi.org/pypi/remotior_sensus/json') + ) + cfg.remotior_reply = QgsNetworkAccessManager.instance().get(request) + cfg.remotior_reply.finished.connect(remotior_label) + + +# check Remotior Sensus version +def remotior_label(): + try: + package = json.loads( + QByteArray(cfg.remotior_reply.readAll()).data().decode('utf-8') + ) + latest_version = package['info']['version'] + from remotior_sensus import __version__ as version + if parse(latest_version) > parse(version): + cfg.dock_class_dlg.ui.rs_version.setText( + 'A new version of Remotior Sensus is available.' + '\nPlease update the Remotior Sensus package.' + ) + except Exception as err: + return str(err) + + +# download html file +def download_html(url, second_url=None): + request = QNetworkRequest(QUrl(url)) + cfg.second_url = second_url + cfg.first_reply = QgsNetworkAccessManager.instance().get(request) + cfg.first_reply.finished.connect(reply_in_text_browser) + + +# load reply in text browser +# noinspection PyUnresolvedReferences +def reply_in_text_browser(): + cfg.first_reply.deleteLater() + html_data = cfg.first_reply.readAll().data() + html = bytes.decode(html_data) + # GitHub file not found + if '

404

' in html: + second_request = QNetworkRequest(QUrl(cfg.second_url)) + cfg.second_reply = QgsNetworkAccessManager.instance().get( + second_request + ) + cfg.second_reply.finished.connect(reply_in_text_browser_second_request) + if len(html) > 0: + cfg.dock_class_dlg.ui.main_textBrowser.clear() + cfg.dock_class_dlg.ui.main_textBrowser.setHtml(html) + cfg.first_reply.finished.disconnect() + cfg.first_reply.abort() + cfg.first_reply.close() + + +# load reply in text browser +# noinspection PyUnresolvedReferences +def reply_in_text_browser_second_request(): + cfg.second_reply.deleteLater() + html_data = cfg.second_reply.readAll().data() + html = bytes.decode(html_data) + if len(html) > 0: + cfg.dock_class_dlg.ui.main_textBrowser.clear() + cfg.dock_class_dlg.ui.main_textBrowser.setHtml(html) + else: + html_text_f = open('%s/ui/welcome.html' % cfg.plugin_dir, 'r') + html_text = html_text_f.read() + cfg.dock_class_dlg.ui.main_textBrowser.clear() + cfg.dock_class_dlg.ui.main_textBrowser.setHtml(html_text) + html_text_f.close() + cfg.second_reply.finished.disconnect() + cfg.second_reply.abort() + cfg.second_reply.close() + + +""" encrypt functions """ + + +# encrypt password +def encrypt_password(password): + e = base64.b64encode(bytes(password, 'utf-8')) + return str(e) + + +# decrypt password +def decrypt_password(password): + if password is not None: + d = base64.b64decode(password) + return d + else: + return '' + + +""" time functions """ + + +# get time +def get_time(): + return datetime.datetime.now().strftime('%Y%m%d_%H%M%S%f') + + +# get date +def get_date(): + return datetime.datetime.now().strftime('%Y_%m_%d') + + +""" QGIS map and symbology functions """ + + +# refresh extent combo +def refresh_raster_extent_combo(): + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.raster_extent_combo.clear() + cfg.dialog.raster_extent_combo(cfg.union_extent) + cfg.dialog.raster_extent_combo(cfg.map_extent) + cfg.dialog.raster_extent_combo(cfg.intersection_extent) + cfg.dialog.raster_extent_combo(cfg.custom_extent) + for layer in sorted(layers, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_raster(): + cfg.dialog.raster_extent_combo(layer.name()) + + +# refresh raster align combo +def refresh_raster_align_combo(): + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.raster_extent_combo_2.clear() + cfg.dialog.raster_extent_combo_2(cfg.default_align) + for layer in sorted(layers, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_raster(): + cfg.dialog.raster_extent_combo_2(layer.name()) + + +# refresh classification combo +def refresh_raster_layer(): + ls = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.classification_name_combo.clear() + cfg.dialog.ui.classification_name_combo_2.clear() + cfg.dialog.ui.classification_report_name_combo.clear() + cfg.dialog.ui.classification_vector_name_combo.clear() + cfg.dialog.ui.reclassification_name_combo.clear() + cfg.dialog.ui.classification_name_combo_4.clear() + cfg.dialog.ui.reference_raster_name_combo.clear() + cfg.dialog.ui.raster_align_comboBox.clear() + for layer in sorted(ls, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_raster(): + if layer.bandCount() == 1: + cfg.dialog.classification_layer_combo(layer.name()) + cfg.dialog.classification_layer_combo_2(layer.name()) + cfg.dialog.classification_report_combo(layer.name()) + cfg.dialog.classification_to_vector_combo(layer.name()) + cfg.dialog.reclassification_combo(layer.name()) + cfg.dialog.cloud_mask_raster_combo(layer.name()) + cfg.dialog.reference_raster_combo(layer.name()) + cfg.dialog.project_raster_combo(layer.name()) + + +# refresh vector combo +def refresh_vector_layer(): + cfg.dialog.ui.vector_name_combo.blockSignals(True) + ls = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.shapefile_comboBox.clear() + cfg.dialog.ui.vector_name_combo.clear() + for layer in sorted(ls, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + if ((layer.wkbType() == cfg.util_qgis.get_qgis_wkb_types().Polygon) + or (layer.wkbType() == + cfg.util_qgis.get_qgis_wkb_types().MultiPolygon)): + cfg.dialog.shape_clip_combo(layer.name()) + cfg.dialog.vector_to_raster_combo(layer.name()) + cfg.dialog.ui.vector_name_combo.blockSignals(False) + refresh_vector_fields() + + +# reference layer name +def refresh_vector_fields(): + reference_layer = cfg.dialog.ui.vector_name_combo.currentText() + cfg.dialog.ui.field_comboBox.clear() + cfg.dialog.ui.select_shapefile_label.setText('') + cfg.dialog.ui.MC_ID_combo.clear() + cfg.dialog.ui.MC_Info_combo.clear() + cfg.dialog.ui.C_ID_combo.clear() + cfg.dialog.ui.C_Info_combo.clear() + layer = cfg.util_qgis.select_layer_by_name(reference_layer) + try: + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + f = layer.dataProvider().fields() + for i in f: + if str(i.typeName()).lower() != 'string': + cfg.dialog.reference_field_combo(str(i.name())) + except Exception as err: + return str(err) + + +# set vector symbology +def vector_symbol(layer, value_name_dictionary, value_color_dictionary): + symbol = QgsSymbol.defaultSymbol(layer.geometryType()) + symbol.setColor(QColor('#000000')) + classes = [ + QgsRendererCategory(0, symbol, '0 - ' + cfg.translate('Unclassified'))] + for value in value_name_dictionary: + symbol = QgsSymbol.defaultSymbol(layer.geometryType()) + symbol.setColor(QColor(value_color_dictionary[value])) + renderer = QgsRendererCategory( + value, symbol, '%s - %s' % ( + str(value), value_name_dictionary[value] + ) + ) + classes.append(renderer) + raster = QgsCategorizedSymbolRenderer('DN', classes) + layer.setRenderer(raster) + + +# set classification symbology +def classification_raster_symbol( + classification_layer, value_name_dictionary, value_color_dictionary +): + # class list value, color, name for ramp + class_list = [QgsPalettedRasterRenderer.Class( + 0, QColor('#000000'), '0 - ' + cfg.translate('Unclassified') + )] + for value in value_name_dictionary: + class_list.append( + QgsPalettedRasterRenderer.Class( + value, QColor(value_color_dictionary[value]), + '%s - %s' % (str(value), value_name_dictionary[value]) + ) + ) + # create the renderer + renderer = QgsPalettedRasterRenderer( + classification_layer.dataProvider(), 1, class_list + ) + # apply the renderer to classLayer + classification_layer.setRenderer(renderer) + # refresh legend + if hasattr(classification_layer, 'setCacheImage'): + classification_layer.setCacheImage(None) + classification_layer.triggerRepaint() + cfg.util_qgis.refresh_layer_symbology(classification_layer) + + +# Define raster symbology +def raster_symbol_generic( + raster_layer, nodata_tag='0', raster_unique_value_list=None +): + if raster_unique_value_list is None: + unique_value_list = raster_unique_value_list + else: + unique_value_list = raster_unique_value_list + try: + max_value = max(unique_value_list) + except Exception as err: + str(err) + max_value = 1 + # Color list for ramp + color_list = [QgsPalettedRasterRenderer.Class( + 0, QColor(0, 0, 0), nodata_tag + )] + for i in unique_value_list: + if i > max_value / 2: + c = QColor( + int(255 * (i / max_value)), + int(255 * (1 - (i / max_value))), + int(255 * (1 - (i / max_value))) + ) + color_list.append( + QgsPalettedRasterRenderer.Class(i, c, str(i)) + ) + elif i > 0: + c = QColor( + int(255 * (i / max_value)), + int(255 * (i / max_value)), + int(255 * (1 - (i / max_value))) + ) + color_list.append( + QgsPalettedRasterRenderer.Class(i, c, str(i)) + ) + # create the renderer + try: + renderer = QgsPalettedRasterRenderer( + raster_layer.dataProvider(), 1, color_list + ) + except Exception as err: + str(err) + renderer = None + # Apply the renderer to rasterLayer + raster_layer.setRenderer(renderer) + # refresh legend + if hasattr(raster_layer, 'setCacheImage'): + raster_layer.setCacheImage(None) + raster_layer.triggerRepaint() + cfg.util_qgis.refresh_layer_symbology(raster_layer) + + +""" process functions """ + + +# create value list from text +def text_to_value_list(text): + values = [] + if ',' in text: + commas = text.split(',') + elif '-' in text: + dashes = text.split('-') + for val in range(int(dashes[0]), int(dashes[-1]) + 1): + values.append(int(val)) + commas = [] + else: + values.append(int(text)) + commas = [] + for part in commas: + if '-' in part: + dashes = part.split('-') + for val in range(int(dashes[0]), int(dashes[-1]) + 1): + values.append(int(val)) + else: + values.append(int(part)) + return np.unique(values).tolist() + + +# check if the clicked point is inside the image +def check_point_in_image( + point, bandset_number=None, point_crs=None, + output_crs=None +): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + if band_count == 0: + return False + cfg.logger.log.debug( + 'point: %s; bandset_number: %s' % (str(point), str(bandset_number)) + ) + band_crs = str( + cfg.bandset_catalog.get_bandset(bandset_number).bands[0].crs + ) + band_left = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].left + band_top = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].top + band_right = cfg.bandset_catalog.get_bandset(bandset_number).bands[0].right + band_bottom = cfg.bandset_catalog.get_bandset(bandset_number).bands[ + 0].bottom + if point_crs is None: + point_crs = cfg.util_qgis.get_qgis_crs().toWkt() + cfg.logger.log.debug( + 'point_crs: %s; band_crs: %s' % (str(point_crs), str(band_crs)) + ) + if band_crs is not None and point_crs is not None: + if cfg.util_gdal.compare_crs(point_crs, band_crs) is False: + try: + # noinspection PyTypeChecker + point = project_qgis_point_coordinates( + point, point_crs, band_crs + ) + point_crs = band_crs + if point is False: + cfg.util_qgis.set_qgis_crs(band_crs) + cfg.logger.log.error('unable to project point') + return False + # Error latitude or longitude exceeded limits + except Exception as err: + cfg.logger.log.error(str(err)) + return False + if (point.x() > band_right or point.x() < band_left + or point.y() > band_top or point.y() < band_bottom): + cfg.logger.log.debug('point check failed') + return False + if output_crs is not None: + if cfg.util_gdal.compare_crs(point_crs, output_crs) is False: + try: + point = project_qgis_point_coordinates( + point, point_crs, output_crs + ) + if point is False: + cfg.logger.log.error('unable to project point') + return False + # Error latitude or longitude exceeded limits + except Exception as err: + cfg.logger.log.error(str(err)) + return False + cfg.logger.log.debug('point check successful') + return point + + +# Project point coordinates +def project_qgis_point_coordinates( + point, input_coordinates, output_coordinates +): + try: + # spatial reference + input_sr = osr.SpatialReference() + try: + input_sr.ImportFromWkt(input_coordinates.toWkt()) + except Exception as err: + input_sr.ImportFromWkt(input_coordinates) + str(err) + output_sr = osr.SpatialReference() + try: + output_sr.ImportFromWkt(output_coordinates.toWkt()) + except Exception as err: + output_sr.ImportFromWkt(output_coordinates) + str(err) + # required by GDAL 3 coordinate order + try: + input_sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) + output_sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) + except Exception as err: + str(err) + # Coordinate Transformation + transformation = osr.CoordinateTransformation(input_sr, output_sr) + point_proj = ogr.Geometry(ogr.wkbPoint) + point_proj.AddPoint(point.x(), point.y()) + point_proj.Transform(transformation) + point_qgis = cfg.util_qgis.create_qgis_point( + point_proj.GetX(), point_proj.GetY() + ) + return point_qgis + except Exception as err: + str(err) + return False + + +# calculate the distance between points in array +def pair_point_distance(numpy_array): + return cdist(numpy_array, numpy_array) + + +# calculate random points in grid +def random_points_in_grid(point_number, x_min, x_max, y_min, y_max): + x_coordinates = np.random.uniform(x_min, x_max, point_number) + y_coordinates = np.random.uniform(y_min, y_max, point_number) + points = list(zip(x_coordinates, y_coordinates)) + return points + + +# calculate random points with condition +def random_points_with_condition( + raster_path, point_number, condition, x_min, y_top +): + # get pixel size + x_size, y_size = cfg.util_gdal.get_pixel_size(raster_path) + points = [] + # band array + _array = cfg.util_gdal.read_raster(raster_path) + condition = condition.replace( + cfg.qgis_registry[cfg.reg_raster_variable_name], '_array' + ) + arr = np.argwhere(eval(condition)) + rng = np.random.default_rng() + try: + pixels = rng.choice(arr, size=point_number) + except Exception as err: + cfg.logger.log.error(str(err)) + return None + for pixel in pixels.tolist(): + points.append( + [x_min + pixel[1] * x_size + x_size / 2, + y_top - pixel[0] * y_size - y_size / 2] + ) + return points + + +# create KML from map +# noinspection SpellCheckingInspection +def create_kml_from_map(): + cfg.ui_utils.add_progress_bar() + cfg.ui_utils.update_bar(10) + ext1 = cfg.map_canvas.extent() + qgis_crs = cfg.util_qgis.get_qgis_crs() + crs_wgs_84 = QgsCoordinateReferenceSystem(4326) + cfg.util_qgis.set_qgis_crs(crs_wgs_84) + cfg.map_canvas.refreshAllLayers() + qApp.processEvents() + cfg.ui_utils.update_bar(30) + time.sleep(1) + qApp.processEvents() + ext = cfg.map_canvas.extent() + # date time for temp name + _time = get_time() + png = '%s/%sSCP_kml.png' % (cfg.temp_dir, _time) + kml = '%s/SCP_kml.kml' % cfg.temp_dir + cfg.map_canvas.setCanvasColor(Qt.transparent) + cfg.map_canvas.saveAsImage(png) + xml = ''' + + + %s + + %s + + + %.10f + %.10f + %.10f + %.10f + + + %.10f + %.10f + 5000 + + + + ''' + source = xml % ( + 'SCP_kml', '%sSCP_kml.png' % _time, ext.yMaximum(), ext.yMinimum(), + ext.xMaximum(), + ext.xMinimum(), (ext.xMaximum() + ext.xMinimum()) / 2, + (ext.yMinimum() + ext.yMaximum()) / 2) + layer = open(kml, 'w') + try: + layer.write(source) + layer.close() + except Exception as err: + str(err) + if check_file(kml): + if cfg.system_platform == 'Darwin': + subprocess.call(('open', kml)) + elif cfg.system_platform == 'Windows': + os.startfile(kml) + else: + subprocess.call(('xdg-open', kml)) + cfg.util_qgis.set_qgis_crs(qgis_crs) + cfg.map_canvas.setExtent(ext1) + cfg.map_canvas.refreshAllLayers() + cfg.ui_utils.update_bar(100) + cfg.ui_utils.remove_progress_bar() + + +""" raster color composite functions """ + + +# set RGB color composite +def set_rgb_color_composite(composite=None): + if ((len(cfg.rgb_combo.currentText()) > 0 + and cfg.rgb_combo.currentText() != '-') or composite is not None): + try: + if composite is None: + composite = cfg.rgb_combo.currentText() + cfg.logger.log.debug( + 'set_rgb_color_composite rgb: %s' % str(composite) + ) + if composite is not None: + check = create_rgb_color_composite(composite) + if check is True: + if composite not in cfg.project_registry[cfg.reg_rgb_list]: + cfg.project_registry[cfg.reg_rgb_list].append( + composite + ) + cfg.project_registry[cfg.reg_rgb_list] = list( + set(cfg.project_registry[cfg.reg_rgb_list]) + ) + cfg.rgb_composite.rgb_table_from_list( + cfg.project_registry[cfg.reg_rgb_list] + ) + return True + else: + return False + else: + return False + except Exception as err: + if 'string index' not in str(err): + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_4() + return False + + +# create RGB color composite +def create_rgb_color_composite(color_composite, bandset_number=None): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + cfg.logger.log.debug( + 'create_rgb_color_composite bandset: %s' % bandset_number + ) + virtual_raster_name = '%s %s' % ( + cfg.virtual_bandset_name, str(bandset_number)) + if bandset_number in cfg.virtual_bandset_dict: + layer = cfg.util_qgis.select_layer_by_name(virtual_raster_name, True) + else: + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + if band_count == 0: + cfg.logger.log.debug('empty bandset') + return False + # create temporary virtual raster + virtual_raster_path = cfg.bandset_catalog.create_virtual_raster( + bandset_number=bandset_number + ) + cfg.util_qgis.remove_layer_by_name(virtual_raster_name) + layer = cfg.iface.addRasterLayer( + virtual_raster_path, + virtual_raster_name + ) + # get band numbers + composite = str(color_composite).split(',') + if len(composite) == 1: + composite = str(color_composite).split('-') + if len(composite) == 1: + composite = str(color_composite).split(';') + if len(composite) == 1: + composite = str(color_composite) + if layer is None: + del cfg.virtual_bandset_dict[bandset_number] + cfg.logger.log.error('create_rgb_color_composite') + return False + elif len(composite) < 3: + cfg.logger.log.error('create_rgb_color_composite') + return False + else: + cfg.virtual_bandset_dict[bandset_number] = layer + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + count = bandset_x.get_band_count() + try: + if int(composite[0]) > count: + composite[0] = count + if int(composite[1]) > count: + composite[1] = count + if int(composite[2]) > count: + composite[2] = count + except Exception as err: + cfg.logger.log.error(str(err)) + return False + cfg.logger.log.error( + 'create_rgb_color_composite: %s-%s-%s' + % (str(composite[0]), str(composite[1]), str(composite[2])) + ) + qApp.processEvents() + cfg.util_qgis.set_raster_color_composite( + layer, int(composite[0]), int(composite[1]), int(composite[2]) + ) + return True + + +""" general functions """ + + +# read variables from project instance +def read_project_variables(): + for r in cfg.project_registry: + try: + cfg.project_registry[r] = cfg.util_qgis.read_project_variable( + r, cfg.project_registry[r] + ) + except Exception as err: + cfg.logger.log.debug('error: %s' % str(err)) + cfg.logger.log.debug('project_registry: %s' % str(cfg.project_registry)) + # set vegetation index calculation checkbox state + cfg.dock_class_dlg.ui.display_cursor_checkBox.setCheckState( + int(cfg.project_registry[cfg.reg_index_calculation_check]) + ) + # set custom index + cfg.dock_class_dlg.ui.custom_index_lineEdit.setText( + cfg.project_registry[cfg.reg_custom_index_calculation] + ) + # set RGB list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + # set signature calculation checkbox state + cfg.dock_class_dlg.ui.signature_checkBox.setCheckState( + int(cfg.project_registry[cfg.reg_signature_calculation_check]) + ) + cfg.dialog.ui.signature_checkBox2.setCheckState( + int(cfg.project_registry[cfg.reg_signature_calculation_check]) + ) + # set rapid ROI checkbox state + cfg.dock_class_dlg.ui.rapid_ROI_checkBox.setCheckState( + int(cfg.project_registry[cfg.reg_rapid_roi_check]) + ) + # set save training input + cfg.dock_class_dlg.ui.save_input_checkBox.setCheckState( + int(cfg.project_registry[cfg.reg_save_training_input_check]) + ) + # rapid ROI band + cfg.dock_class_dlg.ui.rapidROI_band_spinBox.setValue( + int(cfg.project_registry[cfg.reg_roi_main_band]) + ) + # max ROI width + cfg.max_roi_width_spin.setValue( + int(cfg.project_registry[cfg.reg_roi_max_width]) + ) + # min ROI size + cfg.roi_min_size_spin.setValue( + int(cfg.project_registry[cfg.reg_roi_min_size]) + ) + # ROI range radius + cfg.Range_radius_spin.setValue( + float(cfg.project_registry[cfg.reg_roi_range_radius]) + ) + # ROI class ID field + cfg.dock_class_dlg.ui.ROI_ID_spin.setValue( + int(cfg.project_registry[cfg.reg_roi_class_id]) + ) + # ROI class info field + cfg.dock_class_dlg.ui.ROI_Class_line.setText( + cfg.project_registry[cfg.reg_roi_class_name] + ) + # ROI macroclass ID field + cfg.dock_class_dlg.ui.ROI_Macroclass_ID_spin.setValue( + int(cfg.project_registry[cfg.reg_roi_macroclass_id]) + ) + # ROI macroclass info field + cfg.dock_class_dlg.ui.ROI_Macroclass_line.setText( + cfg.project_registry[cfg.reg_roi_macroclass_name] + ) + # restore active bandset number + active_bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + # bandset restore + for bandset_number in range( + 1, cfg.project_registry[cfg.reg_bandset_count] + 1 + ): + cfg.logger.log.debug('bandset restore: %s' % str(bandset_number)) + bandset_key = '%s%s' % (cfg.reg_bandset, bandset_number) + # import xml + xml_file = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.xml' + ) + xml = cfg.util_qgis.read_project_variable(bandset_key, '') + with open(xml_file, 'w') as output_file: + output_file.write(xml) + # add empty bandset + cfg.bst.add_band_set_tab(position=bandset_number) + try: + cfg.bandset_catalog.import_bandset_from_xml( + bandset_number=bandset_number, xml_path=xml_file + ) + except Exception as err: + str(err) + cfg.bst.band_set_to_table(bandset_number) + cfg.dialog.ui.bandset_number_spinBox.setValue(active_bandset_number) + # rgb list + cfg.rgb_composite.rgb_table_from_list( + cfg.project_registry[cfg.reg_rgb_list] + ) + # training path restore + if len(cfg.project_registry[cfg.reg_training_input_path]) > 0: + cfg.scp_dock.open_signature_catalog_file( + cfg.project_registry[cfg.reg_training_input_path], + cfg.project_registry[cfg.reg_training_bandset_number] + ) + # download table restore + cfg.download_products.open_download_table() + + +# find available RAM +# noinspection SpellCheckingInspection +def find_available_ram(): + try: + if cfg.system_platform == 'Windows': + class GlobalMemoryStatus(ctypes.Structure): + _fields_ = [ + ('length', ctypes.c_ulong), ('memoryLoad', ctypes.c_ulong), + ('totalRam', ctypes.c_ulong), + ('availPhys', ctypes.c_ulonglong), + ('totalPageFile', ctypes.c_ulonglong), + ('availPageFile', ctypes.c_ulonglong), + ('totalVirt', ctypes.c_ulonglong), + ('availVirt', ctypes.c_ulonglong), + ('availExVirt', ctypes.c_ulonglong) + ] + + memory_status = GlobalMemoryStatus() + ctypes.windll.kernel32.GlobalMemoryStatus( + ctypes.byref(memory_status) + ) + ram_value = memory_status.totalRam + cfg.qgis_registry[cfg.reg_ram_value] = int( + (ram_value / 1048576) / 2 + ) + elif cfg.system_platform == 'Darwin': + cfg.qgis_registry[cfg.reg_ram_value] = 2048 + else: + with open('/proc/meminfo') as info: + for line in info: + if line.startswith('MemTotal'): + ram_value = line.split()[1] + break + cfg.qgis_registry[cfg.reg_ram_value] = int( + (int(ram_value) / 1000) / 2 + ) + cfg.dialog.ui.RAM_spinBox.setValue( + cfg.qgis_registry[cfg.reg_ram_value] + ) + except Exception as err: + str(err) + + +# find available processors +def find_available_processors(): + try: + threads = os.cpu_count() + cfg.dialog.ui.CPU_spinBox.setValue(int((threads + 1) / 2)) + except Exception as err: + str(err) + cfg.dialog.ui.CPU_spinBox.setValue(2) + + +# numpy array from list +def numpy_array_from_list(values): + return np.array(values) + + +# get random integer +def random_integer(min, max): + return random.randint(min, max) + + +# get random color +def random_color(): + r = random.randint(0, 255) + g = random.randint(0, 255) + b = random.randint(0, 255) + return '#%02x%02x%02x' % (r, g, b) + + +# remove file +def remove_file(file_path): + os.remove(file_path) + + +# check if file exists +def check_file(file_path): + return os.path.isfile(file_path) + + +# get parent directory name +def directory_name(file_path): + return os.path.dirname(file_path) + + +# get base name +def base_name(file_path): + return os.path.basename(file_path) + + +# relative path +def absolute_to_relative(path, root=None): + p = Path(path) + try: + relative = p.relative_to(root) + except Exception as err: + str(err) + relative = p + return relative.as_posix() + + +# absolute path +def relative_to_absolute_path(path, root=None): + if root is None: + absolute = path + else: + absolute = '/'.join([root, path]).replace('\\', '/').replace( + '//', '/' + ).replace('/\\', '/').replace('//', '/') + return absolute + + +# Try to get GDAL for macOS +def get_gdal_path_for_mac(): + if cfg.system_platform == 'Darwin': + gdal_line = cfg.qgis_registry[cfg.reg_gdal_path] + if len(gdal_line) > 0: + cfg.qgis_registry[cfg.reg_gdal_path] = gdal_line.rstrip('/') + '/' + if not check_file( + cfg.qgis_registry[cfg.reg_gdal_path] + 'gdal_translate' + ): + cfg.qgis_registry[cfg.reg_gdal_path] = '' + else: + v = cfg.util_gdal.get_gdal_version() + cfg.qgis_registry[cfg.reg_gdal_path] = ( + '/Library/Frameworks/GDAL.framework/Versions/' + '%s.%s/Programs/' % (v[0], v[1]) + ) + if not check_file( + cfg.qgis_registry[cfg.reg_gdal_path] + 'gdal_translate' + ): + cfg.qgis_registry[cfg.reg_gdal_path] = '' diff --git a/debug/raster.tif b/debug/raster.tif old mode 100644 new mode 100755 diff --git a/debug/roi.cpg b/debug/roi.cpg deleted file mode 100644 index 746faa2..0000000 --- a/debug/roi.cpg +++ /dev/null @@ -1 +0,0 @@ -1250 \ No newline at end of file diff --git a/debug/roi.dbf b/debug/roi.dbf deleted file mode 100644 index 087f0f0..0000000 Binary files a/debug/roi.dbf and /dev/null differ diff --git a/debug/roi.prj b/debug/roi.prj deleted file mode 100644 index e6a08c2..0000000 --- a/debug/roi.prj +++ /dev/null @@ -1 +0,0 @@ -PROJCS["WGS_1984_UTM_Zone_33N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] \ No newline at end of file diff --git a/debug/roi.qpj b/debug/roi.qpj deleted file mode 100644 index ff53c94..0000000 --- a/debug/roi.qpj +++ /dev/null @@ -1 +0,0 @@ -PROJCS["WGS 84 / UTM zone 33N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32633"]] diff --git a/debug/roi.shp b/debug/roi.shp deleted file mode 100644 index 17551c2..0000000 Binary files a/debug/roi.shp and /dev/null differ diff --git a/debug/roi.shx b/debug/roi.shx deleted file mode 100644 index 706f228..0000000 Binary files a/debug/roi.shx and /dev/null differ diff --git a/debug/roi_raster.tif b/debug/roi_raster.tif deleted file mode 100644 index 5da612d..0000000 Binary files a/debug/roi_raster.tif and /dev/null differ diff --git a/dock/classificationpreview.py b/dock/classificationpreview.py deleted file mode 100644 index 31ed512..0000000 --- a/dock/classificationpreview.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassificationPreview(QgsMapTool): - - rightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - leftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(point) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.rightClicked.emit(pnt) - else: - self.leftClicked.emit(pnt) - - def keyPressEvent(self, event): - if event.key()==(cfg.QtSCP.Key_Control): - pass \ No newline at end of file diff --git a/dock/manualroi.py b/dock/manualroi.py deleted file mode 100644 index be4094d..0000000 --- a/dock/manualroi.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ManualROI(QgsMapTool): - - rightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - leftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(pnt) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.rightClicked.emit(pnt) - else: - self.leftClicked.emit(pnt) - - def keyPressEvent(self, event): - if event.key()==(cfg.QtSCP.Key_Control): - cfg.ctrlClick = 1 - elif event.key()==(cfg.QtSCP.Key_Control and cfg.QtSCP.Key_Z): - #cfg.ctrlClick = 0 - cfg.SCPD.deleteLastROI() - - \ No newline at end of file diff --git a/dock/regionroi.py b/dock/regionroi.py deleted file mode 100644 index 8159a23..0000000 --- a/dock/regionroi.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class RegionROI(QgsMapTool): - - ROIrightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - ROIleftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(point) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.ROIrightClicked.emit(pnt) - else: - self.ROIleftClicked.emit(pnt) - - def keyPressEvent(self, event): - if event.key()==(cfg.QtSCP.Key_Control): - cfg.ctrlClick = 1 - elif event.key()==(cfg.QtSCP.Key_Control and cfg.QtSCP.Key_Z): - #cfg.ctrlClick = 0 - cfg.SCPD.deleteLastROI() diff --git a/dock/scpdock.py b/dock/scpdock.py deleted file mode 100644 index 935dddc..0000000 --- a/dock/scpdock.py +++ /dev/null @@ -1,2982 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SCPDock: - - def __init__(self): - cfg.shpLay = None - cfg.shpLayList = [] - cfg.shpLayListCounter = 1 - cfg.uidc.undo_save_Button.setEnabled(False) - cfg.uidc.redo_save_Button.setEnabled(False) - # rubber band - cfg.rbbrBnd = cfg.qgisGuiSCP.QgsRubberBand(cfg.cnvs, cfg.qgisCoreSCP.QgsWkbTypes.LineGeometry) - cfg.rbbrBnd.setColor(cfg.QtGuiSCP.QColor(0,255,255)) - cfg.rbbrBnd.setWidth(2) - cfg.mrctrVrtc = [] - self.clearCanvas() - - # set preview transparency - def changePreviewTransparency(self, value): - try: - l = cfg.utls.selectLayerbyName(cfg.lastPrev) - if l is not None: - cfg.cnvs.setRenderFlag(False) - l.renderer().setOpacity(float(1) - float(value) / 100) - if hasattr(l, 'setCacheImage'): - l.setCacheImage(None) - l.triggerRepaint() - cfg.cnvs.setRenderFlag(True) - cfg.cnvs.refresh() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # show hide preview radio button 2 - def showHidePreview2(self): - try: - l = cfg.utls.selectLayerbyName(cfg.lastPrev) - if l is not None: - if cfg.show_preview_radioButton2.isChecked(): - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - else: - cfg.utls.setLayerVisible(l, False) - except: - pass - - # left click pointer for classification preview - def pointerClickPreview(self, point): - # check if other processes are active - if cfg.actionCheck == 'No': - cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if cfg.pntCheck == 'Yes': - cfg.pntPrvw = cfg.lstPnt - self.algRasterPrevw = 'No' - cfg.classTab.createPreview(cfg.pntPrvw, self.algRasterPrevw ) - - # right click pointer for preview algorithm raster - def pointerRightClickPreview(self, point): - # check if other processes are active - if cfg.actionCheck == 'No': - point = cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if cfg.pntCheck == 'Yes': - cfg.pntPrvw = cfg.lstPnt - self.algRasterPrevw = 'Yes' - cfg.classTab.createPreview(cfg.pntPrvw, self.algRasterPrevw) - - # Activate pointer for classification preview - def pointerPreviewActive(self): - # connect to click - t = cfg.classPrev - cfg.cnvs.setMapTool(t) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "pointer active: preview") - - # set preview size - def previewSize(self): - cfg.prvwSz = int(float(cfg.preview_size_spinBox.value())) - cfg.utls.writeProjectVariable("previewSize", str(cfg.prvwSz)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "preview size: " + str(cfg.prvwSz)) - - # redo preview - def redoPreview(self): - # check if other processes are active - if cfg.actionCheck == 'No': - if cfg.pntPrvw is None: - pass - else: - cfg.classTab.createPreview(cfg.pntPrvw, self.algRasterPrevw) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "REDO Preview") - - # set all items to state 0 or 2 - def allItemsSetState(self, value, selected = None): - tW = cfg.uidc.signature_list_treeWidget - tW.setSortingEnabled(False) - tW.blockSignals(True) - if selected is None: - for id, val in cfg.treeDockItm.items(): - if cfg.actionCheck == 'Yes': - cfg.treeDockItm[str(id)].setCheckState(0, value) - cfg.signList['CHECKBOX_' + str(id)] = cfg.treeDockItm[str(id)].checkState(0) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' cancelled') - break - else: - for i in tW.selectedItems(): - if cfg.actionCheck == 'Yes': - # classes - if len(i.text(1)) > 0: - try: - i.setCheckState(0, value) - cfg.signList['CHECKBOX_' + str(i.text(5))] = cfg.treeDockItm[str(i.text(5))].checkState(0) - except: - pass - # macroclasses - else: - count = i.childCount() - for roi in range(0, count): - try: - i.child(roi).setCheckState(0, value) - cfg.signList['CHECKBOX_' + str(i.child(roi).text(5))] = cfg.treeDockItm[str(i.child(roi).text(5))].checkState(0) - except: - pass - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' cancelled') - break - tW.setSortingEnabled(True) - tW.blockSignals(False) - - # select all signatures - def selectAllSignatures(self, check = None, selected = None): - cfg.uiUtls.addProgressBar() - try: - # select all - if check is True: - cfg.SCPD.allItemsSetState(2, selected) - # unselect all - else: - cfg.SCPD.allItemsSetState(0, selected) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' all signatures') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.uiUtls.removeProgressBar() - - # export signature list to file - def saveSignatureList(self, signatureFile): - try: - root = cfg.ETSCP.Element('signaturelist') - MCID_LIST = cfg.SCPD.exportMCIDList() - root.set('MCID_LIST', str(MCID_LIST)) - for k in list(cfg.signIDs.values()): - sigItem = cfg.ETSCP.SubElement(root, 'signature') - sigItem.set('ID', str(cfg.signIDs['ID_' + str(k)])) - mcIDField = cfg.ETSCP.SubElement(sigItem, 'MACROCLASSID') - mcIDField.text = str(cfg.signList['MACROCLASSID_' + str(k)]) - mcInfoField = cfg.ETSCP.SubElement(sigItem, 'MACROCLASSINFO') - mcInfoField.text = str(cfg.signList['MACROCLASSINFO_' + str(k)]) - cIDField = cfg.ETSCP.SubElement(sigItem, 'CLASSID') - cIDField.text = str(cfg.signList['CLASSID_' + str(k)]) - cInfoField = cfg.ETSCP.SubElement(sigItem, 'CLASSINFO') - cInfoField.text = str(cfg.signList['CLASSINFO_' + str(k)]) - wvLngField = cfg.ETSCP.SubElement(sigItem, 'VALUES') - wvLngField.text = str(cfg.signList['VALUES_' + str(k)]) - lcsMinField = cfg.ETSCP.SubElement(sigItem, 'LCS_MIN') - lcsMinField.text = str(cfg.signList['LCS_MIN_' + str(k)]) - lcsMaxField = cfg.ETSCP.SubElement(sigItem, 'LCS_MAX') - lcsMaxField.text = str(cfg.signList['LCS_MAX_' + str(k)]) - wvLngField = cfg.ETSCP.SubElement(sigItem, 'WAVELENGTH') - wvLngField.text = str(cfg.signList['WAVELENGTH_' + str(k)]) - meanValField = cfg.ETSCP.SubElement(sigItem, 'MEAN_VALUE') - meanValField.text = str(cfg.signList['MEAN_VALUE_' + str(k)]) - checkboxField = cfg.ETSCP.SubElement(sigItem, 'CHECKBOX') - checkboxField.text = str(cfg.signList['CHECKBOX_' + str(k)]) - SDField = cfg.ETSCP.SubElement(sigItem, 'SD') - SDField.text = str(cfg.signList['SD_' + str(k)]) - unitField = cfg.ETSCP.SubElement(sigItem, 'WAVELENGTH_UNIT') - unitField.text = str(cfg.signList['UNIT_' + str(k)]) - colorField = cfg.ETSCP.SubElement(sigItem, 'COLOR') - colorField.text = str(cfg.signList['COLOR_' + str(k)].toRgb().name()) - covMatrField = cfg.ETSCP.SubElement(sigItem, 'COVARIANCE_MATRIX') - covMatrField.text = str(cfg.utls.covarianceMatrixToList(cfg.signList['COVMATRIX_' + str(k)])) - roiSizeField = cfg.ETSCP.SubElement(sigItem, 'ROI_SIZE') - roiSizeField.text = str(cfg.signList['ROI_SIZE_' + str(k)]) - maxValField = cfg.ETSCP.SubElement(sigItem, 'MAX_VALUE') - maxValField.text = str(cfg.signList['MAX_VALUE_' + str(k)]) - minValField = cfg.ETSCP.SubElement(sigItem, 'MIN_VALUE') - minValField.text = str(cfg.signList['MIN_VALUE_' + str(k)]) - sigThrField = cfg.ETSCP.SubElement(sigItem, 'SIGNATURE_THRESHOLD_MD') - sigThrField.text = str(cfg.signList['MD_THRESHOLD_' + str(k)]) - sigThrField = cfg.ETSCP.SubElement(sigItem, 'SIGNATURE_THRESHOLD_ML') - sigThrField.text = str(cfg.signList['ML_THRESHOLD_' + str(k)]) - sigThrField = cfg.ETSCP.SubElement(sigItem, 'SIGNATURE_THRESHOLD_SAM') - sigThrField.text = str(cfg.signList['SAM_THRESHOLD_' + str(k)]) - o = open(signatureFile, 'w') - f = cfg.minidomSCP.parseString(cfg.ETSCP.tostring(root)).toprettyxml() - o.write(f) - o.close() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures saved in: ' + str(signatureFile)) - except Exception as err: - cfg.mx.msgErr15() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - def openSignatureList(self, path = None): - if path is None: - signFilePath = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a signature list file'), '', 'Signature list file .slf (*.slf)') - else: - signFilePath = path - if len(signFilePath) > 0: - if cfg.absolutePath == 'false': - signFile = cfg.utls.qgisAbsolutePathToRelativePath(signFilePath, cfg.projPath) - else: - signFile = signFilePath - self.openSignatureListFile(signFilePath) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures opened: ' + str(signFilePath)) - - # open training file - def openTrainingFile(self): - scpPath = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a SCP training input'), '', 'SCP file (*.scp)') - if len(scpPath) > 0: - cfg.signList = {} - cfg.signIDs = {} - cfg.SCPD.openInput(scpPath) - - # open input - def openInput(self, scpPath = None): - # shape layer - cfg.shpLay = None - # training layer name - cfg.trnLay = None - # signature file path - cfg.sigFile = None - cfg.inptDir = None - if scpPath is None: - scpPath = cfg.utls.readProjectVariable('trainingLayer', '') - check = cfg.SCPD.openShapeFile(scpPath) - if check == 'Yes': - cfg.utls.writeProjectVariable('trainingLayer', str(scpPath)) - cfg.scpFlPath = scpPath - cfg.uidc.trainingFile_lineEdit.setText(str(scpPath)) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " signatures opened: " + str(scpPath)) - else: - cfg.SCPD.resetShapeList() - cfg.uidc.undo_save_Button.setEnabled(False) - cfg.uidc.redo_save_Button.setEnabled(False) - # training layer name - cfg.trnLay = None - # signature file path - cfg.sigFile = None - cfg.inptDir = None - cfg.uidc.trainingFile_lineEdit.setText('') - - # open input file - def openShapeFile(self, shapeFilePath): - # shapefile - name = cfg.utls.fileNameNoExt(shapeFilePath) - dT = cfg.utls.getTime() - cfg.inptDir = cfg.tmpDir + '/' + name + dT - oDir = cfg.utls.makeDirectory(cfg.inptDir) - nm = '' - # unzip to temp dir - try: - with cfg.zipfileSCP.ZipFile(shapeFilePath) as zOpen: - for flName in zOpen.namelist(): - zipF = zOpen.open(flName) - fileName = cfg.utls.fileName(flName) - if fileName.endswith('.gpkg') or fileName.endswith('.shp') : - nm = fileName - try: - zipO = open(cfg.inptDir + '/' + fileName, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - except Exception as err: - return 'No' - # try to remove SCP input - try: - # issue in QGIS 3.18 - #cfg.utls.removeLayer(name) - pass - except: - pass - # convert to geopackage - if nm.endswith('.shp'): - try: - nm2 = nm[:-3] + 'gpkg' - v = cfg.utls.mergeAllLayers([cfg.inptDir + '/' + nm], cfg.inptDir + '/' + nm2) - nm = nm2 - except: - pass - if not cfg.osSCP.path.isfile(cfg.inptDir + '/' + nm): - cfg.mx.msgErr59() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error training input') - return 'No' - try: - tSS = cfg.utls.addVectorLayer(cfg.inptDir + '/' + nm) - except: - cfg.mx.msgErr59() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error training input') - return 'No' - check = cfg.SCPD.checkFields(tSS) - vCrs = cfg.utls.getCrsGDAL(cfg.inptDir + '/' + nm) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - try: - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][0]) - ql = cfg.utls.layerSource(b) - rCrs = cfg.utls.getCrsGDAL(ql) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - else: - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8]) - ql = cfg.utls.layerSource(b) - rCrs = cfg.utls.getCrsGDAL(ql) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - rEPSG = None - #return 'No' - try: - if vEPSG.IsSame(rEPSG) != 1: - cfg.mx.msgWar22() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if check == 'Yes': - # create memory layer - provider = tSS.dataProvider() - fields = provider.fields().toList() - pCrs = cfg.utls.getCrs(tSS) - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), name, 'memory') - mL2 = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), dT, 'memory') - mL.setCrs(pCrs) - mL2.setCrs(pCrs) - pr = mL.dataProvider() - pr2 = mL2.dataProvider() - pr.addAttributes(fields) - pr2.addAttributes(fields) - mL.updateFields() - mL2.updateFields() - f = cfg.qgisCoreSCP.QgsFeature() - mL.startEditing() - mL2.startEditing() - for f in tSS.getFeatures(): - mL.addFeature(f) - mL2.addFeature(f) - mL.commitChanges() - mL2.commitChanges() - mL.dataProvider().createSpatialIndex() - mL2.dataProvider().createSpatialIndex() - mL.updateExtents() - mL2.updateExtents() - cfg.utls.ROISymbol(mL) - cfg.shpLay = mL - cfg.trnLay = name - cfg.utls.addLayerToMap(cfg.shpLay) - sigFileNm = cfg.trnLay + '.slf' - cfg.sigFile = cfg.inptDir + '/' + sigFileNm - sigFile = cfg.sigFile - for root, dirs, files in cfg.osSCP.walk(cfg.inptDir): - for x in files: - if x.lower().endswith('.slf'): - sigFile = root + '/' + x - break - break - if cfg.osSCP.path.isfile(sigFile): - cfg.SCPD.openSignatureList(sigFile) - else: - cfg.SCPD.saveSignatureList(cfg.sigFile) - cfg.mx.msg20() - cfg.SCPD.openSignatureList(cfg.sigFile) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(False) - cfg.uidc.redo_save_Button.setEnabled(False) - return check - - # save memory layer to shapefile - def saveMemToSHP(self, memoryLayer): - dT = cfg.utls.getTime() - try: - cfg.inptDir = cfg.tmpDir + '/' + cfg.trnLay + dT - except Exception as err: - cfg.mx.msgErr59() - cfg.inptDir = cfg.tmpDir + '/' + dT - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error training input') - return 'No' - oDir = cfg.utls.makeDirectory(cfg.inptDir) - shpF = cfg.inptDir + '/' + cfg.trnLay + '.gpkg' - l = cfg.utls.saveMemoryLayerToShapefile(memoryLayer, shpF, cfg.trnLay, format = 'GPKG') - if l == 'No': - cfg.SCPD.openInput() - return 'No' - tSS = cfg.shpLay - # create memory layer - try: - provider = tSS.dataProvider() - except Exception as err: - cfg.mx.msgErr59() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error training input') - return 'No' - fields = provider.fields().toList() - pCrs = cfg.utls.getCrs(tSS) - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), cfg.trnLay, 'memory') - mL2 = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), dT, 'memory') - mL.setCrs(pCrs) - mL2.setCrs(pCrs) - pr = mL.dataProvider() - pr2 = mL2.dataProvider() - pr.addAttributes(fields) - pr2.addAttributes(fields) - mL.updateFields() - mL2.updateFields() - f = cfg.qgisCoreSCP.QgsFeature() - mL.startEditing() - mL2.startEditing() - for f in tSS.getFeatures(): - mL.addFeature(f) - mL2.addFeature(f) - mL.commitChanges() - mL2.commitChanges() - mL.dataProvider().createSpatialIndex() - mL2.dataProvider().createSpatialIndex() - mL.updateExtents() - mL2.updateExtents() - cfg.utls.ROISymbol(mL) - try: - cfg.utls.removeLayerByLayer(cfg.shpLay) - except: - pass - cfg.shpLay = mL - cfg.utls.addLayerToMap(cfg.shpLay) - sigFileNm = cfg.trnLay + '.slf' - cfg.sigFile = cfg.inptDir + '/' + sigFileNm - cfg.SCPD.saveSignatureList(cfg.sigFile) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - - # reset shape list - def resetShapeList(self): - for i in range(0, len(cfg.shpLayList)): - try: - cfg.utls.removeLayerByLayer(cfg.shpLayList[i][0]) - except: - pass - try: - cfg.shpLayList.pop(i) - except: - pass - # shape layer - cfg.shpLay = None - cfg.shpLayList = [] - cfg.shpLayListCounter = 1 - - # manage shape list - def manageShapeList(self, memoryLayer, sigFile): - try: - for sK in range(1, cfg.shpLayListCounter): - cfg.shpLayList.pop(-sK) - except: - pass - cfg.shpLayList.append([memoryLayer, sigFile]) - cfg.shpLayListCounter = 1 - if len(cfg.shpLayList) > 10: - try: - cfg.utls.removeLayerByLayer(cfg.shpLayList[0][0]) - except: - pass - try: - cfg.shpLayList.pop(0) - except: - pass - - # check shapefile and fields - def checkFields(self, trainingLayer): - try: - if (trainingLayer.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon): - # filter if shapefile has ID_class and ROI_info fields - f = trainingLayer.dataProvider().fields() - if f.indexFromName(cfg.fldID_class) > -1 and f.indexFromName(cfg.fldROI_info) > -1 and f.indexFromName(cfg.fldMacroID_class) > -1 and f.indexFromName(cfg.fldROIMC_info) > -1 and f.indexFromName(cfg.fldSCP_UID) > -1: - return 'Yes' - else: - # ask for confirm - a = cfg.utls.questionBox('Missing fields in shapefile', 'Add missing fields to shapefile?') - if a == 'Yes': - cfg.SCPD.addFieldsToLayer(trainingLayer) - f = trainingLayer.dataProvider().fields() - if f.indexFromName(cfg.fldID_class) > -1 and f.indexFromName(cfg.fldROI_info) > -1 and f.indexFromName(cfg.fldMacroID_class) > -1 and f.indexFromName(cfg.fldROIMC_info) > -1 and f.indexFromName(cfg.fldSCP_UID) > -1: - return 'Yes' - else: - return 'No' - else: - return 'No' - except Exception as err: - return 'No' - - # Add required fields if missing - def addFieldsToLayer(self, layer): - f = [] - fi = layer.dataProvider().fields() - # add fields - if fi.indexFromName(cfg.fldID_class) == -1: - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldID_class, cfg.QVariantSCP.Int)) - if fi.indexFromName(cfg.fldROI_info) == -1: - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROI_info, cfg.QVariantSCP.String)) - if fi.indexFromName(cfg.fldMacroID_class) == -1: - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldMacroID_class, cfg.QVariantSCP.Int)) - if fi.indexFromName(cfg.fldROIMC_info) == -1: - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROIMC_info, cfg.QVariantSCP.String)) - if fi.indexFromName(cfg.fldSCP_UID) == -1: - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldSCP_UID, cfg.QVariantSCP.String)) - layer.startEditing() - aF = layer.dataProvider().addAttributes(f) - # commit changes - layer.commitChanges() - layer.dataProvider().createSpatialIndex() - layer.updateExtents() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' fields added') - - # import SLC signature list - def importSLCSignatureList(self, signatureFile, addToSignature = 'No'): - # shapefile - name = cfg.utls.fileNameNoExt(signatureFile) - dT = cfg.utls.getTime() - unzipDir = cfg.tmpDir + '/' + name + dT - oDir = cfg.utls.makeDirectory(unzipDir) - # unzip to temp dir - try: - with cfg.zipfileSCP.ZipFile(signatureFile) as zOpen: - for flName in zOpen.namelist(): - if flName.endswith('.gpkg') or flName.endswith('.shp') : - nm = cfg.utls.fileNameNoExt(flName) - zipF = zOpen.open(flName) - fileName = cfg.utls.fileName(flName) - zipO = open(unzipDir + '/' + fileName, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - except: - return 'No' - shpF = unzipDir + '/' + nm + '.gpkg' - if not cfg.osSCP.path.isfile(shpF): - shpF = unzipDir + '/' + nm + '.shp' - sigFile = unzipDir + '/' + nm + '.slf' - sL = cfg.utls.createTempRasterPath('gpkg') - s = cfg.utls.saveMemoryLayerToShapefile(cfg.shpLay, sL, format = 'GPKG') - tVect = cfg.utls.createTempRasterPath('gpkg') - inputLayersList = [sL, shpF] - v = cfg.utls.mergeAllLayers(inputLayersList, tVect) - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - try: - tSS = cfg.utls.addVectorLayer(tVect) - except: - cfg.mx.msgErr59() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error training input') - return 'No' - # try to remove SCP input - try: - cfg.utls.removeLayerByLayer(cfg.shpLay) - except: - pass - # create memory layer - provider = tSS.dataProvider() - fields = provider.fields().toList() - pCrs = cfg.utls.getCrs(tSS) - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), cfg.trnLay , 'memory') - mL.setCrs(pCrs) - pr = mL.dataProvider() - pr.addAttributes(fields) - mL.updateFields() - fldSCP_UID = cfg.utls.fieldID(tSS, cfg.fldSCP_UID) - f = cfg.qgisCoreSCP.QgsFeature() - mL.startEditing() - UIDList = [] - for f in tSS.getFeatures(): - UID = f.attributes()[fldSCP_UID] - if UID not in UIDList: - mL.addFeature(f) - UIDList.append(UID) - mL.commitChanges() - mL.dataProvider().createSpatialIndex() - mL.updateExtents() - cfg.utls.ROISymbol(mL) - cfg.shpLay = mL - cfg.utls.addLayerToMap(cfg.shpLay) - cfg.SCPD.openSignatureListFile(sigFile, addToSignature) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - - # open signature file - def openSignatureListFile(self, signatureFile, addToSignature = 'No'): - try: - tree = cfg.ETSCP.parse(signatureFile) - root = tree.getroot() - if addToSignature == 'No': - cfg.signList = {} - cfg.signIDs = {} - try: - MCID_LIST = root.get('MCID_LIST') - MC_List = eval(MCID_LIST) - newList = [] - idList = [] - for k in cfg.MCID_List: - idList.append(k[0]) - newList.append(k) - for k in MC_List: - if k[0] not in idList: - idList.append(k[0]) - newList.append(k) - cfg.MCID_List = newList - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - for child in root: - try: - b = child.get('ID') - if len(b) == 0: - b = cfg.utls.signatureID() - except: - b = cfg.utls.signatureID() - cfg.signList['MACROCLASSID_' + str(b)] = str(child.find('MACROCLASSID').text).strip() - cfg.signList['MACROCLASSINFO_' + str(b)] = str(child.find('MACROCLASSINFO').text).strip() - cfg.signList['CLASSID_' + str(b)] = str(child.find('CLASSID').text).strip() - cfg.signList['CLASSINFO_' + str(b)] = str(child.find('CLASSINFO').text).strip() - cfg.signList['UNIT_' + str(b)] = str(child.find('WAVELENGTH_UNIT').text).strip() - cfg.signList['ROI_SIZE_' + str(b)] = str(child.find('ROI_SIZE').text).strip() - cfg.signIDs['ID_' + str(b)] = b - # get values - vls = str(child.find('VALUES').text).strip().replace('nan', '0') - x = eval(vls) - cfg.signList['VALUES_' + str(b)] = x - try: - lcsMin = str(child.find('LCS_MIN').text).strip() - min = eval(lcsMin) - cfg.signList['LCS_MIN_' + str(b)] = min - lcsMax = str(child.find('LCS_MAX').text).strip() - max = eval(lcsMax) - cfg.signList['LCS_MAX_' + str(b)] = max - except: - cfg.signList['LCS_MIN_' + str(b)] = x - cfg.signList['LCS_MAX_' + str(b)] = x - try: - minV = str(child.find('MIN_VALUE').text).strip() - minVal = eval(minV) - cfg.signList['MIN_VALUE_' + str(b)] = minVal - maxV = str(child.find('MAX_VALUE').text).strip() - maxVal = eval(maxV) - cfg.signList['MAX_VALUE_' + str(b)] = maxVal - except: - cfg.signList['MIN_VALUE_' + str(b)] = x - cfg.signList['MAX_VALUE_' + str(b)] = x - cfg.signList['WAVELENGTH_' + str(b)] = eval(str(child.find('WAVELENGTH').text).strip()) - cfg.signList['SD_' + str(b)] = eval(str(child.find('SD').text).strip().replace('nan', '0')) - cfg.signList['MEAN_VALUE_' + str(b)] = eval(str(child.find('MEAN_VALUE').text).strip().replace('nan', '0')) - try: - cfg.signList['CHECKBOX_' + str(b)] = eval(str(child.find('CHECKBOX').text).strip()) - except: - cfg.signList['CHECKBOX_' + str(b)] = 2 - c = cfg.QtGuiSCP.QColor() - c.setNamedColor(str(child.find('COLOR').text).strip()) - cfg.signList['COLOR_' + str(b)] = c - # get covariance matrix - mt = str(child.find('COVARIANCE_MATRIX').text).strip() - try: - cm = eval(mt) - except: - cm = 'No' - cfg.signList['COVMATRIX_' + str(b)] = cfg.utls.listToCovarianceMatrix(cm) - try: - cfg.signList['MD_THRESHOLD_' + str(b)] = float((child.find('SIGNATURE_THRESHOLD_MD').text).strip()) - except: - cfg.signList['MD_THRESHOLD_' + str(b)] = 0 - try: - cfg.signList['ML_THRESHOLD_' + str(b)] = float((child.find('SIGNATURE_THRESHOLD_ML').text).strip()) - except: - cfg.signList['ML_THRESHOLD_' + str(b)] = 0 - try: - cfg.signList['SAM_THRESHOLD_' + str(b)] = float((child.find('SIGNATURE_THRESHOLD_SAM').text).strip()) - except: - cfg.signList['SAM_THRESHOLD_' + str(b)] = 0 - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' opened signature ' + str(len(cfg.signIDs))) - except Exception as err: - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.mx.msgErr16() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # export signature to file - def exportSignatureFile(self): - sL = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export SCP training input'), '', '*.scp', 'scp') - if sL is not False: - # create vector - crs = cfg.shpLay.crs() - f = cfg.qgisCoreSCP.QgsFields() - # add Class ID, macroclass ID and Info fields - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldMacroID_class, cfg.QVariantSCP.Int)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROIMC_info, cfg.QVariantSCP.String)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldID_class, cfg.QVariantSCP.Int)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldROI_info, cfg.QVariantSCP.String)) - f.append(cfg.qgisCoreSCP.QgsField(cfg.fldSCP_UID, cfg.QVariantSCP.String)) - # vector - name = cfg.utls.fileNameNoExt(sL) - dT = cfg.utls.getTime() - unzipDir = cfg.tmpDir + '/' + name + dT - shpF = unzipDir + '/' + name + '.gpkg' - sigFile = unzipDir + '/' + name + '.slf' - oDir = cfg.utls.makeDirectory(unzipDir) - cfg.qgisCoreSCP.QgsVectorFileWriter(str(shpF), 'CP1250', f, cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon , crs, 'GPKG') - tSS = cfg.utls.addVectorLayer(shpF, name + dT, 'ogr') - signIDorig = cfg.signIDs.copy() - cfg.signIDs = {} - tW = cfg.uidc.signature_list_treeWidget - v = [] - for i in tW.selectedItems(): - # classes - if len(i.text(1)) > 0: - try: - id = i.text(5) - cfg.ROI_C_ID[id] - cfg.signIDs['ID_' + str(id)] = id - v.append(id) - except: - pass - # macroclasses - else: - count = i.childCount() - for roi in range(0, count): - try: - id = i.child(roi).text(5) - cfg.ROI_C_ID[id] - cfg.signIDs['ID_' + str(id)] = id - v.append(id) - except: - pass - if len(v) == 0: - for id, val in cfg.treeDockItm.items(): - cfg.signIDs['ID_' + str(id)] = id - v.append(id) - self.saveSignatureList(sigFile) - cfg.signIDs = signIDorig.copy() - f = cfg.qgisCoreSCP.QgsFeature() - tSS.startEditing() - for f in cfg.shpLay.getFeatures(): - SCP_UID = str(f[cfg.fldSCP_UID]) - if SCP_UID in v: - tSS.addFeature(f) - tSS.commitChanges() - tSS.dataProvider().createSpatialIndex() - tSS.updateExtents() - # create zip file - cfg.utls.zipDirectoryInFile(sL, unzipDir) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures exported in: ' + str(sL)) - cfg.mx.msg27() - - # export signature to shapefile - def exportSignatureShapefile(self): - sL = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export SCP training input'), '', 'SHP file (*.shp);;GPKG file (*.gpkg)', None) - if sL is not False: - crs = cfg.utls.getCrs(cfg.shpLay) - if str(sL).endswith('.shp'): - format = 'ESRI Shapefile' - elif str(sL).endswith('.gpkg'): - format = 'GPKG' - else: - sL = sL + '.gpkg' - format = 'GPKG' - # filter IDs - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('Yes') - s = cfg.utls.saveMemoryLayerToShapefile(cfg.shpLay, sL, format = format, IDList = v, listFieldName = cfg.fldSCP_UID) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures exported in: ' + str(sL)) - cfg.mx.msg27() - - # get highlighted IDs - def getHighlightedIDs(self, selectAll = None, signatures = None): - # filter IDs - tW = cfg.uidc.signature_list_treeWidget - v = [] - for i in tW.selectedItems(): - # classes - if len(i.text(1)) > 0: - try: - cfg.ROI_C_ID[i.text(5)] - v.append(i.text(5)) - except: - if signatures == 'Yes': - try: - cfg.signIDs['ID_' + i.text(5)] - v.append(i.text(5)) - except: - pass - # macroclasses - else: - count = i.childCount() - for roi in range(0, count): - try: - cfg.ROI_C_ID[i.child(roi).text(5)] - v.append(i.child(roi).text(5)) - except: - if signatures == 'Yes': - try: - cfg.signIDs['ID_' + i.child(roi).text(5)] - v.append(i.child(roi).text(5)) - except: - pass - if len(v) == 0 and selectAll == 'Yes': - for id, val in cfg.treeDockItm.items(): - v.append(id) - return v - - # save signature to file - def saveSignatureListToFile(self): - try: - cfg.SCPD.saveSignatureList(cfg.sigFile) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures saved in: ' + str(cfg.sigFile)) - except Exception as err: - cfg.mx.msgErr15() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # open signature file - def openLibraryFile(self, libraryFile): - try: - if cfg.bandSetsList[cfg.bndSetNumber][5] == cfg.noUnit: - cfg.mx.msgWar8() - libFileList = cfg.utls.getOpenFileNames(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a library file'), '', 'SCP file (*.scp);;USGS library (*.zip);;ASTER library (*.txt);;CSV (*.csv)') - if len(libFileList) > 0: - for libFile in libFileList: - cfg.uiUtls.addProgressBar() - if libFile.lower().endswith('.zip'): - libraryR, libraryW, libraryS = cfg.usgsLib.unzipLibrary(libFile) - cfg.sigImport.USGSLibrary(libraryR, libraryW, libraryS) - elif libFile.lower().endswith('.txt'): - cfg.sigImport.ASTERLibrary(libFile) - elif libFile.lower().endswith('.csv'): - cfg.sigImport.CSVLibrary(libFile) - elif libFile.lower().endswith('.scp'): - self.importSLCSignatureList(libFile, 'Yes') - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' spectral library ' + str(libFile)) - cfg.mx.msg28() - except Exception as err: - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar8() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # export signatures to CSV library - def exportToCSVLibrary(self): - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('Yes', 'Yes') - if len(v) > 0: - d = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export the highlighted signatures to CSV library')) - if len(d) > 0: - for id in v: - mID = cfg.signList['MACROCLASSID_' + str(id)] - mC = cfg.signList['MACROCLASSINFO_' + str(id)] - cID = cfg.signList['CLASSID_' + str(id)] - c = cfg.signList['CLASSINFO_' + str(id)] - signFile = d + '/' + str(mID) + '_' + str(mC) + '_' + str(cID) + '_' + str(c) + str('.csv') - # open file - l = open(signFile, 'w') - try: - l.write('wavelength;reflectance;standardDeviation;waveLengthUnit \n') - l.close() - except Exception as err: - cfg.mx.msgErr18() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - u = str(cfg.signList['UNIT_' + str(id)]) - # wavelength - a = str(cfg.signList['WAVELENGTH_' + str(id)]) - wlg = eval(a) - # signature values - n = str(cfg.signList['VALUES_' + str(id)]) - val = eval(n) - # open file - l = open(signFile, 'a') - for k in range(0, len(wlg)): - wl = wlg[k] - vl = val[k*2] - sD = val[k*2 + 1] - line = str(wl) + ';' + str(vl) + ';' + str(sD) + ';' + str(u) + '\n' - try: - l.write(line) - except Exception as err: - cfg.mx.msgErr18() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - l.close() - cfg.mx.msg27() - - # zoom to preview - def zoomToPreview(self): - preP = cfg.utls.selectLayerbyName(cfg.lastPrev) - if preP is not None: - cfg.utls.setMapExtentFromLayer(preP) - preP.triggerRepaint() - cfg.cnvs.refresh() - -################################## - ''' Table functions ''' -################################## - - # calculate signatures - def calculateSignatures(self): - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('No') - if len(v) == 0: - return 0 - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate signatures'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate signatures for highlighted items?')) - if a == 'Yes': - cfg.uiUtls.addProgressBar() - progresStep = 100 / len(v) - progress = 0 - for id in v: - progress = progress * progresStep - # if ROI - if str(id) in list(cfg.ROI_SCP_UID.values()): - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, cfg.ROI_MC_ID[id], cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.ROI_C_Info[id], progress, progresStep, 'No', 'No', id) - if id in list(cfg.signPlotIDs.values()): - cfg.SCPD.sigListToPlot(id) - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - if cfg.saveInputCheck == '2': - cfg.SCPD.saveMemToSHP(cfg.shpLay) - cfg.utls.zipDirectoryInFile(cfg.scpFlPath, cfg.inptDir) - else: - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - cfg.uiUtls.removeProgressBar() - - # merge highlighted signatures - def mergeSelectedSignatures(self): - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('No') - if len(set(v)) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Merge signatures'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Merge highlighted signatures?')) - if a == 'Yes': - cfg.uiUtls.addProgressBar() - wl = [] - val = [] - min = [] - max = [] - vmin = [] - vmax = [] - unit = [] - covMat = [] - ids = [] - ROIcheck = [] - for id in v: - # if ROI - if str(id) in list(cfg.ROI_SCP_UID.values()): - ifd = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - ids.append(ifd[0]) - ROIcheck.append(1) - else: - ROIcheck.append(0) - # if not signatue - if str(id) not in list(cfg.signIDs.values()): - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, cfg.ROI_MC_ID[id], cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.ROI_C_Info[id], None, None, 'No', 'No', id) - if len(wl) == 0: - wl = cfg.signList['WAVELENGTH_' + str(id)] - unit = cfg.signList['UNIT_' + str(id)] - MC_ID = cfg.signList['MACROCLASSID_' + str(id)] - MC_Info = cfg.merged_name + cfg.signList['MACROCLASSINFO_' + str(id)] - C_ID = cfg.signList['CLASSID_' + str(id)] - C_Info = cfg.merged_name + cfg.signList['CLASSINFO_' + str(id)] - color = cfg.signList['COLOR_' + str(id)] - checkbox = cfg.signList['CHECKBOX_' + str(id)] - sigThr = cfg.signList['MD_THRESHOLD_' + str(id)] - sigThrML = cfg.signList['ML_THRESHOLD_' + str(id)] - sigThrSAM = cfg.signList['SAM_THRESHOLD_' + str(id)] - elif wl != cfg.signList['WAVELENGTH_' + str(id)] or unit != cfg.signList['UNIT_' + str(id)]: - cfg.mx.msgErr35() - return 'No' - val.append(cfg.signList['VALUES_' + str(id)]) - min.append(cfg.signList['LCS_MIN_' + str(id)]) - max.append(cfg.signList['LCS_MAX_' + str(id)]) - vmin.append(cfg.signList['MIN_VALUE_' + str(id)]) - vmax.append(cfg.signList['MAX_VALUE_' + str(id)]) - covMat.append(cfg.signList['COVMATRIX_' + str(id)]) - i = cfg.utls.signatureID() - # if ROIs - if 0 not in ROIcheck: - oFid = cfg.shpLay.fields().indexFromName('fid') - mFid = cfg.shpLay.maximumValue(oFid) + 1 - if mFid < 1: - mFid = 1 - attributeList = [mFid, cfg.ROI_MC_ID[id], cfg.merged_name + cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.merged_name + cfg.ROI_C_Info[id], i] - tl = cfg.utls.mergePolygons(cfg.shpLay, ids, attributeList) - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(i)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, cfg.ROI_MC_ID[id], cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.ROI_C_Info[id], None, None, 'No', 'No', i) - else: - covMatrixSum = 0 - try: - for cvm in covMat: - covMatrixSum = covMatrixSum + cvm - covMatrix = covMatrixSum / len(covMat) - cfg.np.linalg.inv(covMatrix) - except: - covMatrix = 'No' - cfg.uiUtls.updateBar(10) - # calculate mean - vals = cfg.np.array(val) - val_mean = cfg.np.mean(vals, axis=0).tolist() - mins = cfg.np.array(min) - min_mean = cfg.np.mean(mins, axis=0).tolist() - maxs = cfg.np.array(max) - max_mean = cfg.np.mean(maxs, axis=0).tolist() - vmins = cfg.np.array(vmin) - vmin_mean = cfg.np.mean(vmins, axis=0).tolist() - vmaxs = cfg.np.array(vmax) - vmaxs_mean = cfg.np.mean(vmaxs, axis=0).tolist() - # add spectral signature - cfg.signList['CHECKBOX_' + str(i)] = cfg.QtSCP.Checked - cfg.signList['MACROCLASSID_' + str(i)] = MC_ID - cfg.signList['MACROCLASSINFO_' + str(i)] = MC_Info - cfg.signList['CLASSID_' + str(i)] = C_ID - cfg.signList['CLASSINFO_' + str(i)] = C_Info - cfg.signList['WAVELENGTH_' + str(i)] = wl - cfg.signList['VALUES_' + str(i)] = val_mean - cfg.signList['LCS_MIN_' + str(i)] = min_mean - cfg.signList['LCS_MAX_' + str(i)] = max_mean - cfg.signList['MIN_VALUE_' + str(i)] = vmin_mean - cfg.signList['MAX_VALUE_' + str(i)] = vmaxs_mean - cfg.signList['ROI_SIZE_' + str(i)] = 0 - cfg.signList['COVMATRIX_' + str(i)] = covMatrix - cfg.signList['MD_THRESHOLD_' + str(i)] = sigThr - cfg.signList['ML_THRESHOLD_' + str(i)] = sigThrML - cfg.signList['SAM_THRESHOLD_' + str(i)] = sigThrSAM - # counter - n = 0 - m = [] - sdL = [] - for wi in wl: - m.append(val_mean[n * 2]) - sdL.append(val_mean[n * 2 +1]) - n = n + 1 - cfg.signList['MEAN_VALUE_' + str(i)] = m - cfg.signList['SD_' + str(i)] = sdL - if unit is None: - unit = cfg.bandSetsList[cfg.bndSetNumber][5] - cfg.signList['UNIT_' + str(i)] = unit - cfg.signList['COLOR_' + str(i)] = color - cfg.signIDs['ID_' + str(i)] = i - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - if cfg.saveInputCheck == '2': - cfg.SCPD.saveMemToSHP(cfg.shpLay) - cfg.utls.zipDirectoryInFile(cfg.scpFlPath, cfg.inptDir) - else: - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' merged signatures: ' + str(v)) - - # remove selected signatures - def removeSelectedSignatures(self): - tW = cfg.uidc.signature_list_treeWidget - selected = tW.selectedItems() - if len(selected) > 0: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Delete signatures'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to delete highlighted ROIs and signatures?')) - if a == 'Yes': - ids = [] - for i in tW.selectedItems(): - # classes - if i.text(5) in list(cfg.signIDs.values()): - cfg.SCPD.deleteSignatureByID(i.text(5)) - if i.text(5) in list(cfg.ROI_SCP_UID.values()): - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(i.text(5))) - for rI in rId: - ids.append(rI) - # macroclasses - if i.text(5) in cfg.treeDockMCItm: - c = cfg.treeDockMCItm[i.text(5)] - for x in range(0, c.childCount()): - if c.child(x).text(5) in list(cfg.signIDs.values()): - cfg.SCPD.deleteSignatureByID(c.child(x).text(5)) - if c.child(x).text(5) in list(cfg.ROI_SCP_UID.values()): - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(c.child(x).text(5))) - for rI in rId: - ids.append(rI) - if cfg.shpLay is not None: - cfg.utls.deleteFeatureShapefile(cfg.shpLay, ids) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - if cfg.saveInputCheck == '2': - cfg.SCPD.saveMemToSHP(cfg.shpLay) - cfg.utls.zipDirectoryInFile(cfg.scpFlPath, cfg.inptDir) - else: - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' removed signatures: ' + str(ids)) - - # delete signature by ID - def deleteSignatureByID(self, id): - cfg.signIDs.pop('ID_' + str(id)) - cfg.signList.pop('MACROCLASSID_' + str(id)) - cfg.signList.pop('MACROCLASSINFO_' + str(id)) - cfg.signList.pop('CLASSID_' + str(id)) - cfg.signList.pop('CLASSINFO_' + str(id)) - cfg.signList.pop('WAVELENGTH_' + str(id)) - try: - cfg.signList.pop('MEAN_VALUE_' + str(id)) - cfg.signList.pop('SD_' + str(id)) - except: - pass - cfg.signList.pop('VALUES_' + str(id)) - cfg.signList.pop('LCS_MIN_' + str(id)) - cfg.signList.pop('LCS_MAX_' + str(id)) - cfg.signList.pop('MIN_VALUE_' + str(id)) - cfg.signList.pop('MAX_VALUE_' + str(id)) - cfg.signList.pop('ROI_SIZE_' + str(id)) - cfg.signList.pop('COLOR_' + str(id)) - cfg.signList.pop('UNIT_' + str(id)) - cfg.signList.pop('COVMATRIX_' + str(id)) - cfg.signList.pop('MD_THRESHOLD_' + str(id)) - cfg.signList.pop('ML_THRESHOLD_' + str(id)) - cfg.signList.pop('SAM_THRESHOLD_' + str(id)) - try: - cfg.signList.pop('CHECKBOX' + str(id)) - except: - pass - try: - cfg.signList.pop('LCS_ROW' + str(id)) - except: - pass - try: - cfg.scaPlT.removeScatterByID(id) - cfg.scaPlT.scatterPlotListTable(cfg.uiscp.scatter_list_plot_tableWidget) - except: - pass - - # add signatures to spectral plot - def addSignatureToSpectralPlot(self, tabIndex = 0): - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('No', 'Yes') - check = 'Yes' - if len(v) > 0: - progresStep = 100 / len(v) - progress = 0 - cfg.uiUtls.addProgressBar() - for id in v: - progress = progress * progresStep - if id in list(cfg.signIDs.values()): - if id not in list(cfg.signPlotIDs.values()): - cfg.SCPD.sigListToPlot(id) - else: - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, cfg.ROI_MC_ID[id], cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.ROI_C_Info[id], progress, progresStep, 'No', 'No', id) - cfg.SCPD.sigListToPlot(id) - check = 'No' - cfg.uiUtls.removeProgressBar() - if check == 'No': - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.utls.spectralPlotTab() - cfg.utls.selectSpectralPlotTabSettings(tabIndex) - else: - cfg.utls.spectralPlotTab() - cfg.utls.selectSpectralPlotTabSettings(tabIndex) - - # add ROI to scatter plot - def addROIToScatterPlot(self): - tW = cfg.uidc.signature_list_treeWidget - v = cfg.SCPD.getHighlightedIDs('No') - if len(v) > 0: - progresStep = 100 / len(v) - progress = 0 - cfg.uiUtls.addProgressBar() - for id in v: - progress = progress * progresStep - if str(id) in list(cfg.ROI_SCP_UID.values()): - h = cfg.utls.calculateScatterPlot(cfg.shpLay, cfg.fldSCP_UID, str(id)) - # add ROI to scatter plot table - cfg.scaPlT.sigListToScatterPlot(id, h, [cfg.scatterBandX, cfg.scatterBandY]) - cfg.scaPlT.scatterPlotListTable(cfg.uiscp.scatter_list_plot_tableWidget) - cfg.utls.scatterPlotTab() - cfg.uiUtls.removeProgressBar() - else: - cfg.utls.scatterPlotTab() - - # signature list to plot list - def sigListToPlot(self, id): - try: - cfg.signPlotIDs['ID_' + str(id)] = id - cfg.spectrPlotList['MACROCLASSID_' + str(id)] = cfg.signList['MACROCLASSID_' + str(id)] - cfg.spectrPlotList['MACROCLASSINFO_' + str(id)] = cfg.signList['MACROCLASSINFO_' + str(id)] - cfg.spectrPlotList['CLASSID_' + str(id)] = cfg.signList['CLASSID_' + str(id)] - cfg.spectrPlotList['CLASSINFO_' + str(id)] = cfg.signList['CLASSINFO_' + str(id)] - cfg.spectrPlotList['VALUES_' + str(id)] = cfg.signList['VALUES_' + str(id)] - cfg.spectrPlotList['ROI_SIZE_' + str(id)] = cfg.signList['ROI_SIZE_' + str(id)] - cfg.spectrPlotList['MIN_VALUE_' + str(id)] = cfg.signList['MIN_VALUE_' + str(id)] - cfg.spectrPlotList['MAX_VALUE_' + str(id)] = cfg.signList['MAX_VALUE_' + str(id)] - cfg.spectrPlotList['LCS_MIN_' + str(id)] = cfg.signList['LCS_MIN_' + str(id)] - cfg.spectrPlotList['LCS_MAX_' + str(id)] = cfg.signList['LCS_MAX_' + str(id)] - cfg.spectrPlotList['WAVELENGTH_' + str(id)] = cfg.signList['WAVELENGTH_' + str(id)] - cfg.spectrPlotList['MEAN_VALUE_' + str(id)] = cfg.signList['MEAN_VALUE_' + str(id)] - cfg.spectrPlotList['SD_' + str(id)] = cfg.signList['SD_' + str(id)] - cfg.spectrPlotList['COLOR_' + str(id)] = cfg.signList['COLOR_' + str(id)] - cfg.spectrPlotList['CHECKBOX_' + str(id)] = 2 - cfg.spectrPlotList['UNIT_' + str(id)] = cfg.signList['UNIT_' + str(id)] - cfg.spectrPlotList['COVMATRIX_' + str(id)] = cfg.signList['COVMATRIX_' + str(id)] - cfg.spectrPlotList['MD_THRESHOLD_' + str(id)] = cfg.signList['MD_THRESHOLD_' + str(id)] - cfg.spectrPlotList['ML_THRESHOLD_' + str(id)] = cfg.signList['ML_THRESHOLD_' + str(id)] - cfg.spectrPlotList['SAM_THRESHOLD_' + str(id)] = cfg.signList['SAM_THRESHOLD_' + str(id)] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg3() - - # get all ROI attributes - def getROIAttributes(self, layer): - l = layer - cfg.ROI_MC_ID = {} - cfg.ROI_MC_Info = {} - cfg.ROI_C_ID = {} - cfg.ROI_C_Info = {} - cfg.ROI_Count = {} - cfg.ROI_ShapeID = {} - cfg.ROI_SCP_UID = {} - cfg.treeDockItm = {} - cfg.treeDockMCItm = {} - if l is not None: - i = 0 - for f in l.getFeatures(): - id = f.id() - SCP_UID = str(f[cfg.fldSCP_UID]) - try: - cfg.ROI_SCP_UID[SCP_UID]= SCP_UID - cfg.ROI_MC_ID[SCP_UID]= str(f[cfg.fldMacroID_class]) - cfg.ROI_MC_Info[SCP_UID] = str(f[cfg.fldROIMC_info]) - cfg.ROI_C_ID[SCP_UID] = str(f[cfg.fldID_class]) - cfg.ROI_C_Info[SCP_UID] = str(f[cfg.fldROI_info]) - cfg.ROI_Count[SCP_UID]= str(i) - cfg.ROI_ShapeID[SCP_UID]= str(id) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg3() - i = i + 1 - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ROI attributes') - - # add item to tree - def addTreeItem(self, tree, textList, color = None, checkboxState = None, tooltip = None, foreground = None, bold = None): - mc = textList[0] - mcInfo = textList[1] - row = tree.topLevelItemCount() - cfg.treeDockMCItm[str(mc)] = cfg.QTreeWidgetItemSCP(row) - tree.addTopLevelItem(cfg.treeDockMCItm[str(mc)]) - cfg.treeDockMCItm[str(mc)].setFlags(cfg.QtSCP.ItemIsEditable | cfg.QtSCP.ItemIsEnabled | cfg.QtSCP.ItemIsSelectable | cfg.QtSCP.ItemIsDropEnabled) - cfg.treeDockMCItm[str(mc)].setExpanded(True) - cfg.treeDockMCItm[str(mc)].setData(0, 0, int(mc)) - cfg.treeDockMCItm[str(mc)].setData(2, 0, str(mcInfo)) - cfg.treeDockMCItm[str(mc)].setData(5, 0, int(mc)) - font = cfg.QtGuiSCP.QFont() - font.setBold(True) - cfg.treeDockMCItm[str(mc)].setFont(0, font) - cfg.treeDockMCItm[str(mc)].setFont(2, font) - if checkboxState is not None: - cfg.treeDockMCItm[str(mc)].setCheckState(column, checkboxState) - if color is not None: - cfg.treeDockMCItm[str(mc)].setBackground(4, color) - -# add item to tree - def addChildTreeItem(self, tree, textList, color = None, checkboxState = None): - mc = textList[0] - mcInfo = textList[1] - cId = textList[2] - cInfo = textList[3] - type = textList[4] - k = textList[5] - cfg.treeDockItm[str(k)] = cfg.QTreeWidgetItemSCP() - try: - cfg.treeDockMCItm[str(mc)].addChild(cfg.treeDockItm[str(k)]) - except: - cfg.SCPD.addTreeItem(tree, [mc, mcInfo], color = color) - cfg.treeDockMCItm[str(mc)].addChild(cfg.treeDockItm[str(k)]) - cfg.treeDockItm[str(k)].setFlags(cfg.QtSCP.ItemIsEditable | cfg.QtSCP.ItemIsEnabled | cfg.QtSCP.ItemIsUserCheckable | cfg.QtSCP.ItemIsSelectable | cfg.QtSCP.ItemIsDragEnabled) - if checkboxState is not None: - cfg.treeDockItm[str(k)].setCheckState(0, checkboxState) - cfg.treeDockItm[str(k)].setData(0, 0, int(mc)) - cfg.treeDockItm[str(k)].setData(1, 0, int(cId)) - cfg.treeDockItm[str(k)].setData(2, 0, str(cInfo)) - cfg.treeDockItm[str(k)].setData(3, 0, str(type)) - cfg.treeDockItm[str(k)].setData(5, 0, str(k)) - if color is not None: - cfg.treeDockItm[str(k)].setBackground(4, color) - - # clear tree - def clearTree(self, tree = None): - if tree is None: - order = 0 - sorter = cfg.QtSCP.AscendingOrder - else: - order = tree.header().sortIndicatorOrder() - sorter = tree.header().sortIndicatorSection() - tree.deleteLater() - cfg.uidc.signature_list_treeWidget = cfg.QtWidgetsSCP.QTreeWidget(cfg.uidc.tab_2) - cfg.uidc.signature_list_treeWidget.setEditTriggers(cfg.QtWidgetsSCP.QAbstractItemView.AnyKeyPressed|cfg.QtWidgetsSCP.QAbstractItemView.SelectedClicked) - cfg.uidc.signature_list_treeWidget.setAlternatingRowColors(True) - cfg.uidc.signature_list_treeWidget.setSelectionMode(cfg.QtWidgetsSCP.QAbstractItemView.MultiSelection) - cfg.uidc.signature_list_treeWidget.setIndentation(5) - cfg.uidc.signature_list_treeWidget.setExpandsOnDoubleClick(False) - cfg.uidc.signature_list_treeWidget.setObjectName('signature_list_treeWidget') - cfg.uidc.gridLayout.addWidget(cfg.uidc.signature_list_treeWidget, 1, 1, 1, 1) - cfg.uidc.signature_list_treeWidget.setSortingEnabled(True) - cfg.uidc.signature_list_treeWidget.headerItem().setText(0, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'MC ID')) - cfg.uidc.signature_list_treeWidget.headerItem().setText(1, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'C ID')) - cfg.uidc.signature_list_treeWidget.headerItem().setText(2, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Name')) - cfg.uidc.signature_list_treeWidget.headerItem().setText(3, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Type')) - cfg.uidc.signature_list_treeWidget.headerItem().setText(4, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Color')) - cfg.uidc.signature_list_treeWidget.headerItem().setText(5, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SCPID')) - # tree list - cfg.uidc.signature_list_treeWidget.header().hideSection(5) - cfg.uidc.signature_list_treeWidget.header().setSortIndicator(sorter, order) - cfg.utls.setTreeColumnWidthList(cfg.uidc.signature_list_treeWidget, [[0, 60], [1, 30], [2, 100], [3, 40], [4, 30]]) - # connect to edited cell - cfg.uidc.signature_list_treeWidget.itemChanged.connect(cfg.SCPD.editedCellTree) - # connect to signature list double click - cfg.uidc.signature_list_treeWidget.itemDoubleClicked.connect(cfg.SCPD.signatureListDoubleClickTree) - # context menu - cfg.uidc.signature_list_treeWidget.setContextMenuPolicy(cfg.QtCoreSCP.Qt.CustomContextMenu) - cfg.uidc.signature_list_treeWidget.customContextMenuRequested.connect(cfg.SCPD.contextMenu) - return cfg.uidc.signature_list_treeWidget - - # add item to menu - def addMenuItem(self, menu, function, iconName, name, tooltip = ''): - try: - action = cfg.QtWidgetsSCP.QAction(cfg.QtGuiSCP.QIcon(':/plugins/semiautomaticclassificationplugin/icons/' + iconName), name, cfg.iface.mainWindow()) - except: - action = cfg.QtWidgetsSCP.QAction(name, cfg.iface.mainWindow()) - action.setObjectName('action') - action.setToolTip(tooltip) - action.triggered.connect(function) - menu.addAction(action) - return action - - # menu - def contextMenu(self, event): - #index = cfg.uidc.signature_list_treeWidget.indexAt(event) - #cfg.itemMenu = cfg.uidc.signature_list_treeWidget.itemAt(event) - #cfg.uidc.signature_list_treeWidget.setCurrentItem(cfg.itemMenu) - m = cfg.QtWidgetsSCP.QMenu() - m.setToolTipsVisible(True) - zoomToMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.zoomToMenu, 'semiautomaticclassificationplugin_zoom_to_ROI.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zoom to'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Zoom to highlighted items')) - selectAllMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.selectAllMenu, 'semiautomaticclassificationplugin_batch_check.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Check/uncheck'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Check/uncheck highlighted items')) - clearSelectionMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.clearSelectionMenu, 'semiautomaticclassificationplugin_select_all.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clear selection'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clear selection of highlighted items')) - collapseMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.collapseMenu, 'semiautomaticclassificationplugin_docks.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Collapse/expand all'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Collapse/expand all macroclasses')) - m.addSeparator() - changeMacroclassMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.changeMacroclassMenu, 'semiautomaticclassificationplugin_enter.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change MC ID'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change MC ID for highlighted items')) - changeColorMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.changeColorMenu, 'semiautomaticclassificationplugin_enter.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change color'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change color for highlighted items')) - m.addSeparator() - mergeSignaturesMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.mergeSelectedSignatures, 'semiautomaticclassificationplugin_merge_sign_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Merge items'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Merge highlighted items')) - calculateSignaturesMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.calculateSignatures, 'semiautomaticclassificationplugin_add_sign_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate signatures'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate signatures for highlighted items')) - deleteSignaturesMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.removeSelectedSignatures, 'semiautomaticclassificationplugin_delete_signature.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Delete items'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Delete highlighted items')) - m.addSeparator() - addSignaturesPlotMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.addSignatureToSpectralPlot, 'semiautomaticclassificationplugin_sign_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Add to spectral plot'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Add highlighted items to spectral plot')) - addScatterPlotMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.addROIToScatterPlot, 'semiautomaticclassificationplugin_scatter_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Add to scatter plot'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Add highlighted items to scatter plot')) - propertiesMenu = cfg.SCPD.addMenuItem(m, cfg.SCPD.propertiesMenu, 'semiautomaticclassificationplugin_accuracy_tool.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Properties'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Properties for highlighted items')) - m.addSeparator() - importMenu = cfg.SCPD.addMenuItem(m, cfg.utls.importSignaturesTab, 'semiautomaticclassificationplugin_import_spectral_library.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Import spectral signatures')) - exportMenu = cfg.SCPD.addMenuItem(m, cfg.utls.exportSignaturesTab, 'semiautomaticclassificationplugin_export_spectral_library.svg', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export highlighted items')) - m.exec_(cfg.uidc.signature_list_treeWidget.mapToGlobal(event)) - - # properties menu - def propertiesMenu(self): - cfg.SCPD.addSignatureToSpectralPlot(1) - - # collaps menu - def collapseMenu(self): - try: - if cfg.collapseDock == True: - cfg.uidc.signature_list_treeWidget.collapseAll() - cfg.collapseDock = False - else: - cfg.uidc.signature_list_treeWidget.expandAll() - cfg.collapseDock = True - except: - cfg.uidc.signature_list_treeWidget.collapseAll() - cfg.collapseDock = False - - # change macroclass menu - def changeMacroclassMenu(self): - if len(cfg.uidc.signature_list_treeWidget.selectedItems()) > 0: - mc = cfg.ROIMacroID - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change Macroclass ID'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change the Macroclass ID for highlighted items to ') + str(mc) + ' ?') - if a == 'Yes': - for i in cfg.uidc.signature_list_treeWidget.selectedItems(): - # classes - if len(i.text(1)) > 0: - id = i.text(5) - cfg.signList['MACROCLASSID_' + str(id)] = mc - if id in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_MC_ID[id] = mc - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldMacroID_class, mc) - # macroclasses - else: - count = i.childCount() - for roi in reversed(range(0, count)): - idC = i.child(roi).text(5) - cfg.signList['MACROCLASSID_' + str(idC)] = mc - if idC in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_MC_ID[idC] = mc - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(idC)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldMacroID_class, mc) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - - # change color menu - def changeColorMenu(self): - if len(cfg.uidc.signature_list_treeWidget.selectedItems()) > 0: - c = cfg.utls.selectColor() - if c is not None: - r = [] - for i in cfg.uidc.signature_list_treeWidget.selectedItems(): - id = i.text(5) - try: - cfg.treeDockItm[str(id)].setBackground(4, c) - cfg.signList['COLOR_' + str(id)] = c - except: - pass - try: - cfg.treeDockMCItm[str(id)].setBackground(4, c) - cfg.SCPD.roiMacroclassInfoCompleter() - except: - pass - - # clear selection menu - def clearSelectionMenu(self): - cfg.uidc.signature_list_treeWidget.clearSelection() - - # zoom to menu - def zoomToMenu(self): - id = cfg.SCPD.getHighlightedIDs('No', 'No') - cfg.SCPD.zoomToROI(id) - - # select all menu - def selectAllMenu(self): - for i in cfg.uidc.signature_list_treeWidget.selectedItems(): - # classes - if len(i.text(1)) > 0: - try: - v = cfg.signList['CHECKBOX_' + str(i.text(5))] - break - except: - pass - # macroclasses - else: - count = i.childCount() - for roi in range(0, count): - try: - v = cfg.signList['CHECKBOX_' + str(i.child(roi).text(5))] - break - except: - pass - try: - cfg.SCPD.selectAllSignatures(check = not v, selected = True) - except: - pass - - # Create ROI list - def ROIListTableTree(self, layer, tree, checkstate=0): - l = self.clearTree(tree) - # get ROIs - cfg.SCPD.getROIAttributes(layer) - l.blockSignals(True) - l.setSortingEnabled(False) - try: - # macroclasses - for k in cfg.MCID_List: - try: - if k[2] is None: - c, cc = cfg.utls.randomColor() - k[2] = c - except: - c, cc = cfg.utls.randomColor() - k[2] = c - cfg.SCPD.addTreeItem(l, [k[0], k[1]], color = cfg.QtGuiSCP.QColor(k[2])) - # ROIs - for k in sorted(cfg.ROI_SCP_UID.values()): - if str(k) in list(cfg.signIDs.values()): - cfg.SCPD.addChildTreeItem(l, [int(float(cfg.ROI_MC_ID[k])), str(cfg.ROI_MC_Info[k]), int(float(cfg.ROI_C_ID[k])), str(cfg.ROI_C_Info[k]), cfg.ROISigTypeNm, k], checkboxState = cfg.signList['CHECKBOX_' + str(k)], color = cfg.signList['COLOR_' + str(k)]) - # for signature list coherence - try: - cfg.signList['MACROCLASSID_' + str(k)] = int(float(cfg.ROI_MC_ID[k])) - except: - cfg.signList['MACROCLASSID_' + str(k)] = int(0) - cfg.signList['MACROCLASSINFO_' + str(k)] = str(cfg.ROI_MC_Info[k]) - try: - cfg.signList['CLASSID_' + str(k)] = int(float(cfg.ROI_C_ID[k])) - except: - cfg.signList['CLASSID_' + str(k)] = int(0) - cfg.signList['CLASSINFO_' + str(k)] = str(cfg.ROI_C_Info[k]) - else: - try: - cfg.SCPD.addChildTreeItem(l, [int(float(cfg.ROI_MC_ID[k])), str(cfg.ROI_MC_Info[k]), int(float(cfg.ROI_C_ID[k])), str(cfg.ROI_C_Info[k]), cfg.ROITypeNm, k], checkboxState = cfg.signList['CHECKBOX_' + str(k)]) - except: - cfg.SCPD.addChildTreeItem(l, [int(float(cfg.ROI_MC_ID[k])), str(cfg.ROI_MC_Info[k]), int(float(cfg.ROI_C_ID[k])), str(cfg.ROI_C_Info[k]), cfg.ROITypeNm, k], checkboxState = cfg.QtSCP.Checked) - # for signature list coherence - try: - cfg.signList['MACROCLASSID_' + str(k)] = int(float(cfg.ROI_MC_ID[k])) - except: - cfg.signList['MACROCLASSID_' + str(k)] = int(0) - cfg.signList['MACROCLASSINFO_' + str(k)] = str(cfg.ROI_MC_Info[k]) - try: - cfg.signList['CLASSID_' + str(k)] = int(float(cfg.ROI_C_ID[k])) - except: - cfg.signList['CLASSID_' + str(k)] = int(0) - cfg.signList['CLASSINFO_' + str(k)] = str(cfg.ROI_C_Info[k]) - cfg.signList['CHECKBOX_' + str(k)] = 2 - cfg.signList['COLOR_' + str(k)] = cfg.QtGuiSCP.QColor(255, 255, 225) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr43() - # signature - for k in sorted(cfg.signIDs.values()): - if str(k) not in list(cfg.ROI_SCP_UID.values()): - cfg.SCPD.addChildTreeItem(l, [int(cfg.signList['MACROCLASSID_' + str(k)]), str(cfg.signList['MACROCLASSINFO_' + str(k)]), int(cfg.signList['CLASSID_' + str(k)]), str(cfg.signList['CLASSINFO_' + str(k)]), cfg.SIGTypeNm, k], checkboxState = cfg.signList['CHECKBOX_' + str(k)], color = cfg.signList['COLOR_' + str(k)]) - l.show() - l.setSortingEnabled(True) - l.blockSignals(False) - cfg.SCPD.exportMCIDList() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.signT.signatureThresholdListTable() - # info completer - cfg.SCPD.roiInfoCompleter() - cfg.SCPD.roiMacroclassInfoCompleter() - - # filter tree - def filterTree(self): - try: - text = cfg.uidc.ROI_filter_lineEdit.text() - t = cfg.uidc.signature_list_treeWidget - r = t.invisibleRootItem() - t.blockSignals(True) - if len(text)>0: - t.expandAll() - items = t.findItems(text, cfg.QtSCP.MatchContains) - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - for x in range(0, c.childCount()): - if text.lower() in c.child(x).text(2).lower(): - c.child(x).setHidden(False) - else: - c.child(x).setHidden(True) - else: - t.expandAll() - for i in range(0, r.childCount()): - c = r.child(i) - c.setHidden(False) - for x in range(0, c.childCount()): - if text in c.child(x).text(0): - c.child(x).setHidden(False) - t.blockSignals(False) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - -################################## - ''' Interface functions ''' -################################## - - # right click ROI pointer for pixel signature - def pointerRightClickROI(self, point): - if cfg.ctrlClick == 1: - bandSetNumList = list(range(0, len(cfg.bandSetsList))) - else: - bandSetNumList = [cfg.bndSetNumber] - for i in bandSetNumList: - point = cfg.utls.checkPointImage(cfg.bandSetsList[i][8], point) - if cfg.pntCheck == 'Yes': - cfg.utls.calculatePixelSignature(point, cfg.bandSetsList[i][8], i, 'Yes') - cfg.ctrlClick = None - - # zoom to ROI - def zoomToTempROI(self): - if cfg.lstROI is not None: - cfg.utls.setMapExtentFromLayer(cfg.lstROI) - - # create a ROI in the same point - def redoROI(self): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '>>> REDO ROI creation') - # check if other processes are active - if cfg.actionCheck == 'No': - if cfg.pntROI is None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'REDO ROI fail: no point') - pass - else: - self.createROI(cfg.pntROI) - # logger - cfg.utls.logCondition('redoROI ' + cfg.utls.lineOfCode(), '<<< REDO ROI creation') - - # show hide ROI radio button - def showHideROI(self): - try: - if cfg.show_ROI_radioButton.isChecked(): - if cfg.shpLay is not None: - cfg.utls.setLayerVisible(cfg.shpLay, True) - cfg.utls.moveLayerTop(cfg.shpLay) - cfg.rbbrBndPol.show() - # ROI point - self.vx.show() - else: - if cfg.shpLay is not None: - cfg.utls.setLayerVisible(cfg.shpLay, False) - cfg.rbbrBndPol.hide() - # ROI point - self.vx.hide() - cfg.cnvs.setRenderFlag(False) - cfg.cnvs.refresh() - cfg.cnvs.setRenderFlag(True) - except: - pass - - # set Min ROI size - def minROISize(self): - cfg.minROISz = int(cfg.Min_region_size_spin.value()) - cfg.utls.writeProjectVariable('minROISize', str(cfg.minROISz)) - # auto refresh ROI - if cfg.uidc.auto_refresh_ROI_radioButton.isChecked() and cfg.ROITime is not None: - StartT = cfg.datetimeSCP.datetime.now() - diffT = StartT - cfg.ROITime - if StartT > (cfg.ROITime + cfg.datetimeSCP.timedelta(seconds=1)): - self.redoROI() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'min roi size: ' + str(cfg.minROISz)) - - # set Max ROI size - def maxROIWidth(self): - cfg.maxROIWdth = int(cfg.Max_ROI_width_spin.value()) - if (cfg.maxROIWdth % 2 == 0): - cfg.maxROIWdth = cfg.maxROIWdth + 1 - cfg.utls.writeProjectVariable('maxROIWidth', str(cfg.maxROIWdth)) - # auto refresh ROI - if cfg.uidc.auto_refresh_ROI_radioButton.isChecked() and cfg.ROITime is not None: - StartT = cfg.datetimeSCP.datetime.now() - diffT = StartT - cfg.ROITime - if StartT > (cfg.ROITime + cfg.datetimeSCP.timedelta(seconds=1)): - self.redoROI() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'max roi width: ' + str(cfg.maxROIWdth)) - - def pointerClickROI(self, point): - # check if other processes are active - if cfg.actionCheck == 'No': - cfg.origPoint = point - cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if cfg.pntCheck == 'Yes': - cfg.pntROI = cfg.lstPnt - self.createROI(cfg.pntROI) - - # Activate pointer for ROI creation - def pointerManualROIActive(self): - cfg.lastVrt = [] - cfg.mrctrVrtc = [] - t = cfg.mnlROI - cfg.cnvs.setMapTool(t) - c = cfg.QtGuiSCP.QCursor() - c.setShape(cfg.QtSCP.CrossCursor) - cfg.cnvs.setCursor(c) - - # pointer moved - def movedPointer(self, point): - px = cfg.QtGuiSCP.QPixmap(':/pointer/icons/pointer/ROI_pointer.svg') - c = cfg.QtGuiSCP.QCursor(px) - if cfg.uidc.display_cursor_checkBox.isChecked() is True: - nm = 'No' - try: - if len(cfg.bandSetsList[cfg.bndSetNumber][3]) > 0: - point = cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point, 'Yes') - if point is not None and point != 'No': - if str(cfg.indName) == cfg.indNDVI: - nm = cfg.utls.NDVIcalculator(cfg.bandSetsList[cfg.bndSetNumber][8], point) - elif str(cfg.indName) == cfg.indEVI: - nm = cfg.utls.EVIcalculator(cfg.bandSetsList[cfg.bndSetNumber][8], point) - elif str(cfg.indName) == cfg.indCustom: - nm = cfg.utls.customIndexCalculator(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if nm != 'No': - c = cfg.SCPD.cursorCreation(nm) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.cnvs.setCursor(c) - - # Activate pointer for ROI creation - def pointerROIActive(self): - self.clearCanvas() - # connect to click - t = cfg.regionROI - cfg.cnvs.setMapTool(t) - px = cfg.QtGuiSCP.QPixmap(':/pointer/icons/pointer/ROI_pointer.svg') - c = cfg.QtGuiSCP.QCursor(px) - cfg.cnvs.setCursor(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'pointer active: ROI') - - def cursorCreation(self, number): - num = str(number)[0:6] - pmap = cfg.QtGuiSCP.QPixmap(["48 48 3 1", - " c None", - ". c #ffffff", - "+ c #000000", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - "................................................", - " ", - " ++++ ", - " +..+ ", - " +..+ ", - " +..+ ", - " +..+ ", - " +++++++..+++++++ ", - " +..............+ ", - " +..............+ ", - " +++++++..+++++++ ", - " +..+ ", - " +..+ ", - " +..+ ", - " +..+ ", - " ++++ ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ",]) - painter = cfg.QtGuiSCP.QPainter() - painter.begin(pmap) - painter.setPen(cfg.QtGuiSCP.QColor(0, 0, 0)) - painter.setFont(cfg.QtGuiSCP.QFont('Monospace', 9)) - painter.drawText(cfg.QtCoreSCP.QPoint(2, 12), num) - painter.end() - crsr = cfg.QtGuiSCP.QCursor(pmap) - return crsr - - # set Range radius - def rangeRadius(self): - cfg.rngRad = float(cfg.Range_radius_spin.value()) - cfg.utls.writeProjectVariable('rangeRadius', str(cfg.rngRad)) - # auto refresh ROI - if cfg.uidc.auto_refresh_ROI_radioButton.isChecked() and cfg.ROITime is not None: - StartT = cfg.datetimeSCP.datetime.now() - diffT = StartT - cfg.ROITime - if StartT > (cfg.ROITime + cfg.datetimeSCP.timedelta(seconds=1)): - self.redoROI() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'range radius: ' + str(cfg.rngRad)) - - # set rapid ROI band - def rapidROIband(self): - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - iB = len(cfg.bandSetsList[cfg.bndSetNumber][3]) - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - try: - iB = i.bandCount() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - iB = 1 - if cfg.uidc.rapidROI_band_spinBox.value() > iB: - cfg.uidc.rapidROI_band_spinBox.setValue(iB) - cfg.ROIband = cfg.uidc.rapidROI_band_spinBox.value() - cfg.utls.writeProjectVariable('rapidROIBand', str(cfg.ROIband)) - # auto refresh ROI - if cfg.uidc.auto_refresh_ROI_radioButton.isChecked() and cfg.ROITime is not None: - StartT = cfg.datetimeSCP.datetime.now() - diffT = StartT - cfg.ROITime - if StartT > (cfg.ROITime + cfg.datetimeSCP.timedelta(seconds=1)): - self.redoROI() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ROI band: ' + str(cfg.ROIband)) - - # Activate rapid ROI creation - def rapidROICheckbox(self): - if cfg.uidc.rapid_ROI_checkBox.isChecked() is True: - cfg.rpdROICheck = '2' - else: - cfg.rpdROICheck = '0' - cfg.utls.writeProjectVariable('rapidROI', cfg.rpdROICheck) - # auto refresh ROI - if cfg.uidc.auto_refresh_ROI_radioButton.isChecked() and cfg.ROITime is not None: - StartT = cfg.datetimeSCP.datetime.now() - diffT = StartT - cfg.ROITime - if StartT > (cfg.ROITime + cfg.datetimeSCP.timedelta(seconds=1)): - self.redoROI() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.rpdROICheck)) - - # set vegetation index name - def vegetationIndexName(self): - cfg.indName = str(cfg.uidc.vegetation_index_comboBox.currentText()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'index name: ' + str(cfg.indName)) - - # Activate vegetation index checkbox - def vegetationIndexCheckbox(self): - if cfg.uidc.display_cursor_checkBox.isChecked() is True: - cfg.vegIndexCheck = '2' - cfg.msgWar8check = '0' - else: - cfg.vegIndexCheck = '0' - cfg.utls.writeProjectVariable('vegetationIndex', cfg.vegIndexCheck) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.vegIndexCheck)) - - # set ROI macroclass ID - def setROIMacroID(self): - cfg.ROIMacroID = cfg.uidc.ROI_Macroclass_ID_spin.value() - cfg.utls.writeProjectVariable('ROIMacroIDField', str(cfg.ROIMacroID)) - for i in cfg.MCID_List: - if str(cfg.ROIMacroID) == i[0]: - cfg.uidc.ROI_Macroclass_line.setText(i[1]) - cfg.ROIMacroClassInfo = str(i[1]) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi macroclass id: ' + str(cfg.ROIMacroID)) - - # set ROI class ID - def setROIID(self): - cfg.ROIID = cfg.uidc.ROI_ID_spin.value() - cfg.utls.writeProjectVariable('ROIIDField', str(cfg.ROIID)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi id: ' + str(cfg.ROIID)) - - # set ROI class info - def roiClassInfo(self): - cfg.uidc.ROI_Class_line.blockSignals(True) - iTxt = str(cfg.uidc.ROI_Class_line.text()) - cfg.ROIInfo = str(iTxt) - cfg.utls.writeProjectVariable('ROIInfoField', str(cfg.ROIInfo)) - cfg.uidc.ROI_Class_line.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi info: ' + str(cfg.ROIInfo)) - - # ROI info completer - def roiInfoCompleter(self): - if cfg.shpLay is not None: - try: - l = cfg.utls.getFieldAttributeList(cfg.shpLay, cfg.fldROI_info) - # class names - cfg.cmplClsNm = cfg.QtWidgetsSCP.QCompleter(l) - cfg.uidc.ROI_Class_line.setCompleter(cfg.cmplClsNm) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # set custom expression - def customExpressionEdited(self): - cfg.customExpression = str(cfg.uidc.custom_index_lineEdit.text()) - cfg.utls.writeProjectVariable('customExpression', str(cfg.customExpression)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' expression: ' + str(cfg.customExpression)) - - # set ROI class info - def roiMacroclassInfo(self): - cfg.uidc.ROI_Macroclass_line.blockSignals(True) - iTxt = str(cfg.uidc.ROI_Macroclass_line.text()) - cfg.ROIMacroClassInfo = str(iTxt) - cfg.utls.writeProjectVariable('ROIMacroclassInfoField', str(cfg.ROIMacroClassInfo)) - cfg.uidc.ROI_Macroclass_line.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi info: ' + str(cfg.ROIInfo)) - - # ROI info completer - def roiMacroclassInfoCompleter(self): - if cfg.shpLay is not None: - try: - MCID_LIST = cfg.SCPD.exportMCIDList() - l = [MC[1] for MC in MCID_LIST] - # class names - cfg.cmplMClsNm = cfg.QtWidgetsSCP.QCompleter(l) - cfg.uidc.ROI_Macroclass_line.setCompleter(cfg.cmplMClsNm) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # signature table double click - def signatureListDoubleClickTree(self, item, column): - tW = cfg.uidc.signature_list_treeWidget - for id, val in cfg.treeDockItm.items(): - if val == item: - #if column == 0: - # self.selectAllSignatures(not item.checkState(0)) - if column == 4: - c = cfg.utls.selectColor() - if c is not None: - r = [] - for i in tW.selectedItems(): - id = i.text(5) - try: - cfg.treeDockItm[str(id)].setBackground(4, c) - cfg.signList['COLOR_' + str(id)] = c - except: - pass - else: - cfg.SCPD.zoomToROI([id]) - break - for id, val in cfg.treeDockMCItm.items(): - if val == item: - if column == 0 or column == 1 or column == 2 or column == 3: - item.setExpanded(not item.isExpanded()) - elif column == 4: - c = cfg.utls.selectColor() - if c is not None: - cfg.treeDockMCItm[str(id)].setBackground(4, c) - cfg.SCPD.roiMacroclassInfoCompleter() - break - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signatures index: ' + str(column)) - - # edited cell - def editedCellTree(self, item, column): - tW = cfg.uidc.signature_list_treeWidget - tW.setSortingEnabled(False) - tW.blockSignals(True) - move = 'No' - # items - for id, val in cfg.treeDockItm.items(): - if val == item: - if column == 0: - cfg.signList['CHECKBOX_' + str(id)] = item.checkState(0) - oldV = int(cfg.signList['MACROCLASSID_' + str(id)]) - v = int(item.text(column)) - if oldV != v: - try: - if v < 0: - v = 0 - item.setData(column, v) - cfg.mx.msg17() - cfg.signList['MACROCLASSID_' + str(id)] = v - if id in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_MC_ID[id] = v - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldMacroID_class, v) - move = 'Yes' - except: - item.setData(column, 0, oldV) - elif column == 1: - try: - v = int(item.text(column)) - if v < 0: - v = 0 - item.setData(column, v) - cfg.mx.msg17() - cfg.signList['CLASSID_' + str(id)] = v - if id in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_C_ID[id] = v - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldID_class, v) - except: - item.setData(column, 0, int(cfg.signList['CLASSID_' + str(id)])) - elif column == 2: - iTxt2 = item.text(column) - cfg.signList['CLASSINFO_' + str(id)] = iTxt2 - if id in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_C_Info[id] = iTxt2 - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldROI_info, iTxt2) - elif column == 3: - item.setData(column, 0, '') - elif column == 4: - item.setData(column, 0, '') - tW.clearSelection() - break - # macroclasses - for id, val in cfg.treeDockMCItm.items(): - if val == item: - if column == 0: - v = item.text(column) - oldV = str(id) - if str(v) != str(oldV): - count = item.childCount() - try: - v = int(v) - if v < 0: - v = 0 - item.setData(column, v) - cfg.mx.msg17() - move = 'Yes' - for roi in reversed(range(0, count)): - cld = item.child(roi) - idC = cld.text(5) - cfg.signList['MACROCLASSID_' + str(idC)] = v - if idC in list(cfg.ROI_SCP_UID.values()): - cfg.ROI_MC_ID[idC] = v - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(idC)) - for rI in rId: - cfg.utls.editFeatureShapefile(cfg.shpLay, rI, cfg.fldMacroID_class, v) - except: - item.setData(column, 0, int(oldV)) - elif column == 2: - v = item.text(column) - count = item.childCount() - for roi in reversed(range(0, count)): - cld = item.child(roi) - idC = cld.text(5) - cfg.signList['MACROCLASSINFO_' + str(idC)] = v - elif column == 3: - item.setData(column, 0, '') - elif column == 4: - item.setData(column, 0, '') - tW.clearSelection() - break - tW.setSortingEnabled(True) - tW.blockSignals(False) - if move == 'Yes': - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - else: - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.signT.signatureThresholdListTable() - cfg.SCPD.exportMCIDList() - # info completer - cfg.SCPD.roiInfoCompleter() - cfg.SCPD.roiMacroclassInfoCompleter() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'edited cell' + str(column)) - - # create MCID list for symbology - def createMCIDList(self): - sL = [] - for k in cfg.MCID_List: - sL.append([k[0], k[1], None, None, None, None, k[2]]) - return sL - - # export MCID list for symbology - def exportMCIDList(self): - sL = [] - s = [] - delete = [] - tW = cfg.uidc.signature_list_treeWidget - for id, val in cfg.treeDockMCItm.items(): - try: - count = val.childCount() - if count > 0: - mID = val.text(0) - mC = val.text(2) - c = val.background(4).color() - s = [] - s.append(mID) - s.append(mC) - s.append(c.toRgb().name()) - sL.append(s) - else: - delete.append([id, val]) - except: - delete.append([id, val]) - for id, val in delete: - try: - tW.takeTopLevelItem(tW.indexOfTopLevelItem(val)) - except: - pass - try: - del cfg.treeDockMCItm[id] - except: - pass - cfg.MCID_List = sL - return sL - - # zoom to clicked ROI - def zoomToROI(self, idList): - l = cfg.shpLay - rId = [] - if l is not None: - for id in idList: - if id in list(cfg.ROI_SCP_UID.values()): - rId.append(cfg.utls.getIDByAttributes(l, cfg.fldSCP_UID, str(id))) - cfg.utls.zoomToSelected(l, rId) - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - - # Activate signature calculation - def signatureCheckbox(self): - if cfg.uidc.signature_checkBox.isChecked() is True: - cfg.sigClcCheck = '2' - cfg.ui.signature_checkBox2.setCheckState(2) - else: - cfg.sigClcCheck = '0' - cfg.ui.signature_checkBox2.setCheckState(0) - cfg.utls.writeProjectVariable('calculateSignature', cfg.sigClcCheck) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.sigClcCheck)) - - # Activate save input file - def saveInputCheckbox(self): - if cfg.uidc.save_input_checkBox.isChecked() is True: - cfg.saveInputCheck = '2' - cfg.uidc.save_input_checkBox.setCheckState(2) - else: - cfg.saveInputCheck = '0' - cfg.uidc.save_input_checkBox.setCheckState(0) - cfg.utls.writeProjectVariable('saveInput', cfg.saveInputCheck) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.saveInputCheck)) - -################################## - ''' Shapefile functions ''' -################################## - - # reset input - def resetInput(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Remove training input'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to remove training input?')) - if a == 'Yes': - cfg.SCPD.resetInputDock() - - # reset input - def resetInputDock(self): - cfg.treeDockItm = {} - cfg.treeDockMCItm = {} - cfg.uidc.signature_list_treeWidget.clear() - try: - cfg.utls.removeLayerByLayer(cfg.shpLay) - cfg.cnvs.refresh() - except: - pass - cfg.SCPD.resetShapeList() - cfg.uidc.undo_save_Button.setEnabled(False) - cfg.uidc.redo_save_Button.setEnabled(False) - # training layer name - cfg.trnLay = None - # signature file path - cfg.sigFile = None - cfg.inptDir = None - cfg.scpFlPath = None - cfg.signList = {} - cfg.signIDs = {} - cfg.uidc.trainingFile_lineEdit.setText('') - cfg.utls.writeProjectVariable('trainingLayer', '') - - # Create new input - def createInput(self): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '>>> create input click') - try: - sL = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Create SCP training input'), '', '*.scp', 'scp') - if sL is not False: - cfg.SCPD.resetInputDock() - try: - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - iB = len(cfg.bandSetsList[cfg.bndSetNumber][3]) - # crs of loaded raster - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][0], 'Yes') - filePath = cfg.utls.layerSource(b) - crs = cfg.utls.getCrsGDAL(filePath) - if len(crs) == 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR crs') - cfg.mx.msgErr61(cfg.bandSetsList[cfg.bndSetNumber][3][0]) - return - else: - # crs of loaded raster - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8]) - filePath = cfg.utls.layerSource(b) - crs = cfg.utls.getCrsGDAL(filePath) - iB = b.bandCount() - if len(crs) == 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR crs') - cfg.mx.msgErr61(cfg.bandSetsList[cfg.bndSetNumber][8]) - return - # shapefile - name = cfg.utls.fileNameNoExt(sL) - dT = cfg.utls.getTime() - unzipDir = cfg.tmpDir + '/' + name + dT - #shpF = unzipDir + '/' + name + '.shp' - shpF = unzipDir + '/' + name + '.gpkg' - oDir = cfg.utls.makeDirectory(unzipDir) - #cfg.utls.createSCPShapefile(crs, shpF) - cfg.utls.createSCPVector(crs, shpF) - sigFile = unzipDir + '/' + name + '.slf' - cfg.SCPD.saveSignatureList(sigFile) - # create zip file - cfg.utls.zipDirectoryInFile(sL, unzipDir) - # open input - cfg.SCPD.openInput(sL) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '<<< SCP created: ' + '\'' + str(sL) + '\'') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.ipt.refreshRasterLayer() - cfg.mx.msg4() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg4() - - # Save last ROI to shapefile - def saveROItoShapefile(self, progressbar = 'Yes', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - l = cfg.shpLay - if l is None: - cfg.mx.msg3() - return 0 - if progressbar is False: - progressbar = 'Yes' - # check if layer was removed ## there is an issue if the removed layer was already saved in the project ## - try: - sN = str(cfg.shpLay.name()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg3() - # check if no layer is selected - if cfg.shpLay is None: - cfg.mx.msg3() - # check if no ROI created - elif cfg.lstROI is None: - cfg.mx.msg6() - elif len(cfg.bandSetsList[bandSetNumber][3])==0: - cfg.mx.msgErr2(SMTP = 'No') - else: - if progressbar == 'Yes': - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Creating ROI')) - # get polygon from ROI - try: - # region growing ROI - cfg.utls.copyFeatureToLayer(cfg.lstROI, 0, cfg.shpLay) - except: - # manual ROI - cfg.utls.copyFeatureToLayer(cfg.lstROI, 1, cfg.shpLay) - self.ROILastID = cfg.utls.getLastFeatureID(cfg.shpLay) - if progressbar == 'Yes': - cfg.uiUtls.updateBar(30) - try: - # start editing - cfg.shpLay.startEditing() - # set ID class attribute - fdID = cfg.utls.fieldID(cfg.shpLay, str(cfg.fldID_class)) - cfg.shpLay.changeAttributeValue(self.ROILastID, fdID, cfg.ROIID) - # set macroclass ID attribute - fdMID = cfg.utls.fieldID(cfg.shpLay, str(cfg.fldMacroID_class)) - cfg.shpLay.changeAttributeValue(self.ROILastID, fdMID, cfg.ROIMacroID) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - cfg.shpLay.startEditing() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - return 0 - cfg.shpLay.dataProvider().deleteFeatures([self.ROILastID]) - cfg.shpLay.commitChanges() - cfg.shpLay.dataProvider().createSpatialIndex() - cfg.shpLay.updateExtents() - cfg.uidc.undo_save_Button.setEnabled(False) - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Add required fields'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'It appears that the shapefile ') + cfg.shpLay.name() + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' is missing some fields that are required for the signature calculation. \nDo you want to add the required fields to this shapefile?')) - if a == 'Yes': - fds = [] - fds.append(cfg.qgisCoreSCP.QgsField(cfg.fldMacroID_class, cfg.QVariantSCP.Int)) - cfg.shpLay.startEditing() - aF = cfg.shpLay.dataProvider().addAttributes(fds) - # commit changes - cfg.shpLay.commitChanges() - cfg.shpLay.dataProvider().createSpatialIndex() - cfg.shpLay.updateExtents() - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - return 1 - else: - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - return 0 - # set ROI Class info attribute - fdInfo = cfg.utls.fieldID(cfg.shpLay, str(cfg.fldROI_info)) - cfg.shpLay.changeAttributeValue(self.ROILastID, fdInfo, cfg.ROIInfo) - # set ROI Macroclass info attribute - fdMCInfo = cfg.utls.fieldID(cfg.shpLay, str(cfg.fldROIMC_info)) - cfg.shpLay.changeAttributeValue(self.ROILastID, fdMCInfo, cfg.ROIMacroClassInfo) - # set SCP UID attribute - UID = cfg.utls.signatureID() - SCP_UID = cfg.utls.fieldID(cfg.shpLay, str(cfg.fldSCP_UID)) - cfg.shpLay.changeAttributeValue(self.ROILastID, SCP_UID, UID) - # commit changes - cfg.shpLay.commitChanges() - cfg.shpLay.dataProvider().createSpatialIndex() - cfg.shpLay.updateExtents() - cfg.uidc.undo_save_Button.setEnabled(True) - try: - self.clearCanvasPoly() - except: - pass - try: - self.clearROICanvas() - except: - pass - if progressbar == 'Yes': - cfg.uiUtls.updateBar(40) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi: ' + str(cfg.ROIID) + ', ' + str(cfg.ROIInfo) + ' saved to shapefile: ' + str(cfg.shpLay.name())) - # calculate signature if checkbox is yes - if cfg.uidc.signature_checkBox.isChecked() is True: - if progressbar == 'Yes': - cfg.uiUtls.updateBar(50) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[bandSetNumber][8], [self.ROILastID], cfg.ROIMacroID, cfg.ROIMacroClassInfo, cfg.ROIID, cfg.ROIInfo, 50, 40, 'No', 'No', UID, bandSetNumber = bandSetNumber) - else: - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[bandSetNumber][8], [self.ROILastID], cfg.ROIMacroID, cfg.ROIMacroClassInfo, cfg.ROIID, cfg.ROIInfo, None, None, 'No', 'No', UID, bandSetNumber = bandSetNumber) - if progressbar == 'Yes': - cfg.uiUtls.updateBar(90) - else: - cfg.signList['MACROCLASSID_' + str(UID)] = cfg.ROIMacroID - cfg.signList['MACROCLASSINFO_' + str(UID)] = cfg.ROIMacroClassInfo - cfg.signList['CLASSID_' + str(UID)] = cfg.ROIID - cfg.signList['CLASSINFO_' + str(UID)] = cfg.ROIInfo - cfg.signList['CHECKBOX_' + str(UID)] = 2 - cfg.signList['COLOR_' + str(UID)] = cfg.QtGuiSCP.QColor(255, 255, 225) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - # increase C_ID - v = cfg.uidc.ROI_ID_spin.value() - cfg.uidc.ROI_ID_spin.setValue(v+1) - if cfg.saveInputCheck == '2': - cfg.SCPD.saveMemToSHP(cfg.shpLay) - cfg.utls.zipDirectoryInFile(cfg.scpFlPath, cfg.inptDir) - else: - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.SCPD.manageShapeList(mL2, cfg.sigFile) - cfg.uidc.undo_save_Button.setEnabled(True) - cfg.uidc.redo_save_Button.setEnabled(False) - if progressbar == 'Yes': - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - - # delete last saved ROI - def undoSaveROI(self): - l = cfg.shpLay - if l is None: - cfg.mx.msg3() - return 0 - # check if layer was removed ## there is an issue if the removed layer was already saved in the project ## - try: - s = str(cfg.shpLay.name()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg3() - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Undo save ROI'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to undo?')) - if a == 'Yes': - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.shpLayList[-(cfg.shpLayListCounter)][0] = mL2 - cfg.shpLayListCounter = cfg.shpLayListCounter+1 - try: - cfg.utls.removeLayerByLayer(cfg.shpLay) - except: - pass - # create memory layer - cfg.shpLay = cfg.utls.duplicateMemoryLayer(cfg.shpLayList[-(cfg.shpLayListCounter)][0]) - cfg.utls.ROISymbol(cfg.shpLay) - cfg.utls.addLayerToMap(cfg.shpLay) - cfg.sigFile = cfg.shpLayList[-(cfg.shpLayListCounter)][1] - cfg.uidc.redo_save_Button.setEnabled(True) - if cfg.shpLayListCounter == len(cfg.shpLayList): - cfg.uidc.undo_save_Button.setEnabled(False) - cfg.SCPD.openSignatureListFile(cfg.sigFile) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.cnvs.refresh() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'undo ROI') - - # redo saved ROI - def redoSaveROI(self): - l = cfg.shpLay - if l is None: - cfg.mx.msg3() - return 0 - # check if layer was removed ## there is an issue if the removed layer was already saved in the project ## - try: - s = str(cfg.shpLay.name()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg3() - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Redo save ROI'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to redo?')) - if a == 'Yes': - # create memory layer - mL2 = cfg.utls.duplicateMemoryLayer(cfg.shpLay) - cfg.shpLayList[-(cfg.shpLayListCounter)][0] = mL2 - cfg.shpLayListCounter = cfg.shpLayListCounter-1 - try: - cfg.utls.removeLayerByLayer(cfg.shpLay) - except: - pass - cfg.shpLay = cfg.utls.duplicateMemoryLayer(cfg.shpLayList[-(cfg.shpLayListCounter)][0]) - cfg.utls.ROISymbol(cfg.shpLay) - cfg.utls.addLayerToMap(cfg.shpLay) - cfg.sigFile = cfg.shpLayList[-(cfg.shpLayListCounter)][1] - cfg.uidc.undo_save_Button.setEnabled(True) - if cfg.shpLayListCounter == 1: - cfg.uidc.redo_save_Button.setEnabled(False) - cfg.SCPD.openSignatureListFile(cfg.sigFile) - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.cnvs.refresh() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'redo ROI') - -################################## - ''' Map functions ''' -################################## - - # add Highlight Polygon - def addHighlightPolygon(self, sourceLayer, ID): - try: - self.clearCanvasPoly() - except: - pass - clr = cfg.QtGuiSCP.QColor(cfg.ROIClrVal) - try: - rT = 255 - int(cfg.ROITrnspVal) * 255 / 100 - clr.setAlpha(rT) - except: - clr.setAlpha(100) - f = cfg.utls.getFeaturebyID(sourceLayer, ID) - cfg.rbbrBndPol = cfg.qgisGuiSCP.QgsHighlight(cfg.cnvs, f.geometry(), sourceLayer) - cfg.rbbrBndPol.setWidth(2) - cfg.rbbrBndPol.setColor(cfg.QtGuiSCP.QColor(cfg.ROIClrOutlineValDefault)) - try: - cfg.rbbrBndPol.setFillColor(clr) - except: - pass - cfg.rbbrBndPol.show() - cfg.show_ROI_radioButton.setChecked(True) - cfg.ctrlClick = None - - # clear canvas - def clearCanvas(self): - cfg.lastVrt = [] - cfg.rbbrBnd.reset() - for m in cfg.mrctrVrtc: - cfg.cnvs.scene().removeItem(m) - del m - cfg.cnvs.refresh() - try: - self.clearROICanvas() - except: - pass - - # clear ROI point canvas - def clearROICanvas(self): - cfg.rbbrBnd.reset() - for m in self.ROIVrtc: - cfg.cnvs.scene().removeItem(m) - del m - cfg.cnvs.refresh() - - # clear canvas - def clearCanvasPoly(self): - cfg.rbbrBndPol.hide() - cfg.cnvs.refresh() - -################################## - ''' ROI functions ''' -################################## - - # left click - def clckL(self, pnt): - pntO = pnt - # band set - if len(cfg.bandSetsList[cfg.bndSetNumber][3])>0: - pnt = cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], pnt) - if cfg.pntCheck == 'No': - return 'No' - dT = cfg.utls.getTime() - # temp name - tN = cfg.subsTmpROI + dT - # crs - pCrs = cfg.utls.getQGISCrs() - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(pCrs.toWkt()), tN, 'memory') - mL.setCrs(pCrs) - cfg.lastVrt.append(pnt) - cfg.rbbrBnd.addPoint(cfg.qgisCoreSCP.QgsPointXY(pntO)) - geom = cfg.rbbrBnd.asGeometry() - v = cfg.qgisGuiSCP.QgsVertexMarker(cfg.cnvs) - v.setCenter(pntO) - cfg.mrctrVrtc.append(v) - cfg.rbbrBnd.setToGeometry(geom, mL) - cfg.rbbrBnd.show() - - # right click - def clckR(self, pnt): - self.clckL(pnt) - f = cfg.qgisCoreSCP.QgsFeature() - dT = cfg.utls.getTime() - # temp name - tN = cfg.subsTmpROI + dT - crs = cfg.utls.getQGISCrs() - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - try: - # crs of loaded raster - bN = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][3][0], 'Yes') - crs = cfg.utls.getCrs(bN) - except: - crs = cfg.utls.getQGISCrs() - else: - try: - # crs of loaded raster - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8]) - crs = cfg.utls.getCrs(b) - except: - crs = cfg.utls.getQGISCrs() - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(crs.toWkt()), tN, 'memory') - mL.setCrs(crs) - if not len(cfg.lastVrt) >= 3: - cfg.mx.msg16() - self.clearCanvas() - return - pointF = cfg.QtCoreSCP.QPointF() - polF = cfg.QtGuiSCP.QPolygonF() - for v in cfg.lastVrt: - pointF.setX(v.x()) - pointF.setY(v.y()) - polF.append(pointF) - pointF.setX(cfg.lastVrt[0].x()) - pointF.setY(cfg.lastVrt[0].y()) - polF.append(pointF) - g = cfg.qgisCoreSCP.QgsGeometry().fromQPolygonF(polF) - mL.addTopologicalPoints(g) - pr = mL.dataProvider() - # create temp ROI - mL.startEditing() - # add fields - pr.addAttributes( [cfg.qgisCoreSCP.QgsField('ID', cfg.QVariantSCP.Int)] ) - # add a feature - if cfg.ctrlClick is not None: - g = self.addPartToROI(g) - else: - cfg.lstROI2 = cfg.lstROI2 - f.setGeometry(g) - f.setAttributes([1]) - pr.addFeatures([f]) - mL.commitChanges() - mL.updateExtents() - self.clearCanvas() - # add ROI layer - cfg.lstROI = mL - self.addHighlightPolygon(cfg.lstROI, 1) - if cfg.uidc.auto_calculate_ROI_signature_radioButton.isChecked(): - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - # ROI date time for temp name - cfg.ROITime = cfg.datetimeSCP.datetime.now() - self.tempROISpectralSignature() - cfg.uiUtls.removeProgressBar() - cfg.uidc.button_Save_ROI.setEnabled(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '<<< ROI created: ' + str(tN)) - - # add multipart ROI - def addPartToROI(self, part): - if cfg.lstROI is not None and cfg.ctrlClick == 1: - ft = cfg.lstROI.getFeatures() - f = cfg.qgisCoreSCP.QgsFeature() - ft.nextFeature(f) - g = cfg.qgisCoreSCP.QgsGeometry(f.geometry()) - g.convertToMultiType() - part.convertToMultiType() - g.addPartGeometry(part) - cfg.lstROI2 = cfg.lstROI - return g - else: - return part - - def deleteLastROI(self): - cfg.lstROI = cfg.lstROI2 - try: - self.addHighlightPolygon(cfg.lstROI, 1) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # create a ROI - def createROI(self, point, progressbar = 'Yes', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if (float(cfg.maxROIWdth) % 2 == 0): - cfg.maxROIWdth = float(cfg.maxROIWdth) + 1 - if cfg.scipyCheck == 'No': - if str(cfg.osSCP.name) == 'nt': - cfg.mx.msgWar2Windows() - else: - cfg.mx.msgWar2Linux() - cfg.pntROI = None - elif cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') is None: - # if band set then pass - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - pass - else: - cfg.mx.msg4() - self.refreshRasterLayer() - cfg.pntROI = None - if cfg.pntROI != None: - if progressbar == 'Yes': - cfg.uiUtls.addProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '>>> ROI click') - if progressbar == 'Yes': - cfg.uiUtls.updateBar(10) - # ROI date time for temp name - cfg.ROITime = cfg.datetimeSCP.datetime.now() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'point (X,Y) = (%s,%s)' % (cfg.pntROI.x() , cfg.pntROI.y())) - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - # temp files - tS = cfg.utls.createTempRasterPath('gpkg') - # temp name - dT = cfg.utls.getTime() - tN = cfg.subsTmpROI + dT - # crs - pCrs = cfg.utls.getQGISCrs() - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - imageName = cfg.bandSetsList[bandSetNumber][3][0] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgWar25(bandSetNumber + 1) - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - return 'No' - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - filePath = cfg.utls.layerSource(bN0) - iCrs = cfg.utls.getCrsGDAL(filePath) - bList = [] - bandNumberList = [] - bandNumberList2 = [] - functionList = [] - if cfg.rpdROICheck == '0': - # subset - for b in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - oL = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][3][b], point.x(), point.y(), float(cfg.maxROIWdth), float(cfg.maxROIWdth), virtual ='Yes') - bList.append(oL) - bandNumberList.append(1) - bandNumberList2.append([b]) - functionList.append(b) - # rapid ROI - else: - b = int(cfg.ROIband) - 1 - oL = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][3][b], point.x(), point.y(), float(cfg.maxROIWdth), float(cfg.maxROIWdth), virtual ='Yes') - bList.append(oL) - bandNumberList.append(1) - bandNumberList2.append([b]) - functionList.append(0) - # multiband image - else: - # image CRS - bN0 = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - filePath = cfg.utls.layerSource(bN0) - iCrs = cfg.utls.getCrsGDAL(filePath) - tRR = cfg.utls.createTempRasterPath('tif') - bList = [] - bandNumberList = [] - bandNumberList2 = [] - functionList = [] - if cfg.rpdROICheck == '0': - # subset image - oL = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][8], point.x(), point.y(), int(cfg.maxROIWdth), int(cfg.maxROIWdth), tRR, cfg.outTempRastFormat, 'Yes') - bList = cfg.utls.rasterToBands(tRR, cfg.tmpDir, None, 'No', cfg.bandSetsList[bandSetNumber][6]) - for b in range(0, len(bList)): - bandNumberList.append(1) - bandNumberList2.append([b]) - functionList.append(b) - # rapid ROI - else: - # subset image - oL = cfg.utls.subsetImage(cfg.bandSetsList[bandSetNumber][8], point.x(), point.y(), int(cfg.maxROIWdth), int(cfg.maxROIWdth), tRR) - bList = cfg.utls.rasterToBands(tRR, cfg.tmpDir, None, 'No', cfg.bandSetsList[bandSetNumber][6]) - b = int(cfg.ROIband) - 1 - bList = [bList[b]] - bandNumberList.append(1) - bandNumberList2.append([b]) - functionList.append(0) - # open input with GDAL - try: - rD = cfg.gdalSCP.Open(oL, cfg.gdalSCP.GA_ReadOnly) - # number of x pixels - rX = rD.RasterXSize - # number of y pixels - rY = rD.RasterYSize - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - return 'No' - # pixel size and origin - rGT = rD.GetGeoTransform() - UX = abs(rGT[0]) - UY = abs(rGT[3]) - pX = abs(rGT[1]) - pY = abs(rGT[5]) - # seed pixel number - sPX = abs(int((abs(point.x()) - UX)/ pX)) - sPY = abs(int((UY - abs(point.y()))/ pY)) - # area - area = int(cfg.maxROIWdth) * int(cfg.maxROIWdth) - minimumSize = int(cfg.minROISz) - if area < minimumSize: - minimumSize = area - # array area - aBArea = (rX * rY) - if aBArea < minimumSize: - minimumSize = aBArea - # variables for multiprocess - fVarList = [] - oM = [] - for rb in range(0, len(bList)): - fVarList.append([sPX, sPY, cfg.rngRad, int(minimumSize)]) - oM.append(None) - # create virtual raster of subset bands - tPMD = cfg.utls.createTempRasterPath('vrt') - vrtCheck = cfg.utls.createVirtualRaster(bList, tPMD, bandNumberList, 'Yes', 'Yes', 0) - # region growing - #o = cfg.utls.multiProcessRaster(rasterPath = tPMD, functionBand = 'No', functionRaster = cfg.utls.regionGrowingAlgMultiprocess, outputRasterList = oM, functionBandArgument = functionList, functionVariable = fVarList, progressMessage = 'Region growing', parallel = cfg.parallelRaster, skipSingleBand = 'Yes') - o = cfg.utls.multiProcessNoBlocks(rasterPath = tPMD, bandNumberList = bandNumberList2, functionRaster = cfg.utls.regionGrowingAlgMultiprocess, functionBandArgument = functionList, functionVariable = fVarList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Region growing')) - # run segmentation - for x in sorted(o): - try: - for arr in o[x]: - try: - r = r * arr.astype(int) - except: - r = arr.astype(int) - except: - pass - check = 'Yes' - if cfg.np.count_nonzero(r) > 0: - try: - lR, num_features = cfg.labelSCP(r) - # value of ROI seed - rV = lR[sPY, sPX] - r = (lR == rV).astype(int) - except: - r = 0 - else: - check = 'No' - if cfg.np.count_nonzero(r) > 0 and r[sPY, sPX] == 1 and check == 'Yes': - # output ROI - d = cfg.ogrSCP.GetDriverByName('GPKG') - # use ogr - dS = d.CreateDataSource(tS) - # shapefile - sR = cfg.osrSCP.SpatialReference() - sR.ImportFromWkt(rD.GetProjectionRef()) - rL = dS.CreateLayer('ROILayer', sR, cfg.ogrSCP.wkbMultiPolygon) - fN = 'DN' - fd = cfg.ogrSCP.FieldDefn(fN, cfg.ogrSCP.OFTInteger) - rL.CreateField(fd) - fld = rL.GetLayerDefn().GetFieldIndex(fN) - # prepare output raster - tR = cfg.utls.createTempRasterPath('tif') - iRB = rD.GetRasterBand(1) - dtTp = iRB.DataType - tD = cfg.gdalSCP.GetDriverByName('GTiff') - rR = tD.Create(tR, rX, rY, 1, dtTp) - rR.SetGeoTransform( [ rGT[0] , rGT[1] , 0 , rGT[3] , 0 , rGT[5] ] ) - rP = rD.GetProjection() - rR.SetProjection(rP) - rRB = rR.GetRasterBand(1) - rRB.SetNoDataValue(0) - # write array - rRB.WriteArray(r) - # raster to polygon - cfg.gdalSCP.Polygonize(rRB, rRB.GetMaskBand(), rL, fld) - # close bands - rRB = None - # close rasters - rR = None - rD = None - dS = None - rL = None - d = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'output segmentation: ' + str(tS)) - tSS = cfg.utls.addVectorLayer(tS) - # check if segmentation failed - if tSS is None: - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error: failed ROI creation') - cfg.pntROI = None - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr2(SMTP = 'No') - else: - # add ROI layer - if progressbar == 'Yes': - cfg.uiUtls.updateBar(90) - # add a feature - f = cfg.qgisCoreSCP.QgsFeature() - idf = cfg.utls.getLastFeatureID(tSS) - q = cfg.utls.getFeaturebyID(tSS, idf) - # get geometry - g = q.geometry() - mL = cfg.qgisCoreSCP.QgsVectorLayer('MultiPolygon?crs=' + str(iCrs), tN, 'memory') - iCrsQ = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem.fromWkt(iCrs) - mL.setCrs(iCrsQ) - pr = mL.dataProvider() - # create temp ROI - mL.startEditing() - # add fields - pr.addAttributes( [cfg.qgisCoreSCP.QgsField('ID', cfg.QVariantSCP.Int)] ) - # add a feature - if cfg.ctrlClick is not None: - g = self.addPartToROI(g) - else: - cfg.lstROI2 = cfg.lstROI - f.setGeometry(g) - f.setAttributes([1]) - pr.addFeatures([f]) - mL.commitChanges() - mL.updateExtents() - # add ROI layer - cfg.lstROI = mL - self.addHighlightPolygon(cfg.lstROI, 1) - # add point marker - try: - self.clearROICanvas() - except: - self.ROIVrtc = [] - self.vx = cfg.qgisGuiSCP.QgsVertexMarker(cfg.cnvs) - self.vx.setCenter(cfg.origPoint) - self.vx.setIconType(1) - self.vx.setColor(cfg.QtGuiSCP.QColor(0,255,255)) - self.vx.setIconSize(12) - self.ROIVrtc.append(self.vx) - if cfg.uidc.auto_calculate_ROI_signature_radioButton.isChecked(): - self.tempROISpectralSignature(bandSetNumber) - if progressbar == 'Yes': - cfg.uiUtls.updateBar(100) - cfg.uidc.button_Save_ROI.setEnabled(True) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '<<< ROI created: ' + str(tSS.name())) - # enable Redo button - cfg.redo_ROI_Button.setEnabled(True) - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - else: - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error: failed ROI creation') - cfg.pntROI = None - if progressbar == 'Yes': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr2(SMTP = 'No') - return 'No' - - # calculate temporary ROI spectral signature - def tempROISpectralSignature(self, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - idList = [] - for f in cfg.lstROI .getFeatures(): - idList.append(f.id()) - cfg.utls.calculateSignature(cfg.lstROI, cfg.bandSetsList[bandSetNumber][8], idList, 0, cfg.tmpROINm, 0, cfg.ROITime.strftime('%H-%M-%S'), 0, 50, 'Yes', 'Yes', bandSetNumber = bandSetNumber) - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - diff --git a/docs/install SCP from zip archive.png b/docs/install_archive.png old mode 100644 new mode 100755 similarity index 100% rename from docs/install SCP from zip archive.png rename to docs/install_archive.png diff --git a/docs/openstreetmap_wms.xml b/docs/openstreetmap_wms.xml deleted file mode 100644 index 72687da..0000000 --- a/docs/openstreetmap_wms.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - http://tile.openstreetmap.org/${z}/${x}/${y}.png - - - -20037508.34 - 20037508.34 - 20037508.34 - -20037508.34 - 18 - 1 - 1 - top - - EPSG:3857 - 256 - 256 - 3 - - \ No newline at end of file diff --git a/docs/openstreetmap_wms.xml.aux.xml b/docs/openstreetmap_wms.xml.aux.xml deleted file mode 100644 index 0978c63..0000000 --- a/docs/openstreetmap_wms.xml.aux.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - PIXEL - - - ./gdalwmscache/b16d16bcf8902cea55a9ebf9e3f4cd32 - - - - - 96.50342465753425 - 242.4965753424657 - 146 - 0 - 1 - 0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|36058|0|0|0|620|0|0|0|523|0|0|0|201|0|0|289|0|0|0|0|168|199|0|0|0|0|284|0|0|0|0|220|0|0|0|303|0|0|0|0|0|391|0|0|0|0|0|0|0|364|0|0|0|211|0|0|0|227|0|158|0|0|161|18|193|0|0|415|0|0|0|0|24533 - - - - YES - 242 - 196.68952941895 - 97 - 37.009942828247 - 100 - - - - - - 172.5074626865672 - 239.4925373134328 - 67 - 0 - 1 - 0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|36058|620|0|523|0|201|289|0|168|199|284|0|220|0|303|0|391|0|0|364|0|211|227|158|161|211|415|0|24533 - - - - YES - 239 - 221.10260009766 - 173 - 14.858582287847 - 100 - - - - - - 194.5128205128205 - 233.4871794871795 - 39 - 0 - 1 - 0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|36058|1143|490|367|504|303|391|364|456|927|24533 - - - - YES - 233 - 226.18321228027 - 195 - 6.2300893425706 - 100 - - - diff --git a/docs/repository.xml b/docs/repository.xml old mode 100644 new mode 100755 index fd6b8c3..77c5c4a --- a/docs/repository.xml +++ b/docs/repository.xml @@ -1,23 +1,23 @@ - + - - 7.10.11 + + 8.0.0 3.0.0 3.99.0 SemiAutomaticClassificationPlugin-master.zip - https://1.bp.blogspot.com/-Vo3Oba6OQic/X58XMwoE98I/AAAAAAAAGGI/bKIZ-VcKzVgiBWMox37wYrgCKmZaNS41ACLcBGAsYHQ/s96/semiautomaticclassificationplugin.png + https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgScfQYBCTR7v-gAL1DeZIxvGuevGYvc5xTlal05-0CpJwgVex_7oMpcxaHtKTTsjONTaoBI7Bz_HbM6kQg6TZ3lTSPrGzRRgb3g3IyZGdNRaL4_VqmqToztTr3BZUCF5ib6E4SAhNzxd-nJj-_kDGpZnlYAC5Ly7ngGjxSnyz6Ow62stHV7vgIjmrXhFSF/s1600/semiautomaticclassificationplugin.png https://codeload.github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/zip/master - + 00 5 00 - + False diff --git a/firstrun b/firstrun deleted file mode 100644 index 605b812..0000000 --- a/firstrun +++ /dev/null @@ -1 +0,0 @@ -firstrun diff --git a/i18n/models/semiautomaticclassificationplugin.ts b/i18n/models/semiautomaticclassificationplugin.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/models/semiautomaticclassificationplugin.ts +++ b/i18n/models/semiautomaticclassificationplugin.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin.ts b/i18n/semiautomaticclassificationplugin.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin.ts +++ b/i18n/semiautomaticclassificationplugin.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_ar.ts b/i18n/semiautomaticclassificationplugin_ar.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_ar.ts +++ b/i18n/semiautomaticclassificationplugin_ar.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_de.ts b/i18n/semiautomaticclassificationplugin_de.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_de.ts +++ b/i18n/semiautomaticclassificationplugin_de.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_el_GR.ts b/i18n/semiautomaticclassificationplugin_el_GR.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_el_GR.ts +++ b/i18n/semiautomaticclassificationplugin_el_GR.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_es.qm b/i18n/semiautomaticclassificationplugin_es.qm index e5a7c6a..bccb517 100644 Binary files a/i18n/semiautomaticclassificationplugin_es.qm and b/i18n/semiautomaticclassificationplugin_es.qm differ diff --git a/i18n/semiautomaticclassificationplugin_es.ts b/i18n/semiautomaticclassificationplugin_es.ts old mode 100644 new mode 100755 index 6f909e7..c7dfa4e --- a/i18n/semiautomaticclassificationplugin_es.ts +++ b/i18n/semiautomaticclassificationplugin_es.ts @@ -1,371 +1,363 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - <html><head/><body><p><span >Calculadora de Bandas</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Calculadora de Bandas&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Preprocessing</p></body></html> - <html><head/><body><p>Preprocesamiento</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Preprocesamiento&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Postprocessing</p></body></html> - <html><head/><body><p>Postprocesamiento</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Postprocesamiento&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>User manual</p></body></html> - <html><head/><body><p>Manual del Usuario</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Manual del Usuario&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Input file path</p></body></html> - <html><head/><body><p>Ruta de archivo de Entrada</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ruta de archivo de Entrada&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Open a training input</span></p></body></html> - <html><head/><body><p><span >Abrir un Entrenamiento de Entrada</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Abrir un Entrenamiento de Entrada&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - <html><head/><body><p><span >Crear un nuevo Entrenamiento de Entrada</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Crear un nuevo Entrenamiento de Entrada&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Gráfico - + <html><head/><body><p><span >Band set</span></p></body></html> - <html><head/><body><p><span >Juego de Bandas</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Juego de Bandas&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + MC ID MC ID - + C ID C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - <html><head/><body><p>Agregar al gráfico de dispersión los elementos seleccionados</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agregar al gráfico de dispersión los elementos seleccionados&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + ... ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - <html><head/><body><p>Importar firmas espectrales</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importar firmas espectrales&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import library Importar librería - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Exportar las firmas espectrales seleccionadas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exportar las firmas espectrales seleccionadas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Delete highlighted items</p></body></html> - <html><head/><body><p>Suprimir los elementos seleccionados</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Suprimir los elementos seleccionados&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - <html><head/><body><p>Calcular firmas para los elementos seleccionados</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcular firmas para los elementos seleccionados&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - <html><head/><body><p >Combinar las firmas espectrales seleccionadas para obtener la firma promedio</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Combinar las firmas espectrales seleccionadas para obtener la firma promedio&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Agregar las firmas espectrales seleccionadas al gráfico de firmas espectrales</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Agregar las firmas espectrales seleccionadas al gráfico de firmas espectrales&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - <html><head/><body><p>Mostrar el índice de vegetación con el cursor</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mostrar el índice de vegetación con el cursor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Display Mostrar - + <html><head/><body><p>Select a vegetation index</p></body></html> - <html><head/><body><p>Selecciona el índice de vegetación</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el índice de vegetación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + NDVI NDVI - + EVI EVI - + Custom Personalizado - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - <html><head/><body><p>Expresión personalizada (Ej. bandset#b4 / bandset#b3 )</p></body></html> - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - <html><head/><body><p>El nombre de Clase de la Firma del ROI</p></body></html> - - - - C 1 - C 1 + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El nombre de Clase de la Firma del ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - <html><head/><body><p>La ID de la Macroclase de la firma del ROI</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;La ID de la Macroclase de la firma del ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - <html><head/><body><p>El nombre de la Macroclase de la firma del ROI</p></body></html> - - - - MC 1 - MC 1 - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - <html><head/><body><p>La ID de la Clase de la firma del ROI</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El nombre de la Macroclase de la firma del ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Undo ROI save</p></body></html> - <html><head/><body><p >Deshacer ROI guardado</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Deshacer ROI guardado&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p>Agregar firma espectral al ROI en la lista de firmas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agregar firma espectral al ROI en la lista de firmas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - <html><head/><body><p >Guardar el ROI temporal en el Entrenamiento de Entrada</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Guardar el ROI temporal en el Entrenamiento de Entrada&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - <html><head/><body><p>Actualizar automáticamente el ROI temporal, cuando cambien los parámetros</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Actualizar automáticamente el ROI temporal, cuando cambien los parámetros&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Band number</p></body></html> - <html><head/><body><p>Número de Banda</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Número de Banda&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - <html><head/><body><p>Calcular el ROI temporal en una sola banda</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcular el ROI temporal en una sola banda&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - <html><head/><body><p>Calcular automáticamente el gráfico de firmas del ROI temporal</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcular automáticamente el gráfico de firmas del ROI temporal&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual Manual del Usuario - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter Filtro - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + SCP Dock + + + + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> + + + + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> + + + + + Support forum + + + + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + + + + Maximum training buffer + + + + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> + + + + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> + + + + + <html><head/><body><p></p></body></html> - SCP_Welcome + SCP_Widget - - Welcome to Semi-Automatic Classification Plugin - + + Semi-Automatic Classification Plugin + Semi-Automatic Classification Plugin - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> + + <html><head/><body><p>Select all</p></body></html> + + + Plot + Gráfico + ScatterPlot @@ -375,6621 +367,3633 @@ p, li { white-space: pre-wrap; } SCP: Gráfico de Dispersión - + S S - + MC ID MC ID - + C ID C ID - + Color Color - - Scatter raster - Ráster de Dispersión - - - + Calculate Calcular - + <html><head/><body><p>Calculate scatter plot</p></body></html> - <html><head/><body><p>Calcula el gráfico de dispersión</p></body></html> - - - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> - <html><head/><body><p>Calcula y muestra el ráster de dispersión</p></body></html> - - - - <html><head/><body><p>Calculate and save to signature list</p></body></html> - <html><head/><body><p>Calcula y guarda en la lista de firmas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcula el gráfico de dispersión&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + x=0.000000 y=0.000000 x=0.000000 y=0.000000 - + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Ajusta el gráfico a los datos automaticamente</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajusta el gráfico a los datos automaticamente&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Guarda el gráfico en un archivo (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Guarda el gráfico en un archivo (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Gráfico - + Colormap Rampa de color - - <html><head/><body><p>Select a colormap</p></body></html> - <html><head/><body><p>Selecciona una rampa de color</p></body></html> - - - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> - <html><head/><body><p>Asigna rampa de colores al gráfico espectral seleccionado</p></body></html> - - - - Extent - Extensión - - - - <html><head/><body><p>Select extent of scatter raster</p></body></html> - <html><head/><body><p>Selecciona la extensión del ráster de dispersión</p></body></html> - - - - same as display - igual a pantalla - - - - same as image - igual a imagen - - - - <html><head/><body><p>Create selection polygons</p></body></html> - <html><head/><body><p>Crear polígonos de selección</p></body></html> - - - - color - color - - - - <html><head/><body><p>Select polygon color</p></body></html> - <html><head/><body><p>Seleccionar color del polígono</p></body></html> - - - - <html><head/><body><p>Remove selection polygons</p></body></html> - <html><head/><body><p>Quitar polígonos de selección</p></body></html> - - - + Band Y Banda Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - <html><head/><body><p align="justify">Banda Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Banda Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band X Banda X - + <html><head/><body><p align="justify">Band X</p></body></html> - <html><head/><body><p align="justify">Banda X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Banda X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Use custom decimal precision</p></body></html> - <html><head/><body><p>Usar precisión decimal personalizada</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar precisión decimal personalizada&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Precision Precisión - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - <html><head/><body><p>Seleccionar precisión decimal:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - + 4 4 - + 3 3 - + 2 2 - + 1 1 - + 0 0 - + -1 -1 - + -2 -2 - + -3 -3 - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Suprimir fila</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Suprimir fila&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Gráfico - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - <html><head/><body><p>Calcular gráfico de dispersión desde el ROI temporal</p></body></html> - - - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - <html><head/><body><p>Calcular el gráfico de dispersión para la extensión actual de la pantalla</p></body></html> - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - <html><head/><body><p>Calcular el gráfico de dispersión para toda la imagen</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcular gráfico de dispersión desde el ROI temporal&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Scatter list Listado de dispersión - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - RGB = - - - ROI - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> + - - Preview - Previa + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - <html><head/><body><p>Preprocesar imágenes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Preprocesar imágenes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Preprocess images Preprocesar imágenes - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - <html><head/><body><p>Cargar imágenes en QGIS después de la descarga</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cargar imágenes en QGIS después de la descarga&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Load bands in QGIS Cargar bandas en QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - <html><head/><body><p>Descarga imágenes solo si su correspondiente vista previa está cargada en QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Descarga imágenes solo si su correspondiente vista previa está cargada en QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Only if preview in Layers Solo con vista previa - + <html><head/><body><p><span >Run</span></p></body></html> - <html><head/><body><p><span >Ejecutar</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Ejecutar&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import library Importar librería - + <html><head/><body><p>Export download links to a text file</p></body></html> - <html><head/><body><p>Exporta los enlaces de descarga a un archivo de texto</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporta los enlaces de descarga a un archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Set area in the map</p></body></html> - <html><head/><body><p>Establecer área en el mapa</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Establecer área en el mapa&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right X</p></body></html> - <html><head/><body><p>Inferior derecha X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Inferior derecha X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right Y</p></body></html> - <html><head/><body><p>Inferior derecha Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Inferior derecha Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Upper left X</p></body></html> - <html><head/><body><p>Superior izquierda X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Superior izquierda X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Upper left Y</p></body></html> - <html><head/><body><p>Superior izquierda Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Superior izquierda Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Show / hide area</p></body></html> - <html><head/><body><p>Mostrar / ocultar área</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mostrar / ocultar área&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Show Mostrar - + <html><head/><body><p>Find images</p></body></html> - <html><head/><body><p>Encontrar imágenes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Encontrar imágenes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Find Encontrar - + yyyy-MM-dd yyyy-MM-dd - + Max cloud cover (%) Máx. nubosidad (%) - + to hasta - + Date from Fecha desde - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - <html><head/><body><p>Máximo porcentaje de cobertura de nubes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Máximo porcentaje de cobertura de nubes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Filter Filtro - + <html><head/><body><p>Filter images</p></body></html> - <html><head/><body><p>Filtrar imágenes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Filtrar imágenes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Suprimir fila</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Suprimir fila&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Gráfico - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - <html><head/><body><p>Muestra en el mapa una vista previa de las imágenes seleccionadas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Muestra en el mapa una vista previa de las imágenes seleccionadas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Reset</span></p></body></html> - <html><head/><body><p><span >Reiniciar</span></p></body></html> - - - - AcquisitionDate - FechaDeAdquisición - - - - CloudCover - Nubosidad + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Reiniciar&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min_lat lat_min - + min_lon lon_min - + max_lat lat_max - + max_lon lon_max - + Preview VistaPrevia - - Download options - Opciones de Descarga - - - + <html><head/><body><p >Select all</p></body></html> - <html><head/><body><p >Seleccionar todas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Seleccionar todas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - <html><head/><body><p>Si está seleccionado, recuerda el nombre de usuario y la contraseña internamente en QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si está seleccionado, recuerda el nombre de usuario y la contraseña internamente en QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + remember recordar - + <html><head/><body><p>Password</p></body></html> - <html><head/><body><p>Contraseña</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Contraseña&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Password Contraseña - + <html><head/><body><p>User name</p></body></html> - <html><head/><body><p>Usuario</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usuario&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + User Usuario - - <html><head/><body><p>Login Sentinels</p></body></html> - <html><head/><body><p>Acceso a Sentinels</p></body></html> - - - - Service - Servicio - - - - Sentinel-2 bands - Bandas de Sentinel-2 - - - + Multiple ROI creation Creación de ROI múltiples - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - <html><head/><body><p align="justify">Distancia mínima entre puntos</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Distancia mínima entre puntos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - <html><head/><body><p align="justify">Tamaño de la cuadrícula en la que se crearán los puntos aleatorios</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Tamaño de la cuadrícula en la que se crearán los puntos aleatorios&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Create points Crear puntos - + Number of points Número de puntos - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - <html><head/><body><p align="justify">Número de puntos creados aleatoriamente</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Número de puntos creados aleatoriamente&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create points</p></body></html> - <html><head/><body><p>Crear puntos</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Crear puntos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - <html><head/><body><p>Crear puntos aleatorios con una distancia mínima</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Crear puntos aleatorios con una distancia mínima&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min distance distancia min - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - <html><head/><body><p>Crear puntos aleatorios dentro de cada celda en una cuadrícula con este tamaño</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Crear puntos aleatorios dentro de cada celda en una cuadrícula con este tamaño&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + inside grid dentro de la cuadrícula - + Point coordinates and ROI definition Coordenadas de los Puntos y definición de ROI - + X X - + Y Y - + MC ID MC ID - + C ID C ID - + Min Min - + Max Max - + Dist Dist - + Rapid ROI band Banda para ROI rápido - + <html><head/><body><p >Add row</p></body></html> - <html><head/><body><p >Agregar fila</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Agregar fila&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Export point list to text file</p></body></html> - <html><head/><body><p >Exportar la lista de puntos a un archovo de texto</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exportar la lista de puntos a un archovo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Import point list from text file</p></body></html> - <html><head/><body><p >Importar una lista de puntos desde un archivo de texto</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Importar una lista de puntos desde un archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - <html><head/><body><p>Agrega las firmas espectrales de los ROI al listado de firmas espectrales</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agrega las firmas espectrales de los ROI al listado de firmas espectrales&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Calculate sig. Calcular firm. - + Run Ejecutar - + Import signatures Importar firmas - + Import library file Importar archivo de librerías - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - <html><head/><body><p>Selecciona un archivo: archivo SCP (*.scp) ; librería USGS (*.asc) ; librería ASTER (*.txt) ; CSV (*.csv)</p></body></html> - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - <html><head/><body><p><span >Abrir archivo</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Abrir archivo&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Open a file</p></body></html> - <html><head/><body><p>Abre un archivo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Abre un archivo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C ID field Campo C ID - + MC ID field Campo MC ID - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p>Agregar las firmas espectrales del ROI a la lista de firmas espectrales</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agregar las firmas espectrales del ROI a la lista de firmas espectrales&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Download USGS Spectral Library Descarga Librería Espectral de USGS - + <html><head/><body><p>Select a chapter</p></body></html> - <html><head/><body><p>Selecciona un capítulo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona un capítulo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a library</p></body></html> - <html><head/><body><p>Selecciona una librería</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona una librería&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import spectral library Importar una librería espectral - + <html><head/><body><p>Import spectral library</p></body></html> - <html><head/><body><p>Importar una librería espectral</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importar una librería espectral&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Library Description (requires internet connection) Descripción de la Librería ( riquiere conexión a Internet) - + Export signatures Exportar librerías - + Export Exportar - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - <html><head/><body><p>Exportar como archivo CSV (.csv)</p></body></html> - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - <html><head/><body><p>Exportar como archivo SCP (*.scp)</p></body></html> - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Exportar las firmas espectrales seleccionadas</p></body></head></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exportar las firmas espectrales seleccionadas&lt;/p&gt;&lt;/body&gt;&lt;/head&gt;&lt;/html&gt; - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - <html><head/><body><p>Selecciona el directorio donde las firmas espectrales seleccionadas serán guardadas como .csv</p></body></html> - - - - Algorithm band weight - Algoritmo peso de banda - - - - Band name - Nombre de banda + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el directorio donde las firmas espectrales seleccionadas serán guardadas como .csv&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Reset</p></body></html> - <html><head/><body><p >Restaurar</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Restaurar&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Set</p></body></html> - <html><head/><body><p >Asignar</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Asignar&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Set weight - Asignar peso - - - + <html><head/><body><p>Set a value</p></body></html> - <html><head/><body><p>Asignar un valor</p></body></html> - - - - Automatic weight - Peso automático - - - - MD Threshold - Umbral MD - - - - ML Threshold - Umbral ML + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Asignar un valor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - SAM Threshold - Umbral SAM - - - + Set threshold = σ * Establecer umbral = σ * - + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Establecer el valor que será multiplicado por la esviación estándar</p></body></html> - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - <html><head/><body><p>Establecer umbral automáticamente σ</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Establecer el valor que será multiplicado por la esviación estándar&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Set threshold Establecer umbral - - Automatic thresholds - Umbrales Automáticos - - - - LCS threshold - Umbral LCS - - - - Color [overlap MC_ID-C_ID] - Color [superponer MC_ID-C_ID] - - - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Agregar las firmas seleccionadas al gráfico de firmas espectrales</p></body></html> - - - - Min Max - Min Max - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Establecer umbral Min Max automáticamente</p></body></html> - - - - σ * - σ * - - - - From pixel - Desde pixel - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Activar el puntero para establecer umbrales desde pixel</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>Si está seleccionado, el umbral de firma se extiende para incluir la firma del pixel</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>Si se selecciona, el umbral de firma se reduce para excluir la firma de pixel</p></body></html> - - - - From ROI - Desde ROI - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Establecer umbrales desde el ROI temporal</p></body></html> - - - - RGB list - Lista RGB - - - + <html><head/><body><p>Sort RGB automatically</p></body></html> - <html><head/><body><p>Ordena automáticamente combinaciones RGB</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ordena automáticamente combinaciones RGB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB down</p></body></html> - <html><head/><body><p>Mueve la combinación RGB seleccionada hacia abajo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mueve la combinación RGB seleccionada hacia abajo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB up</p></body></html> - <html><head/><body><p>Mueve la combinación RGB seleccionada hacia arriba</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mueve la combinación RGB seleccionada hacia arriba&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Export RGB list to text file</p></body></html> - <html><head/><body><p>Exportar la lista RGB a un archivo de texto</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exportar la lista RGB a un archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Import RGB list from text file</p></body></html> - <html><head/><body><p>Importar lista RGB desde archivo de texto</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importar lista RGB desde archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + RGB RGB - + Automatic RGB RGB Automático - + Band combinations Combinaciones de bandas - + <html><head/><body><p>Add all combinations of bands</p></body></html> - <html><head/><body><p>Agregar todas la combinaciones de bandas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agregar todas la combinaciones de bandas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Preprocessing Preprocesamiento - - Landsat - Landsat - - - - Directory containing Landsat bands - Directorio conteniendo bandas Landsat - - - - Landsat conversion to TOA reflectance and brightness temperature - Conversión a reflectancia TOA y Temperatura de Brillo - - - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> - <html><head/><body><p>Activa/Desactiva el cálculo de la temperatura en grados Celsius para la banda térmica</p></body></html> - - - - Brightness temperature in Celsius - Temperatura de brillo en Celsius - - - + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - <html><head/><body><p>Activa/Desactiva la corrección atmosférica DOS1 (no se corrige la banda térmica)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activa/Desactiva la corrección atmosférica DOS1 (no se corrige la banda térmica)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Apply DOS1 atmospheric correction Aplicar la corrección atmosférica DOS1 - + <html><head/><body><p>No data value</p></body></html> - <html><head/><body><p>Valor para SinDatos</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valor para SinDatos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Select a directory</p></body></html> - <html><head/><body><p >Selecciona un directorio</p></body></html> - - - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> - <html><head/><body><p>Realizar el pan-sharpening (Transformación de Brovey)</p></body></html> - - - - Perform pansharpening (Landsat 7 or 8) - Realizar pansharpening (Landsat 7 u 8) + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Selecciona un directorio&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - <html><head/><body><p>Crea el conjunto de bandas automáticamente y utiliza las herramientas seleccionadas en la pestaña Juego de Bandas</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Crea el conjunto de bandas automáticamente y utiliza las herramientas seleccionadas en la pestaña Juego de Bandas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Create Band set and use Band set tools Crear Juego de Bandas y utilizar sus herramientas - + <html><head/><body><p>Edit metadata</p></body></html> - <html><head/><body><p>Editar metadatos</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Editar metadatos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Band - Banda + + Metadata + Metadatos - - RADIANCE_MULT - RADIANCE_MULT + + <html><head/><body><p >Refresh list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Recargar lista&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - RADIANCE_ADD - RADIANCE_ADD + + Clip coordinates + Coordenadas de Corte - - REFLECTANCE_MULT - REFLECTANCE_MULT + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar límites de ROI temporal para cortar rásters&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - REFLECTANCE_ADD - REFLECTANCE_ADD + + Use temporary ROI for clipping + Usar ROI temporal para cortar - - RADIANCE_MAXIMUM - RADIANCE_MAXIMUM + + <html><head/><body><p>NoData value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valor SinDatos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - REFLECTANCE_MAXIMUM - REFLECTANCE_MAXIMUM + + <html><head/><body><p>Output name prefix</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Prefijo para el nombre de salida&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - K1_CONSTANT - K1_CONSTANT + + clip + clip - - K2_CONSTANT - K2_CONSTANT + + Output name prefix + Prefijo para nombre de salida - - LMAX - LMAX + + Split raster bands + Separar bandas ráster - - LMIN - LMIN + + <html><head/><body><p>Select the image to be split</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona la imagen a separar&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - QCALMAX - QCALMAX + + Select a multiband raster + Selecciona una ráster multibanda - - QCALMIN - QCALMIN + + split + split - - Satellite - Satélite + + PCA + PCA - - Sun elevation - Elevación del Sol + + Input + Entrada - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - <html><head/><body><p>Fecha de adquisición (DATE ACQUIRED)</p></body></html> + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si está seleccionada, solo calcula este número de componentes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Date (YYYY-MM-DD) - Date (YYYY-MM-DD) + + Number of components + Número de componentes - - Earth sun distance - Distancia Tierra-Sol + + <html><head/><body><p>Number of components</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Número de componentes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>SUN ELEVATION</p></body></html> - <html><head/><body><p>Elevación del Sol (SUN ELEVATION)</p></body></html> + + Output + Salida - - <html><head/><body><p>Earth sun distance</p></body></html> - <html><head/><body><p>Distancia de la tierra al Sol</p></body></html> + + Vector to raster + Vectorial a ráster - - Metadata - Metadatos + + Select the vector + Selecciona el vectorial - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> - <html><head/><body><p>Satélite (Ej. LANDSAT8)</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el vectorial&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Sentinel-2 - Sentinel-2 + + <html><head/><body><p>Use the value field of the vector</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar el valor del campo del vector&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Directory containing Sentinel-2 bands - Directorio conteniendo bandas Sentinel-2 + + Use the value field of the vector + Usar el valor del campo del vector - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> - <html><head/><body><p>Activa/Desactiva la corrección atmosférica DOS1</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleccionar el campo con valores&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Sentinel-2 conversion - Conversión de Sentinel-2 + + <html><head/><body><p>Use constant value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar un valor constante&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Quantification value - Valor de Cuantificación + + Use constant value + Usar un valor constante - - Solar irradiance - Irradiancia solar + + <html><head/><body><p>Value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - <html><head/><body><p>Satélite (Ej. Sentinel-2A)</p></body></html> + + Select the type of conversion + Selecciona el tipo de conversión - - ASTER - ASTER + + <html><head/><body><p>Select the type of conversion</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el tipo de conversión&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - ASTER conversion to TOA reflectance and brightness temperature - ASTER convertir a reflectancia TOA y a Temperatura de Brillo + + Select the reference raster + Selecciona el ráster de referencia - - Select file ASTER L1T (.hdf) - Seleccionar archivo ASTER L1T (.hdf) + + <html><head/><body><p>Select the reference raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el ráster de referencia&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - UnitConversionCoeff - UnitConversionCoeff + + Postprocessing + Postprocesamiento - - PixelSize - PixelSize + + Accuracy + Precisión - - UTM zone - Zona UTM + + Select the classification to assess + Selecciona la clasificación a evaluar - - <html><head/><body><p>UTM zone</p></body></html> - <html><head/><body><p>Zona UTM</p></body></html> + + <html><head/><body><p>Select the classification to assess</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona la clasificación para ser evaluada&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - UPPERLEFTM - SUPIZQUIERDAM + + <html><head/><body><p>Select the field of the classification code </p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el campo con el código de la clasificación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Clip multiple rasters - Recortar múltiples rásters + + Classification report + Reporte de la clasificación - - <html><head/><body><p >Refresh list</p></body></html> - <html><head/><body><p >Recargar lista</p></body></html> - - - - Clip coordinates - Coordenadas de Corte - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - <html><head/><body><p>Usar límites de ROI temporal para cortar rásters</p></body></html> - - - - Use temporary ROI for clipping - Usar ROI temporal para cortar - - - - <html><head/><body><p>NoData value</p></body></html> - <html><head/><body><p>Valor SinDatos</p></body></html> - - - - <html><head/><body><p>Output name prefix</p></body></html> - <html><head/><body><p>Prefijo para el nombre de salida</p></body></html> - - - - clip - clip - - - - Output name prefix - Prefijo para nombre de salida - - - - Split raster bands - Separar bandas ráster - - - - <html><head/><body><p>Select the image to be split</p></body></html> - <html><head/><body><p>Selecciona la imagen a separar</p></body></html> - - - - Select a multiband raster - Selecciona una ráster multibanda - - - - split - split - - - - PCA - PCA - - - - Input - Entrada - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - <html><head/><body><p>Si está seleccionada, solo calcula este número de componentes</p></body></html> - - - - Number of components - Número de componentes - - - - <html><head/><body><p>Number of components</p></body></html> - <html><head/><body><p>Número de componentes</p></body></html> - - - - Output - Salida - - - - Vector to raster - Vectorial a ráster - - - - Select the vector - Selecciona el vectorial - - - - <html><head/><body><p>Select the vector</p></body></html> - <html><head/><body><p>Selecciona el vectorial</p></body></html> - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - <html><head/><body><p>Usar el valor del campo del vector</p></body></html> - - - - Use the value field of the vector - Usar el valor del campo del vector - - - - <html><head/><body><p>Select the value field</p></body></html> - <html><head/><body><p>Seleccionar el campo con valores</p></body></html> - - - - <html><head/><body><p>Use constant value</p></body></html> - <html><head/><body><p>Usar un valor constante</p></body></html> - - - - Use constant value - Usar un valor constante - - - - <html><head/><body><p>Value</p></body></html> - <html><head/><body><p>Valor</p></body></html> - - - - Select the type of conversion - Selecciona el tipo de conversión - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - <html><head/><body><p>Selecciona el tipo de conversión</p></body></html> - - - - Select the reference raster - Selecciona el ráster de referencia - - - - <html><head/><body><p>Select the reference raster</p></body></html> - <html><head/><body><p>Selecciona el ráster de referencia</p></body></html> - - - - Postprocessing - Postprocesamiento - - - - Accuracy - Precisión - - - - Select the classification to assess - Selecciona la clasificación a evaluar - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - <html><head/><body><p>Selecciona la clasificación para ser evaluada</p></body></html> - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - <html><head/><body><p>Selecciona el campo con el código de la clasificación</p></body></html> - - - - Land cover change - Cambio de cobertura del suelo - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - <html><head/><body><p align="justify">Si se selecciona, los pixeles que tienen el mismo valor en ambas clasificaciones se reportarán; si está desactivado, se asigna el valor 0 para los pixeles sin cambios</p></body></html> - - - - Report unchanged pixels - Reportar pixeles sin cambios - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - <html><head/><body><p>Selecciona el ráster con la clasificación de referencia</p></body></html> - - - - Select the new classification - Selecciona la nueva clasificación - - - - Select the reference classification - Selecciona la clasificación de referencia - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - <html><head/><body><p>Selecciona un nuevo ráster que será comparado con el ráster de referencia</p></body></html> - - - - Classification report - Reporte de la clasificación - - - + <html><head/><body><p>Select the classification raster</p></body></html> - <html><head/><body><p>Selecciona el ráster con la clasificación</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el ráster con la clasificación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the classification Selecciona la clasificación - + Classification to vector Clasificación a vectorial - + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - <html><head/><body><p>Usa los códigos de la tabla del listado de Firmas para la simbología vectorial</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usa los códigos de la tabla del listado de Firmas para la simbología vectorial&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Use code from Signature list Usar código del listado de Firmas - + <html><head/><body><p>Select the code field</p></body></html> - <html><head/><body><p>Selecciona el código del campo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona el código del campo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C_ID C_ID - + MC_ID MC_ID - + Symbology Simbología - + Reclassification Reclasificación - + <html><head/><body><p>Calculate unique values</p></body></html> - <html><head/><body><p>Calcula valores únicos</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcula valores únicos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - <html><head/><body><p>Selecciona esta casilla para la reclasificación de C ID a MC ID; si está seleccionada, se calculan valores únicos de la lista de Firmas, colocando los viejos valores de C ID y nuevos valores para MC ID</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona esta casilla para la reclasificación de C ID a MC ID; si está seleccionada, se calculan valores únicos de la lista de Firmas, colocando los viejos valores de C ID y nuevos valores para MC ID&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + calculate C ID to MC ID values calcular valores de C ID a MC ID - + Calculate unique values Calcular valores únicos - + Values Valores - + Old value Valor antiguo - + New value Valor Nuevo - - Edit raster - Editar ráster - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - <html><head/><body><p>Deshacer editar (solo para polígonos ROI)</p></body></html> - - - - Select the input raster - Selecciona el ráster de entrada - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - <html><head/><body><p>Selecciona el ráster para ser editado</p></body></html> - - - - <html><head/><body><p>Use expression</p></body></html> - <html><head/><body><p>Usar una expresión</p></body></html> - - - - Use expression - Usar expresión - - - - <html><head/><body><p>Enter expression</p></body></html> - <html><head/><body><p>Ingresa una expresión</p></body></html> - - - - where(raster == 1, 2, raster) - where(raster == 1, 2, raster) - - - - Edit raster values - Editar valores de un ráster - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - <html><head/><body><p>Editar los valores utilizando un vectorial</p></body></html> - - - - Edit values using a vector - Editar valores usando vectorial - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - <html><head/><body><p>Editar valores utilizando ROIs temporales</p></body></html> - - - - Edit values using ROI polygons - Editar valores usando polígonos ROI - - - - Edit options - Opciones de Edición - - - - Classification sieve - Filtrado de la Clasificación - - - + <html><head/><body><p>Select the classification</p></body></html> - <html><head/><body><p>Selecciona la clasificación</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona la clasificación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Size threshold Tamaño de umbral - + <html><head/><body><p>Size threshold in pixels</p></body></html> - <html><head/><body><p>Tamaño del umbral en pixeles</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Tamaño del umbral en pixeles&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Pixel connection Conexión de pixeles - + <html><head/><body><p>Pixel connection</p></body></html> - <html><head/><body><p>Conexión de pixeles</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Conexión de pixeles&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + 4 4 - + 8 8 - - Classification erosion - Erosión de la clasificación - - - + Size in pixels Tamaño en pixeles - + <html><head/><body><p>Size in pixels</p></body></html> - <html><head/><body><p>Tamaño en pixeles</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Tamaño en pixeles&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Class values Valores de Clase - + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - <html><head/><body><p>Ingresa valores de Clases separados por , o -</p></body></html> - - - - Classification dilation - Dilatación de la Clasificación + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ingresa valores de Clases separados por , o -&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band calc Calculadora de Bandas - + Band list Lista de Bandas - - Expression - Expresión - - - - <html><head/><body><p>Not equals</p></body></html> - <html><head/><body><p>No iguales</p></body></html> - - - - != - != - - - - <html><head/><body><p>Equals</p></body></html> - <html><head/><body><p>Iguales</p></body></html> - - - - == - == - - - - <html><head/><body><p>Multiplication</p></body></html> - <html><head/><body><p>Multiplicación</p></body></html> - - - - * - * - - - - <html><head/><body><p>Power</p></body></html> - <html><head/><body><p>Potencia</p></body></html> - - - - ^ - ^ - - - - <html><head/><body><p>Minus</p></body></html> - <html><head/><body><p>Menos</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - <html><head/><body><p>Más</p></body></html> + + <html><head/><body><p>Band list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lista de bandas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - + - + + + Variable + Variable - - <html><head/><body><p>Division</p></body></html> - <html><head/><body><p>División</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si está seleccionada, los pixeles iguales al valor SinDatos serán excluidos del ráster de salida&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - / - / + + <html><head/><body><p>Select a raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona un ráster&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Close parenthesis</p></body></html> - <html><head/><body><p>Cerrar paréntesis</p></body></html> + + Extent: + Extensión: - - ) - ) + + Output raster + Ráster de salida - - <html><head/><body><p>Square root</p></body></html> - <html><head/><body><p>Raíz cuadrada</p></body></html> - - - - √ - + + Band set + Juego de bandas - - <html><head/><body><p>Open parenthesis</p></body></html> - <html><head/><body><p>Abrir paréntesis</p></body></html> + + Band set definition + Definición del Juego de bandas - - ( - ( + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ordenar bandas por nombre (teniendo prioridad el número final)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Greater than</p></body></html> - <html><head/><body><p>Mayor que</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mueve la banda seleccionada hacia abajo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - > - > + + <html><head/><body><p>Move highlighted band up</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mueve la banda seleccionada hacia arriba&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Less than</p></body></html> - <html><head/><body><p>Menor que</p></body></html> + + <html><head/><body><p>Export band set to text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exportar el juego de bandas a un archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - < - < + + <html><head/><body><p>Import band set from text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importar un juego de bandas desde un archivo de texto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - <html><head/><body><p>Escribe una expresión (Ej. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecciona una configuración para establecer el centro de la longitud de onda&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Decision rules - Reglas de decisión + + <html><head/><body><p>Wavelength unit</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Unidad de longitud de onda&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - <html><head/><body><p>Ingresa una o más reglas separadas por punto y coma (Ej. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calcular expresión ingresada en Calculadora de Bandas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Value - Valor + + Band calc expressions + Expresiones en Calculadora de Bandas - - Rule - Regla + + Build band overviews + Construir Vistas Generales - - <html><head/><body><p>Move highlighted rule up</p></body></html> - <html><head/><body><p>Mueve la regla seleccionada hacia arriba</p></body></html> + + Band set tools + Herramientas para Juego de bandas - - <html><head/><body><p>Import rules from text file</p></body></html> - <html><head/><body><p>Importar reglas desde archivo de texto</p></body></html> + + Functions + Funciones - - <html><head/><body><p>Export rules to text file</p></body></html> - <html><head/><body><p>Exportar reglas hacia archivo de texto</p></body></html> + + Settings + Configuración - - <html><head/><body><p>Move highlighted rule down</p></body></html> - <html><head/><body><p>Mueve la regla seleccionada hacia abajo</p></body></html> + + Interface + Interfaz - - <html><head/><body><p>Band list</p></body></html> - <html><head/><body><p>Lista de bandas</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Asignar el nombre de campo Class ID&lt;/p&gt;&lt;p&gt;[máx 10 caracteres]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Variable - Variable + + ROI style + Estilo del ROI - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - <html><head/><body><p>Si está seleccionada, los pixeles iguales al valor SinDatos serán excluidos del ráster de salida</p></body></html> + + <html><head/><body><p>Select temporary ROI color</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleccionar color del ROI temporal&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - <html><head/><body><p>Si está seleccionada, la extensión del ráster de salida será igual que la del ráster seleccionado</p></body></html> + + ROI color + Color del ROI - - Same as - Igual que + + Transparency + Transparencia - - <html><head/><body><p>Select a raster</p></body></html> - <html><head/><body><p>Selecciona un ráster</p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cambia la transparencia del ROI temporal&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - <html><head/><body><p>Si está seleccionada, la extensión del ráster de salida será igual a la intersección con el ráster de entrada</p></body></html> - - - - Intersection - Intersección - - - - Extent: - Extensión: - - - - Output raster - Ráster de salida - - - - Band set - Juego de bandas - - - - <html><head/><body><p>Add band to Band set</p></body></html> - <html><head/><body><p>Agregar bandas al Juego de Bandas</p></body></html> - - - - Band set definition - Definición del Juego de bandas - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - <html><head/><body><p>Ordenar bandas por nombre (teniendo prioridad el número final)</p></body></html> - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - <html><head/><body><p>Mueve la banda seleccionada hacia abajo</p></body></html> - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - <html><head/><body><p>Mueve la banda seleccionada hacia arriba</p></body></html> - - - - <html><head/><body><p>Export band set to text file</p></body></html> - <html><head/><body><p>Exportar el juego de bandas a un archivo de texto</p></body></html> - - - - <html><head/><body><p>Import band set from text file</p></body></html> - <html><head/><body><p>Importar un juego de bandas desde un archivo de texto</p></body></html> - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - <html><head/><body><p>Selecciona una configuración para establecer el centro de la longitud de onda</p></body></html> - - - - <html><head/><body><p>Wavelength unit</p></body></html> - <html><head/><body><p>Unidad de longitud de onda</p></body></html> - - - - Create virtual raster of band set - Crear ráster virtual de Juego de Bandas - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - <html><head/><body><p>Calcular expresión ingresada en Calculadora de Bandas</p></body></html> - - - - Band calc expressions - Expresiones en Calculadora de Bandas - - - - Build band overviews - Construir Vistas Generales - - - - Band set tools - Herramientas para Juego de bandas - - - - Batch - En Lotes - - - - <html><head/><body><p>Enter a batch function</p></body></html> - <html><head/><body><p>Ingrese un lote de funciones</p></body></html> - - - - Functions - Funciones - - - - <html><head/><body><p>Import batch from text file</p></body></html> - <html><head/><body><p>Importar proceso en lotes desde archivo de texto</p></body></html> - - - - <html><head/><body><p>Export batch to text file</p></body></html> - <html><head/><body><p>Exportar proceso en lotes a un archivo de texto</p></body></html> - - - - Settings - Configuración - - - - Interface - Interfaz - - - - Field names of training input - Nombres de campo del Entrenamiento de Entrada - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Asignar el nombre de campo Class ID</p><p>[máx 10 caracteres]</p></body></html> - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Asignar el nombre de campo Macroclass ID</p><p>[máx 10 caracteres]</p></body></html> - - - - ROI style - Estilo del ROI - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - <html><head/><body><p>Seleccionar color del ROI temporal</p></body></html> - - - - ROI color - Color del ROI - - - - Transparency - Transparencia - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - <html><head/><body><p>Cambia la transparencia del ROI temporal</p></body></html> - - - + Variable name Nombre de variable - - <html><head/><body><p>Variable name for expressions</p></body></html> - <html><head/><body><p>Nombre de variable para expresiones</p></body></html> - - - - raster - ráster - - - - Variable name for expressions (tab Reclassification and Edit raster) - Nombre de variable para expresiones (pestaña Reclasificación y Editar ráster) - - - - Group name - Nombre de grupo - - - - <html><head/><body><p>Group name</p></body></html> - <html><head/><body><p>Nombre de grupo</p></body></html> - - - - Class_temp_group - Class_temp_group - - - - Dock - Panel - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - <html><head/><body><p>Si está seleccionado, las noticias sobre SCP son descargadas y mostradas en el panel</p></body></html> - - - - Download news on startup - Descarga noticias al inicio - - - - Processing - Procesado - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - <html><head/><body><p>Activar/Desactivar el sonido cuando el proceso termina</p></body></html> - - - - Play sound when finished - Reproducir sonido cuando termina - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - <html><head/><body><p>Si está seleccionado, crea rásters virtuales para ciertos archivos temporales</p></body></html> - - - - Use virtual raster for temp files - Usar ráster virtual para archivos temporales - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - <html><head/><body><p>Si está seleccionado, se aplica la compresión sin pérdidas a los rásters con el fin de ahorrar espacio en disco</p></body></html> - - - - Raster compression - Compresión Ráster - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - <html><head/><body><p>Asignar RAM disponible para los procesos</p></body></html> - - - - Available RAM (MB) - RAM disponible (MB) - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - <html><head/><body><p>Restaurar al directorio temporal por defecto</p></body></html> - - - - Temporary directory - Directorio temporal - - - - Debug - Depurar - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - <html><head/><body><p>Activar/Desactivar Log de eventos</p></body></html> - - - - Record events in a Log file - Guardar eventos en un archivo Log - - - - <html><head/><body><p>Export the Log file</p></body></html> - <html><head/><body><p>Exportar el archivo Log</p></body></html> - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - <html><head/><body><p>Vaciar el contenido del archivo Log</p></body></html> - - - - Log file - Archivo Log - - - - <html><head/><body><p>Test dependencies</p></body></html> - <html><head/><body><p>Comprobar dependencias</p></body></html> - - - - Test dependencies - Verificar dependencias - - - - Test - Prueba - - - - About - Acerca de - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - Distancia mínima - - - - Spectral Angle Mapping - Mapeo del Angulo Espectral - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - 6 - - - - 1 - 1 - - - - 3 - 3 - - - - 2 - 2 - - - - 11 - - - - - 5 - 5 - - - - 7 - 7 - - - - 8A - - - - - 9 - 9 - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - Bandas de Sentinel-2 {3 ?} - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - Sentinel-3 - - - - Sentinel-3 conversion - Conversión de Sentinel-2 {3 ?} - - - - Directory containing Sentinel-3 bands - Directorio conteniendo bandas Sentinel-2 {3 ?} - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - <html><head/><body><p>Satélite (Ej. Sentinel-2A)</p></body></html> {3A?} - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - Bandas - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - Sentinel-1 - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - Manual del Usuario - - - - Support the SCP - - - - - Use - Usar - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - <html><head/><body><p>Usar las ID de las macroclases para la clasificación</p></body></html> - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - <html><head/><body><p>Usar las ID de las clases para la clasificación</p></body></html> - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - <html><head/><body><p>Abrir pestaña del Algoritmo de peso de banda</p></body></html> - - - - W - W - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - <html><head/><body><p>Seleccionar un algoritmo de clasificación</p></body></html> - - - - Maximum Likelihood - Máxima Probabilidad - - - - Algorithm - Algoritmo - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - <html><head/><body><p>Establecer el umbral de clasificación para todas las firmas</p></body></html> - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - <html><head/><body><p>Abrir la pestaña Umbrales de Firmas</p></body></html> - - - - Threshold - Umbral - - - - Classification - Classificación - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - <html><head/><body><p>Si está seleccionado, se usará la Clasificación de Firmas de Cobertura Terrestre</p></body></html> - - - - LCS - LCS - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - <html><head/><body><p>Abrir pestaña Umbral de Firmas de Cobertura del Suelo LCS-Land Cover Signature</p></body></html> - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - <html><head/><body><p>Si está seleccionado, el Algoritmo elegido se usará solo para las Clases que se sobreponen con pixeles de la Clasificación de Firmas de la Cobertura Terrestre</p></body></html> - - - - only overlap - solo sobreposición - - - - Land Cover Signature Classification - Clasificación de Firmas de la Cobertura Terrestre - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - <html><head/><body><p>Si está seleccionado, el Algoritmo elegido se usará para los pixeles no clasificados de la Clasificación de Firmas de la Cobertura Terrestre</p></body></html> - - - - Algorithm - Algoritmo - - - - Classification output - Resultado de la Clasificación - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - <html><head/><body><p><span >Seleccionar estilo desde archivo qml</span></p></body></html> - - - - <html><head/><body><p>Qml file path</p></body></html> - <html><head/><body><p>Ruta a archivo qml</p></body></html> - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - <html><head/><body><p>Seleccionar una máscara vectorial opcional</p></body></html> - - - - Apply mask - Aplicar máscara - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - <html><head/><body><p>Ruta al archivo de máscara shape opcional</p></body></html> - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - <html><head/><body><p>Crear un archivo shape después del proceso de clasificación</p></body></html> - - - - Create vector - Crear vector - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - <html><head/><body><p>Calcular un reporte de la clasificación</p></body></html> - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - <html><head/><body><p>Si se selecciona, los rásters resultado de la clasificación (uno por Firma) son guardados con la clasificación</p></body></html> - - - - Save algorithm files - Guardar archivos de algoritmos - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> - - - - - <html><head/><body><p>Minumum power</p></body></html> - - - - - <html><head/><body><p>Maximum power</p></body></html> - - - - - <html><head/><body><p>If checked, save classifier</p></body></html> - - - - - Import vector - - - - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - - - - <html><head/><body><p>C ID field</p></body></html> - - - - - <html><head/><body><p>MC ID field</p></body></html> - - - - - <html><head/><body><p>MC Name field</p></body></html> - - - - - <html><head/><body><p>C Name field</p></body></html> - - - - - Vector fields - - - - - Import vector - - - - - <html><head/><body><p>Import vector</p></body></html> - - - - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - - - - Python executable path - - - - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> - - - - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - - - - GDAL installation directory - - - - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> - - - - - Same extent as reference raster - - - - - <html><head/><body><p>Import reclassification table from text file</p></body></html> - - - - - <html><head/><body><p>Export reclassification table to text file</p></body></html> - - - - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - - - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> - - - - - Use alternative search for Sentinel-2 (no authentication required) - - - - - Matrix file (optional) - - - - - neighbor - - - - - Neighbor pixels - - - - - Neighbor pixels - - - - - Neighbor distance in pixels - - - - - <html><head/><body><p>Distance in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> - - - - - Enable writing verification - - - - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - - - - Create virtual raster output - - - - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> - - - - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - - - - Circular - - - - - Calculation -data type - - - - - Python modules path - - - - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - - - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - - - - Virtual download - - - - - <html><head/><body><p>Sort band sets by date</p></body></html> - + + <html><head/><body><p>Variable name for expressions</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nombre de variable para expresiones&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> - + + raster + ráster - - NoData mask - + + Group name + Nombre de grupo - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - + + <html><head/><body><p>Group name</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nombre de grupo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Calculate linear regression - + + Class_temp_group + Class_temp_group - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot - SCP: Gráfico de Firma Espectral + + Dock + Panel - - S - S + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si está seleccionado, las noticias sobre SCP son descargadas y mostradas en el panel&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - MC ID - MC ID + + Download news on startup + Descarga noticias al inicio - - C ID - C ID + + Processing + Procesado - - Color - Color + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activar/Desactivar el sonido cuando el proceso termina&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Activar el puntero para establecer umbrales desde pixel</p></body></html> + + Play sound when finished + Reproducir sonido cuando termina - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>Si se selecciona, el umbral de firma se reduce para excluir la firma de pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si está seleccionado, se aplica la compresión sin pérdidas a los rásters con el fin de ahorrar espacio en disco&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>Si está seleccionado, el umbral de firma se extiende para incluir la firma del pixel</p></body></html> + + Raster compression + Compresión Ráster - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Establecer umbrales desde el ROI temporal</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Asignar RAM disponible para los procesos&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Automatic thresholds - Umbrales Automáticos + + Available RAM (MB) + RAM disponible (MB) - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Establecer umbral Min Max automáticamente</p></body></html> + + <html><head/><body><p>Reset to default temporary directory</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Restaurar al directorio temporal por defecto&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Min Max - Min Max - - - - σ * - σ * + + Temporary directory + Directorio temporal - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Establecer el valor que será multiplicado por la esviación estándar</p></body></html> + + Debug + Depurar - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - <html><head/><body><p>Establecer umbral automáticamente σ</p></body></html> + + + <html><head/><body><p>Export the Log file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exportar el archivo Log&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Undo thresholds</p></body></html> - <html><head/><body><p>Deshacer umbrales</p></body></html> + + Log file + Archivo Log - - Import library - Importar librería + + <html><head/><body><p>Test dependencies</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Comprobar dependencias&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Eliminar fila</p></body></html> + + Test dependencies + Verificar dependencias - - Plot - Gráfico + + Test + Prueba - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - <html><head/><body><p>Agregar las firmas espectrales seleccionadas a la lista de firmas</p></body></html> + + About + Acerca de - - <html><head/><body><p>Calculate spectral distances</p></body></html> - <html><head/><body><p>Calcula las distancias espectrales</p></body></html> + + Align + - - Signature list - Lista de firmas + + Results + - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - <html><head/><body><p>Grafica el rango de valores (desviación estándar o el mínimo máximo definido) para cada firma</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> + - - Band lines - Líneas de bandas + + Cross classification + - - Max characters - Caracteres Máx + + Ancillary data + - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - <html><head/><body><p align="justify">Largo del texto para los nombres en la leyenda del gráfico espectral</p></body></html> + + Products + - - x=0.000000 y=0.000000 - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> + - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> - <html><head/><body><p>Cambiar interactivamente el rango de valores en el gráfico</p></body></html> + + Stack raster bands + - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Ajusta el gráfico a los datos automaticamente</p></body></html> + + Login data + - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Guarda el gráfico en un archivo (jpg, png, pdf)</p></body></html> + + Search + - - Plot value range - Graficar rango de valores + + Search parameters + - - Grid - Cuadrícula + + Product list + - - Signature details - Detalles de firmas + + Download products + - - Spectral distances - Distancias espectrales + + <html><head/><body><p>Export table to text file</p></body></html> + - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile - Selecciona archivo shape de máscara + + Y (Lat) + - - Save classification output - Guardar los resultados de la clasificación + + Date + - - Select a qml style - Selecciona un estilo qml + + Minimum Distance + Distancia mínima - - Select a signature list file - Selecciona un archivo de lista de firma + + Spectral Angle Mapping + Mapeo del Angulo Espectral - - Select a SCP training input - Selecciona una Entrada de Entrenamiento SCP + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> + - - Export SCP training input - Exportar Entrada de Entrenamiento SCP + + Use vector for clipping + - - Select a library file - Selecciona un archivo de librería + + <html><head/><body><p>Select the vector for clipping</p></body></html> + - - Export the highlighted signatures to CSV library - Exportar las firmas seleccionadas a librería CSV + + 6 + 6 - - Calculate signatures - Calcular firmas + + 1 + 1 - - Calculate signatures for highlighted items? - ¿Calcular firmas para los elementos seleccionados? + + 3 + 3 - - Merge signatures - Combinar firmas + + 2 + 2 - - Merge highlighted signatures? - ¿Combinar firmas seleccionadas? + + 11 + - - Delete signatures - Eliminar firmas + + 5 + 5 - - Are you sure you want to delete highlighted ROIs and signatures? - ¿Estás seguro que quieres eliminar los ROIs y las firmas seleccionadas? + + 7 + 7 - - Create SCP training input - Crear Entrenamiento de Entrada SCP + + 8A + - - It appears that the shapefile - Parece que el archivo shape + + 9 + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? - no se encuentran algunos campos que son requeridos para el cálculo de firmas. -¿Deseas agregar los campos requeridos a este archivo shape? + + 10 + - - Undo save ROI - Deshacer guardar ROI + + 12 + - - Semi-Automatic Classification Plugin - Semi-Automatic Classification Plugin + + 20 + - - Zoom to input image extent - Zoom a la extensión de la imagen de entrada + + SMTP server + - - Show/hide the input image - Mostrar/Ocultar la imagen de entrada + + password + - - Select a RGB color composite - Selecciona una composición RGB + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> + - - Local cumulative cut stretch of band set - Cortar estiramiento local acumulativo del juego de bandas + + Send email of completed process to + - - Local standard deviation stretch of band set - Desviación estándar del estiramiento local del juego de bandas + + SMTP process notification + - - Zoom to temporary ROI - Zoom al ROI temporal + + user + - - Show/hide the temporary ROI - Mostrar/Ocultar ROI temporal + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> + - - Create a ROI polygon - Crear un ROI de polígono + + RUN + - - Activate ROI pointer - Activar el puntero ROI + + <html><head/><body><p>Add a new band set</p></body></html> + - - Redo the ROI at the same point - Rehacer el ROI al mismo punto + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> + - - Dist - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> + - - Similarity of pixels (distance in radiometry unit) - Similitud de pixeles (distancia en unidad radiométrica) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> + - - Min - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> + - - Minimum area of ROI (in pixel unit) - Area mínima del ROI (en unidades de pixel) + + Mosaic band sets + - - Max - Máx + + 1, 2 + - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) - Lado de un cuadrado que inscribe al ROI, que define la anchura máxima de los mismos (en unidades de pixel) + + Select input band set + - - Zoom to the classification preview - Zoom a la clasificación preliminar + + <html><head/><body><p>Band set number</p></body></html> + - - Show/hide the classification preview - Muestra/Oculta la clasificación preliminar + + Select the reference vector or raster + - - Activate classification preview pointer - Activa el puntero para clasificación preliminar + + Vector field + - - Redo the classification preview at the same point - Rehacer la clasificación preliminar en el mismo puto + + <html><head/><body><p>Select the reference vector or raster</p></body></html> + - - T - T + + <html><head/><body><p>Select the vector field</p></body></html> + - - Set preview transparency - Establecer la transparencia de la vista preliminar + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> + - - S - S + + Use vector field for output name + - - Set the preview size (in pixel unit) - Establecer el tamaño de la vista preliminar (en unidades de pixel) + + Stack band set + - - Remove temporary files - Eliminar archivos temporales + + Band processing + - - Band set - Juego de bandas + + Basic tools + - - Preprocessing - Preprocesamiento + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> + - - Postprocessing - Postprocesamiento + + Mask class values + - - Band calc - Calculadora de Bandas + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> + - - Spectral plot - Gráfico espectral + + Use buffer of pixel size + - - Scatter plot - Gráfico de dispersión + + Create random points + - - Batch - En Lotes + + Signature threshold + - - Settings - Configuración + + Automatic thresholds + - - User manual - Manual del Usuario + + Convert vector to raster + - - Online help - Ayuda en línea + + Clip band set + - - SCP - SCP + + Split raster bands + - - Test results - Resultados de la prueba + + Mosaic of band sets + - - Information - Información + + Band set list + - - No log file found - No se encuentra el archivo Log + + Mask of band set + - - Select a SCP training input; input is not loaded - Selecciona una Entrada de Entrenamiento SCP, la entrada no se ha cargado + + Combination of band values + - - Select a raster; raster is not loaded - Selecciona un ráster, no se ha cargado el ráster + + Principal Components Analysis of band set + - - Select a point inside the image area - Selecciona un punto dentro del área de la imagen + + Accuracy assessment + - - Data projections do not match. Reproject data to the same projection - Las proyecciones de los datos no coinciden. Reproyecta los datos a la misma proyección + + Classification report + - - Maximum Likelihood threshold must be less than 100 - El umbral de probabilidad máximo debe ser menor que 100 + + Cross classification + - - Spectral Angle Mapping threshold must be less than 90 - El umbral para el Angulo Espectral de Mapeo debe ser menor que 90 + + Classification to vector + - - Select a directory - Selecciona un directorio + + Reclassification + - - At least 3 points are required - Se requieren al menos 3 puntos + + Select input band set (of classifications) + - - Negative IDs are not allowed - No están permitidos los IDs negativos + + Signature threshold + Umbral de firma - - Select at least one signature - Selecciona al menos una firma + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> + - - SCP is recording the Log file - SCP está guardando el archivo Log + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> + - - Signature list file (.slf) created - Se ha creado el archivo de listado de firmas (.slf) + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> + - - No image found. Try with a larger area - No se encontró la imagen. Intenta con un área más grande + + stratified for the values + - - Create a ROI polygon or use a vector - Crea un polígono ROI o utiliza un vectorial + + of first band of band set + - - Define a search area - Define un área de búsqueda + + raster > 0 + - - Error - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> + - - No metadata found inside the input directory (a .txt file whose name contains MTL) - No se encontró metadatos en el directorio de entrada (un archivo .txt cuyo nombre contiene MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> + - - Raster not found - Ráster no encontrada + + <html><head/><body><p>Filter</p></body></html> + - - Error saving signatures - Error guardando firmas + + Advanced search + - - Error opening signatures - Error abriendo firmas + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> + - - Error opening spectral library - Error abriendo librería espectral + + System + - - Error saving spectral library - Error guardando librería espectral + + CPU threads + - - Import failed - Falló la importación + + <html><head/><body><p>Select a type</p></body></html> + - - ROI creation failed - Falló la creación del ROI + + Float32 + - - Internet connection failed - Falló la conexión a internet + + Int16 + - - Error reading raster. Possibly the raster path contains unicode characters - Error leyendo ráster. Posiblemente la ruta contiene caracteres unicode + + Byte + - - Error calculating signature. Possibly ROI is too small - Error calculando firmas. Tal vez el ROI es demasiado pequeño + + Create raster of band set +(stack bands) + - - Unable to split bands - Imposible separar las bandas + + Input NoData + as value + - - Error reading band set. Possibly raster files are not loaded - Error leyendo el Juego de Bandas. Es posible que los archivos ráster no se hayan cargado + + External programs + - - Clip area outside image. Check the raster projection - Area de corte fuera de la imagen. Revisa la proyección del ráster + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> + - - Unable to merge. Signatures have different unit or wavelength - Imposible combinar. Las Firmas tienen diferente unidad de longitud de onda + + <html><head/><body><p>Select a statistic</p></body></html> + - - Unable to calculate. Expression error - Imposible calcular. Error en la expresión + + Select a statistic + - - Unable to calculate. Metadata error - Imposible calcular. Error en metadatos + + <html><head/><body><p>Enter a value</p></body></html> + - - Unable to find images - Imposible encontrar imágenes + + Statistic + - - Unable to connect - Imposible conectar + + Project + - - Unable to load image - Imposible cargar imagen + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> + - - Attribute table error - Error en tabla de atributos + + Create RGB composite of band set when a project is loaded + - - Unable to pansharpen: missing bands - Imposible realizar pansharpen: bandas ausentes + + User manual + Manual del Usuario - - Unable to calculate - Imposible calcular + + Use + Usar - - Error reading raster. Possibly bands are not aligned - Error leyendo ráster. Es posible que las bandas no estén alineadas + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar las ID de las macroclases para la clasificación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Unable to get raster projection. Try to reproject the raster - Imposible obtener la proyección del ráster. Intenta reproyectar el ráster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usar las ID de las clases para la clasificación&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Memory error. Please, decrease decimal precision - Error de memoria. Por favor, disminuye la precisión decimal + + W + W - - Error calculating plot - Error calculando el gráfico + + Maximum Likelihood + Máxima Probabilidad - - SSL connection error. Please see the FAQ of the plugin user manual for solving this - Error de conexión SSL. Por favor mira las FAQ o el Manual del Usuario del complemento para resolver esto + + Algorithm + Algoritmo - - Warning - Advertencia + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Establecer el umbral de clasificación para todas las firmas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - It appears that SciPy is not correctly installed. Please, update QGIS - Parece que SciPy no está instalado correctamente. Por favor, actualiza QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Abrir la pestaña Umbrales de Firmas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Wavelength already present - Longitud de onda ya presente + + Classification + Classificación - - Wavelength unit not provided in band set - No se ha indicado la unidad de longitud de onda en el Juego de Bandas + + Processing setting + - - RAM value was too high. Value has been decreased automatically - El valor de RAM era demasiado alto. El valor se ha disminuido automáticamente + + Help + - - Unable to load the virtual raster. Please create it manually - Imposible cargar el ráster virtual. Por favor procede a crearlo manualmente + + Tool + - - Unable to proceed. The raster must be in projected coordinates - Imposible continuar. El ráster debe estar en coordenadas proyectadas + + Load classifier + - - Incorrect expression - Expresión incorrecta + + Reproject raster bands + - - Unable to access the temporary directory - Imposible acceder al directorio temporal + + Use EPSG code + - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude - Reduce la extensión del área de búsqueda en 10 grados de latitud y 10 grados de longitud + + reproj + - - Macroclass symbology is missing - No se encuentra la simbología de la Macroclase + + <html><head/><body><p>EPSG value</p></body></html> + - - Missing bands - Bandas perdidas + + <html><head/><body><p>X resolution</p></body></html> + - - No metadata found inside the input directory. Default values will be used - No se encuentran metadatos en el directorio de entrada. Se usarán los valores por defecto + + <html><head/><body><p>Y resolution</p></body></html> + - - Select a shapefile - Selecciona un archivo shape + + <html><head/><body><p>Align to raster</p></body></html> + - - Set thresholds - Establecer umbrales + + Align to raster + - - Are you sure you want to set thresholds for several signatures? - ¿Estás seguro que quieres establecer umbrales para varias firmas? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> + - - Save error matrix raster output - Guardar matriz de error ráster + + same extent as reference + - - Classification - Classificación + + Y resolution + - - ErrMatrixCode - ErrMatrixCode + + X resolution + - - Reference - Referencia + + <html><head/><body><p>NoData value of the output raster</p></body></html> + - - PixelSum - PixelSum + + Int32 + - - Total - Total + + UInt32 + - - Overall accuracy [%] = - Precisión total [%] = + + UInt16 + - - Kappa hat classification = - Clasificación Kappa = + + <html><head/><body><p>If checked, set a scale</p></body></html> + - - Reset weights - Restaurar pesos + + <html><head/><body><p>Scale</p></body></html> + - - Are you sure you want to reset weights? - ¿Estás seguro que quieres restaurar los pesos? + + <html><head/><body><p>If checked, set an offset</p></body></html> + - - Select a HDF file - Selecciona un archivo HDF + + Output +NoData value + - - Clear rules - Borrar reglas + + Set +scale + - - Are you sure you want to clear the rules? - ¿Estás seguro que quieres borrar las reglas? + + Set +offset + - - Select a text file of rules - Selecciona un archivo de reglas + + Calculation process + - - Save the rules to file - Guarda las reglas en un archivo + + Resampling method + - - Save raster output - Guarda el ráster de salida + + average + - - Select a raster - Selecciona un ráster + + sum + - - Clear band set - Borrar juego de bandas + + maximum + - - Are you sure you want to clear the band set? - ¿Estás seguro que quieres borrar el juego de bandas? + + minimum + - - Save the band set to file - Guardar el juego de bandas a un archivo + + mode + - - Select a band set file - Selecciona un archivo de juego de bandas + + median + - - Remove band - Quitar banda + + nearest_neighbour + - - Are you sure you want to remove the selected bands from band set? - ¿Estás seguro que quieres quitar las bandas seleccionadas del juego de bandas? + + first_quartile + - - Save virtual raster - Guardar ráster virtual + + third_quartile + - - Save raster - Guardar ráster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> + - - Build overviews - Construir vistas generales + + Resample pixel factor + - - Do you want to build the external overviews of bands? - ¿Quieres construir vistas generales externas? + + <html><head/><body><p>Resample factor</p></body></html> + - - Select a batch file - Seleccionar un archivo de lotes + + <html><head/><body><p>Select the resampling method</p></body></html> + - - Save the batch to file - Guardar los lotes en un archivo + + Output type + - - Save classification report - Guardar el reporte de clasificación + + Auto + - - Unknown - Desconocido + + <html><head/><body><p>If checked, change output NoData value</p></body></html> + - - Class - Clase + + Change output NoData value + - - Percentage % - Porcentaje % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> + - - Select a directory where to save clipped rasters - Selecciona un directorio para guardar los rásters cortados + + Dissolve output + - - Save output - Guardar salida + + Use value as NoData + - - Searching ... - Buscando ... + + Use value +as NoData + - - Download the images in the table (requires internet connection) - Descarga las imágenes de la tabla (se requiere conexión a internet) + + <html><head/><body><p>Set incremental new values</p></body></html> + - - Export download links - Exportar enlaces de descarga + + Incremental new values + - - Reset signature list - Restaurar lista de firmas + + Output NoData value + - - Are you sure you want to clear the table? - ¿Estás seguro que quieres borrar la tabla? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> + - - Save land cover change raster output - Guardar el ráster de salida de la clasificación + + C Name field + - - ReferenceClass - ReferenceClass + + MC Name field + - - NewClass - NewClass + + MC Name + - - Select a MTL file - Seleccionar archivo MTL + + C Name + - - Save the point list to file - Guardar la lista de puntos a un archivo + + <html><head/><body><p>Set the number of CPU threads </p></body></html> + - - Principal Components Analysis - Análisis de Componentes Principales + + Import vector + - - Covariance matrix - Matriz de covarianza + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + - - Bands - Bandas + + <html><head/><body><p>C ID field</p></body></html> + - - Correlation matrix - Matriz de correlación + + <html><head/><body><p>MC ID field</p></body></html> + - - Eigen vectors - Vectores propios + + <html><head/><body><p>MC Name field</p></body></html> + - - Vector_ - Vector_ + + <html><head/><body><p>C Name field</p></body></html> + - - Eigen values - Valores propios + + Vector fields + - - Accounted variance - Varianza explicada + + Import vector + - - Cumulative variance - Varianza acumulativa + + <html><head/><body><p>Import vector</p></body></html> + - - Reset RGB list - Restaurar lista RGB + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + - - Are you sure you want to clear the RGB list? - ¿Estás seguro de querer borrar la lista RGB? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + - - RGB list - Lista RGB + + GDAL installation directory + - - Calculate all the RGB combinations? - ¿Calcular todas las combinaciones RGB? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> + - - Save the RGB list to file - Guardar la lista RGB en un archivo + + <html><head/><body><p>Export reclassification table to text file</p></body></html> + - - Select a XML file - Selecciona un archivo XML + + Matrix file (optional) + - - Transparency - Transparencia + + Neighbor pixels + - - Save Log file - Guardar archivo de Log + + Neighbor distance in pixels + - - Reset field names - Restaurar nombres de campo + + <html><head/><body><p>Distance in pixels</p></body></html> + - - Are you sure you want to reset field names? - ¿Estás seguro que quieres restaurar los nombres de campo? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + - - Reset variable name - Restaurar el nombre de la variable + + Create virtual raster output + - - Are you sure you want to reset variable name? - ¿Estás seguro que quieres restaurar el nombre de la variable? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> + - - Reset group name - Restaurar nombre de grupo + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + - - Are you sure you want to reset group name? - ¿Estás seguro que quieres restaurar el nombre del grupo? + + Circular + - - Change temporary directory - Cambiar directorio temporal + + Calculation +data type + - - Are you sure you want to change the temporary directory? - ¿Estás seguro que quieres cambiar el directorio temporal? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + - - Reset temporary directory - Restaurar directorio temporal + + Virtual download + - - Are you sure you want to reset the temporary directory? - ¿Estás seguro que quieres restaurar el directorio temporal? + + <html><head/><body><p>Sort band sets by date</p></body></html> + - - Reset thresholds - Restaurar umbrales + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + - - Are you sure you want to reset thresholds? - ¿Estás seguro que quieres restaurar los umbrales? + + Calculate linear regression + - - Delete scatter plot - Eliminar gráfico de dispersión + + Create virtual raster +of band set + - - Are you sure you want to delete highlighted scatter plots? - ¿Estás seguro que quieres eliminar los gráficos de dispersión seleccionados? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> + - - Save plot to file - Guardar gráfico en archivo + + Wavelength unit + Unidad de longitud de onda - - Edit value range - Editar rango de valores + + Wavelength + - - Are you sure you want to edit the value range for several signatures? - ¿Estás seguro que quieres editar el rango de valores para varias firmas? + + Band quick settings + - - Add to Signature list - Agregar a la lista de Firmas + + Band set table + - - Are you sure you want to add highlighted signatures to the list? - ¿Estás seguro que quieres agregar las firmas seleccionadas a la lista? + + Active band set + - - Are you sure you want to delete highlighted signatures? - ¿Estás seguro que quieres borrar las firmas seleccionadas? + + Root directory + - - Values - Valores + + Script + - - Undo thresholds - Deshacer umbrales + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> + - - Are you sure you want to undo thresholds? - ¿Estás seguro que quieres deshacer los umbrales? + + Copy + - - Multiple ROI creation - Creación de ROI múltiples + + Band dilation + - - Import signatures - Importar firmas + + Output name + - - Export signatures - Exportar librerías + + dilation_ + - - Algorithm band weight - Algoritmo peso de banda + + Virtual output + - - Signature threshold - Umbral de firma + + <html><head/><body><p>Enter output name</p></body></html> + - - LCS threshold - Umbral LCS + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> + - - Landsat - Landsat + + erosion_ + - - Sentinel-2 - Sentinel-2 + + Band erosion + - - ASTER - ASTER + + Band sieve + - - Clip multiple rasters - Recortar múltiples rásters + + sieve_ + - - Split raster bands - Separar bandas ráster + + Script (copy the code in a Python shell) + - - PCA - PCA + + Script + - - Vector to raster - Vectorial a ráster + + <html><head/><body><p>Enter an expression</p></body></html> + - - Accuracy - Precisión + + Expression + - - Land cover change - Cambio de cobertura del suelo + + NoData +mask + - - Classification report - Reporte de la clasificación + + UL X + - - Classification to vector - Clasificación a vectorial + + UL Y + - - Reclassification - Reclasificación + + LR X + - - Edit raster - Editar ráster + + LR Y + - - Classification sieve - Filtrado de la Clasificación + + Output +data type + - - Classification erosion - Erosión de la clasificación + + False + - - Classification dilation - Dilatación de la Clasificación + + True + - - About - Acerca de + + None + - - Interface - Interfaz + + <html><head/><body><p>Upperleft X</p></body></html> + - - Debug - Depurar + + <html><head/><body><p>Upper-left Y</p></body></html> + - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 - Sentinel-3 + + cloud_cover + - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name - Nombre de banda + + collection + - - Center wavelength - Centro de longitud de onda + + size + - - Multiplicative Factor - Factor Multiplicativo + + uid + - - Additive Factor - Factor Aditivo + + preview + - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit - Unidad de longitud de onda + + Bands + - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> + - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing - Procesado + + <html><head/><body><p>Use NoData mask</p></body></html> + - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> + - - C ID - C ID + + Save to file + - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type - Tipo + + SCP: Spectral Signature Plot + SCP: Gráfico de Firma Espectral - - Color - Color + + S + S - - SCPID - + + MC ID + MC ID - - Zoom to highlighted items - + + C ID + C ID - - Clear selection - + + Color + Color - - Collapse/expand all - + + <html><head/><body><p >Delete row</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Eliminar fila&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Merge highlighted items - + + Plot + Gráfico - - Calculate signatures for highlighted items - + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Agregar las firmas espectrales seleccionadas a la lista de firmas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Delete highlighted items - + + Signature list + Lista de firmas - - Change MC ID for highlighted items - + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Grafica el rango de valores (desviación estándar o el mínimo máximo definido) para cada firma&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Add highlighted items to spectral plot - + + Band lines + Líneas de bandas - - Add highlighted items to scatter plot - + + Max characters + Caracteres Máx - - Change Macroclass ID - + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Largo del texto para los nombres en la leyenda del gráfico espectral&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Change the Macroclass ID for highlighted items to - + + x=0.000000 y=0.000000 + x=0.000000 y=0.000000 - - Properties - + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajusta el gráfico a los datos automaticamente&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Zoom to - + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Guarda el gráfico en un archivo (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Check/uncheck - + + Plot value range + Graficar rango de valores - - Check/uncheck highlighted items - + + Grid + Cuadrícula - - Clear selection of highlighted items - + + Signature details + Detalles de firmas - - Collapse/expand all macroclasses - + + Spectral distances + Distancias espectrales - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot - + + Delete signatures + Eliminar firmas - - Add to scatter plot - + + Delete scatter plot + Eliminar gráfico de dispersión - - Properties for highlighted items - + + Are you sure you want to delete highlighted scatter plots? + ¿Estás seguro que quieres eliminar los gráficos de dispersión seleccionados? - - Import - + + Save plot to file + Guardar gráfico en archivo - - Import spectral signatures - + + Add to Signature list + Agregar a la lista de Firmas - - Export - + + Are you sure you want to add highlighted signatures to the list? + ¿Estás seguro que quieres agregar las firmas seleccionadas a la lista? - - Export highlighted items - + + Are you sure you want to delete highlighted signatures? + ¿Estás seguro que quieres borrar las firmas seleccionadas? - - Select a reclassification file - + + Values + Valores - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_fr.qm b/i18n/semiautomaticclassificationplugin_fr.qm index 3da694e..acaa307 100644 Binary files a/i18n/semiautomaticclassificationplugin_fr.qm and b/i18n/semiautomaticclassificationplugin_fr.qm differ diff --git a/i18n/semiautomaticclassificationplugin_fr.ts b/i18n/semiautomaticclassificationplugin_fr.ts old mode 100644 new mode 100755 index a53afac..5077b36 --- a/i18n/semiautomaticclassificationplugin_fr.ts +++ b/i18n/semiautomaticclassificationplugin_fr.ts @@ -1,212 +1,188 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - <html><head/><body><p><span >Calcul de bande</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Calcul de bande&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Preprocessing</p></body></html> - <html><head/><body><p>Pré-traitement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pré-traitement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Postprocessing</p></body></html> - <html><head/><body><p>Post-traitement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Post-traitement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>User manual</p></body></html> - <html><head/><body><p>Manuel d'utilisateur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Manuel d'utilisateur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Input file path</p></body></html> - <html><head/><body><p>Chemin du fichier en entrée</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Chemin du fichier en entrée&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Open a training input</span></p></body></html> - <html><head/><body><p><span >Ouvrir un fichier de données d'entrainement</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Ouvrir un fichier de données d'entrainement&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - <html><head/><body><p><span >Créer une nouvelle donnée d'entrainement</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Créer une nouvelle donnée d'entrainement&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Graphique - + <html><head/><body><p><span >Band set</span></p></body></html> - <html><head/><body><p><span >Jeu de bandes</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Jeu de bandes&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + MC ID MC ID - + C ID C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - <html><head/><body><p>Ajouter les éléments surlignés au nuage de points</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter les éléments surlignés au nuage de points&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + ... ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - <html><head/><body><p>Importer des signatures spectrales </p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importer des signatures spectrales &lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import library Importer des signatures spectrales - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Exporter des signatures spectrales</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exporter des signatures spectrales&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Delete highlighted items</p></body></html> - <html><head/><body><p>Supprimer les éléments surlignés</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Supprimer les éléments surlignés&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - <html><head/><body><p>Calculer les signatures pour les éléments surlignés</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer les signatures pour les éléments surlignés&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - <html><head/><body><p >Fusionner les signatures spectrales surlignées pour obtenir la signature moyenne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Fusionner les signatures spectrales surlignées pour obtenir la signature moyenne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Ajouter les signatures spectrales surlignées au graphique</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Ajouter les signatures spectrales surlignées au graphique&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - <html><head/><body><p>Afficher une valeur d'indice de végétation avec le curseur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher une valeur d'indice de végétation avec le curseur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Display Afficher - + <html><head/><body><p>Select a vegetation index</p></body></html> - <html><head/><body><p>Sélectionner un indice de végetation</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un indice de végetation&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + NDVI NDVI - + EVI EVI - + Custom Personnalisé - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - <html><head/><body><p>Formule personnalisée (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - <html><head/><body><p>Nom de classe de la signature ROI</p></body></html> - - - - C 1 - C 1 + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nom de classe de la signature ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - <html><head/><body><p>Identifiant de la macroclasse de la signature ROI</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Identifiant de la macroclasse de la signature ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - <html><head/><body><p>Nom de la macroclasse de la signature ROI</p></body></html> - - - - MC 1 - MC 1 - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - <html><head/><body><p>Identifiant de classe de la signature ROI</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nom de la macroclasse de la signature ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Undo ROI save</p></body></html> - <html><head/><body><p >Annuler la sauvegarde des ROI</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Annuler la sauvegarde des ROI&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p >Ajouter la signature spectrale des ROI à la liste des signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Ajouter la signature spectrale des ROI à la liste des signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - <html><head/><body><p >Sauver les ROI temporaires dans les données d'entrainement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Sauver les ROI temporaires dans les données d'entrainement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - <html><head/><body><p>Actualiser automatiquement la région d'intérêt lorsque les paramètres changent</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Actualiser automatiquement la région d'intérêt lorsque les paramètres changent&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Band number</p></body></html> Numéro de bande - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - <html><head/><body><p>Calculer la ROI sur une seule bande</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer la ROI sur une seule bande&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - <html><head/><body><p>Calculer automatiquement le graphique pour la ROI temporaire</p></body></html> - - - - SCP &Dock - Menu SCP + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer automatiquement le graphique pour la ROI temporaire&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; @@ -214,157 +190,173 @@ Accueil - + News - + <html><head/><body><p>Batch</p></body></html> - + <html><head/><body><p>Download products</p></body></html> - <html><head/><body><p>Téléchargement produits</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Téléchargement produits&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Band processing</p></body></html> - <html><head/><body><p>Traitement de bande</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Traitement de bande&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Basic tools</p></body></html> - <html><head/><body><p>Outils basiques</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Outils basiques&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + User manual - Manuel d'utilisateur + Manuel d'utilisateur - + <html><head/><body><p>Ask a question</p></body></html> - <html><head/><body><p>Poser une question</p></body></html> - - - - Ask a question - Poser une question - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - <html><head/><body><p><span style=" color:#ffffff;">Soutenir SCP</span></p></body></html> - - - - Support the SCP - Soutenir SCP + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Poser une question&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Training input - Entrée données d'entrainement - - - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - <html><head/><body><p>Sauvegarder automatiquement les données d'entrainement quand une ROI est sauvegardée</p></body></html> + Entrée données d'entrainement - + Autosave Sauvegarde auto - + Signature Signature - + ROI options Options ROI - + Rapid ROI b. ROI rapide b. - + A&uto-refresh ROI Actualiser auto. la ROI - + Auto-plot Graphique auto. - + <html><head/><body><p>Filter</p></body></html> - + Filter Filtre - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list ROI & Liste des signatures - + C Name Nom de C - + MC Name Nom de MC - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + SCP Dock + + + + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> + + + + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> + + + + + Support forum + + + + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + + + + Maximum training buffer + + + + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> + + + + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> + + + + + <html><head/><body><p></p></body></html> - SCP_Welcome + SCP_Widget - - Welcome to Semi-Automatic Classification Plugin - Bienvenue dans le Semi-Automatic Classification Plugin + + Semi-Automatic Classification Plugin + - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> + + <html><head/><body><p>Select all</p></body></html> + + + Plot + Graphique + ScatterPlot @@ -374,6620 +366,3631 @@ p, li { white-space: pre-wrap; } SCP: Nuage de points - + S S - + MC ID MC ID - + C ID C ID - + Color Couleur - - Scatter raster - Nuage de points du raster - - - + Calculate Calculer - + <html><head/><body><p>Calculate scatter plot</p></body></html> - <html><head/><body><p>Calculer le nuage de points</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer le nuage de points&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> - <html><head/><body><p>Calculer et afficher le nuage de points</p></body></html> - - - - <html><head/><body><p>Calculate and save to signature list</p></body></html> - <html><head/><body><p>Calculer et sauvegarder dans la liste des signatures</p></body></html> - - - + x=0.000000 y=0.000000 - + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Adapter automatiquement le graphique aux données</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Adapter automatiquement le graphique aux données&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Sauvegarder le graphique (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sauvegarder le graphique (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Graphique - + Colormap Couleur de carte - - <html><head/><body><p>Select a colormap</p></body></html> - <html><head/><body><p>Sélectionner une couleur de carte</p></body></html> - - - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> - <html><head/><body><p>Sélectionner une couleur pour la signature surlignée</p></body></html> - - - - Extent - Etendue - - - - <html><head/><body><p>Select extent of scatter raster</p></body></html> - <html><head/><body><p>Sélectionner l'étendue du nuage de points du raster</p></body></html> - - - - same as display - comme l'affichage - - - - same as image - comme l'image - - - - <html><head/><body><p>Create selection polygons</p></body></html> - <html><head/><body><p>Créer des polygones de sélection</p></body></html> - - - - color - couleur - - - - <html><head/><body><p>Select polygon color</p></body></html> - <html><head/><body><p>Sélectionner la couleur du polygone</p></body></html> - - - - <html><head/><body><p>Remove selection polygons</p></body></html> - <html><head/><body><p>Retirer les polygones de sélection</p></body></html> - - - + Band Y Bande Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - <html><head/><body><p align="justify">Bande Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Bande Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band X Bande X - + <html><head/><body><p align="justify">Band X</p></body></html> - <html><head/><body><p align="justify">Bande X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Bande X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Use custom decimal precision</p></body></html> - <html><head/><body><p>Utiliser une précision décimale personnalisée</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser une précision décimale personnalisée&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Precision Précision - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Supprimer une ligne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Supprimer une ligne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Graphique - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - <html><head/><body><p>Calculer le nuage de points pour une ROI temporaire</p></body></html> - - - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - <html><head/><body><p>Calculer le nuage de point sur l'étendue actuelle d'affichage</p></body></html> - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - <html><head/><body><p>Calculer le nuage de point sur l'image entière</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer le nuage de points pour une ROI temporaire&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Scatter list Liste des nuages de points - + MC Name Nom de MC - + C Name Nom de C - - + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> + + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - <html><head/><body><p>Pré-traitement des images</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pré-traitement des images&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Preprocess images Prétraitement des images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - <html><head/><body><p>Charger les images dans QGIS après téléchargement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Charger les images dans QGIS après téléchargement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Load bands in QGIS Charger les bandes dans QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - <html><head/><body><p>Télécharger les images de la liste si les aperçus correspondant sont chargés dans QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Télécharger les images de la liste si les aperçus correspondant sont chargés dans QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Only if preview in Layers Seulement si les aperçus sont chargés en couche - + <html><head/><body><p><span >Run</span></p></body></html> - <html><head/><body><p><span >Lancer</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Lancer&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import library Importer la bibliothèque de signatures - + <html><head/><body><p>Export download links to a text file</p></body></html> - <html><head/><body><p>Exporter les liens de téléchargement dans un fichier</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporter les liens de téléchargement dans un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Set area in the map</p></body></html> - <html><head/><body><p>Mettre l'aire sur la carte</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mettre l'aire sur la carte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right X</p></body></html> - <html><head/><body><p>Bas droit X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Bas droit X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right Y</p></body></html> - <html><head/><body><p>Bas droit Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Bas droit Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Upper left X</p></body></html> - <html><head/><body><p>Haut gauche X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Haut gauche X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Upper left Y</p></body></html> - <html><head/><body><p>Haut gauche Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Haut gauche Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Show / hide area</p></body></html> - <html><head/><body><p>Afficher/cacher l'aire</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher/cacher l'aire&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Show Afficher - + <html><head/><body><p>Find images</p></body></html> - <html><head/><body><p>Chercher des images</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Chercher des images&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Find Chercher - + yyyy-MM-dd yyyy-MM-dd - + Max cloud cover (%) Max couvert nuageux (%) - + to - jusqu'à + jusqu'à - + Date from Date depuis - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - <html><head/><body><p>Max couvert nuageux</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Max couvert nuageux&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Filter Filtre - + <html><head/><body><p>Filter images</p></body></html> Filtrer les images - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Supprimer une ligne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Supprimer une ligne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Graphique - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - <html><head/><body><p>Afficher un aperçu des images surlignées sur la carte</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher un aperçu des images surlignées sur la carte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Reset</span></p></body></html> - <html><head/><body><p><span >Réinitialiser</span></p></body></html> - - - - AcquisitionDate - - - - - CloudCover - + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Réinitialiser&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min_lat - + min_lon - + max_lat - + max_lon - + Preview Aperçu - - Download options - Options de téléchargement - - - + <html><head/><body><p >Select all</p></body></html> - <html><head/><body><p >Tout sélectionner</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Tout sélectionner&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - <html><head/><body><p>Si coché, les identifiants seront mémorisé par Qgis</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, les identifiants seront mémorisé par Qgis&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + remember garder en mémoire - + <html><head/><body><p>Password</p></body></html> - <html><head/><body><p>Mot de passe</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mot de passe&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Password Mot de passe - + <html><head/><body><p>User name</p></body></html> - <html><head/><body><p>Nom d'utilisateur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nom d'utilisateur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + User Utilisateur - - <html><head/><body><p>Login Sentinels</p></body></html> - <html><head/><body><p>Login Sentinels</p></body></html> - - - - Service - Service - - - - Sentinel-2 bands - - - - + Multiple ROI creation Creation de ROI multiple - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - <html><head/><body><p align="justify">Distance minimum entre les points</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Distance minimum entre les points&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - <html><head/><body><p align="justify">Taille de la grille dans laquelle les points sont créés aléatoirement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Taille de la grille dans laquelle les points sont créés aléatoirement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Create points Créer des points - + Number of points Nombre de points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - <html><head/><body><p align="justify">Nombre de points créés aléatoirement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Nombre de points créés aléatoirement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create points</p></body></html> - <html><head/><body><p>Créer des points</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer des points&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - <html><head/><body><p>Créer des points aléatoires avec une distance minimale</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer des points aléatoires avec une distance minimale&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - <html><head/><body><p>Créer des points aléatoires dans chaque cellule de la grille avec cette taille</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer des points aléatoires dans chaque cellule de la grille avec cette taille&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + inside grid dans la grille - + Point coordinates and ROI definition Coordonnées des points et définition des ROI - + X - + Y - + MC ID MC ID - + C ID C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - <html><head/><body><p >Ajouter une ligne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Ajouter une ligne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Export point list to text file</p></body></html> - <html><head/><body><p >Exporter la liste de point dans un fichier</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exporter la liste de point dans un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Import point list from text file</p></body></html> - <html><head/><body><p >Importer la liste de point depuis un fichier</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Importer la liste de point depuis un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - <html><head/><body><p>Ajouter les signatures spectrales de la ROI à la liste des signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter les signatures spectrales de la ROI à la liste des signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Calculate sig. Calculer les signatures - + Run Lancer - + Import signatures Importer des signatures - + Import library file Importer une bibliothèque de signatures - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - <html><head/><body><p>Sélectionner un fichier: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - <html><head/><body><p><span >Ouvrir un fichier</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Ouvrir un fichier&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Open a file</p></body></html> - <html><head/><body><p>Ouvrir un fichier</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ouvrir un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p>Ajouter les signatures spectrales de la ROI à la liste des signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter les signatures spectrales de la ROI à la liste des signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Download USGS Spectral Library Télécharger USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - <html><head/><body><p>Sélectionner un chapitre</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un chapitre&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a library</p></body></html> - <html><head/><body><p>Sélectionner une bibliothèque de signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner une bibliothèque de signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import spectral library Importer une bibliothèque de signatures - + <html><head/><body><p>Import spectral library</p></body></html> - <html><head/><body><p>Importer une bibliothèque de signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importer une bibliothèque de signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Library Description (requires internet connection) Description de la bibliothèque (nécessite une connexion internet) - + Export signatures Exporter les signatures - + Export Exporter - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - <html><head/><body><p>Exporter comme fichier CSV (.csv)</p></body></html> - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - <html><head/><body><p>Exporter comme fichier SCP (*.scp)</p></body></html> - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Exporter les signatures spectrales surlignés</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Exporter les signatures spectrales surlignés&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - <html><head/><body><p>Sélectionner un dossier où les signatures surlignées seront sauvegardées comme .csv</p></body></html> - - - - Algorithm band weight - Algorithme : poids des bandes - - - - Band name - Nom de bande + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un dossier où les signatures surlignées seront sauvegardées comme .csv&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Reset</p></body></html> - <html><head/><body><p >Réinitialiser</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Réinitialiser&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Set</p></body></html> - <html><head/><body><p >Fixer</p></body></html> - - - - Set weight - Fixer le poids + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Fixer&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Set a value</p></body></html> - <html><head/><body><p>Utiliser la valeur</p></body></html> - - - - Automatic weight - Poids automatique + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser la valeur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Signature threshold Seuil des signatures - - MD Threshold - - - - - ML Threshold - - - - - SAM Threshold - - - - + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Utilise une valeur qui sera multiplié par l'écart type</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utilise une valeur qui sera multiplié par l'écart type&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Set threshold Utiliser un seuil - - Automatic thresholds - Seuils automatiques - - - - LCS threshold - Seuil LCS - - - - Color [overlap MC_ID-C_ID] - Couleur [superposition MC_ID-C_ID] - - - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Ajouter les signatures surlignés au graphique</p></body></html> - - - - Min Max - - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Utiliser un seuil automatique Min Max</p></body></html> - - - - From pixel - pixel - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Activer le paramétrage des seuils en pointant sur les pixels</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>Si coché, le seuil de signature est augmenté pour inclure la signature des pixels</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>Si coché, le seuil de signature est réduit pour exclure la signature des pixels </p></body></html> - - - - From ROI - ROI - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Utiliser les seuils de la ROI temporaire</p></body></html> - - - - RGB list - Liste RGB - - - + <html><head/><body><p>Sort RGB automatically</p></body></html> - <html><head/><body><p>Ordonner les RGB automatiquement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ordonner les RGB automatiquement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB down</p></body></html> - <html><head/><body><p>Descendre le RGB surligné</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Descendre le RGB surligné&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB up</p></body></html> - <html><head/><body><p>Monter le RGB surligné</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Monter le RGB surligné&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Export RGB list to text file</p></body></html> - <html><head/><body><p>Exporter la liste de RGB</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporter la liste de RGB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Import RGB list from text file</p></body></html> - <html><head/><body><p>Importer une liste de RGB</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importer une liste de RGB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + RGB - + Automatic RGB RGB automatique - + Band combinations Combinaisons de bandes - + <html><head/><body><p>Add all combinations of bands</p></body></html> - <html><head/><body><p>Ajouter toutes les combinaisons de bandes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter toutes les combinaisons de bandes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Preprocessing Pré-traitement - - Landsat - Landsat - - - - Directory containing Landsat bands - Dossier contenant les bandes Landsat - - - - Landsat conversion to TOA reflectance and brightness temperature - Conversion des bandes Landsat en réflectance TOA et température de surface - - - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> - <html><head/><body><p>Activer/Désactiver le calcul des bandes thermiques en celsius</p></body></html> - - - - Brightness temperature in Celsius - Température de surface en celsius - - - + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - <html><head/><body><p>Activer/Désactiver la correction atmosphérique DOS1 (thermal band is not corrected)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activer/Désactiver la correction atmosphérique DOS1 (thermal band is not corrected)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Apply DOS1 atmospheric correction Appliquer correction atmosphérique DOS1 - + <html><head/><body><p>No data value</p></body></html> - <html><head/><body><p>Valeur NoData</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valeur NoData&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Select a directory</p></body></html> - <html><head/><body><p >Sélectionner un dossier</p></body></html> - - - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> - <html><head/><body><p>Réaliser le pan-sharpening (Brovey Transform)</p></body></html> - - - - Perform pansharpening (Landsat 7 or 8) - Appliquer pansharpening (Landsat 7 ou 8) + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Sélectionner un dossier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - <html><head/><body><p>Créer un jeu de bandes automatiquement et utiliser la boîte à outils de vérification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer un jeu de bandes automatiquement et utiliser la boîte à outils de vérification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Create Band set and use Band set tools Créer un jeu de bandes et utiliser la boîte à outils de bandes - + <html><head/><body><p>Edit metadata</p></body></html> - <html><head/><body><p>Editer les métadonnées</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Editer les métadonnées&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Band - Bande + + Metadata + Métadonnée - - RADIANCE_MULT - + + <html><head/><body><p >Refresh list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Actualiser la liste&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - RADIANCE_ADD + + Clip coordinates - - REFLECTANCE_MULT - + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser les limites de la ROI temporaire pour découper les rasters&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - REFLECTANCE_ADD - + + Use temporary ROI for clipping + Utiliser la ROI temporaire pour découper - - RADIANCE_MAXIMUM - + + <html><head/><body><p>NoData value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valeur NoData&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - REFLECTANCE_MAXIMUM - + + <html><head/><body><p>Output name prefix</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Préfixe du nom de sortie&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - K1_CONSTANT - + + clip + clip - - K2_CONSTANT - + + Output name prefix + Préfixe de sortie - - LMAX - + + Split raster bands + Séparer les bandes - - LMIN - + + <html><head/><body><p>Select the image to be split</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner l'image dont les bandes sont à séparer&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - QCALMAX - + + Select a multiband raster + Sélectionner un raster multibande - - QCALMIN - + + split + Separer - - Satellite - + + PCA + ACP - - Sun elevation - Elevation du soleil + + Input + Entrée - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - <html><head/><body><p>Date d'acquisition</p></body></html> + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, calcule ce nombre d'éléments seulement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Date (YYYY-MM-DD) - + + Number of components + Nombre d'éléments - - Earth sun distance - Distance Terre-Soleil + + <html><head/><body><p>Number of components</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nombre d'éléments&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>SUN ELEVATION</p></body></html> - <html><head/><body><p>Elévation du soleil</p></body></html> + + Output + Sortie - - <html><head/><body><p>Earth sun distance</p></body></html> - <html><head/><body><p>Distance Terre-Soleil</p></body></html> + + Vector to raster + Vecteur vers raster - - Metadata - Métadonnée + + Select the vector + Sélectionner un vecteur - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> - + + <html><head/><body><p>Select the vector</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un vecteur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Sentinel-2 - Sentinel-2 + + <html><head/><body><p>Use the value field of the vector</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser la valeur du champ du vecteur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Directory containing Sentinel-2 bands - Dossier contenant les bandes Sentinel-2 + + Use the value field of the vector + Utiliser la valeur du champ du vecteur - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> - <html><head/><body><p>Activer/Désactiver la correction atmosphérique DOS1 (thermal band is not corrected)</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser la valeur du champ&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Sentinel-2 conversion - Sentinel-2 conversion + + <html><head/><body><p>Use constant value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser une valeur constante&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Quantification value - Valeur de quantification + + Use constant value + Utiliser une valeur constante - - Solar irradiance - Irradiance solaire + + <html><head/><body><p>Value</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Valeur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - + + Select the type of conversion + Sélectionner le type de conversion - - ASTER - ASTER + + <html><head/><body><p>Select the type of conversion</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le type de conversion&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - ASTER conversion to TOA reflectance and brightness temperature - Conversion ASTER en réflectance TOA et température de surface + + Select the reference raster + Sélectionner le raster de référence - - Select file ASTER L1T (.hdf) - Sélectionner un fichier ASTER L1T (.hdf) + + <html><head/><body><p>Select the reference raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le raster de référence&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - UnitConversionCoeff - + + Postprocessing + Post-traitement - - PixelSize - Taille de pixel + + Accuracy + Précision - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - Découper plusieurs rasters - - - - <html><head/><body><p >Refresh list</p></body></html> - <html><head/><body><p >Actualiser la liste</p></body></html> - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - <html><head/><body><p>Utiliser les limites de la ROI temporaire pour découper les rasters</p></body></html> - - - - Use temporary ROI for clipping - Utiliser la ROI temporaire pour découper - - - - <html><head/><body><p>NoData value</p></body></html> - <html><head/><body><p>Valeur NoData</p></body></html> - - - - <html><head/><body><p>Output name prefix</p></body></html> - <html><head/><body><p>Préfixe du nom de sortie</p></body></html> - - - - clip - clip - - - - Output name prefix - Préfixe de sortie - - - - Split raster bands - Séparer les bandes - - - - <html><head/><body><p>Select the image to be split</p></body></html> - <html><head/><body><p>Sélectionner l'image dont les bandes sont à séparer</p></body></html> - - - - Select a multiband raster - Sélectionner un raster multibande - - - - split - Separer - - - - PCA - ACP - - - - Input - Entrée - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - <html><head/><body><p>Si coché, calcule ce nombre d'éléments seulement</p></body></html> - - - - Number of components - Nombre d'éléments - - - - <html><head/><body><p>Number of components</p></body></html> - <html><head/><body><p>Nombre d'éléments</p></body></html> - - - - Output - Sortie - - - - Vector to raster - Vecteur vers raster - - - - Select the vector - Sélectionner un vecteur - - - - <html><head/><body><p>Select the vector</p></body></html> - <html><head/><body><p>Sélectionner un vecteur</p></body></html> - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - <html><head/><body><p>Utiliser la valeur du champ du vecteur</p></body></html> - - - - Use the value field of the vector - Utiliser la valeur du champ du vecteur - - - - <html><head/><body><p>Select the value field</p></body></html> - <html><head/><body><p>Utiliser la valeur du champ</p></body></html> - - - - <html><head/><body><p>Use constant value</p></body></html> - <html><head/><body><p>Utiliser une valeur constante</p></body></html> - - - - Use constant value - Utiliser une valeur constante - - - - <html><head/><body><p>Value</p></body></html> - <html><head/><body><p>Valeur</p></body></html> - - - - Select the type of conversion - Sélectionner le type de conversion - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - <html><head/><body><p>Sélectionner le type de conversion</p></body></html> - - - - Select the reference raster - Sélectionner le raster de référence - - - - <html><head/><body><p>Select the reference raster</p></body></html> - <html><head/><body><p>Sélectionner le raster de référence</p></body></html> - - - - Postprocessing - Post-traitement - - - - Accuracy - Précision - - - + Select the classification to assess Sélectionner la classification à évaluer - + <html><head/><body><p>Select the classification to assess</p></body></html> - <html><head/><body><p>Sélectionner la classification à évaluer</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner la classification à évaluer&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select the field of the classification code </p></body></html> - <html><head/><body><p>Sélectionner le champ du code de classification</p></body></html> - - - - Land cover change - Changement d'occupation des sols - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - Si coché, les pixels ayant la même valeur dans les deux classification seront signalés; sinon la valeur 0 sera appliquée pour les pixels inchangés - - - - Report unchanged pixels - Signaler les pixels inchangés - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - <html><head/><body><p>Sélectionner le raster de classification de référence</p></body></html> - - - - Select the new classification - Sélectionner la nouvelle classification - - - - Select the reference classification - Sélectionner la classification de référence - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - <html><head/><body><p>Sélectionner un nouveau raster à comparer avec celui de référence</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le champ du code de classification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Classification report Rapport de classification - + <html><head/><body><p>Select the classification raster</p></body></html> - <html><head/><body><p>Sélectionner un raster de classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un raster de classification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the classification Sélectionner la classification - + Classification to vector Classification vers vecteur - + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - <html><head/><body><p>Utiliser les codes de la liste des signatures pour la symbologie vecteur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser les codes de la liste des signatures pour la symbologie vecteur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Use code from Signature list Utiliser les codes de la liste des signatures - + <html><head/><body><p>Select the code field</p></body></html> - <html><head/><body><p>Sélectionner le champ code</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le champ code&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C_ID - + MC_ID - + Symbology Symbologie - + Reclassification Reclassification - + <html><head/><body><p>Calculate unique values</p></body></html> - <html><head/><body><p>Calculer les valeurs uniques</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer les valeurs uniques&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - <html><head/><body><p>Activer pour la reclassification de C ID vers MC ID; si coché, les valeurs uniques seront calculées depuis la liste des signatures</p></body>< + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activer pour la reclassification de C ID vers MC ID; si coché, les valeurs uniques seront calculées depuis la liste des signatures&lt;/p&gt;&lt;/body&gt;&lt; - + calculate C ID to MC ID values Valeur C ID vers MC ID - + Calculate unique values Calculer les valeurs uniques - + Values Valeurs - + Old value Ancienne valeur - + New value Nouvelle valeur - - Edit raster - Editer raster - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - <html><head/><body><p>Annuler l'édition (pour les polygones ROI uniquement)</p></body></html> - - - - Select the input raster - Sélectionner les entrées raster - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - <html><head/><body><p>Sélectionner les rasters à éditer</p></body></html> - - - - <html><head/><body><p>Use expression</p></body></html> - <html><head/><body><p>Utiliser expression</p></body></html> - - - - Use expression - Utiliser expression - - - - <html><head/><body><p>Enter expression</p></body></html> - <html><head/><body><p>Entrer l'expression</p></body></html> - - - - where(raster == 1, 2, raster) - where(raster == 1, 2, raster) - - - - Edit raster values - Editer les valeurs raster - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - <html><head/><body><p>Editer les valeurs par un vecteur</p></body></html> - - - - Edit values using a vector - Editer les valeurs par un vecteur - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - lt;html><head/><body><p>Editer les valeurs par des ROI temporaires</p></body></html> - - - - Edit values using ROI polygons - Editer les valeurs par des ROI temporaires - - - - Edit options - Editer les options - - - - Classification sieve - Cribler la classification - - - + <html><head/><body><p>Select the classification</p></body></html> - <html><head/><body><p>Sélectionner la classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner la classification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Size threshold Seuil de taille - + <html><head/><body><p>Size threshold in pixels</p></body></html> - <html><head/><body><p>Seuil de taille en pixels</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seuil de taille en pixels&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Pixel connection Nombre de pixels voisins - + <html><head/><body><p>Pixel connection</p></body></html> - <html><head/><body><p>Nombre de pixels voisins</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nombre de pixels voisins&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + 4 - + 8 - - Classification erosion - Eroder la classification - - - + Size in pixels Taille en pixels - + <html><head/><body><p>Size in pixels</p></body></html> - <html><head/><body><p>Taille en pixels</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Taille en pixels&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Class values Valeur de classe - + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - <html><head/><body><p>Entrer les valeurs de classe séparé par , ou -</p></body></html> - - - - Classification dilation - Dilater la classification + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Entrer les valeurs de classe séparé par , ou -&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band calc Calcul de bande - + Band list Liste de bande - - Expression - Expression - - - - <html><head/><body><p>Not equals</p></body></html> - <html><head/><body><p>Non égal</p></body></html> + + <html><head/><body><p>Band list</p></body></html> + Liste de bandes - - != + + Variable - - <html><head/><body><p>Equals</p></body></html> - <html><head/><body><p>Egal</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, les pixels de valeur NoDate seront exclus du raster de sortie&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - == - + + <html><head/><body><p>Select a raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un raster&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Multiplication</p></body></html> - + + Extent: + Etendue - - * - + + Output raster + Sortie raster - - <html><head/><body><p>Power</p></body></html> - <html><head/><body><p>Puissance</p></body></html> + + Band set + Jeu de bandes - - ^ - + + Band set definition + Détail du jeu de bande - - <html><head/><body><p>Minus</p></body></html> - <html><head/><body><p>Moins</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Trier les bandes par nom (priorité au nombre final)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - - - + + <html><head/><body><p>Move highlighted band down</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Descendre la bande sélectionnée&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Plus</p></body></html> - + + <html><head/><body><p>Move highlighted band up</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Monter la bande sélectionnée&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - + - + + <html><head/><body><p>Export band set to text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporter le jeu de bandes dans un fichier texte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Division</p></body></html> - + + <html><head/><body><p>Import band set from text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importer le jeu de bandes à partir d'un fichier texte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - / - + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner une configuration pour fixer les longueurs d'onde centrales des bandes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Close parenthesis</p></body></html> - <html><head/><body><p>Parenthèse fermante</p></body></html> + + <html><head/><body><p>Wavelength unit</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Unité de longueur d'onde&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - ) - + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Calculer avec l'expression du calcul de band&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Square root</p></body></html> - <html><head/><body><p>Racine carré</p></body></html> + + Band calc expressions + Expressions du calcul de bande - - <html><head/><body><p>Open parenthesis</p></body></html> - <html><head/><body><p>Parenthèse ouvrante</p></body></html> + + Build band overviews + Créer un aperçu - - ( - + + Band set tools + Outils de jeu de bandes - - <html><head/><body><p>Greater than</p></body></html> - <html><head/><body><p>Supérieur à</p></body></html> + + Functions + Fonctions - - > - + + Settings + Paramètres - - <html><head/><body><p>Less than</p></body></html> - <html><head/><body><p>inférieur à</p></body></html> + + Interface + Interface - - < - + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Renseigner le nom de champ de l'identifiant de classe&lt;/p&gt;&lt;p&gt;[max 10 caractères]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - <html><head/><body><p>Entrer une expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> + + ROI style + Style ROI - - Decision rules - Règles de décision + + <html><head/><body><p>Select temporary ROI color</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner une couleur de ROI temporaire&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - <html><head/><body><p>Entrer une ou plusieurs règles séparées par un point virgules (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> + + ROI color + Couleur ROI - - Value - Valeur + + Transparency + Transparence - - Rule - Règle + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Changer la transparence de la ROI temporaire&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Move highlighted rule up</p></body></html> - <html><head/><body><p>Monter la règle sélectionnée</p></body></html> + + Variable name + Nom de variable - - <html><head/><body><p>Import rules from text file</p></body></html> - <html><head/><body><p>Importer les règles depuis un fichier texte</p></body></html> + + <html><head/><body><p>Variable name for expressions</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nom de variable pour les expressions&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Export rules to text file</p></body></html> - <html><head/><body><p>Exporter les règles dans un fichier texte</p></body></html> + + raster + - - <html><head/><body><p>Move highlighted rule down</p></body></html> - <html><head/><body><p>Descendre la règle sélectionnée</p></body></html> + + Group name + Nom de groupe - - <html><head/><body><p>Band list</p></body></html> - Liste de bandes + + <html><head/><body><p>Group name</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nom de groupe&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Variable + + Class_temp_group - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - <html><head/><body><p>Si coché, les pixels de valeur NoDate seront exclus du raster de sortie</p></body></html> + + Dock + Menu - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - <html><head/><body><p>Si coché, l'étendue du raster de sortie sera égale à celle du raster sélectionné</p></body></html> + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, les actualités de SCP seront téléchargées au démarrage et affichées dans le menu&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Same as - Identique à + + Download news on startup + Télécharger les actualités au démarrage - - <html><head/><body><p>Select a raster</p></body></html> - <html><head/><body><p>Sélectionner un raster</p></body></html> - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - <html><head/><body><p>Si coché, l'étendue du raster de sortie sera égale à l'intersection des rasters en entrées</p></body></html> - - - - Intersection - - - - - Extent: - Etendue - - - - Output raster - Sortie raster - - - - Band set - Jeu de bandes - - - - <html><head/><body><p>Add band to Band set</p></body></html> - <html><head/><body><p>Ajouter une bande au jeu de bandes</p></body></html> - - - - Band set definition - Détail du jeu de bande - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - <html><head/><body><p>Trier les bandes par nom (priorité au nombre final)</p></body></html> - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - <html><head/><body><p>Descendre la bande sélectionnée</p></body></html> - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - <html><head/><body><p>Monter la bande sélectionnée</p></body></html> - - - - <html><head/><body><p>Export band set to text file</p></body></html> - <html><head/><body><p>Exporter le jeu de bandes dans un fichier texte</p></body></html> - - - - <html><head/><body><p>Import band set from text file</p></body></html> - <html><head/><body><p>Importer le jeu de bandes à partir d'un fichier texte</p></body></html> - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - <html><head/><body><p>Sélectionner une configuration pour fixer les longueurs d'onde centrales des bandes</p></body></html> - - - - <html><head/><body><p>Wavelength unit</p></body></html> - <html><head/><body><p>Unité de longueur d'onde</p></body></html> - - - - Create virtual raster of band set - Créer un raster virtuel à partir du jeu de bandes - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - <html><head/><body><p>Calculer avec l'expression du calcul de band</p></body></html> - - - - Band calc expressions - Expressions du calcul de bande - - - - Build band overviews - Créer un aperçu - - - - Band set tools - Outils de jeu de bandes - - - - Batch - Batch - - - - <html><head/><body><p>Enter a batch function</p></body></html> - <html><head/><body><p>Entrer une fonction batch</p></body></html> - - - - Functions - Fonctions - - - - <html><head/><body><p>Import batch from text file</p></body></html> - <html><head/><body><p>Importer un fichier batch</p></body></html> - - - - <html><head/><body><p>Export batch to text file</p></body></html> - <html><head/><body><p>Exporter un fichier batch</p></body></html> - - - - Settings - Paramètres - - - - Interface - Interface - - - - Field names of training input - Noms des champs des données d'entrainement - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Renseigner le nom de champ de l'identifiant de classe</p><p>[max 10 caractères]</p></body></html> - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Renseigner le nom de champ de l'identifiant de macroclasse</p><p>[max 10 caractères]</p></body></html> - - - - ROI style - Style ROI - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - <html><head/><body><p>Sélectionner une couleur de ROI temporaire</p></body></html> - - - - ROI color - Couleur ROI - - - - Transparency - Transparence - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - <html><head/><body><p>Changer la transparence de la ROI temporaire</p></body></html> - - - - Variable name - Nom de variable - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - <html><head/><body><p>Nom de variable pour les expressions</p></body></html> - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - Nom de variable pour les expressions (menu reclassification et éditer raster) - - - - Group name - Nom de groupe - - - - <html><head/><body><p>Group name</p></body></html> - <html><head/><body><p>Nom de groupe</p></body></html> - - - - Class_temp_group - - - - - Dock - Menu - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - <html><head/><body><p>Si coché, les actualités de SCP seront téléchargées au démarrage et affichées dans le menu</p></body></html> - - - - Download news on startup - Télécharger les actualités au démarrage - - - + Processing Traitement - + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - <html><head/><body><p>Activer/désactiver le son quand le traitement est fini</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activer/désactiver le son quand le traitement est fini&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Play sound when finished Alarme à la fin du traitement - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - <html><head/><body><p>Si coché, crée un raster virtual pour certain fichier temporaire</p></body></html> - - - - Use virtual raster for temp files - Utiliser un raster virtuel pour les fichiers temporaires - - - + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - <html><head/><body><p>Si coché, une compression est appliqué aux raster pour économiser de l'espace disque</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, une compression est appliqué aux raster pour économiser de l'espace disque&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Raster compression Compression des rasters - + <html><head/><body><p>Set available RAM for processes</p></body></html> - <html><head/><body><p>Fixer la RAM disponible pour le traitement</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Fixer la RAM disponible pour le traitement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Available RAM (MB) RAM disponible (MB) - + <html><head/><body><p>Reset to default temporary directory</p></body></html> - <html><head/><body><p>Réinitialiser le dossier temporaire par défaut</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Réinitialiser le dossier temporaire par défaut&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Temporary directory Dossier temporaire - + Debug Debug - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - <html><head/><body><p>Activer/Désactiver les logs</p></body></html> - - - - Record events in a Log file - Enregistrer les évènements dans le fichier log - - - + <html><head/><body><p>Export the Log file</p></body></html> - <html><head/><body><p>Exporter le fichier log</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporter le fichier log&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Clear the Log file content</p></body></html> - <html><head/><body><p>Vider le fichier log</p></body></html> - - - + Log file Fichier log - + <html><head/><body><p>Test dependencies</p></body></html> - <html><head/><body><p>Test des dépendances</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Test des dépendances&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Test dependencies Test des dépendances - + Test Test - + About A propos - + Align Aligner - + Results Résultats - + <html><head/><body><p>Maximum number of results (images)</p></body></html> - <html><head/><body><p>Nombre maximum de résultats (images)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nombre maximum de résultats (images)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Cross classification Classification croisé - + Ancillary data Données auxilliaires - - MODIS - MODIS - - - - MODIS conversion - Conversion MODIS - - - - Select file MODIS (.hdf) - Sélectionner un fichier MODIS (.hdf) - - - - ID - ID - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - <html><head/><body><p>Reprojeter les bandes en WGS 84</p></body></html> - - - - Reproject to WGS 84 - Reprojeter en WGS 84 - - - + Products Produits - + <html><head/><body><p>Select a product</p></body></html> - <html><head/><body><p>Sélectionner un produit</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner un produit&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Stack raster bands Assembler les bandes raster - + Basic tools Outils basiques - + Download products Télécharger des produits - + Band processing Traitement de bande - + <html><head/><body><p>Add a new band set</p></body></html> - <html><head/><body><p>Ajouter un nouveau jeu de bandes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter un nouveau jeu de bandes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - <html><head/><body><p>Créer un raster virtuel</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer un raster virtuel&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - <html><head/><body><p>Créer un raster tif assemblant les bandes</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer un raster tif assemblant les bandes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - <html><head/><body><p>Construire les pyramides pour une visualisation plus rapide</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Construire les pyramides pour une visualisation plus rapide&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + RUN Lancer - - Multiband image list - Liste d'images multibandes - - - - <html><head/><body><p>Select a multiband image</p></body></html> - <html><head/><body><p>Sélectionner une image multibande</p></body></html> - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - <html><head/><body><p>Sélectionner tout / Désélectionner tout</p></body></html> - - - - Single band list - Liste des bandes - - - + Create random points Créer des points aléatoires - - - Signature threshold - Seuil de signature - - - - Automatic thresholds - Seuils automatique - - - - LC Signature threshold - Seuil de signature LC - - - - Login data - Identifiant - - - - Search - Rechercher - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - <html><head/><body><p>Ajouter OpenStreetMap à la carte</p></body></html> - - - - Search parameters - Paramètres de recherche - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - <html><head/><body><p>Export table to text file</p></body></html> - <html><head/><body><p>Exporter la table depuis un fichier</p></body></html> - - - - <html><head/><body><p>Import table from text file</p></body></html> - <html><head/><body><p>Importer la table depuis un fichier</p></body></html> - - - - Product list - Liste de produits - - - - Product - Produit - - - - ProductID - - - - - Zone/Path - - - - - Row/DayNight - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8A - - - - - 11 - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - <html><head/><body><p><span style=" color:#ffffff;"> Télécharger</span></p></body></html> - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - Sélectionner le fichier MTL - - - - Select MTL file - Sélectionner le fichier MTL - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - <html><head/><body><p>Créer un nouveau jeu de bandes à partir des bandes ajoutés</p></body></html> - - - - Add bands in a new Band set - Ajouter les bandes à un nouveau jeu de bandes - - - - Select metadata file (MTD_MSI) - Sélectionner un fichier de métadonnées (MTD_MSI) - - - - Sentinel-3 - Sentinel-3 - - - - Sentinel-3 conversion - Sentinel-3 conversion - - - - Directory containing Sentinel-3 bands - Dossier contenant les bandes Sentinel-3 - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - Convert vector to raster - Convertir vecteur vers raster - - - - Clip band set - Découper un jeu de bandes - - - - <html><head/><body><p>Band set number</p></body></html> - <html><head/><body><p>Numéro du jeu de bandes</p></body></html> - - - - Select input band set - Sélectionner un jeu de bandes - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - <html><head/><body><p>Sélectionner le vecteur de découpe</p></body></html> - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - <html><head/><body><p>Utiliser les limites du vecteur pour découper les rasters</p></body></html> - - - - Use vector for clipping - Utiliser un vecteur de découpe - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - <html><head/><body><p>Si coché, le clip itère sur chaque polygone et ajoute la valeur du champ </p></body></html> - - - - Use vector field for output name - Utilise un champ du vecteur pour le nom de sortie - - - - <html><head/><body><p>Select the vector field</p></body></html> - <html><head/><body><p>Sélectionner le champ</p></body></html> - - - - Split raster bands - Découper les bandes raster - - - - Stack band set - Assembler les bandes - - - - Mosaic band sets - Mosaïque de jeu de bandes - - - - Mosaic of band sets - Mosaïque de jeu de bandes - - - - mosaic - mosaique - - - - 1, 2 - - - - - Band set list - Liste des bandes - - - - Cloud masking - Masque nuage - - - - Mask of band set - Masque de bande - - - - mask - masque - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - <html><head/><body><p>Si coché, créer un buffer pour les valeurs de classe</p></body></html> - - - - Use buffer of pixel size - Utiliser un buffer en taille de pixel - - - - Mask class values - Valeurs de classe du masque - - - - Band combination - Combinaison de bandes - - - - Select input band set (of classifications) - Sélectionner le jeu de bandes en entrée (de classification) - - - - Combination of band values - Combinaison de valeur de bandes - - - - Principal Components Analysis of band set - Analyse à composante principale du jeu de bandes - - - - Clustering - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - <html><head/><body><p>Si coché, utiliser ISODATA</p></body></html> - - - - ISODATA - - - - - Method - Méthode - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - <html><head/><body><p>Si coché, utiliser K-means</p></body></html> - - - - &K-means - - - - - Clustering of band set - Cluster du jeu de bandes - - - - Max number of iterations - Nombre max d'itérations - - - - <html><head/><body><p>Number of classes</p></body></html> - <html><head/><body><p>Nombre de classes</p></body></html> - - - - <html><head/><body><p>Threshold</p></body></html> - <html><head/><body><p>Seuil</p></body></html> - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - <html><head/><body><p>Si coché, pour K-means: stopper les itérations si la distance plus faible que le seuil; pour ISODATA: les signatures sont fusionnées si la distance est plus grande que les seuils</p></body></html> - - - - Distance threshold - Seuil de distance - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - <html><head/><body><p>Fixer le nombre maximum d'itérations</p></body></html> - - - - Number of classes - Nombre de classes - - - - ISODATA max standard deviation - ISODATA écart type maximum - - - - ISODATA minimum class size in pixels - ISODATA taille minimum de taille en pixel - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - <html><head/><body><p>Taille minimum de taille en pixel</p></body></html> - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - <html><head/><body><p>Si coché, utilisé l'algorithme de plus proche voisin</p></body></html> - - - - Minimum Distance - Plus proche voisin - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - <html><head/><body><p>Si coché, sauvegarder les résultats à la liste des signatures</p></body></html> - - - - Save resulting signatures to Signature list - sauvegarder les résultats à la liste des signatures - - - - Distance algorithm - - - - - Seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - <html><head/><body><p>Si coché, utiliser l'algorithme Spectral Angle Mapping (seulement pour K-means)</p></body></html> - - - - Spectral Angle Mapping - - - - - Spectral distance - Distance spectrale - - - - Spectral distance of band sets - Distance spectrale du jeu de bandes - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - <html><head/><body><p>Si coché, calculer un raster de changement quand la distance est supérieure au seuil</p></body></html> - - - - Select first input band set - Sélectionner le premier jeu de bandes - - - - Select second input band set - Sélectionner le deuxième jeu de bandes - - - - Select the reference vector or raster - Sélectionner le vecteur ou raster de référence - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - <html><head/><body><p>Sélectionner le vecteur ou raster de référence</p></body></html> - - - - Vector field - Champ vecteur - - - - Accuracy assessment - Vérification de la précision - - - - Land cover change - Changement d'occupation des sols - - - - Classification report - Rapport de classification - - - - Cross classification - Classification croisée - - - - Class signature - Classe signature - - - - Class signature - Classe signature - - - - Classification to vector - Classification vers vecteur - - - - Reclassification - Reclassification - - - - Edit raster - Editer raster - - - - Classification sieve - Cribler la classification - - - - Classification erosion - Eroder la classification - - - - Classification dilation - Dilater la classification - - - - SMTP server - Serveur SMTP - - - - password - mot de passe - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - <html><head/><body><p>Activer/Désactiver l'envoie d'un mail à la fin du traitement</p></body></html> - - - - Send email of completed process to - envoyer un mail à la fin du traitement - - - - SMTP process notification - Notification SMTP - - - - user - utilisateur - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - <html><head/><body><p>Liste d'adresse (séparée par une virgule , ) à qui envoyer le mail </p></body></html> - - - - Date - Date - - - - Function - Fonction - - - - Message - Message - - - - RGB = - - - - - ROI - - - - - Preview - Aperçu - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - stratified for the values - - - - - of first band of band set - de la première bande du jeu de bandes - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - Créer un raster à partir du jeu de bandes - - - - Input NoData - as value - - - - - Sentinel-1 - Sentinel-1 - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - Manuel d'utilisateur - - - - Support the SCP - Soutenir SCP - - - - Use - Utiliser - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - <html><head/><body><p>Utiliser l'ID des macroclasses pour la classification</p></body></html> - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - <html><head/><body><p>Utiliser l'ID des classes pour la classification</p></body></html> - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - <html><head/><body><p>Ouvrir le tableau de poids des bandes</p></body></html> - - - - W - W - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - <html><head/><body><p>Selectionner un algorithme de classification</p></body></html> - - - - Maximum Likelihood - Maximum de vraisemblance - - - - Algorithm - Algorithme - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - <html><head/><body><p>Appliquer un seuil de classification pour toutes les signatures</p></body></html> - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - <html><head/><body><p>Ouvrir le tableau des seuils des signatures</p></body></html> - - - - Threshold - Seuil - - - - Classification - Classification - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - <html><head/><body><p>Si coché, la classification d'occupation des sols est utilisée</p></body></html> - - - - LCS - LCS - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - <html><head/><body><p>Ouvrir le tableau des seuils LCS</p></body></html> - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - <html><head/><body><p>Si coché, l'algorithme sélectionné est utilisé seulement pour la classe superposée à des pixels de la classification d'occupation des sols</p></body></html> - - - - only overlap - superposé uniquement - - - - Land Cover Signature Classification - Classification d'occupation des sols - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - <html><head/><body><p>Si coché, l'algorithme sélectionné est utilisé pour les pixels non-classifiés de la classification d'occupation des sols</p></body></html> - - - - Algorithm - Algorithme - - - - Classification output - Sortie de la classification - - - - Load qml style - Charger le style qml - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - <html><head/><body><p><span >Sélectionner le style qml</span></p></body></html> - - - - <html><head/><body><p>Qml file path</p></body></html> - <html><head/><body><p>Chemin vers fichier Qml</p></body></html> - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - <html><head/><body><p>Selectionner un masque vectoriel (optionnel)</p></body></html> - - - - Apply mask - Appliquer le masque - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - <html><head/><body><p>Chemin vers le masque (.shp)</p></body></html> - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - <html><head/><body><p>Créer un fichier vecteur de la classification après le traitement</p></body></html> - - - - Create vector - Créer un fichier vecteur - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - <html><head/><body><p>Calculer un rapport de la classification</p></body></html> - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - <html><head/><body><p>Si coché, tous les rasters temporaire de la classification (un par signature) sont sauvegardés au cours du traitement</p></body></html> - - - - Save algorithm files - Sauvegarde les fichiers temporaires - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - Unité de -longueur d'onde - - - - Wavelength -quick settings - Paramétrage rapide -des longueur d'onde - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - <html><head/><body><p>Login ASTER et MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - Nom de MC - - - - C Name - Nom de C - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> - - - - - <html><head/><body><p>Minumum power</p></body></html> - - - - - <html><head/><body><p>Maximum power</p></body></html> - - - - - <html><head/><body><p>If checked, save classifier</p></body></html> - - - - - Import vector - - - - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - - - - <html><head/><body><p>C ID field</p></body></html> - - - - - <html><head/><body><p>MC ID field</p></body></html> - - - - - <html><head/><body><p>MC Name field</p></body></html> - - - - - <html><head/><body><p>C Name field</p></body></html> - - - - - Vector fields - - - - - Import vector - - - - - <html><head/><body><p>Import vector</p></body></html> - - - - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - - - - Python executable path - - - - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> - - - - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - - - - GDAL installation directory - - - - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> - - - - - Same extent as reference raster - - - - - <html><head/><body><p>Import reclassification table from text file</p></body></html> - - - - - <html><head/><body><p>Export reclassification table to text file</p></body></html> - - - - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - - - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> - - - - - Use alternative search for Sentinel-2 (no authentication required) - - - - - Matrix file (optional) - - - - - neighbor - - - - - Neighbor pixels - - - - - Neighbor pixels - - - - - Neighbor distance in pixels - - - - - <html><head/><body><p>Distance in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> - - - - - Enable writing verification - - - - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - - - - Create virtual raster output - - - - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> - - - - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - - - - Circular - - - - - Calculation -data type - - - - - Python modules path - - - - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - - - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - - - - Virtual download - - - - - <html><head/><body><p>Sort band sets by date</p></body></html> - - - - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> - - - - - NoData mask - - - - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - - - - Calculate linear regression - - - - - Set threshold = σ * - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - - - - - σ * - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - √ - - - - - SpectralSignaturePlot - - - SCP: Spectral Signature Plot - SCP: Graphique Signature Spectrale - - - - S - S - - - - MC ID - MC ID - - - - C ID - C ID - - - - Color - Couleur - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Activer le paramétrage des seuils en pointant sur les pixels</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>Si coché, le seuil de signature est réduit pour exclure la signature des pixels </p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>Si coché, le seuil de signature est augmenté pour inclure la signature des pixels</p></body></html> - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Utiliser les seuils de la ROI temporaire</p></body></html> - - - - Automatic thresholds - Seuils automatiques - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Utiliser un seuil automatique Min Max</p></body></html> - - - - Min Max - - - - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Utiliser une valeur qui sera multiplié par l'écart type</p></body></html> - - - - <html><head/><body><p>Undo thresholds</p></body></html> - <html><head/><body><p>Retirer les seuils</p></body></html> - - - - Import library - Importer - - - - <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Supprimer une ligne</p></body></html> - - - - Plot - Graphique - - - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - <html><head/><body><p>Ajouter les signatures spectrales surlignées à la liste des signatures</p></body></html> - - - - <html><head/><body><p>Calculate spectral distances</p></body></html> - <html><head/><body><p>Calculer les distances spectrales</p></body></html> - - - - Signature list - Liste des signatures - - - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - <html><head/><body><p>Afficher l'étendue de valeur pour chaque signature</p></body></html> - - - - Band lines - Bandes - - - - Max characters - Maximum de caractères - - - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - <html><head/><body><p align="justify">Longueur des noms dans la légende du graphique</p></body></html> - - - - x=0.000000 y=0.000000 - - - - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> - <html><head/><body><p>Changer l'étendue des valeurs de façon interactive</p></body></html> - - - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Adapter automatiquement le graphique aux données</p></body></html> - - - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Sauvegarder le graphique (jpg, png, pdf)</p></body></html> - - - - Plot value range - Etendue des valeurs du graphique - - - - Grid - Grille - - - - Signature details - Détails de la signature - - - - Spectral distances - Distance spectrale - - - - From -pixel - - - - - From -ROI - - - - - MC Name - Nom de MC - - - - C Name - Nom de C - - - - σ * - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - + + + Signature threshold + Seuil de signature - - - semiautomaticclassificationplugin - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin - + + Automatic thresholds + Seuils automatique - - Please restart QGIS for installing the Semi-Automatic Classification Plugin - + + Login data + Identifiant - - Select a mask shapefile - + + Search + Rechercher - - Save classification output - + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter OpenStreetMap à la carte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Select a qml style - + + Search parameters + Paramètres de recherche - - Select a signature list file + + X (Lon) - - Select a SCP training input + + LR - - Export SCP training input + + UL - - Select a library file + + Y (Lat) - - Export the highlighted signatures to CSV library - + + <html><head/><body><p>Export table to text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exporter la table depuis un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Calculate signatures - + + <html><head/><body><p>Import table from text file</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importer la table depuis un fichier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Calculate signatures for highlighted items? - + + Product list + Liste de produits - - Merge signatures + + 1 - - Merge highlighted signatures? + + 2 - - Delete signatures + + 3 - - Are you sure you want to delete highlighted ROIs and signatures? + + 5 - - Create SCP training input + + 6 - - Add required fields + + 7 - - It appears that the shapefile + + 8A - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 11 - - Undo save ROI + + 9 - - Semi-Automatic Classification Plugin + + 10 - - Zoom to input image extent + + 12 - - Show/hide the input image + + 20 - - Select a RGB color composite - + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ffffff;&quot;&gt; Télécharger&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Local cumulative cut stretch of band set - + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> + Sélectionner le fichier MTL - - Local standard deviation stretch of band set - + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Créer un nouveau jeu de bandes à partir des bandes ajoutés&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Zoom to temporary ROI - + + Convert vector to raster + Convertir vecteur vers raster - - Show/hide the temporary ROI - + + Clip band set + Découper un jeu de bandes - - Create a ROI polygon - + + <html><head/><body><p>Band set number</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Numéro du jeu de bandes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Activate ROI pointer - + + Select input band set + Sélectionner un jeu de bandes - - Redo the ROI at the same point - + + <html><head/><body><p>Select the vector for clipping</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le vecteur de découpe&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Dist - + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser les limites du vecteur pour découper les rasters&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Similarity of pixels (distance in radiometry unit) - + + Use vector for clipping + Utiliser un vecteur de découpe - - Min - + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, le clip itère sur chaque polygone et ajoute la valeur du champ &lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Minimum area of ROI (in pixel unit) - + + Use vector field for output name + Utilise un champ du vecteur pour le nom de sortie - - Max - + + <html><head/><body><p>Select the vector field</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le champ&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) - + + Split raster bands + Découper les bandes raster - - Zoom to the classification preview - + + Stack band set + Assembler les bandes - - Show/hide the classification preview - + + Mosaic band sets + Mosaïque de jeu de bandes - - Activate classification preview pointer - + + Mosaic of band sets + Mosaïque de jeu de bandes - - Redo the classification preview at the same point + + 1, 2 - - T - + + Band set list + Liste des bandes - - Set preview transparency - + + Mask of band set + Masque de bande - - S - + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Si coché, créer un buffer pour les valeurs de classe&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Set the preview size (in pixel unit) - + + Use buffer of pixel size + Utiliser un buffer en taille de pixel - - Remove temporary files - + + Mask class values + Valeurs de classe du masque - - Create KML - + + Select input band set (of classifications) + Sélectionner le jeu de bandes en entrée (de classification) - - Edit raster - Editer raster + + Combination of band values + Combinaison de valeur de bandes - - Value 0 - + + Principal Components Analysis of band set + Analyse à composante principale du jeu de bandes - - Set value 0 - + + Minimum Distance + Plus proche voisin - - Value 1 + + Spectral Angle Mapping - - Set value 1 - + + Select the reference vector or raster + Sélectionner le vecteur ou raster de référence - - Value 2 - + + <html><head/><body><p>Select the reference vector or raster</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionner le vecteur ou raster de référence&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Set value 2 - + + Vector field + Champ vecteur - - Undo edit (only for ROI polygons) - + + Accuracy assessment + Vérification de la précision - - SCP - SCP + + Classification report + Rapport de classification - - Band set - Jeu de bandes + + Cross classification + Classification croisée - - Basic tools - Outils basiques + + Classification to vector + Classification vers vecteur - - RGB list - Liste RGB + + Reclassification + Reclassification - - Algorithm band weight - Algorithme : poids des bandes + + SMTP server + Serveur SMTP - - Multiple ROI creation - Creation de ROI multiple + + password + mot de passe - - Import signatures - Importer des signatures + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activer/Désactiver l'envoie d'un mail à la fin du traitement&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Export signatures - Exporter les signatures + + Send email of completed process to + envoyer un mail à la fin du traitement - - Signature threshold - Seuil des signatures + + SMTP process notification + Notification SMTP - - LCS threshold - Seuil LCS + + user + utilisateur - - Download products - Télécharger des produits + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Liste d'adresse (séparée par une virgule , ) à qui envoyer le mail &lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Preprocessing - Pré-traitement + + Date + Date - - Landsat - Landsat + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> + - - Sentinel-2 - Sentinel-2 + + stratified for the values + - - Sentinel-3 - Sentinel-3 + + of first band of band set + de la première bande du jeu de bandes - - ASTER - ASTER + + raster > 0 + - - MODIS - MODIS + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> + - - Vector to raster - Vecteur vers raster + + <html><head/><body><p>Create stratified random points</p></body></html> + - - Clip multiple rasters - Découper plusieurs rasters + + <html><head/><body><p>Filter</p></body></html> + - - Split raster bands - Séparer les bandes + + Advanced search + - - Stack raster bands - Assembler les bandes raster + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> + - - Mosaic band sets - Mosaïque de jeu de bandes + + System + - - Cloud masking - Masque nuage + + CPU threads + - - Band processing - Traitement de bande + + <html><head/><body><p>Select a type</p></body></html> + - - Band combination - Combinaison de bandes + + Float32 + - - PCA - ACP + + Int16 + - - Clustering + + Byte - - Spectral distance - Distance spectrale + + Create raster of band set +(stack bands) + Créer un raster à partir du jeu de bandes - - Postprocessing - Post-traitement + + Input NoData + as value + - - Accuracy - Précision + + External programs + - - Land cover change - Changement d'occupation des sols + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> + - - Classification report - Rapport de classification + + <html><head/><body><p>Select a statistic</p></body></html> + - - Cross classification - Classification croisé + + Select a statistic + - - Class signature - Classe signature + + <html><head/><body><p>Enter a value</p></body></html> + - - Classification to vector - Classification vers vecteur + + Statistic + - - Reclassification - Reclassification + + Project + - - Classification sieve - Cribler la classification + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> + - - Classification erosion - Eroder la classification + + Create RGB composite of band set when a project is loaded + - - Classification dilation - Dilater la classification + + User manual + Manuel d'utilisateur - - Band calc - Calcul de bande + + Use + Utiliser - - Batch - Batch + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser l'ID des macroclasses pour la classification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Settings - Paramètres + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Utiliser l'ID des classes pour la classification&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Interface - Interface + + W + W - - Debug - Debug + + Maximum Likelihood + Maximum de vraisemblance - - Spectral plot - + + Algorithm + Algorithme - - Scatter plot - + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Appliquer un seuil de classification pour toutes les signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - User manual - Manuel d'utilisateur + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ouvrir le tableau des seuils des signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Online help - Aide en ligne + + Classification + Classification - - About - A propos + + Processing setting + - - Show plugin + + Help - - Test results + + Tool - - Information + + Load classifier - - No log file found + + Reproject raster bands - - Select a SCP training input; input is not loaded + + Use EPSG code - - Select a raster; raster is not loaded + + reproj - - Select a point inside the image area + + <html><head/><body><p>EPSG value</p></body></html> - - Data projections do not match. Reproject data to the same projection + + <html><head/><body><p>X resolution</p></body></html> - - Maximum Likelihood threshold must be less than 100 + + <html><head/><body><p>Y resolution</p></body></html> - - Spectral Angle Mapping threshold must be less than 90 + + <html><head/><body><p>Align to raster</p></body></html> - - Select a directory + + Align to raster - - At least 3 points are required + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Negative IDs are not allowed + + same extent as reference - - Select at least one signature + + Y resolution - - SCP is recording the Log file + + X resolution - - Signature list file (.slf) created - Fichier (.slf) de liste des signatures créé + + <html><head/><body><p>NoData value of the output raster</p></body></html> + - - No image found. Try with a larger area + + Int32 - - Create a ROI polygon or use a vector + + UInt32 - - Define a search area + + UInt16 - - At least one band set is required + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Unable to remove bands from a multiband image + + <html><head/><body><p>Scale</p></body></html> - - Error + + <html><head/><body><p>If checked, set an offset</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + Output +NoData value - - Raster not found + + Set +scale - - Vector or raster not found + + Set +offset - - Error saving signatures + + Calculation process - - Error opening signatures + + Resampling method - - Error opening spectral library + + average - - Error saving spectral library + + sum - - Import failed + + maximum - - ROI creation failed + + minimum - - Internet connection failed + + mode - - Error saving raster + + median - - Error reading raster. Possibly the raster path contains unicode characters + + nearest_neighbour - - The version of Numpy is outdated + + first_quartile - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + third_quartile - - Memory error. Please, set a lower value of RAM in the tab Settings + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Edge error. Reduce the ROI width or draw a ROI manually + + Resample pixel factor - - Error calculating signature. Possibly ROI is too small + + <html><head/><body><p>Resample factor</p></body></html> - - Unable to split bands + + <html><head/><body><p>Select the resampling method</p></body></html> - - Error reading band set. Possibly raster files are not loaded + + Output type - - Clip area outside image. Check the raster projection + + Auto - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Unable to calculate. Expression error + + Change output NoData value - - Unable to calculate. Metadata error + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Unable to find images + + Dissolve output - - Unable to connect + + Use value as NoData - - Unable to load image + + Use value +as NoData - - Attribute table error + + <html><head/><body><p>Set incremental new values</p></body></html> - - Unable to pansharpen: missing bands + + Incremental new values - - Unable to calculate + + Output NoData value - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + C Name field - - Memory error. Please, decrease decimal precision + + MC Name field - - Error calculating plot - + + MC Name + Nom de MC - - SSL connection error. Please see the FAQ of the plugin user manual for solving this - + + C Name + Nom de C - - Directory error. Check write permission + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Error accessing training input + + Import vector - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Memory error, too many combinations. Try to reclassify the values + + <html><head/><body><p>C ID field</p></body></html> - - Warning + + <html><head/><body><p>MC ID field</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>MC Name field</p></body></html> - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>C Name field</p></body></html> - - Wavelength already present + + Vector fields - - Wavelength unit not provided in band set + + Import vector - - RAM value was too high. Value has been decreased automatically + + <html><head/><body><p>Import vector</p></body></html> - - Unable to load the virtual raster. Please create it manually + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Unable to proceed. The raster must be in projected coordinates + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - Select at least one raster band + + GDAL installation directory - - Incorrect expression + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Unable to access the temporary directory + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + Matrix file (optional) - - Macroclass symbology is missing + + Neighbor pixels - - Missing bands + + Neighbor distance in pixels - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Distance in pixels</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Search error HTTP Status 500, reduce the result number + + Create virtual raster output - - Please define band sets with matching number of bands + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Please add single band rasters to the band set + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Select a shapefile + + Circular - - SCP: completed process + + Calculation +data type - - Set thresholds + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Are you sure you want to set thresholds for several signatures? + + Virtual download - - Save error matrix raster output + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Classification - Classification + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + - - ErrMatrixCode + + Calculate linear regression - - Reference - Référence + + Set threshold = σ * + - - PixelSum + + Create virtual raster +of band set - - Total - Total + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> + - - Overall accuracy [%] = - Précision globale [%] + + Wavelength unit + Unité de longueur d'onde - - Kappa hat classification = + + Wavelength - - Band number - Numéro de bande + + Band quick settings + - - Band name - Nom de bande + + Band set table + - - Weight - Poids + + Active band set + - - Reset weights + + Root directory - - Are you sure you want to reset weights? + + Script - - Select a HDF file + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Clear rules + + Copy - - Are you sure you want to clear the rules? + + Band dilation - - Select a text file of rules + + Output name - - Save the rules to file + + dilation_ - - Save raster output + + Virtual output - - Save cross classification raster output + + <html><head/><body><p>Enter output name</p></body></html> - - Unknown + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - RasterValue + + erosion_ - - Select a raster + + Band erosion - - Clear band set + + Band sieve - - Are you sure you want to clear the band set? + + sieve_ - - Center wavelength + + Script (copy the code in a Python shell) - - Multiplicative Factor + + Script - - Additive Factor + + <html><head/><body><p>Enter an expression</p></body></html> - - Wavelength unit - Unité de longueur d'onde + + Expression + - - Image name - Nom de l'image + + NoData +mask + - - Remove band set - Supprimer le jeu de bandes + + UL X + - - Save the band set to file + + UL Y - - Select a band set file + + LR X - - Remove band + + LR Y - - Are you sure you want to remove the selected bands from band set? + + Output +data type - - Save virtual raster + + False - - Save raster + + True - - Build overviews + + None - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Upperleft X</p></body></html> - - Check OK + + <html><head/><body><p>Upper-left Y</p></body></html> - - Select a batch file + + <html><head/><body><p>Lower-right X</p></body></html> - - Save the batch to file + + <html><head/><body><p>Lower-right Y</p></body></html> - - missing parameter + + Masking bands - - Save signature output + + Combination - - Class + + Dilation - - Signature - Signature + + Erosion + - - C_ID_ + + Sieve - - Save classification report + + Neighbor - - Percentage % + + Band neighbor - - Select a directory where to save clipped rasters + + pixel_center - - Save clustering output + + all_touched - - Calculating. Please wait ... + + area_based - - Calculating classification. Please wait ... + + Area precision - - Distance + + Pixel size - - CrossClassCode + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - CROSS MATRIX [ + + Minimum extent - - Save output + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - Select a text file of product table + + <html><head/><body><p>Output pixel size</p></body></html> - - Export table to file + + Reproject and resample band set - - Searching ... + + <html><head/><body><p>Use EPSG code</p></body></html> - - Downloading ... + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Download the images in the table (requires internet connection) + + Compress - - Export download links + + <html><head/><body><p>Compression method</p></body></html> - - Reset signature list + + LZW - - Are you sure you want to clear the table? + + <html><head/><body><p>Output prefix</p></body></html> - - Save land cover change raster output + + mosaic_ - - ReferenceClass + + <html><head/><body><p>Output name</p></body></html> - - NewClass + + band_ - - Select a MTL file + + Output prefix - - Save the point list to file + + Clip raster bands - - Principal Components Analysis + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Covariance matrix + + Use coordinates for clipping - - Bands + + mask_ - - Correlation matrix + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Eigen vectors + + product - - Vector_ + + image - - Eigen values + + product_id - - Accounted variance + + acquisition_date - - Cumulative variance + + cloud_cover - - Reset RGB list + + zone_path - - Are you sure you want to clear the RGB list? + + row - - Calculate all the RGB combinations? + + collection - - Save the RGB list to file + + size - - Select a XML file + + uid - - Transparency + + preview - - Save Log file + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Reset field names + + <html><head/><body><p>Sentinel</p></body></html> - - Are you sure you want to reset field names? + + Bands - - Reset variable name + + Image conversion - - Are you sure you want to reset variable name? + + Directory containing bands - - Reset group name + + Conversion to reflectance and temperature - - Are you sure you want to reset group name? + + Select metadata file (optional) - - Change temporary directory + + spacecraft - - Are you sure you want to change the temporary directory? + + processing_level - - Reset temporary directory + + band_name - - Are you sure you want to reset the temporary directory? + + product_path - - Reset thresholds + + scale - - Are you sure you want to reset thresholds? + + offset - - Delete scatter plot + + nodata - - Are you sure you want to delete highlighted scatter plots? + + date - - Save plot to file + + k1 - - Edit value range + + k2 - - Are you sure you want to edit the value range for several signatures? + + band_number - - Add to Signature list - Ajouter à la liste des signatures + + e_sun + - - Are you sure you want to add highlighted signatures to the list? + + earth_sun_distance - - Are you sure you want to delete highlighted signatures? + + Create a new Band set - - Values + + Input - - Undo thresholds + + Multi-Layer Perceptron - - Are you sure you want to undo thresholds? + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list - Liste des bandes + + Use training + - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> + - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing - Traitement + + <html><head/><body><p>Use NoData mask</p></body></html> + - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Help + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Support the SCP - Soutenir SCP + + neighbor_ + - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> + - - C ID - C ID + + Save to file + - - Name - Nom + + sun_elevation + + + + SpectralSignaturePlot - - Type - Type + + SCP: Spectral Signature Plot + SCP: Graphique Signature Spectrale - - Color - Couleur + + S + S - - SCPID - + + MC ID + MC ID - - Zoom to highlighted items - + + C ID + C ID - - Clear selection - + + Color + Couleur - - Collapse/expand all - + + <html><head/><body><p >Delete row</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Supprimer une ligne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Merge highlighted items - + + Plot + Graphique - - Calculate signatures for highlighted items - + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajouter les signatures spectrales surlignées à la liste des signatures&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Delete highlighted items - + + Signature list + Liste des signatures - - Change MC ID for highlighted items - + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher l'étendue de valeur pour chaque signature&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Add highlighted items to spectral plot - + + Band lines + Bandes - - Add highlighted items to scatter plot - + + Max characters + Maximum de caractères - - Change Macroclass ID - + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Longueur des noms dans la légende du graphique&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties - + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Adapter automatiquement le graphique aux données&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Zoom to - + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sauvegarder le graphique (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Check/uncheck - + + Plot value range + Etendue des valeurs du graphique - - Check/uncheck highlighted items - + + Grid + Grille - - Clear selection of highlighted items - + + Signature details + Détails de la signature - - Collapse/expand all macroclasses - + + Spectral distances + Distance spectrale - - Change MC ID - + + MC Name + Nom de MC - - Change color - + + C Name + Nom de C - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Add to scatter plot + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Properties for highlighted items + + Delete signatures - - Import + + Delete scatter plot - - Import spectral signatures + + Are you sure you want to delete highlighted scatter plots? - - Export + + Save plot to file - - Export highlighted items - + + Add to Signature list + Ajouter à la liste des signatures - - Select a reclassification file + + Are you sure you want to add highlighted signatures to the list? - - Save the reclassification list to file + + Are you sure you want to delete highlighted signatures? - - Reclassify + + Values - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_it.ts b/i18n/semiautomaticclassificationplugin_it.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_it.ts +++ b/i18n/semiautomaticclassificationplugin_it.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_ja.ts b/i18n/semiautomaticclassificationplugin_ja.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_ja.ts +++ b/i18n/semiautomaticclassificationplugin_ja.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_pl.qm b/i18n/semiautomaticclassificationplugin_pl.qm index cce5acf..f693be8 100644 Binary files a/i18n/semiautomaticclassificationplugin_pl.qm and b/i18n/semiautomaticclassificationplugin_pl.qm differ diff --git a/i18n/semiautomaticclassificationplugin_pl.ts b/i18n/semiautomaticclassificationplugin_pl.ts old mode 100644 new mode 100755 index 48a1157..6bd23cd --- a/i18n/semiautomaticclassificationplugin_pl.ts +++ b/i18n/semiautomaticclassificationplugin_pl.ts @@ -1,371 +1,363 @@ - + + DockClass - + MC ID MC ID - + C ID C ID - + ... ... - + Plot Wykres - + Import library Importuj bibliotekę - + <html><head/><body><p><span >Band calc</span></p></body></html> - <html><head/><body><p><span >Kalkulator kanałów</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Kalkulator kanałów&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Preprocessing</p></body></html> - <html><head/><body><p>Wstępna obróbka obrazów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wstępna obróbka obrazów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Postprocessing</p></body></html> - <html><head/><body><p>Końcowa obróbka obrazów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Końcowa obróbka obrazów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>User manual</p></body></html> - <html><head/><body><p>Podręcznik użytkownika</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Podręcznik użytkownika&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Input file path</p></body></html> - <html><head/><body><p>Ścieżka do pliku danych</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ścieżka do pliku danych&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Open a training input</span></p></body></html> - <html><head/><body><p><span >Otwórz plik z danymi treningowymi</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Otwórz plik z danymi treningowymi&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - <html><head/><body><p><span >Twórz plik z danymi treningowymi</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Twórz plik z danymi treningowymi&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Band set</span></p></body></html> - <html><head/><body><p><span >Zestaw kanałów</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Zestaw kanałów&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - <html><head/><body><p>Dodaj zaznaczone obiekty do wykresu punktowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj zaznaczone obiekty do wykresu punktowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Import spectral signatures </p></body></html> - <html><head/><body><p>Importuj sygnatury spektralne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importuj sygnatury spektralne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Eksportuj wybrane sygnatury spektralne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Eksportuj wybrane sygnatury spektralne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Delete highlighted items</p></body></html> - <html><head/><body><p>Usuń zaznaczone obiekty</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usuń zaznaczone obiekty&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - <html><head/><body><p>Oblicz sygnatury dla wybranych obiektów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Oblicz sygnatury dla wybranych obiektów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - <html><head/><body><p >Scal wybrane sygnatury, uzyskując sygnaturę uśrednioną</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Scal wybrane sygnatury, uzyskując sygnaturę uśrednioną&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Dodaj wybrane sygnatury do wykresu spektralnego sygnatur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Dodaj wybrane sygnatury do wykresu spektralnego sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - <html><head/><body><p>Wyświetlaj pod kursorem indeks roślinności </p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wyświetlaj pod kursorem indeks roślinności &lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Display Wyświetl - + <html><head/><body><p>Select a vegetation index</p></body></html> - <html><head/><body><p>Wybierz indeks roślinności</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz indeks roślinności&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + NDVI NDVI - + EVI EVI - + Custom Użytkownika - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - <html><head/><body><p>Wyrażenie użytkownika (np. bandset#b4 / bandset#b3 )</p></body></html> - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - <html><head/><body><p>Nazwa kategorii sygnatury OT</p></body></html> - - - - C 1 - C 1 + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nazwa kategorii sygnatury OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - <html><head/><body><p>Identyfikator makroklas sygnatury OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Identyfikator makroklas sygnatury OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - <html><head/><body><p>Nazwa makroklasy sygnatury OT</p></body></html> - - - - MC 1 - MC 1 - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - <html><head/><body><p>Kategoria identyfikatora sygnatury OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nazwa makroklasy sygnatury OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Undo ROI save</p></body></html> - <html><head/><body><p>Cofnij zapis OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cofnij zapis OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p>Dodaj charakterystykę spektralną OT do listy sygnatur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj charakterystykę spektralną OT do listy sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - <html><head/><body><p>Automatyczne odświeżanie tymczasowego OT przy zmianie parametrów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatyczne odświeżanie tymczasowego OT przy zmianie parametrów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Band number</p></body></html> - <html><head/><body><p>Numer kanału</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Numer kanału&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - <html><head/><body><p>Oblicz tymczasowy OT tylko dla jednego kanału</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Oblicz tymczasowy OT tylko dla jednego kanału&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - <html><head/><body><p>Automatycznie licz wykres sygnatur tymczasowego OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatycznie licz wykres sygnatur tymczasowego OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual Podręcznik użytkownika - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter Filtruj - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + SCP Dock + + + + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> + + + + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> + + + + + Support forum + + + + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + + + + + Maximum training buffer + + + + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> + + + + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> + + + + + <html><head/><body><p></p></body></html> - SCP_Welcome + SCP_Widget - - Welcome to Semi-Automatic Classification Plugin - + + Semi-Automatic Classification Plugin + Semi-Automatic Classification Plugin - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> + + <html><head/><body><p>Select all</p></body></html> + + + Plot + Wykres + ScatterPlot @@ -375,6621 +367,3633 @@ p, li { white-space: pre-wrap; } SCP: Wykres punktowy - + S S - + MC ID MC ID - + C ID C ID - + Color Kolor - + <html><head/><body><p>Calculate scatter plot</p></body></html> - <html><head/><body><p>Wyznacz wykres punktowy</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wyznacz wykres punktowy&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band Y Kanał Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - <html><head/><body><p align="justify">Kanał Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Kanał Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band X Kanał X - + <html><head/><body><p align="justify">Band X</p></body></html> - <html><head/><body><p align="justify">Kanał X</p></body></html> - - - - Scatter raster - + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Kanał X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Calculate Oblicz - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> - - - - - <html><head/><body><p>Calculate and save to signature list</p></body></html> - <html><head/><body><p>Oblicz i zapisz do listy sygnatur</p></body></html> - - - + x=0.000000 y=0.000000 x=0.000000 y=0.000000 - + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Automatycznie dopasuj wykres do danych</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatycznie dopasuj wykres do danych&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Zapisz wykres do pliku (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zapisz wykres do pliku (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Wykres - + Colormap - - <html><head/><body><p>Select a colormap</p></body></html> - - - - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> - - - - - Extent - Zasięg - - - - <html><head/><body><p>Select extent of scatter raster</p></body></html> - - - - - same as display - jak na ekranie - - - - same as image - jak w obrazie - - - - <html><head/><body><p>Create selection polygons</p></body></html> - - - - - color - kolor - - - - <html><head/><body><p>Select polygon color</p></body></html> - - - - - <html><head/><body><p>Remove selection polygons</p></body></html> - - - - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision Dokładność - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 4 - + 3 3 - + 2 2 - + 1 1 - + 0 0 - + -1 -1 - + -2 -2 - + -3 -3 - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Usuń wiersz</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Usuń wiersz&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Wykres - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - <html><head/><body><p>Wyznacz wykres punktowy dla tymczasowego OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wyznacz wykres punktowy dla tymczasowego OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - <html><head/><body><p>Wyznacz wykres punktowy dla aktualnego widoku</p></body></html> + + Scatter list + - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - <html><head/><body><p>Wyznacz wykres punktowy dla całego obrazu</p></body></html> + + MC Name + - - Scatter list + + C Name - - MC Name + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - C Name + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin Semi-Automatic Classification Plugin - + Multiple ROI creation Tworzenie wielu OT - + X X - + Y Y - + MC ID MC ID - + C ID C ID - + Rapid ROI band Szybki kanał OT - + Point coordinates and ROI definition Współrzędne punktu i określenie OT - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - <html><head/><body><p>Generuj losowe punkty wewnątrz każdej komórki siatki o tej wielkości</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Generuj losowe punkty wewnątrz każdej komórki siatki o tej wielkości&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - <html><head/><body><p align="justify">Wielkość komórki siatki wewnątrz punktów jest tworzona losowo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Wielkość komórki siatki wewnątrz punktów jest tworzona losowo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - <html><head/><body><p align="justify">Liczba punktów generowanych losowo</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Liczba punktów generowanych losowo&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - <html><head/><body><p align="justify">Minimalna odległość pomiędzy punktami</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Minimalna odległość pomiędzy punktami&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - <html><head/><body><p>Dodaj sygnatury OT do listy sygnatur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj sygnatury OT do listy sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a library</p></body></html> - <html><head/><body><p>Wybierz bibliotekę</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz bibliotekę&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a chapter</p></body></html> - <html><head/><body><p>Wybierz rozdział</p></body></html> - - - - Algorithm band weight - Wagi kanałów + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz rozdział&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Band name - Nazwa kanału - - - + <html><head/><body><p>Set a value</p></body></html> - <html><head/><body><p>Ustaw wartość</p></body></html> - - - - Automatic thresholds - Automatyczne progi + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ustaw wartość&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right Y</p></body></html> - <html><head/><body><p>Prawy dolny Y</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Prawy dolny Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Lower right X</p></body></html> - <html><head/><body><p>Prawy dolny X</p></body></html> - - - - + - + + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Prawy dolny X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Max cloud cover (%) Maks. pokrycie chmur (%) - + to do - + yyyy-MM-dd yyyy-MM-dd - + <html><head/><body><p>Upper left X</p></body></html> - <html><head/><body><p>Lewy górny X</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lewy górny X&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Upper left Y</p></body></html> - <html><head/><body><p>Lewy górny Y</p></body></html> - - - - AcquisitionDate - Data pozyskania - - - - CloudCover - Pokrycie chmur + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lewy górny Y&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min_lat min_szer - + min_lon min_dł - + max_lat maks_szer - + max_lon maks_dł - - Service - Usługa - - - + Preview Podgląd - - Download options - Opcje - - - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - <html><head/><body><p>Po pobraniu wczytaj obrazy do QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Po pobraniu wczytaj obrazy do QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Load bands in QGIS Wczytaj kanały do QGIS - + <html><head/><body><p>Export download links to a text file</p></body></html> - <html><head/><body><p>Eksportuj pobrane łącza do pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Eksportuj pobrane łącza do pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - <html><head/><body><p>Pobierz tylko te obrazy, których podgląd jest wczytany do QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pobierz tylko te obrazy, których podgląd jest wczytany do QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Password Hasło - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - <html><head/><body><p>zapamiętaj nazwę użytkownika i hasło lokalnie w QGIS</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;zapamiętaj nazwę użytkownika i hasło lokalnie w QGIS&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + remember zapamiętaj - + User Użytkownik - + <html><head/><body><p>User name</p></body></html> - <html><head/><body><p>Nazwa użytkownika</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nazwa użytkownika&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Password</p></body></html> - <html><head/><body><p>Hasło</p></body></html> - - - - Landsat - Landsat - - - - Directory containing Landsat bands - Katalog zawierający kanały Landsat - - - - Landsat conversion to TOA reflectance and brightness temperature - Konwersja Landsat do współczynnika odbicia TOA i temperatury luminancyjnej - - - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> - <html><head/><body><p>Włącz/wyłącz wyliczanie temperatury w st. Celsjusza z kanału termalnego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Hasło&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Brightness temperature in Celsius - Temperatura luminancyjna w st. Celsjusza - - - + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - <html><head/><body><p>Włącz/Wyłącz korekcję atmosferyczną DOS1 (kanał termalny nie jest korygowany)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Włącz/Wyłącz korekcję atmosferyczną DOS1 (kanał termalny nie jest korygowany)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Apply DOS1 atmospheric correction Zastosuj korekcję atmosferyczną DOS1 - + <html><head/><body><p>No data value</p></body></html> - <html><head/><body><p>Wartość "brak danych"</p></body></html> - - - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> - <html><head/><body><p>Zastosuj metodę wyostrzania (Transformacja Brovey'a)</p></body></html> - - - - Satellite - Satelita - - - - Sun elevation - Wysokość słońca + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wartość &quot;brak danych&quot;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - <html><head/><body><p>DATA POZYSKANIA</p></body></html> - - - - Date (YYYY-MM-DD) - Data (YYYY-MM-DD) - - - - Earth sun distance - Odlegość Ziemia-Słońce - - - - <html><head/><body><p>SUN ELEVATION</p></body></html> - <html><head/><body><p>WYSOKOŚĆ SŁOŃCA</p></body></html> - - - - <html><head/><body><p>Earth sun distance</p></body></html> - <html><head/><body><p>Odległość Ziemi do Słońca</p></body></html> - - - + Metadata Metadane - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> - <html><head/><body><p>Satelita (np. LANDSAT8)</p></body></html> - - - + <html><head/><body><p>Edit metadata</p></body></html> - <html><head/><body><p>Edytuj metadane</p></body></html> - - - - Band - Kanał - - - - RADIANCE_MULT - RADIANCE_MULT - - - - RADIANCE_ADD - RADIANCE_ADD - - - - REFLECTANCE_MULT - REFLECTANCE_MULT - - - - REFLECTANCE_ADD - REFLECTANCE_ADD - - - - RADIANCE_MAXIMUM - RADIANCE_MAXIMUM - - - - REFLECTANCE_MAXIMUM - REFLECTANCE_MAXIMUM - - - - K1_CONSTANT - K1_CONSTANT - - - - K2_CONSTANT - K2_CONSTANT - - - - LMAX - LMAX - - - - LMIN - LMIN - - - - QCALMAX - QCALMAX - - - - QCALMIN - QCALMIN - - - - Clip multiple rasters - Przytnij wiele rastrów + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Edytuj metadane&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Clip coordinates Współrzędne przycięcia - + <html><head/><body><p>NoData value</p></body></html> - <html><head/><body><p>Wartość BrakDanych</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wartość BrakDanych&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Output name prefix</p></body></html> - <html><head/><body><p>Prefiks nazwy wynikowej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Prefiks nazwy wynikowej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + clip clip - + Output name prefix Prefiks nazwy wynikowej - + Split raster bands Rozdziel kanały rastra - + <html><head/><body><p>Select the image to be split</p></body></html> - <html><head/><body><p>Wybierz obraz który ma zostać rozdzielony</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz obraz który ma zostać rozdzielony&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select a multiband raster Wybierz raster wielokanałowy - + split split - + Accuracy Dokładność - + <html><head/><body><p>Select the field of the classification code </p></body></html> - <html><head/><body><p>Wybierz pole kodu klasyfikacji</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz pole kodu klasyfikacji&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the classification to assess Wybierz klasyfikację do oszacowania - + <html><head/><body><p>Select the classification to assess</p></body></html> - <html><head/><body><p>Wybierz klasyfikację do oszacowania</p></body></html> - - - - Land cover change - Zmiana pokrycia terenu - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - <html><head/><body><p>Wybierz odniesienie klasyfikacji rastra</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz klasyfikację do oszacowania&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Select the new classification - Wybierz nową klasyfikację - - - - Select the reference classification - Wybierz klasyfikację referencyjną - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - <html><head/><body><p>Wybierz nowy raster w celu porównania z rastrem referencyjnym</p></body></html> - - - - Report unchanged pixels - Zgłoś nie zmienione piksele - - - + Classification report Raport klasyfikacji - + <html><head/><body><p>Select the classification raster</p></body></html> - <html><head/><body><p>Wybierz raster klasyfikacji</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz raster klasyfikacji&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the classification Wybierz klasyfikację - + Classification to vector Klasyfikacja do wektora - + Use code from Signature list Użyj kod z Listy sygnatur - + <html><head/><body><p>Select the code field</p></body></html> - <html><head/><body><p>Wybierz pole kodu</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz pole kodu&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Reclassification Reklasyfikacja - + Calculate unique values Wyznacz niepowtarzalne wartości - + Old value Stare wartości - + New value Nowe wartości - + Band calc Kalkulator - + <html><head/><body><p>Band list</p></body></html> - <html><head/><body><p>Lista kanałów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lista kanałów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Variable Zmienna - - <html><head/><body><p>Multiplication</p></body></html> - <html><head/><body><p>Mnożenie</p></body></html> - - - - * - * - - - - <html><head/><body><p>Power</p></body></html> - <html><head/><body><p>Potęga</p></body></html> - - - - ^ - ^ - - - - <html><head/><body><p>Minus</p></body></html> - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - <html><head/><body><p>Plus</p></body></html> - - - - <html><head/><body><p>Division</p></body></html> - <html><head/><body><p>Dzielenie</p></body></html> - - - - / - / - - - - <html><head/><body><p>Close parenthesis</p></body></html> - <html><head/><body><p>Zamknij nawias</p></body></html> - - - - ) - ) - - - - <html><head/><body><p>Square root</p></body></html> - <html><head/><body><p>Pierwiastek kwadratowy</p></body></html> - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - <html><head/><body><p>Otwórz nawias</p></body></html> - - - - ( - ( - - - + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - <html><head/><body><p>piksele o wartości BrakDanych zostaną wyłączone z rastra wyjściowego</p></body></html> - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - <html><head/><body><p>zasięg rastra wynikowego będzie równy zasięgowi rastra</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;piksele o wartości BrakDanych zostaną wyłączone z rastra wyjściowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Same as - Takie jak - - - + <html><head/><body><p>Select a raster</p></body></html> - <html><head/><body><p>Wybierz raster</p></body></html> - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - <html><head/><body><p>rozszerzenie wyjścia rastra będzie takie jak przecięcie wejścia rastra</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz raster&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Intersection - Przecięcie - - - + Extent: Zasięg: - + Output raster Raster wyjściowy - - Expression - Wyrażenie - - - + Band list Lista kanałów - + Band set Zestaw kanałów - + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - <html><head/><body><p>Sortuj według nazw kanałów (priorytet dla numerów końcowych)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sortuj według nazw kanałów (priorytet dla numerów końcowych)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Wavelength unit</p></body></html> - <html><head/><body><p>Jednostka długości fali</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Jednostka długości fali&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band set definition Definicja zestawu kanałów - + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - <html><head/><body><p>Wybierz konfigurację dla ustawień centralnej długości fali kanału</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz konfigurację dla ustawień centralnej długości fali kanału&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Create virtual raster of band set - Twórz raster wirtualny - - - + Build band overviews Generuj kanały podglądu - + Settings Ustawienia - + Interface Interfejs - + Group name Nazwa grupy - + <html><head/><body><p>Group name</p></body></html> - <html><head/><body><p>Nazwa grupy</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nazwa grupy&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Class_temp_group grupa_tym_klas - + Variable name Nazwa zmiennej - + <html><head/><body><p>Variable name for expressions</p></body></html> - <html><head/><body><p>Nazwa zmiennej do wyrażenia</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nazwa zmiennej do wyrażenia&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + raster raster - + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Ustaw nazwę pola ID klasyfikacji</p><p>[maks 10 znaków]</p></body></html> - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - <html><head/><body><p>Ustaw nazwę pola ID makroklasy</p><p>[maks 10 znaków]</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ustaw nazwę pola ID klasyfikacji&lt;/p&gt;&lt;p&gt;[maks 10 znaków]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C ID field Pole C ID - + MC ID field Pole MC ID - + Transparency Przezroczystość - + ROI style Styl OT - + Processing Obróbka obrazu - + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - <html><head/><body><p>Włącz/Wyłącz dźwięk po zakończeniu obróbki obrazu</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Włącz/Wyłącz dźwięk po zakończeniu obróbki obrazu&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Play sound when finished Odtwórz dźwięk po zakończeniu - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - <html><head/><body><p>stwórz rastry wirtualne dla plików tymczasowych</p></body></html> - - - - Use virtual raster for temp files - Użyj rastrów wirtualnych dla plików tym - - - + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - <html><head/><body><p>kompresja bezstratna dla rastrów w celu zaoszczędzenia miejsca na dysku</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;kompresja bezstratna dla rastrów w celu zaoszczędzenia miejsca na dysku&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Raster compression Kompresja rastrów - + <html><head/><body><p>Set available RAM for processes</p></body></html> - <html><head/><body><p>Ustaw dostępną pamięć RAM do obróbki obrazu</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ustaw dostępną pamięć RAM do obróbki obrazu&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Available RAM (MB) Dostępny RAM (MB) - + <html><head/><body><p>Reset to default temporary directory</p></body></html> - <html><head/><body><p>Zmień folder tymczasowy na domyślny</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zmień folder tymczasowy na domyślny&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Temporary directory Katalog tymczasowy - + Debug Śledź błędy - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - <html><head/><body><p>Włącz/Wyłącz logowanie w pliku zdarzeń</p></body></html> - - - - Record events in a Log file - Rejestruj zdarzenia w pliku - - - + <html><head/><body><p>Export the Log file</p></body></html> - <html><head/><body><p>Eksportuj Plik zdarzeń</p></body></html> - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - <html><head/><body><p>Wyczyść zawartość Pliku zdarzeń</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Eksportuj Plik zdarzeń&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Log file Plik zdarzeń - + Test Test - + <html><head/><body><p>Test dependencies</p></body></html> - <html><head/><body><p>Testuj zależności</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Testuj zależności&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Test dependencies Testuj zależności - + About O wtyczce - - RGB = - RGB = + + <html><head/><body><p>Preprocess images</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wstępna obróbka obrazów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - ROI - OT - - - - Preview - Podgląd - - - - <html><head/><body><p>Preprocess images</p></body></html> - <html><head/><body><p>Wstępna obróbka obrazów</p></body></html> - - - + Preprocess images Wstępna obróbka obrazów - + Only if preview in Layers Tylko te z podglądem w QGIS - + <html><head/><body><p><span >Run</span></p></body></html> - <html><head/><body><p><span >Uruchom</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Uruchom&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Import library Importuj bibliotekę - + <html><head/><body><p>Set area in the map</p></body></html> - <html><head/><body><p>Wybierz obszar na mapie</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz obszar na mapie&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Show / hide area</p></body></html> - <html><head/><body><p>Pokaż / ukryj obszar</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pokaż / ukryj obszar&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Show Pokaż - + <html><head/><body><p>Find images</p></body></html> - <html><head/><body><p>Znajdź obrazy</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Znajdź obrazy&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Find Znajdź - + Date from Data od - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - <html><head/><body><p>Maksymalny procent pokrycia chmurami</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Maksymalny procent pokrycia chmurami&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Filter Filtruj - + <html><head/><body><p>Filter images</p></body></html> - <html><head/><body><p>Filtruj obrazy</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Filtruj obrazy&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Usuń wiersz</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Usuń wiersz&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Plot Wykres - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - <html><head/><body><p>Wyświetl na mapie podgląd wybranych obrazów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wyświetl na mapie podgląd wybranych obrazów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p><span >Reset</span></p></body></html> - <html><head/><body><p><span >Wyczyść</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Wyczyść&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Select all</p></body></html> - <html><head/><body><p >Wybierz wszystkie</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Wybierz wszystkie&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - <html><head/><body><p>Login Sentinels</p></body></html> - <html><head/><body><p>Logowanie do Sentinel</p></body></html> - - - - Sentinel-2 bands - Kanały Sentinel-2 - - - + Create points Generuj punkty - + Number of points Liczba punktów - + <html><head/><body><p>Create points</p></body></html> - <html><head/><body><p>Generuj punkty</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Generuj punkty&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - <html><head/><body><p>Generuj losowe punkty w minimalnej odległości</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Generuj losowe punkty w minimalnej odległości&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + min distance min. odległość - + inside grid wewnątrz siatki - + Min Min - + Max Max - + Dist Odl - + <html><head/><body><p >Add row</p></body></html> - <html><head/><body><p >Dodaj wiersz</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Dodaj wiersz&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Export point list to text file</p></body></html> - <html><head/><body><p>Eksportuj listę punktów do pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Eksportuj listę punktów do pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Import point list from text file</p></body></html> - <html><head/><body><p>Importuj listę punktów z pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importuj listę punktów z pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Calculate sig. Oblicz sygnatury - + Run Uruchom - + Import signatures Importuj sygnatury - + Import library file Importuj plik biblioteki - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - <html><head/><body><p>Wybierz: plik SCP (*.scp) ; bibliotekę USGS (*.asc) ; bibliotekę ASTER (*.txt) ; CSV (*.csv)</p></body></html> - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - <html><head/><body><p><span >Otwórz plik</span></p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span &gt;Otwórz plik&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Open a file</p></body></html> - <html><head/><body><p>Otwórz plik</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Otwórz plik&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - <html><head/><body><p>Dodaj charakterystykę spektralną OT do listy sygnatur</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj charakterystykę spektralną OT do listy sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Download USGS Spectral Library Pobierz bibliotekę spektralną USGS - + Import spectral library Importuj bibliotekę spektralną - + <html><head/><body><p>Import spectral library</p></body></html> - <html><head/><body><p>Importuj bibliotekę spektralną</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importuj bibliotekę spektralną&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Library Description (requires internet connection) Opis biblioteki (wymaga połączenia z internetem) - + Export signatures Eksportuj sygnatury - + Export Eksport - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - <html><head/><body><p>Eksportuj jako plik CSV (.csv)</p></body></html> - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - <html><head/><body><p>Eksportuj jako plik SCP (*.scp)</p></body></html> - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - <html><head/><body><p >Eksportuj wybrane sygnatury spektralne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Eksportuj wybrane sygnatury spektralne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - <html><head/><body><p>Wybierz folder do zapisu wybranych sygnatur spektralnych jako .csv</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz folder do zapisu wybranych sygnatur spektralnych jako .csv&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Reset</p></body></html> - <html><head/><body><p >Wyczyść</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Wyczyść&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p >Set</p></body></html> - <html><head/><body><p >Ustaw</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Ustaw&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Set weight - Ustaw wagę - - - - Automatic weight - Automatyczna waga - - - - MD Threshold - Próg MD - - - - ML Threshold - Próg ML - - - - SAM Threshold - Próg SAM - - - + Set threshold = σ * Ustaw wagę = σ * - + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Ustaw wagę, która będzie mnożona przez odchylenie standardowe</p></body></html> - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - <html><head/><body><p>Ustaw automatyczny próg σ</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ustaw wagę, która będzie mnożona przez odchylenie standardowe&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Set threshold Ustaw próg - - LCS threshold - Próg LCS - - - - Color [overlap MC_ID-C_ID] - Kolor [nałożenie MC_ID-C_ID] - - - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - <html><head/><body><p >Dodaj wybrane sygnatury do wykresu spektralnego sygnatur</p></body></html> - - - - Min Max - Min Max - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Ustaw automatyczny próg Min Max</p></body></html> - - - - σ * - σ * - - - - From pixel - Z piksela - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Aktywuj wskaźnik do wyboru progu z piksela</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>próg sygnatury jest rozszerzany o sygnaturę piksela</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>próg sygnatury jest redukowany o sygnaturę piksela</p></body></html> - - - - From ROI - Z OT - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Ustaw próg z tymczasowego OT</p></body></html> - - - - RGB list - Lista RGB - - - + <html><head/><body><p>Sort RGB automatically</p></body></html> - <html><head/><body><p>Automatycznie sortuj RGB</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatycznie sortuj RGB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB down</p></body></html> - <html><head/><body><p>Przesuń zaznaczone RBG niżej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Przesuń zaznaczone RBG niżej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted RGB up</p></body></html> - <html><head/><body><p>Przesuń zaznaczone RGB wyżej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Przesuń zaznaczone RGB wyżej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Export RGB list to text file</p></body></html> - <html><head/><body><p>Eksportuj listę RGB do pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Eksportuj listę RGB do pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Import RGB list from text file</p></body></html> - <html><head/><body><p>Importuj listę RGB z pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importuj listę RGB z pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + RGB RGB - + Automatic RGB Automatyczne RGB - + Band combinations Kombinacje kanałów - + <html><head/><body><p>Add all combinations of bands</p></body></html> - <html><head/><body><p>Dodaj wszystkie kombinacje kanałów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj wszystkie kombinacje kanałów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Preprocessing Wstępna obróbka obrazów - + <html><head/><body><p >Select a directory</p></body></html> - <html><head/><body><p >Wybierz folder</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Wybierz folder&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Perform pansharpening (Landsat 7 or 8) - Zastosuj pansharpening (Landsat 7 lub 8) - - - + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - <html><head/><body><p>Automatycznie twórz zestaw kanałów i użyj zaznaczone</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatycznie twórz zestaw kanałów i użyj zaznaczone&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Create Band set and use Band set tools Twórz zestaw kanałów i użyj narzędzi zestawu kanałów - - Sentinel-2 - Sentinel-2 - - - - Directory containing Sentinel-2 bands - Folder zawierający kanały Sentinel-2 - - - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> - <html><head/><body><p>Włącz/wyłącz korekcję atmosferyczną DOS1</p></body></html> - - - - Sentinel-2 conversion - Konwersja Sentinel-2 - - - - Quantification value - - - - - Solar irradiance - Irradiancja słoneczna - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - <html><head/><body><p>Satelita (np. Sentinel-2A)</p></body></html> - - - - ASTER - ASTER - - - - ASTER conversion to TOA reflectance and brightness temperature - Konwersja ASTER do współczynnika odbicia TOA i temperatury luminancyjnej - - - - Select file ASTER L1T (.hdf) - Wybierz plik ASTER L1T (.hdf) - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - Strefa UTM - - - - <html><head/><body><p>UTM zone</p></body></html> - <html><head/><body><p>Strefa UTM</p></body></html> - - - - UPPERLEFTM - Lewa-góra [m] - - - + <html><head/><body><p >Refresh list</p></body></html> - <html><head/><body><p >Odśwież listę</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Odśwież listę&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - <html><head/><body><p>Użyj tymczasowego OT do przycięcia rastrów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Użyj tymczasowego OT do przycięcia rastrów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Use temporary ROI for clipping Użyj tymczasowego OT do przycięcia - + PCA - + Input Dane - + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - <html><head/><body><p>oblicz tylko liczbę składowych</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;oblicz tylko liczbę składowych&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Number of components Liczba składowych - + <html><head/><body><p>Number of components</p></body></html> - <html><head/><body><p>Liczba składowych</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Liczba składowych&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Output Wynik - + Vector to raster Wektor na raster - + Select the vector Wybierz wektor - + <html><head/><body><p>Select the vector</p></body></html> - <html><head/><body><p>Wybierz wektor</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz wektor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Use the value field of the vector</p></body></html> - <html><head/><body><p>Użyj pola warstwy wektorowej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Użyj pola warstwy wektorowej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Use the value field of the vector Użyj pola warstwy wektorowej - + <html><head/><body><p>Select the value field</p></body></html> - <html><head/><body><p>Wybierz pole</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz pole&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Use constant value</p></body></html> - <html><head/><body><p>Użyj stałej wartości</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Użyj stałej wartości&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Use constant value Użyj stałej wartości - + <html><head/><body><p>Value</p></body></html> - <html><head/><body><p>Wartość</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wartość&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the type of conversion Wybierz typ konwersji - + <html><head/><body><p>Select the type of conversion</p></body></html> - <html><head/><body><p>Wybierz typ konwersji</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz typ konwersji&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Select the reference raster Wybierz raster referencyjny - + <html><head/><body><p>Select the reference raster</p></body></html> - <html><head/><body><p>Wybierz raster referencyjny</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz raster referencyjny&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Postprocessing Końcowa obróbka obrazów - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - <html><head/><body><p align="justify">piksel zachowa wartość, gdy nie uległa ona zmianie (przy wyłączonej opcji, niezmienionym pikselom przypisana zostanie wartość 0)</p></body></html> - - - + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - <html><head/><body><p>Użyj kodów z listy sygnatur do wektora</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Użyj kodów z listy sygnatur do wektora&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + C_ID C_ID - + MC_ID MC_ID - + Symbology Stylizacja - + <html><head/><body><p>Calculate unique values</p></body></html> - <html><head/><body><p>Wyznacz wartości unikalne</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wyznacz wartości unikalne&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - <html><head/><body><p>Mapuje klasy C ID na MC ID; oblicza unikalne wartości z listy sygnatur, pozostawiając stare C ID i przypisując nowe wartości MC ID</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mapuje klasy C ID na MC ID; oblicza unikalne wartości z listy sygnatur, pozostawiając stare C ID i przypisując nowe wartości MC ID&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + calculate C ID to MC ID values reklasyfikuj C ID na MC ID - + Values Wartości - - Edit raster - Edycja rastra - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - <html><head/><body><p>Cofnij edycję (tylko dla poligonów OT)</p></body></html> - - - - Select the input raster - Wybierz raster źródłowy - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - <html><head/><body><p>Wybierz raster do edycji</p></body></html> - - - - <html><head/><body><p>Use expression</p></body></html> - <html><head/><body><p>Użyj wyrażenia</p></body></html> - - - - Use expression - Użyj wyrażenia - - - - <html><head/><body><p>Enter expression</p></body></html> - <html><head/><body><p>Wprowadź wyrażenie</p></body></html> - - - - where(raster == 1, 2, raster) - where(raster == 1, 2, raster) - - - - Edit raster values - Edytuj wartości rastra - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - <html><head/><body><p>Edytuj wartości używając wektora</p></body></html> - - - - Edit values using a vector - Edytuj wartości używając wektora - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - <html><head/><body><p>Edytuj wartości używając tymczasowych OT</p></body></html> - - - - Edit values using ROI polygons - Edytuj wartości używając poligonów OT - - - - Edit options - Opcje edycji - - - - Classification sieve - Klas. (sieve) - - - + <html><head/><body><p>Select the classification</p></body></html> - <html><head/><body><p>Wybierz klasyfikację</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz klasyfikację&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Size threshold Próg wielkości - + <html><head/><body><p>Size threshold in pixels</p></body></html> - <html><head/><body><p>Próg wielkośći [px]</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Próg wielkośći [px]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Pixel connection Połączeń pikseli - + <html><head/><body><p>Pixel connection</p></body></html> - <html><head/><body><p>Połączeń pikseli</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Połączeń pikseli&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + 4 4 - + 8 8 - - Classification erosion - Klas. (erosion) - - - + Size in pixels Rozmiar [px] - + <html><head/><body><p>Size in pixels</p></body></html> - <html><head/><body><p>Rozmiar w pikselach</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Rozmiar w pikselach&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Class values Wartości klas - + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - <html><head/><body><p>Wprowadź wartości klas oddzielone , lub -</p></body></html> - - - - Classification dilation - Klas. (dilation) - - - - <html><head/><body><p>Not equals</p></body></html> - <html><head/><body><p>Różne od</p></body></html> - - - - != - != - - - - <html><head/><body><p>Equals</p></body></html> - <html><head/><body><p>Równe</p></body></html> - - - - == - == - - - - <html><head/><body><p>Greater than</p></body></html> - <html><head/><body><p>Większe niż</p></body></html> - - - - > - > - - - - <html><head/><body><p>Less than</p></body></html> - <html><head/><body><p>Mniejsze niż</p></body></html> - - - - < - < - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - <html><head/><body><p>Wprowadź wyrażenie (np. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - Decision rules - Reguły - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - <html><head/><body><p>Wprowadź jedną lub więcej reguł, oddzielonych średnikami (np. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - Value - Wartości - - - - Rule - Reguła - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - <html><head/><body><p>Przesuń zaznaczone reguły wyżej</p></body></html> - - - - <html><head/><body><p>Import rules from text file</p></body></html> - <html><head/><body><p>Importuj reguły z pliku tekstowego</p></body></html> - - - - <html><head/><body><p>Export rules to text file</p></body></html> - <html><head/><body><p>Eksportuj reguły do pliku tekstowego</p></body></html> - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - <html><head/><body><p>Przesuń zaznaczone reguły niżej</p></body></html> - - - - <html><head/><body><p>Add band to Band set</p></body></html> - <html><head/><body><p>Dodaj kanał do zestawu kanałów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wprowadź wartości klas oddzielone , lub -&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted band down</p></body></html> - <html><head/><body><p>Przesuń zaznaczone kanały niżej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Przesuń zaznaczone kanały niżej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Move highlighted band up</p></body></html> - <html><head/><body><p>Przesuń zaznaczone kanały wyżej</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Przesuń zaznaczone kanały wyżej&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Export band set to text file</p></body></html> - <html><head/><body><p>Eksportuj zestaw kanałów do pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Eksportuj zestaw kanałów do pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Import band set from text file</p></body></html> - <html><head/><body><p>Importuj zestaw kanałów z pliku tekstowego</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Importuj zestaw kanałów z pliku tekstowego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - <html><head/><body><p>Oblicz wyrażenie z kalkulatora kanałów</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Oblicz wyrażenie z kalkulatora kanałów&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Band calc expressions Wyrażenie kalkulatora - + Band set tools Narzędzia zestawu kanałów - - Batch - Tryb wsadowy - - - - <html><head/><body><p>Enter a batch function</p></body></html> - <html><head/><body><p>Wprowadź funkcję</p></body></html> - - - + Functions Funkcje - - <html><head/><body><p>Import batch from text file</p></body></html> - <html><head/><body><p>Importuj plik wsadowy z pliku tekstowego</p></body></html> - - - - <html><head/><body><p>Export batch to text file</p></body></html> - <html><head/><body><p>Eksportuj plik wsadowy do pliku tekstowego</p></body></html> - - - - Field names of training input - Nazwy pól dla obszarów treningowych (OT) - - - + <html><head/><body><p>Select temporary ROI color</p></body></html> - <html><head/><body><p>Wybierz kolor OT</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierz kolor OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + ROI color Kolor - + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - <html><head/><body><p>Zmień przezroczystość OT</p></body></html> - - - - Variable name for expressions (tab Reclassification and Edit raster) - Nazwa zmiennej do wyrażenia (zakładka Reklasyfikacja i Edycja rastra) + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zmień przezroczystość OT&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Dock Panel - + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - <html><head/><body><p>Aktualności o wtyczce są pobierane przy uruchomieniu i wyświetlane w panelu</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Aktualności o wtyczce są pobierane przy uruchomieniu i wyświetlane w panelu&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - + Download news on startup Wczytaj aktualności przy uruchamianiu - + Align - + Results - + <html><head/><body><p>Maximum number of results (images)</p></body></html> - + Cross classification - + Ancillary data - - MODIS + + Products - - MODIS conversion + + <html><head/><body><p>Select a product</p></body></html> - - Select file MODIS (.hdf) + + Stack raster bands - - ID + + Login data - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> + + Search - - Reproject to WGS 84 + + Search parameters - - Products + + Product list - - <html><head/><body><p>Select a product</p></body></html> + + Download products - - Stack raster bands + + <html><head/><body><p>Export table to text file</p></body></html> - - Select metadata file (MTD_MSI) + + <html><head/><body><p>Import table from text file</p></body></html> - - Product + + X (Lon) - - Login data + + LR - - Search + + UL - - Search parameters + + Y (Lat) - - Product list + + Date - - ProductID - + + Minimum Distance + Minimalna odległość - - Zone/Path - + + Spectral Angle Mapping + Spectral Angle Mapping - - Collection/Size + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Collection/ID + + Use vector for clipping - - Collection/Image + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Download products - + + 6 + 6 - - Row/DayNight - + + 1 + 1 - - <html><head/><body><p>Export table to text file</p></body></html> - + + 3 + 3 - - <html><head/><body><p>Import table from text file</p></body></html> - + + 2 + 2 - - X (Lon) + + 11 - - LR - + + 5 + 5 - - UL - + + 7 + 7 - - Y (Lat) + + 8A - - Date - + + 9 + 9 - - Function + + 10 - - Message + + 12 - - Number of classes + + 20 - - <html><head/><body><p>Threshold</p></body></html> + + SMTP server - - <html><head/><body><p>Number of classes</p></body></html> + + password - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Max number of iterations + + Send email of completed process to - - Distance algorithm + + SMTP process notification - - Minimum Distance - Minimalna odległość + + user + - - Spectral Angle Mapping - Spectral Angle Mapping + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> + - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> + + RUN - - Use vector for clipping + + <html><head/><body><p>Add a new band set</p></body></html> - - <html><head/><body><p>Select the vector for clipping</p></body></html> + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Use Signature list as seed signatures + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Save resulting signatures to Signature list + + Mosaic band sets - - Clustering + + 1, 2 - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> + + Select input band set - - Use random seed signatures + + <html><head/><body><p>Band set number</p></body></html> - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> + + Select the reference vector or raster - - Seed signatures from band values + + Vector field - - Seed signatures + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - <html><head/><body><p>Minimum class size in pixels</p></body></html> + + <html><head/><body><p>Select the vector field</p></body></html> - - <html><head/><body><p>If checked, use ISODATA</p></body></html> + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - ISODATA + + Use vector field for output name - - Distance threshold + + Stack band set - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> + + Band processing - - ISODATA max standard deviation + + Basic tools - - <html><head/><body><p>If checked, use K-means</p></body></html> + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - ISODATA minimum class size in pixels + + Mask class values - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> + + Use buffer of pixel size - - Method + + Create random points - - 6 - 6 + + Signature threshold + - - 1 - 1 + + Automatic thresholds + - - 3 - 3 + + Convert vector to raster + - - 2 - 2 + + Clip band set + - - 11 + + Split raster bands - - 5 - 5 + + Mosaic of band sets + - - 7 - 7 + + Band set list + - - 8A + + Mask of band set - - 9 - 9 + + Combination of band values + - - 10 + + Principal Components Analysis of band set - - 12 + + Accuracy assessment - - 16 + + Classification report - - Sentinel-3 bands - Kanały Sentinel-2 {3 ?} + + Cross classification + - - 20 + + Classification to vector - - 17 + + Reclassification - - 14 + + Select input band set (of classifications) - - 13 - + + Signature threshold + Próg sygnatur - - 19 + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - 15 + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - 21 + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - 18 + + stratified for the values - - SMTP server + + of first band of band set - - password + + raster > 0 - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - Send email of completed process to + + <html><head/><body><p>Create stratified random points</p></body></html> - - SMTP process notification + + <html><head/><body><p>Filter</p></body></html> - - user + + Advanced search - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - RUN + + System - - <html><head/><body><p>Add a new band set</p></body></html> + + CPU threads - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> + + <html><head/><body><p>Select a type</p></body></html> - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> + + Float32 - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> + + Int16 - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> + + Byte - - Add bands in a new Band set + + Create raster of band set +(stack bands) - - Mosaic band sets + + Input NoData + as value - - 1, 2 + + External programs - - mosaic + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Select input band set + + <html><head/><body><p>Select a statistic</p></body></html> - - Band combination + + Select a statistic - - <html><head/><body><p>Band set number</p></body></html> + + <html><head/><body><p>Enter a value</p></body></html> - - Select the reference vector or raster + + Statistic - - Vector field + + Project - - <html><head/><body><p>Select the reference vector or raster</p></body></html> + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - <html><head/><body><p>Select the vector field</p></body></html> + + Create RGB composite of band set when a project is loaded - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - + + User manual + Podręcznik użytkownika - - Use vector field for output name + + Use - - Stack band set - + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Do klasyfikacji wybierz ID makroklas&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Spectral distance of band sets + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Select first input band set - + + W + W - - Select second input band set - + + Maximum Likelihood + Maksymalne prawdopodobieństwo - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - + + Algorithm + Algorytm - - Spectral distance - + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ustaw próg klasyfikacji dla wszystkich sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Band processing - + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Otwórz zakładkę Próg sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Class signature - + + Classification + Klasyfikacja - - Basic tools + + Processing setting - - Cloud masking + + Help - - mask + + Tool - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> + + Load classifier - - Mask class values + + Reproject raster bands - - &K-means + + Use EPSG code - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> + + reproj - - Select MTL file + + <html><head/><body><p>EPSG value</p></body></html> - - Use buffer of pixel size + + <html><head/><body><p>X resolution</p></body></html> - - Create random points + + <html><head/><body><p>Y resolution</p></body></html> - - Signature threshold + + <html><head/><body><p>Align to raster</p></body></html> - - Automatic thresholds + + Align to raster - - LC Signature threshold + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Convert vector to raster + + same extent as reference - - Clip band set + + Y resolution - - Split raster bands + + X resolution - - Mosaic of band sets + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - Band set list + + Int32 - - Mask of band set + + UInt32 - - Combination of band values + + UInt16 - - Principal Components Analysis of band set + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Clustering of band set + + <html><head/><body><p>Scale</p></body></html> - - Accuracy assessment + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Land cover change + + Output +NoData value - - Classification report + + Set +scale - - Cross classification + + Set +offset - - Class signature + + Calculation process - - Classification to vector + + Resampling method - - Reclassification + + average - - Edit raster + + sum - - Classification sieve + + maximum - - Classification erosion + + minimum - - Classification dilation + + mode - - Multiband image list + + median - - <html><head/><body><p>Select a multiband image</p></body></html> + + nearest_neighbour - - <html><head/><body><p>Select all / Unselect all</p></body></html> + + first_quartile - - Single band list + + third_quartile - - Select input band set (of classifications) + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Signature threshold - Próg sygnatur + + Resample pixel factor + - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> + + <html><head/><body><p>Resample factor</p></body></html> - - Sentinel-3 - Sentinel-3 + + <html><head/><body><p>Select the resampling method</p></body></html> + - - Sentinel-3 conversion - Konwersja Sentinel-2 {3 ?} + + Output type + - - Directory containing Sentinel-3 bands - Folder zawierający kanały Sentinel-2 {3 ?} + + Auto + - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - <html><head/><body><p>Satelita (np. Sentinel-2A)</p></body></html> {3A?} + + <html><head/><body><p>If checked, change output NoData value</p></body></html> + - - 6 (Landsat 1-8) + + Change output NoData value - - 4 (Landsat 1-8) + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - 1 (Landsat 4-8) + + Dissolve output - - 3 (Landsat 4-8) + + Use value as NoData - - 2 (Landsat 4-8) + + Use value +as NoData - - 11 (Landsat 8) + + <html><head/><body><p>Set incremental new values</p></body></html> - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - Kanały - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - Sentinel-1 - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic + + Incremental new values - - <html><head/><body><p>Enter a value</p></body></html> + + Output NoData value - - Statistic + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - BATCH + + C Name field - - Project + + MC Name field - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> + + MC Name - - Create RGB composite of band set when a project is loaded + + C Name - - Zonal stat raster + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - User manual - Podręcznik użytkownika - - - - Support the SCP + + Import vector - - Use + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - <html><head/><body><p>Do klasyfikacji wybierz ID makroklas</p></body></html> - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> + + <html><head/><body><p>C ID field</p></body></html> - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> + + <html><head/><body><p>MC ID field</p></body></html> - - W - W - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - <html><head/><body><p>Wybierz algorytm klasyfikacji</p></body></html> - - - - Maximum Likelihood - Maksymalne prawdopodobieństwo - - - - Algorithm - Algorytm - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - <html><head/><body><p>Ustaw próg klasyfikacji dla wszystkich sygnatur</p></body></html> - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - <html><head/><body><p>Otwórz zakładkę Próg sygnatur</p></body></html> - - - - Threshold - Próg - - - - Classification - Klasyfikacja - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> + + <html><head/><body><p>MC Name field</p></body></html> - - LCS + + <html><head/><body><p>C Name field</p></body></html> - - <html><head/><body><p>Open tab LCS threshold</p></body></html> + + Vector fields - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> + + Import vector - - only overlap + + <html><head/><body><p>Import vector</p></body></html> - - Land Cover Signature Classification + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - Algorithm - Algorytm - - - - Classification output - Wynik klasyfikacji - - - - Load qml style + + GDAL installation directory - - <html><head/><body><p><span >Select qml style</span></p></body></html> - <html><head/><body><p><span >Wybierz styl qml</span></p></body></html> - - - - <html><head/><body><p>Qml file path</p></body></html> - <html><head/><body><p>Ścieżka pliku qml</p></body></html> - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - Zastosuj maskę - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - <html><head/><body><p>Ścieżka dodatkowej maski shapefile</p></body></html> - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - <html><head/><body><p>Po procesie klasyfikacji stwórz plik shapefile z klasyfikacją </p></body></html> - - - - Create vector - Stwórz wektor - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - <html><head/><body><p></p>Twórz raport klasyfikacji</body></html> - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - <html><head/><body><p>Kiedy włączone, rastry wyznaczone przez algorytm klasyfikacji (jeden na sygnaturę) zostaną zapisane wraz z klasyfikacją</p></body></html> - - - - Save algorithm files - Zapisz pliki algorytmu - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> - - - - - <html><head/><body><p>Minumum power</p></body></html> - - - - - <html><head/><body><p>Maximum power</p></body></html> - - - - - <html><head/><body><p>If checked, save classifier</p></body></html> - - - - - Import vector - - - - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - - - - <html><head/><body><p>C ID field</p></body></html> - - - - - <html><head/><body><p>MC ID field</p></body></html> - - - - - <html><head/><body><p>MC Name field</p></body></html> - - - - - <html><head/><body><p>C Name field</p></body></html> - - - - - Vector fields - - - - - Import vector - - - - - <html><head/><body><p>Import vector</p></body></html> - - - - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - - - - Python executable path - - - - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> - - - - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - - - - GDAL installation directory - - - - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> - - - - - Same extent as reference raster - - - - - <html><head/><body><p>Import reclassification table from text file</p></body></html> - - - - - <html><head/><body><p>Export reclassification table to text file</p></body></html> - - - - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - - - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> - - - - - Use alternative search for Sentinel-2 (no authentication required) - - - - - Matrix file (optional) - - - - - neighbor - - - - - Neighbor pixels - - - - - Neighbor pixels - - - - - Neighbor distance in pixels - - - - - <html><head/><body><p>Distance in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> - - - - - Enable writing verification - - - - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - - - - Create virtual raster output - - - - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> - - - - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - - - - Circular - - - - - Calculation -data type - - - - - Python modules path - - - - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - - - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - - - - Virtual download - - - - - <html><head/><body><p>Sort band sets by date</p></body></html> - - - - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> - - - - - NoData mask - - - - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - - - - Calculate linear regression - - - - - SpectralSignaturePlot - - - SCP: Spectral Signature Plot - SCP: Wykres Charakterystyki Spektralnej - - - - Signature list - Lista sygnatur - - - - S - S - - - - MC ID - MC ID - - - - C ID - C ID - - - - Color - Kolor - - - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> - <html><head/><body><p>Automatycznie wypełnij wykres danymi</p></body></html> - - - - Plot - Wykres - - - - Signature details - Szczegóły sygnatury - - - - Spectral distances - Odległości spektralne - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - <html><head/><body><p>Aktywuj wskaźnik do wyznaczenia progu z piksela</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - <html><head/><body><p>próg sygnatury z wyłączeniem sygnatury piksela</p></body></html> - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - <html><head/><body><p>próg sygnatury z uwzględnieniem sygnatury piksela</p></body></html> - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - <html><head/><body><p>Ustal próg z tymczasowego OT</p></body></html> - - - - Automatic thresholds - Automatyczne progi - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - <html><head/><body><p>Ustaw automatyczny próg Min Max</p></body></html> - - - - Min Max - Min Max - - - - σ * - σ * - - - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - <html><head/><body><p>Ustal mnożnik odchylenia standardowego</p></body></html> - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - <html><head/><body><p>Ustaw σ jako automatyczy próg</p></body></html> - - - - <html><head/><body><p>Undo thresholds</p></body></html> - <html><head/><body><p>Cofnij progi</p></body></html> - - - - Import library - Importuj bibliotekę - - - - <html><head/><body><p >Delete row</p></body></html> - <html><head/><body><p >Usuń wiersz</p></body></html> - - - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - <html><head/><body><p >Dodaj wybrane sygnatury do listy sygnatur</p></body></html> - - - - <html><head/><body><p>Calculate spectral distances</p></body></html> - <html><head/><body><p>Oblicz odległości spektralne</p></body></html> - - - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - <html><head/><body><p>Rysuj zakres wartości (odchylenie standardowe lub min./max.) dla każdej sygnatury</p></body></html> - - - - Band lines - Linie kanałów - - - - Max characters - Maks. znaków - - - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - <html><head/><body><p align="justify">Długość tekstu w legendzie wykresu spektralnego</p></body></html> - - - - x=0.000000 y=0.000000 - x=0.000000 y=0.000000 - - - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> - <html><head/><body><p>Zmień zakres wartości interaktywnie na wykresie</p></body></html> - - - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - <html><head/><body><p>Zapisz wykres do pliku (jpg, png, pdf)</p></body></html> - - - - Plot value range - Rysuj zakres wartości - - - - Grid - Siatka - - - - From -pixel - - - - - From -ROI - - - - - MC Name - - - - - C Name - - - - - semiautomaticclassificationplugin - - - SCP - SCP - - - - Settings - Ustawienia - - - - Semi-Automatic Classification Plugin - Semi-Automatic Classification Plugin - - - - Band set - Zestaw kanałów - - - - Select a RGB color composite - Wybierz kompozycję kolorów RGB - - - - Show/hide the input image - Pokaż/ukryj obraz wejściowy - - - - Local cumulative cut stretch of band set - Lokalne skumulowane wzmocnienie kontrastu - - - - Local standard deviation stretch of band set - Lokalne wzmocnienie kontrastu (odchylenie standardowe) - - - - Spectral plot - Wykres spektralny - - - - Band calc - Kalkulator kanałów - - - - Online help - Pomoc Online - - - - Select a mask shapefile - Wybierz shapefile maski - - - - Save classification output - Zapisz wyjście klasyfikacji - - - - Select a qml style - Wybierz styl qml - - - - Select a signature list file - Wybierz plik z listą sygnatur - - - - Reset signature list - Wyczyść listę sygnatur - - - - Select a library file - Wybierz bibliotekę pliku - - - - Export the highlighted signatures to CSV library - Eksportuj wybrane sygnatury do biblioteki CSV - - - - Delete signatures - Usuń sygnatury - - - - Are you sure you want to delete highlighted signatures? - Czy na pewno chcesz usunąć wybrane sygnatury? - - - - Merge signatures - Połącz sygnatury - - - - Merge highlighted signatures? - Połączyć wybrane sygnatury? - - - - Test results - Wyniki testu - - - - Information - Informacja - - - - No log file found - Nie znaleziono Pliku zdarzeń - - - - Select a raster; raster is not loaded - Wybierz raster; raster nie jest załadowany - - - - Select a point inside the image area - Wybierz punkt w obszarze obrazu - - - - Data projections do not match. Reproject data to the same projection - Układy współrzędnych nie są zgodne. Dokonaj reprojekcji - - - - Maximum Likelihood threshold must be less than 100 - Maksymalny Próg Prawdopodobieństwa musi być mniejszy niż 100 - - - - Spectral Angle Mapping threshold must be less than 90 - Próg Mapowania Kąta Spektralnego musi być mniejszy niż 90 - - - - Select a directory - Wybierz katalog - - - - At least 3 points are required - Wymagane są przynajmniej 3 punkty - - - - Negative IDs are not allowed - Ujemne ID nie są dozwolone - - - - Select at least one signature - Wybierz przynajmniej jedną sygnaturę - - - - SCP is recording the Log file - SCP zapisuje Plik zdarzeń - - - - Error - Błąd - - - - No metadata found inside the input directory (a .txt file whose name contains MTL) - Nie znaleziono metadanych w katalogu danych (pliku tekstowego, który w nazwie zawiera MTL) - - - - Raster not found - Nie znaleziono rastra - - - - Error saving signatures - Błąd zapisu sygnatur - - - - Error opening signatures - Błąd otwierania sygnatur - - - - Error opening spectral library - Błąd otwierania biblioteki spektralnej - - - - Error saving spectral library - Błąd zapisywania biblioteki spektralnej - - - - Import failed - Importowanie nie powiodło się - - - - ROI creation failed - Tworzenie OT nie powiodło się - - - - Internet connection failed - Łączenie z internetem nie powiodło się - - - - Error reading raster. Possibly the raster path contains unicode characters - Błąd odczytu rastra. Możliwe, że ścieżka dostępu rastra zawiera znaki UNICODE - - - - Error calculating signature. Possibly ROI is too small - Błąd wyznaczania sygnatur. Prawdopodobnie OT jest za mały - - - - Unable to split bands - Nie można rozdzielić kanałów - - - - Error reading band set. Possibly raster files are not loaded - Błąd odczytu zestawu kanałów. Prawdopodobnie pliki rastra nie są załadowane - - - - Clip area outside image. Check the raster projection - Obszar przycięcia poza obrazem. Sprawdź układ wsp. rastra - - - - Unable to merge. Signatures have different unit or wavelength - Nie można połączyć. Sygnatury posiadają różne jednostki długości fali - - - - Unable to calculate. Expression error - Nie można obliczyć. Błąd wyrażenia - - - - Unable to calculate. Metadata error - Nie można wyznaczyć. Błąd metadanych - - - - Unable to find images - Nie można odnaleźć obrazów - - - - Unable to connect - Nie można połączyć - - - - Unable to load image - Nie można załadować obrazu - - - - Attribute table error - Błąd atrybutów tabeli - - - - Unable to pansharpen: missing bands - Nie można wykonać polecenia pansharp: nie znaleziono kanałów - - - - Unable to calculate - Nie można wyznaczyć - - - - Error reading raster. Possibly bands are not aligned - Błąd odczytu rastra. Prawdopodobnie kanały nie są dopasowane - - - - Unable to get raster projection. Try to reproject the raster - Nie można odczytać projekcji rastra. Spróbuj wykonać reprojekcję raster - - - - Warning - Uwaga - - - - It appears that SciPy is not correctly installed. Please, update QGIS - Wygląda na to,że SciPy nie jest zainstalowany poprawnie. Proszę zaktualizować QGIS - - - - Wavelength already present - Długość fali jest już podana - - - - RAM value was too high. Value has been decreased automatically - Wartość RAM'u jest zbyt duża. Wartość została obniżona automatycznie - - - - Unable to load the virtual raster. Please create it manually - Nie można załadować rastra wirtualnego. Proszę stworzyć go ręcznie - - - - Unable to proceed. The raster must be in projected coordinates - Nie można kontynuować. Raster musi znajdować się we współrzędnych odwzorowania - - - - Incorrect expression - Nieprawidłowe wyrażenie - - - - Unable to access the temporary directory - Nie można uzyskać dostępu do katalogu tymczasowego - - - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude - Zmniejsz zakres obszaru wyszukiwania w obrębie 10 stopni szerokości geograficznej i 10 stopni długości geograficznej - - - - Save error matrix raster output - Zapisz błąd macierzy wyjścia rastra - - - - Classification - Klasyfikacja - - - - ErrMatrixCode - BłądKoduMacierzy - - - - Reference - Odniesienie - - - - PixelSum - PodsPiks - - - - Total - Całkowicie - - - - Overall accuracy [%] = - Ogólna dokładność [%] = - - - - Kappa hat classification = - - - - - Reset weights - Wyczyść wagi - - - - Are you sure you want to reset weights? - Czy na pewno wyczyścić wagi? - - - - Save raster output - Zapisz wyjście rastra - - - - Clear band set - Oczyść zestaw kanałów - - - - Are you sure you want to clear the band set? - Czy na pewno oczyścić zestaw kanałów? - - - - Save the band set to file - Zapisz zestaw kanałów w pliku - - - - Select a band set file - Wybierz plik z zestawem kanałów - - - - Remove band - Usuń kanał - - - - Are you sure you want to remove the selected bands from band set? - Czy na pewno usunąć wybrane kanały z zestawu kanałów? - - - - Save virtual raster - Zapisz raster wirtualny - - - - Save raster - Zapisz raster - - - - Build overviews - Zbuduj podglądy - - - - Do you want to build the external overviews of bands? - Czy na pewno zbudować zewnętrzne podglądy na kanały? - - - - Unknown - Nieznane - - - - Class - Klasyf - - - - Percentage % - Procent % - - - - Save classification report - Zapisz raport klasyfikacji - - - - Select a directory where to save clipped rasters - Wybierz katalog do zapisu przyciętych rastrów - - - - Download the images in the table (requires internet connection) - Pobierz obrazy w tabeli (wymaga połączenia z internetem) - - - - Export download links - Eksportuj pobrane łącza - - - - Searching ... - Wyszukiwanie... - - - - Are you sure you want to clear the table? - Czy na pewno oczyścić tabelę? - - - - Save land cover change raster output - Zapisz zmiany rastra wyjściowego z pokryciem terenu - - - - ReferenceClass - OdniesienieKlasyf - - - - NewClass - NowaKlasyf - - - - Select a MTL file - Wybierz plik MTL - - - - Save the point list to file - Zapisz listę punktów w pliku - - - - Transparency - Przezroczystość - - - - Save Log file - Zapisz Plik zdarzeń - - - - Reset field names - Wyczyść nazwy pól - - - - Are you sure you want to reset field names? - Czy na pewno wyczyścić nazwy pól? - - - - Reset variable name - Wyczyść nazwę zmiennej - - - - Are you sure you want to reset variable name? - Czy na pewno wyczyścić nazwę zmiennej? - - - - Reset group name - Wyczyść nazwę grupy - - - - Are you sure you want to reset group name? - Czy na pewno wyczyścić nazwę grupy? - - - - Change temporary directory - Zmień tymczasowy katalog - - - - Are you sure you want to change the temporary directory? - Czy na pewno zmienić tymczasowy katalog? - - - - Are you sure you want to reset the temporary directory? - Czy na pewno wyczyścić katalog tymczasowy? - - - - Reset thresholds - Wyczyść progi - - - - Are you sure you want to reset thresholds? - Czy na pewno wyczyścić progi? - - - - It appears that the shapefile - Wygląda na to, że ten shapefile - - - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? - nie posiada pól, które są potrzebne do wyznaczania sygnatur. -Chcesz dodać wymagane pola do tego shapefile? - - - - Undo save ROI - Cofnij zapisywanie OT - - - - Values - Wartości - - - - Select a SCP training input - Wybierz dane treningowe - - - - Export SCP training input - Eksportuj dane treningowe - - - - Calculate signatures - Oblicz sygnatury - - - - Calculate signatures for highlighted items? - Obliczyć sygnatury wybranych obiektów? - - - - Are you sure you want to delete highlighted ROIs and signatures? - Czy na pewno chcesz usunąć wybrane OT i sygnatury? - - - - Create SCP training input - Stwórz dane treningowe - - - - Zoom to input image extent - Powiększ do zasięgu obrazu - - - - Zoom to temporary ROI - Powiększ do tymczasowego OT - - - - Show/hide the temporary ROI - Pokaż/ukryj tymczasowy OT - - - - Create a ROI polygon - Stwórz poligon OT - - - - Activate ROI pointer - Aktywuj wskaźnik OT - - - - Redo the ROI at the same point - Przywróć OT w tym samym punkcie - - - - Dist - Odl. - - - - Similarity of pixels (distance in radiometry unit) - Podobieństwo pikseli (odl. w jedn. radiometr.) - - - - Min - Min - - - - Minimum area of ROI (in pixel unit) - Minimalna powierzchnia OT [px] - - - - Max - Max - - - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) - Bok kwadratu zawierającego OT [px] - - - - Zoom to the classification preview - Powiększ do podglądu klasyfikacji - - - - Show/hide the classification preview - Pokaż/ukryj podgląd klasyfikacji - - - - Activate classification preview pointer - Aktywuj wskaźnik podglądu klasyfikacji - - - - Redo the classification preview at the same point - Przywróć podgląd klasyfikacji w to samo miejsce - - - - T - T - - - - Set preview transparency - Ustaw przezroczystość podglądu - - - - S - S - - - - Set the preview size (in pixel unit) - Ustaw rozmiar podglądu [px] - - - - Remove temporary files - Usuń pliki tymczasowe - - - - Preprocessing - Wstępna obróbka obrazów - - - - Postprocessing - Końcowa obróbka obrazów - - - - Scatter plot - Wykres punktowy - - - - Batch - Tryb wsadowy - - - - User manual - Podręcznik użytkownika - - - - Select a SCP training input; input is not loaded - Wybierz dane treningowe; nie wczytano danych - - - - Signature list file (.slf) created - Utworzono plik sygnatur (.slf) - - - - No image found. Try with a larger area - Nie znaleziono obrazu. Zwiększ obszar. - - - - Create a ROI polygon or use a vector - Stwórz poligon OT lub wykorzystaj wektor. - - - - Define a search area - Definiuj obszar poszukiwań. - - - - Memory error. Please, decrease decimal precision - Błąd pamięci. Zwiększ liczbę pozycji dziesiętnych. - - - - Error calculating plot - Błąd generowania wykresu - - - - SSL connection error. Please see the FAQ of the plugin user manual for solving this - Błąd połączenia SSL. Sprawdź szczegóły w FAQ podręcznika wtyczki. - - - - Wavelength unit not provided in band set - Nie podano jednostki długości fali dla zestawu kanałów. - - - - Macroclass symbology is missing - Brak stylizacji makroklas. - - - - Missing bands - Brak kanałów - - - - No metadata found inside the input directory. Default values will be used - Nie znaleziono metadanych w katalogu danych. Zostaną użyte wartości domyślne. - - - - Select a shapefile - Wybierz shapefile - - - - Set thresholds - Ustaw próg - - - - Are you sure you want to set thresholds for several signatures? - Czy na pewno chcesz ustalić próg dla wielu sygnatur? - - - - Select a HDF file - Wybierz plik HDF - - - - Clear rules - Wyczyść reguły - - - - Are you sure you want to clear the rules? - Czy na pewno wyczyścić reguły? - - - - Select a text file of rules - Wybierz plik tekstowy z regułami - - - - Save the rules to file - Zapisz reguły do pliku - - - - Select a raster - Wybierz raster - - - - Select a batch file - Wybierz plik wsadowy + + <html><head/><body><p>Import reclassification table from text file</p></body></html> + - - Save the batch to file - Zapisz do pliku wsadowego + + <html><head/><body><p>Export reclassification table to text file</p></body></html> + - - Save output - Zapisz wynik + + Matrix file (optional) + - - Principal Components Analysis - Analiza głównych składowych + + Neighbor pixels + - - Covariance matrix - Macierz kowariancji + + Neighbor distance in pixels + - - Bands - Kanały + + <html><head/><body><p>Distance in pixels</p></body></html> + - - Correlation matrix - Macierz korelacji + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + - - Eigen vectors + + Create virtual raster output - - Vector_ + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Eigen values + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Accounted variance + + Circular - - Cumulative variance + + Calculation +data type - - Reset RGB list - Wyczyść listę RGB + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + - - Are you sure you want to clear the RGB list? + + Virtual download - - RGB list - Lista RGB + + <html><head/><body><p>Sort band sets by date</p></body></html> + - - Calculate all the RGB combinations? - Wygenerować wszystkie kombinacje RGB? + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + - - Save the RGB list to file - Zapisz listę RGB w pliku + + Calculate linear regression + - - Select a XML file - Wybierz plik XML + + Create virtual raster +of band set + - - Reset temporary directory - Wyczyść folder tymczasowy + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> + - - Delete scatter plot - Usuń wykres punktowy + + Wavelength unit + Jednostka długości fali - - Are you sure you want to delete highlighted scatter plots? + + Wavelength - - Save plot to file - Zapisz wykres w pliku + + Band quick settings + - - Edit value range - Edytuj zakres wartości + + Band set table + - - Are you sure you want to edit the value range for several signatures? - Czy na pewno chcesz edytować wartości wielu sygnatur? + + Active band set + - - Add to Signature list - Dodaj do listy sygnatur + + Root directory + - - Are you sure you want to add highlighted signatures to the list? - Czy na pewno chcesz dodać wybrane sygnatury do listy? + + Script + - - Undo thresholds - Cofnij progi + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> + - - Are you sure you want to undo thresholds? - Czy na pewno chcesz wyczyścić progi? + + Copy + - - Multiple ROI creation - Tworzenie wielu OT + + Band dilation + - - Import signatures - Importuj sygnatury + + Output name + - - Export signatures - Eksportuj sygnatury + + dilation_ + - - Algorithm band weight - Wagi kanałów + + Virtual output + - - Signature threshold - Próg sygnatur + + <html><head/><body><p>Enter output name</p></body></html> + - - LCS threshold - Próg LCS + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> + - - Landsat - Landsat + + erosion_ + - - Sentinel-2 - Sentinel-2 + + Band erosion + - - ASTER - ASTER + + Band sieve + - - Clip multiple rasters - Przytnij wiele rastrów + + sieve_ + - - Split raster bands - Rozdziel kanały rastra + + Script (copy the code in a Python shell) + - - PCA - PCA + + Script + - - Vector to raster - Wektor na raster + + <html><head/><body><p>Enter an expression</p></body></html> + - - Accuracy - Dokładność + + Expression + - - Land cover change - Zmiana pokrycia terenu + + NoData +mask + - - Classification report - Raport klasyfikacji + + UL X + - - Classification to vector - Klasyfikacja do wektora + + UL Y + - - Reclassification - Reklasyfikacja + + LR X + - - Edit raster - Edycja rastra + + LR Y + - - Classification sieve - Klasyfikacja (sieve) + + Output +data type + - - Classification erosion - Klasyfikacja (erosion) + + False + - - Classification dilation - Klasyfikacja (dilation) + + True + - - About - O wtyczce + + None + - - Interface - Interfejs + + <html><head/><body><p>Upperleft X</p></body></html> + - - Debug - Śledź błędy + + <html><head/><body><p>Upper-left Y</p></body></html> + - - The coordinate system of training input is different from the input image. Please create a new training input - Układ współrzędnych danych treningowych jest inny niż obrazu. Dokonaj transformacji OT. + + <html><head/><body><p>Lower-right X</p></body></html> + - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 - Sentinel-3 + + cloud_cover + - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name - Nazwa kanału + + collection + - - Center wavelength - Centralna długość fali + + size + - - Multiplicative Factor - Mnożnik + + uid + - - Additive Factor - Współczynnik addytywny + + preview + - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit - Jednostka długości fali + + Bands + - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> + - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing - Obróbka obrazu + + <html><head/><body><p>Use NoData mask</p></body></html> + - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> + - - C ID - C ID + + Save to file + - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type - Typ + + SCP: Spectral Signature Plot + SCP: Wykres Charakterystyki Spektralnej - - Color - Kolor + + Signature list + Lista sygnatur - - SCPID - + + S + S - - Zoom to highlighted items - + + MC ID + MC ID - - Clear selection - + + C ID + C ID - - Collapse/expand all - + + Color + Kolor - - Merge highlighted items - + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Automatycznie wypełnij wykres danymi&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Calculate signatures for highlighted items - + + Plot + Wykres - - Delete highlighted items - + + Signature details + Szczegóły sygnatury - - Change MC ID for highlighted items - + + Spectral distances + Odległości spektralne - - Add highlighted items to spectral plot - + + <html><head/><body><p >Delete row</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Usuń wiersz&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Add highlighted items to scatter plot - + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p &gt;Dodaj wybrane sygnatury do listy sygnatur&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Change Macroclass ID - + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Rysuj zakres wartości (odchylenie standardowe lub min./max.) dla każdej sygnatury&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Change the Macroclass ID for highlighted items to - + + Band lines + Linie kanałów - - Properties - + + Max characters + Maks. znaków - - Zoom to - + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Długość tekstu w legendzie wykresu spektralnego&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Check/uncheck - + + x=0.000000 y=0.000000 + x=0.000000 y=0.000000 - - Check/uncheck highlighted items - + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + &lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zapisz wykres do pliku (jpg, png, pdf)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; - - Clear selection of highlighted items - + + Plot value range + Rysuj zakres wartości - - Collapse/expand all macroclasses - + + Grid + Siatka - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot - + + Delete signatures + Usuń sygnatury - - Add to scatter plot - + + Are you sure you want to delete highlighted signatures? + Czy na pewno chcesz usunąć wybrane sygnatury? - - Properties for highlighted items - + + Values + Wartości - - Import - + + Delete scatter plot + Usuń wykres punktowy - - Import spectral signatures + + Are you sure you want to delete highlighted scatter plots? - - Export - + + Save plot to file + Zapisz wykres w pliku - - Export highlighted items - + + Add to Signature list + Dodaj do listy sygnatur - - Select a reclassification file - + + Are you sure you want to add highlighted signatures to the list? + Czy na pewno chcesz dodać wybrane sygnatury do listy? - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_pt.ts b/i18n/semiautomaticclassificationplugin_pt.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_pt.ts +++ b/i18n/semiautomaticclassificationplugin_pt.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_pt_BR.ts b/i18n/semiautomaticclassificationplugin_pt_BR.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_pt_BR.ts +++ b/i18n/semiautomaticclassificationplugin_pt_BR.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_uk_UA.ts b/i18n/semiautomaticclassificationplugin_uk_UA.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_uk_UA.ts +++ b/i18n/semiautomaticclassificationplugin_uk_UA.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/i18n/semiautomaticclassificationplugin_zh_CN.ts b/i18n/semiautomaticclassificationplugin_zh_CN.ts old mode 100644 new mode 100755 index 296ba92..526acf5 --- a/i18n/semiautomaticclassificationplugin_zh_CN.ts +++ b/i18n/semiautomaticclassificationplugin_zh_CN.ts @@ -1,6991 +1,3996 @@ - + + DockClass - + <html><head/><body><p><span >Band calc</span></p></body></html> - + <html><head/><body><p>Preprocessing</p></body></html> - + <html><head/><body><p>Postprocessing</p></body></html> - + <html><head/><body><p>User manual</p></body></html> - + <html><head/><body><p>Input file path</p></body></html> - + <html><head/><body><p><span >Open a training input</span></p></body></html> - + <html><head/><body><p><span >Create a new training input</span></p></body></html> - + Plot - + <html><head/><body><p><span >Band set</span></p></body></html> - + MC ID - + C ID - + <html><head/><body><p>Add highlighted items to scatter plot</p></body></html> - + ... - + <html><head/><body><p>Import spectral signatures </p></body></html> - + Import library - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Delete highlighted items</p></body></html> - + <html><head/><body><p>Calculate signatures for highlighted items</p></body></html> - + <html><head/><body><p >Merge highlighted spectral signatures obtaining the average signature</p></body></html> - + <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - + <html><head/><body><p>Display a vegetation index value with the cursor</p></body></html> - + Display - + <html><head/><body><p>Select a vegetation index</p></body></html> - + NDVI - + EVI - + Custom - - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - + <html><head/><body><p>The class name of the ROI signature</p></body></html> - - C 1 - - - - + <html><head/><body><p>The macroclass ID of the ROI signature</p></body></html> - + <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - - MC 1 - - - - - <html><head/><body><p>The class ID of the ROI signature</p></body></html> - - - - + <html><head/><body><p >Undo ROI save</p></body></html> - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + <html><head/><body><p >Save temporary ROI to training input</p></body></html> - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> - + <html><head/><body><p>Band number</p></body></html> - + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> - + Autosave - + Rapid ROI b. - + Signature - - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> - - - - + Auto-plot - + <html><head/><body><p>Batch</p></body></html> - + News - + User manual - + <html><head/><body><p>Ask a question</p></body></html> - - - Ask a question - - - - - Support the SCP - - - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - - Home - + Training input - + <html><head/><body><p>Download products</p></body></html> - + <html><head/><body><p>Band processing</p></body></html> - - SCP &Dock - - - - + <html><head/><body><p>Basic tools</p></body></html> - + A&uto-refresh ROI - + ROI options - + <html><head/><body><p>Filter</p></body></html> - + Filter - + <html><head/><body><p>Remove training input</p></body></html> - + ROI & Signature list - + C Name - + MC Name - + <html><head/><body><p>Redo ROI save</p></body></html> - - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - - - - SCP_Welcome - - - Welcome to Semi-Automatic Classification Plugin - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - - - ScatterPlot - - - SCP: Scatter Plot - - - - - S + + SCP Dock - - MC ID + + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> - - C ID + + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> - - Color + + Support forum - - Scatter raster + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> - - Calculate + + Maximum training buffer - - <html><head/><body><p>Calculate scatter plot</p></body></html> + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> + + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> - - <html><head/><body><p>Calculate and save to signature list</p></body></html> + + <html><head/><body><p></p></body></html> + + + SCP_Widget - - x=0.000000 y=0.000000 + + Semi-Automatic Classification Plugin - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + <html><head/><body><p>Select all</p></body></html> - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Plot + + + ScatterPlot - - Plot + + SCP: Scatter Plot - - Colormap + + S - - <html><head/><body><p>Select a colormap</p></body></html> + + MC ID - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> + + C ID - - Extent + + Color - - <html><head/><body><p>Select extent of scatter raster</p></body></html> + + Calculate - - same as display + + <html><head/><body><p>Calculate scatter plot</p></body></html> - - same as image + + x=0.000000 y=0.000000 - - <html><head/><body><p>Create selection polygons</p></body></html> + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - color + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - <html><head/><body><p>Select polygon color</p></body></html> + + Plot - - <html><head/><body><p>Remove selection polygons</p></body></html> + + Colormap - + Band Y - + <html><head/><body><p align="justify">Band Y</p></body></html> - + Band X - + <html><head/><body><p align="justify">Band X</p></body></html> - + <html><head/><body><p>Use custom decimal precision</p></body></html> - + Precision - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - + 4 - + 3 - + 2 - + 1 - + 0 - + -1 - + -2 - + -3 - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Calculate scatter plot from temporary ROI</p></body></html> - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - - + Scatter list - + MC Name - + C Name - - - SemiAutomaticClassificationPlugin - - - RGB = - - - - ROI + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - Preview + + <html><head/><body><p>Select a colormap for selected rows</p></body></html> + + + SemiAutomaticClassificationPlugin - + Semi-Automatic Classification Plugin - + <html><head/><body><p>Preprocess images</p></body></html> - + Preprocess images - + <html><head/><body><p>Load images in QGIS after download</p></body></html> - + Load bands in QGIS - + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - + Only if preview in Layers - + <html><head/><body><p><span >Run</span></p></body></html> - + Import library - + <html><head/><body><p>Export download links to a text file</p></body></html> - + <html><head/><body><p>Set area in the map</p></body></html> - + <html><head/><body><p>Lower right X</p></body></html> - + <html><head/><body><p>Lower right Y</p></body></html> - + <html><head/><body><p>Upper left X</p></body></html> - + <html><head/><body><p>Upper left Y</p></body></html> - + <html><head/><body><p>Show / hide area</p></body></html> - + Show - + <html><head/><body><p>Find images</p></body></html> - + Find - + yyyy-MM-dd - + Max cloud cover (%) - + to - + Date from - + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - + Filter - + <html><head/><body><p>Filter images</p></body></html> - + <html><head/><body><p >Delete row</p></body></html> - + Plot - + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - + <html><head/><body><p><span >Reset</span></p></body></html> - - AcquisitionDate - - - - - CloudCover - - - - + min_lat - + min_lon - + max_lat - + max_lon - + Preview - - Download options - - - - + <html><head/><body><p >Select all</p></body></html> - + <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - + remember - + <html><head/><body><p>Password</p></body></html> - + Password - + <html><head/><body><p>User name</p></body></html> - + User - - <html><head/><body><p>Login Sentinels</p></body></html> - - - - - Service - - - - - Sentinel-2 bands - - - - + Multiple ROI creation - + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - + Create points - + Number of points - + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - + <html><head/><body><p>Create points</p></body></html> - + <html><head/><body><p>Create random points with a minimum distance</p></body></html> - + min distance - + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - + inside grid - + Point coordinates and ROI definition - + X - + Y - + MC ID - + C ID - + Min - + Max - + Dist - + Rapid ROI band - + <html><head/><body><p >Add row</p></body></html> - + <html><head/><body><p >Export point list to text file</p></body></html> - + <html><head/><body><p >Import point list from text file</p></body></html> - + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - + Calculate sig. - + Run - + Import signatures - + Import library file - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - + <html><head/><body><p><span >Open a file</span></p></body></html> - + <html><head/><body><p>Open a file</p></body></html> - + C ID field - + MC ID field - + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - + Download USGS Spectral Library - + <html><head/><body><p>Select a chapter</p></body></html> - + <html><head/><body><p>Select a library</p></body></html> - + Import spectral library - + <html><head/><body><p>Import spectral library</p></body></html> - + Library Description (requires internet connection) - + Export signatures - + Export - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - Algorithm band weight - - - - - Band name - - - - + <html><head/><body><p >Reset</p></body></html> - + <html><head/><body><p >Set</p></body></html> - - Set weight + + <html><head/><body><p>Set a value</p></body></html> - - <html><head/><body><p>Set a value</p></body></html> + + Set threshold = σ * - - Automatic weight + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - MD Threshold + + Set threshold - - ML Threshold + + <html><head/><body><p>Sort RGB automatically</p></body></html> - - SAM Threshold + + <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - Set threshold = σ * + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + <html><head/><body><p>Export RGB list to text file</p></body></html> - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + <html><head/><body><p>Import RGB list from text file</p></body></html> - - Set threshold + + RGB - - Automatic thresholds + + Automatic RGB - - LCS threshold + + Band combinations - - Color [overlap MC_ID-C_ID] + + <html><head/><body><p>Add all combinations of bands</p></body></html> - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> + + Preprocessing - - Min Max + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Apply DOS1 atmospheric correction - - - σ * + + + <html><head/><body><p>No data value</p></body></html> - - From pixel + + <html><head/><body><p >Select a directory</p></body></html> - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + Create Band set and use Band set tools - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + <html><head/><body><p>Edit metadata</p></body></html> - - From ROI + + Metadata - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + <html><head/><body><p >Refresh list</p></body></html> - - RGB list + + Clip coordinates - - <html><head/><body><p>Sort RGB automatically</p></body></html> + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - <html><head/><body><p>Move highlighted RGB down</p></body></html> + + Use temporary ROI for clipping - - <html><head/><body><p>Move highlighted RGB up</p></body></html> + + <html><head/><body><p>NoData value</p></body></html> - - <html><head/><body><p>Export RGB list to text file</p></body></html> + + <html><head/><body><p>Output name prefix</p></body></html> - - <html><head/><body><p>Import RGB list from text file</p></body></html> + + clip - - RGB + + Output name prefix - - Automatic RGB + + Split raster bands - - Band combinations + + <html><head/><body><p>Select the image to be split</p></body></html> - - <html><head/><body><p>Add all combinations of bands</p></body></html> + + Select a multiband raster - - Preprocessing + + split - - Landsat + + PCA - - Directory containing Landsat bands + + Input - - Landsat conversion to TOA reflectance and brightness temperature + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> + + Number of components - - Brightness temperature in Celsius + + <html><head/><body><p>Number of components</p></body></html> - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + Output - - Apply DOS1 atmospheric correction + + Vector to raster - - <html><head/><body><p>No data value</p></body></html> + + Select the vector - - <html><head/><body><p >Select a directory</p></body></html> + + <html><head/><body><p>Select the vector</p></body></html> - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> + + <html><head/><body><p>Use the value field of the vector</p></body></html> - - Perform pansharpening (Landsat 7 or 8) + + Use the value field of the vector - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + <html><head/><body><p>Select the value field</p></body></html> - - Create Band set and use Band set tools + + <html><head/><body><p>Use constant value</p></body></html> - - <html><head/><body><p>Edit metadata</p></body></html> + + Use constant value - - Band + + <html><head/><body><p>Value</p></body></html> - - RADIANCE_MULT + + Select the type of conversion - - RADIANCE_ADD + + <html><head/><body><p>Select the type of conversion</p></body></html> - - REFLECTANCE_MULT + + Select the reference raster - - REFLECTANCE_ADD + + <html><head/><body><p>Select the reference raster</p></body></html> - - RADIANCE_MAXIMUM + + Postprocessing - - REFLECTANCE_MAXIMUM + + Accuracy - - K1_CONSTANT + + Select the classification to assess - - K2_CONSTANT + + <html><head/><body><p>Select the classification to assess</p></body></html> - - LMAX + + <html><head/><body><p>Select the field of the classification code </p></body></html> - - LMIN + + Classification report - - QCALMAX + + <html><head/><body><p>Select the classification raster</p></body></html> - - QCALMIN + + Select the classification - - Satellite + + Classification to vector - - Sun elevation + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - <html><head/><body><p>DATE ACQUIRED</p></body></html> + + Use code from Signature list - - Date (YYYY-MM-DD) + + <html><head/><body><p>Select the code field</p></body></html> - - Earth sun distance + + C_ID - - <html><head/><body><p>SUN ELEVATION</p></body></html> + + MC_ID - - <html><head/><body><p>Earth sun distance</p></body></html> + + Symbology - - Metadata + + Reclassification - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> + + <html><head/><body><p>Calculate unique values</p></body></html> - - Sentinel-2 + + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - Directory containing Sentinel-2 bands + + calculate C ID to MC ID values - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> + + Calculate unique values - - Sentinel-2 conversion + + Values - - Quantification value + + Old value - - Solar irradiance - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - ASTER - - - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - Select file ASTER L1T (.hdf) - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - UTM zone - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - UPPERLEFTM - - - - - Clip multiple rasters - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - - - Clip coordinates - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - - - Use temporary ROI for clipping - - - - - <html><head/><body><p>NoData value</p></body></html> - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - - - clip - - - - - Output name prefix - - - - - Split raster bands - - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - Select a multiband raster - - - - - split - - - - - PCA - - - - - Input - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - - - Number of components - - - - - <html><head/><body><p>Number of components</p></body></html> - - - - - Output - - - - - Vector to raster - - - - - Select the vector - - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - - - Use the value field of the vector - - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - - - Use constant value - - - - - <html><head/><body><p>Value</p></body></html> - - - - - Select the type of conversion - - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - Select the reference raster - - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - Postprocessing - - - - - Accuracy - - - - - Select the classification to assess - - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - Land cover change - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - - - Report unchanged pixels - - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - Select the new classification - - - - - Select the reference classification - - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - Classification report - - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - Select the classification - - - - - Classification to vector - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - - Use code from Signature list - - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - - C_ID - - - - - MC_ID - - - - - Symbology - - - - - Reclassification - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - - - - - calculate C ID to MC ID values - - - - - Calculate unique values - - - - - Values - - - - - Old value - - - - - New value - - - - - Edit raster - - - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - - - Select the input raster - - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - <html><head/><body><p>Use expression</p></body></html> - - - - - Use expression - - - - - <html><head/><body><p>Enter expression</p></body></html> - - - - - where(raster == 1, 2, raster) - - - - - Edit raster values - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - - - Edit values using a vector - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - - - Edit values using ROI polygons - - - - - Edit options - - - - - Classification sieve - - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - Size threshold - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - - - Pixel connection - - - - - <html><head/><body><p>Pixel connection</p></body></html> - - - - - 4 - - - - - 8 - - - - - Classification erosion - - - - - Size in pixels - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - - - Class values - - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - Classification dilation - - - - - Band calc - - - - - Band list - - - - - Expression - - - - - <html><head/><body><p>Not equals</p></body></html> - - - - - != - - - - - <html><head/><body><p>Equals</p></body></html> - - - - - == - - - - - <html><head/><body><p>Multiplication</p></body></html> - - - - - * - - - - - <html><head/><body><p>Power</p></body></html> - - - - - ^ - - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - <html><head/><body><p>Plus</p></body></html> - - - - - + - - - - - <html><head/><body><p>Division</p></body></html> - - - - - / - - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - - - ) - - - - - <html><head/><body><p>Square root</p></body></html> - - - - - √ - - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - - - ( - - - - - <html><head/><body><p>Greater than</p></body></html> - - - - - > - - - - - <html><head/><body><p>Less than</p></body></html> - - - - - < - - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - Decision rules - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - - - Value - - - - - Rule - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - - - <html><head/><body><p>Band list</p></body></html> - - - - - Variable - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - - - Same as - - - - - <html><head/><body><p>Select a raster</p></body></html> - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - - - Intersection - - - - - Extent: - - - - - Output raster - - - - - Band set - - - - - <html><head/><body><p>Add band to Band set</p></body></html> - - - - - Band set definition - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - - - <html><head/><body><p>Export band set to text file</p></body></html> - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - - - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - Create virtual raster of band set - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - - - Band calc expressions - - - - - Build band overviews - - - - - Band set tools - - - - - Batch - - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - Functions - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - - - Settings - - - - - Interface - - - - - Field names of training input - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - - - ROI style - - - - - <html><head/><body><p>Select temporary ROI color</p></body></html> - - - - - ROI color - - - - - Transparency - - - - - <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - - - - Variable name - - - - - <html><head/><body><p>Variable name for expressions</p></body></html> - - - - - raster - - - - - Variable name for expressions (tab Reclassification and Edit raster) - - - - - Group name - - - - - <html><head/><body><p>Group name</p></body></html> - - - - - Class_temp_group - - - - - Dock - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - - - Download news on startup - - - - - Processing - - - - - <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - - - - Play sound when finished - - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - - - Use virtual raster for temp files - - - - - <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - - - - Raster compression - - - - - <html><head/><body><p>Set available RAM for processes</p></body></html> - - - - - Available RAM (MB) - - - - - <html><head/><body><p>Reset to default temporary directory</p></body></html> - - - - - Temporary directory - - - - - Debug - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - - - Record events in a Log file - - - - - <html><head/><body><p>Export the Log file</p></body></html> - - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - - - - - Log file - - - - - <html><head/><body><p>Test dependencies</p></body></html> - - - - - Test dependencies - - - - - Test - - - - - About - - - - - Align - - - - - Results - - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - - - Cross classification - - - - - Ancillary data - - - - - MODIS - - - - - MODIS conversion - - - - - Select file MODIS (.hdf) - - - - - ID - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - - - Reproject to WGS 84 - - - - - Products - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - Stack raster bands - - - - - Select metadata file (MTD_MSI) - - - - - Product - - - - - Login data - - - - - Search - - - - - Search parameters - - - - - Product list - - - - - ProductID - - - - - Zone/Path - - - - - Collection/Size - - - - - Collection/ID - - - - - Collection/Image - - - - - Download products - - - - - Row/DayNight - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - - - X (Lon) - - - - - LR - - - - - UL - - - - - Y (Lat) - - - - - Date - - - - - Function - - - - - Message - - - - - Number of classes - - - - - <html><head/><body><p>Threshold</p></body></html> - - - - - <html><head/><body><p>Number of classes</p></body></html> - - - - - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - - - Max number of iterations - - - - - Distance algorithm - - - - - Minimum Distance - - - - - Spectral Angle Mapping - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - - - Use vector for clipping - - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - - - Use Signature list as seed signatures - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - - - Save resulting signatures to Signature list - - - - - Clustering - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - - - Use random seed signatures - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - - - Seed signatures from band values - - - - - Seed signatures - - - - - <html><head/><body><p>Minimum class size in pixels</p></body></html> - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> - - - - - ISODATA - - - - - Distance threshold - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> - - - - - ISODATA max standard deviation - - - - - <html><head/><body><p>If checked, use K-means</p></body></html> - - - - - ISODATA minimum class size in pixels - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - - - Method - - - - - 6 - - - - - 1 - - - - - 3 - - - - - 2 - - - - - 11 - - - - - 5 - - - - - 7 - - - - - 8A - - - - - 9 - - - - - 10 - - - - - 12 - - - - - 16 - - - - - Sentinel-3 bands - - - - - 20 - - - - - 17 - - - - - 14 - - - - - 13 - - - - - 19 - - - - - 15 - - - - - 21 - - - - - 18 - - - - - SMTP server - - - - - password - - - - - <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - - - - Send email of completed process to - - - - - SMTP process notification - - - - - user - - - - - <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - - - - RUN - - - - - <html><head/><body><p>Add a new band set</p></body></html> - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - - - Add bands in a new Band set - - - - - Mosaic band sets - - - - - 1, 2 - - - - - mosaic - - - - - Select input band set - - - - - Band combination - - - - - <html><head/><body><p>Band set number</p></body></html> - - - - - Select the reference vector or raster - - - - - Vector field - - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - - - Use vector field for output name - - - - - Stack band set - - - - - Spectral distance of band sets - - - - - Select first input band set - - - - - Select second input band set - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - - - Spectral distance - - - - - Band processing - - - - - Class signature - - - - - Basic tools - - - - - Cloud masking - - - - - mask - - - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - - - Mask class values - - - - - &K-means - - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - - - Select MTL file - - - - - Use buffer of pixel size - - - - - Create random points - - - - - Signature threshold - - - - - Automatic thresholds - - - - - LC Signature threshold - - - - - Convert vector to raster - - - - - Clip band set - - - - - Split raster bands - - - - - Mosaic of band sets - - - - - Band set list - - - - - Mask of band set - - - - - Combination of band values - - - - - Principal Components Analysis of band set - - - - - Clustering of band set - - - - - Accuracy assessment - - - - - Land cover change - - - - - Classification report - - - - - Cross classification - - - - - Class signature - - - - - Classification to vector - - - - - Reclassification - - - - - Edit raster - - - - - Classification sieve - - - - - Classification erosion - - - - - Classification dilation - - - - - Multiband image list - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - <html><head/><body><p>Select all / Unselect all</p></body></html> - - - - - Single band list - - - - - Select input band set (of classifications) - - - - - Signature threshold - - - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - - - Sentinel-3 - - - - - Sentinel-3 conversion - - - - - Directory containing Sentinel-3 bands - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - 6 (Landsat 1-8) - - - - - 4 (Landsat 1-8) - - - - - 1 (Landsat 4-8) - - - - - 3 (Landsat 4-8) - - - - - 2 (Landsat 4-8) - - - - - 11 (Landsat 8) - - - - - 5 (Landsat 1-8) - - - - - Landsat bands - - - - - 8 (Landsat 7, 8) - - - - - 10 (Landsat 8) - - - - - 9 (Landsat 8) - - - - - 7 (Landsat 1-8) - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - - - stratified for the values - - - - - of first band of band set - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - - - raster > 0 - - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - - - <html><head/><body><p>Service</p></body></html> - - - - - <html><head/><body><p>Filter</p></body></html> - - - - - Advanced search - - - - - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - - - - Bands - - - - - Number - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - - - System - - - - - CPU threads - - - - - <html><head/><body><p>Select a type</p></body></html> - - - - - Float32 - - - - - Int16 - - - - - Byte - - - - - Preprocess bands 1, 9, 10 - - - - - Create raster of band set -(stack bands) - - - - - Input NoData - as value - - - - - Sentinel-1 - - - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - Sentinel-1 file - - - - - Select SNAP xml graph (optional) - - - - - Polarization - - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - - - VH - - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - - - VV - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - - - convert to dB - - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - - - Raster projection as Band set - - - - - External programs - - - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - - - Zonal stat rasters - - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - Select a statistic - - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - Statistic - - - - - BATCH - - - - - Project - - - - - <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - - - - Create RGB composite of band set when a project is loaded - - - - - Zonal stat raster - - - - - User manual - - - - - Support the SCP - - - - - Use - - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - - - W - - - - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - - Maximum Likelihood - - - - - Algorithm - - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - - - Threshold - - - - - Classification - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - - - LCS - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - - - only overlap - - - - - Land Cover Signature Classification - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - - - Algorithm - - - - - Classification output - - - - - Load qml style - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - - - Apply mask - - - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - - - Create vector - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> - - - - - Save algorithm files - - - - - Processing setting - - - - - Help - - - - - Tool - - - - - Random forest - - - - - Random Forest classification (ESA SNAP software required) - - - - - <html><head/><body><p>Number of training samples</p></body></html> - - - - - Number of trees - - - - - Number of training samples - - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - - - Evaluate classifier - - - - - Evaluate feature power set - - - - - Save classifier - - - - - Load classifier - - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> - - - - - <html><head/><body><p>Classifier file path</p></body></html> - - - - - Reproject raster bands - - - - - Reproject raster bands - - - - - Use EPSG code - - - - - reproj - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - - - Align to raster - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - - - same extent as reference - - - - - Y resolution - - - - - X resolution - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - - - Int32 - - - - - UInt32 - - - - - UInt16 - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> - - - - - <html><head/><body><p>Scale</p></body></html> - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> - - - - - Output -NoData value - - - - - Set -scale - - - - - Set -offset - - - - - Calculation process - - - - - Resampling method - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - nearest_neighbour - - - - - first_quartile - - - - - third_quartile - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - - - Resample pixel factor - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - - Output type - - - - - Auto - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - - - Change output NoData value - - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - - - - Dissolve output - - - - - Wavelength -unit - - - - - Wavelength -quick settings - - - - - Use value as NoData - - - - - Use value -as NoData - - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - - - <html><head/><body><p>Check batch function</p></body></html> - - - - - <html><head/><body><p>Set incremental new values</p></body></html> - - - - - Incremental new values - - - - - CHECK - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - - - Earth sun -distance - - - - - Date - (YYYYMMDD) - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - LOWERRIGHTM - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - Output NoData value - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - - - C Name field - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - - - MC Name field - - - - - GOES bands - - - - - GOES conversion - - - - - Directory containing GOES bands - - - - - MC Name - - - - - C Name - - - - - GOES - - - - - <html><head/><body><p>Set the number of CPU threads </p></body></html> - - - - - <html><head/><body><p>Number of trees</p></body></html> - - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> + + New value - - <html><head/><body><p>Minumum power</p></body></html> + + <html><head/><body><p>Select the classification</p></body></html> - - <html><head/><body><p>Maximum power</p></body></html> + + Size threshold - - <html><head/><body><p>If checked, save classifier</p></body></html> + + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Import vector + + Pixel connection - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> + + <html><head/><body><p>Pixel connection</p></body></html> - - <html><head/><body><p>C ID field</p></body></html> + + 4 - - <html><head/><body><p>MC ID field</p></body></html> + + 8 - - <html><head/><body><p>MC Name field</p></body></html> + + Size in pixels - - <html><head/><body><p>C Name field</p></body></html> + + <html><head/><body><p>Size in pixels</p></body></html> - - Vector fields + + Class values - - Import vector + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - <html><head/><body><p>Import vector</p></body></html> + + Band calc - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> + + Band list - - Python executable path + + <html><head/><body><p>Band list</p></body></html> - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> + + Variable - - <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - GDAL installation directory + + <html><head/><body><p>Select a raster</p></body></html> - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> + + Extent: - - Same extent as reference raster + + Output raster - - <html><head/><body><p>Import reclassification table from text file</p></body></html> + + Band set - - <html><head/><body><p>Export reclassification table to text file</p></body></html> + + Band set definition - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> + + <html><head/><body><p>Move highlighted band down</p></body></html> - - Use alternative search for Sentinel-2 (no authentication required) + + <html><head/><body><p>Move highlighted band up</p></body></html> - - Matrix file (optional) + + <html><head/><body><p>Export band set to text file</p></body></html> - - neighbor + + <html><head/><body><p>Import band set from text file</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - Neighbor pixels + + <html><head/><body><p>Wavelength unit</p></body></html> - - Neighbor distance in pixels + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - <html><head/><body><p>Distance in pixels</p></body></html> + + Band calc expressions - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> + + Build band overviews - - Enable writing verification + + Band set tools - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + Functions - - Create virtual raster output + + Settings - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> + + Interface - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - Circular + + ROI style - - Calculation -data type + + <html><head/><body><p>Select temporary ROI color</p></body></html> - - Python modules path + + ROI color - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> + + Transparency - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> -<hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> + + <html><head/><body><p>Change temporary ROI transparency</p></body></html> - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + Variable name - - Virtual download + + <html><head/><body><p>Variable name for expressions</p></body></html> - - <html><head/><body><p>Sort band sets by date</p></body></html> + + raster - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + + Group name - - NoData mask + + <html><head/><body><p>Group name</p></body></html> - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + Class_temp_group - - Calculate linear regression + + Dock - - - SpectralSignaturePlot - - SCP: Spectral Signature Plot + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - S + + Download news on startup - - MC ID + + Processing - - C ID + + <html><head/><body><p>Enable/Disable the sound when the process is finished</p></body></html> - - Color + + Play sound when finished - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> + + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> + + Raster compression - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> + + <html><head/><body><p>Set available RAM for processes</p></body></html> - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> + + Available RAM (MB) - - Automatic thresholds + + <html><head/><body><p>Reset to default temporary directory</p></body></html> - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> + + Temporary directory - - Min Max - - - - - σ * + + Debug - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> + + <html><head/><body><p>Export the Log file</p></body></html> - - <html><head/><body><p>Undo thresholds</p></body></html> + + Log file - - Import library + + <html><head/><body><p>Test dependencies</p></body></html> - - <html><head/><body><p >Delete row</p></body></html> + + Test dependencies - - Plot + + Test - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + About - - <html><head/><body><p>Calculate spectral distances</p></body></html> + + Align - - Signature list + + Results - - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + + <html><head/><body><p>Maximum number of results (images)</p></body></html> - - Band lines + + Cross classification - - Max characters + + Ancillary data - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> + + Products - - x=0.000000 y=0.000000 + + <html><head/><body><p>Select a product</p></body></html> - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + Stack raster bands - - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + + Login data - - <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> + + Search - - Plot value range + + Search parameters - - Grid + + Product list - - Signature details + + Download products - - Spectral distances + + <html><head/><body><p>Export table to text file</p></body></html> - - From -pixel + + <html><head/><body><p>Import table from text file</p></body></html> - - From -ROI + + X (Lon) - - MC Name + + LR - - C Name + + UL - - - semiautomaticclassificationplugin - - Select a mask shapefile + + Y (Lat) - - Save classification output + + Date - - Select a qml style + + Minimum Distance - - Select a signature list file + + Spectral Angle Mapping - - Select a SCP training input + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - Export SCP training input + + Use vector for clipping - - Select a library file + + <html><head/><body><p>Select the vector for clipping</p></body></html> - - Export the highlighted signatures to CSV library + + 6 - - Calculate signatures + + 1 - - Calculate signatures for highlighted items? + + 3 - - Merge signatures + + 2 - - Merge highlighted signatures? + + 11 - - Delete signatures + + 5 - - Are you sure you want to delete highlighted ROIs and signatures? + + 7 - - Create SCP training input + + 8A - - It appears that the shapefile + + 9 - - is missing some fields that are required for the signature calculation. -Do you want to add the required fields to this shapefile? + + 10 - - Undo save ROI + + 12 - - Semi-Automatic Classification Plugin + + 20 - - Zoom to input image extent + + SMTP server - - Show/hide the input image + + password - - Select a RGB color composite + + <html><head/><body><p>Enable/Disable the sending of email of completed process</p></body></html> - - Local cumulative cut stretch of band set + + Send email of completed process to - - Local standard deviation stretch of band set + + SMTP process notification - - Zoom to temporary ROI + + user - - Show/hide the temporary ROI + + <html><head/><body><p>A list of addresses (separated by comma , ) to send this mail to </p></body></html> - - Create a ROI polygon + + RUN - - Activate ROI pointer + + <html><head/><body><p>Add a new band set</p></body></html> - - Redo the ROI at the same point + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - Dist + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - Similarity of pixels (distance in radiometry unit) + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - Min + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - Minimum area of ROI (in pixel unit) + + Mosaic band sets - - Max + + 1, 2 - - Side of a square which inscribes the ROI, defining the maximum width thereof (in pixel unit) + + Select input band set - - Zoom to the classification preview + + <html><head/><body><p>Band set number</p></body></html> - - Show/hide the classification preview + + Select the reference vector or raster - - Activate classification preview pointer + + Vector field - - Redo the classification preview at the same point + + <html><head/><body><p>Select the reference vector or raster</p></body></html> - - T + + <html><head/><body><p>Select the vector field</p></body></html> - - Set preview transparency + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - S + + Use vector field for output name - - Set the preview size (in pixel unit) + + Stack band set - - Remove temporary files + + Band processing - - Band set + + Basic tools - - Preprocessing + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - Postprocessing + + Mask class values - - Band calc + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - Spectral plot + + Use buffer of pixel size - - Scatter plot + + Create random points - - Batch + + Signature threshold - - Settings + + Automatic thresholds - - User manual + + Convert vector to raster - - Online help + + Clip band set - - SCP + + Split raster bands - - Test results + + Mosaic of band sets - - Information + + Band set list - - No log file found + + Mask of band set - - Select a SCP training input; input is not loaded + + Combination of band values - - Select a raster; raster is not loaded + + Principal Components Analysis of band set - - Select a point inside the image area + + Accuracy assessment - - Data projections do not match. Reproject data to the same projection + + Classification report - - Maximum Likelihood threshold must be less than 100 + + Cross classification - - Spectral Angle Mapping threshold must be less than 90 + + Classification to vector - - Select a directory + + Reclassification - - At least 3 points are required + + Select input band set (of classifications) - - Negative IDs are not allowed + + Signature threshold - - Select at least one signature + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - SCP is recording the Log file + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - Signature list file (.slf) created + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - No image found. Try with a larger area + + stratified for the values - - Create a ROI polygon or use a vector + + of first band of band set - - Define a search area + + raster > 0 - - Error + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - No metadata found inside the input directory (a .txt file whose name contains MTL) + + <html><head/><body><p>Create stratified random points</p></body></html> - - Raster not found + + <html><head/><body><p>Filter</p></body></html> - - Error saving signatures + + Advanced search - - Error opening signatures + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> - - Error opening spectral library + + System - - Error saving spectral library + + CPU threads - - Import failed + + <html><head/><body><p>Select a type</p></body></html> - - ROI creation failed + + Float32 - - Internet connection failed + + Int16 - - Error reading raster. Possibly the raster path contains unicode characters + + Byte - - Error calculating signature. Possibly ROI is too small + + Create raster of band set +(stack bands) - - Unable to split bands + + Input NoData + as value - - Error reading band set. Possibly raster files are not loaded + + External programs - - Clip area outside image. Check the raster projection + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - Unable to merge. Signatures have different unit or wavelength + + <html><head/><body><p>Select a statistic</p></body></html> - - Unable to calculate. Expression error + + Select a statistic - - Unable to calculate. Metadata error + + <html><head/><body><p>Enter a value</p></body></html> - - Unable to find images + + Statistic - - Unable to connect + + Project - - Unable to load image + + <html><head/><body><p>If checked, an RGB composite of the active band set is created when a previous project is loaded</p></body></html> - - Attribute table error + + Create RGB composite of band set when a project is loaded - - Unable to pansharpen: missing bands + + User manual - - Unable to calculate + + Use - - Error reading raster. Possibly bands are not aligned + + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - Unable to get raster projection. Try to reproject the raster + + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - Memory error. Please, decrease decimal precision + + W - - Error calculating plot + + Maximum Likelihood - - SSL connection error. Please see the FAQ of the plugin user manual for solving this + + Algorithm - - Warning + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - It appears that SciPy is not correctly installed. Please, update QGIS + + <html><head/><body><p>Open tab Signature threshold</p></body></html> - - Wavelength already present + + Classification - - Wavelength unit not provided in band set + + Processing setting - - RAM value was too high. Value has been decreased automatically + + Help - - Unable to load the virtual raster. Please create it manually + + Tool - - Unable to proceed. The raster must be in projected coordinates + + Load classifier - - Incorrect expression + + Reproject raster bands - - Unable to access the temporary directory + + Use EPSG code - - Reduce the search area extent within 10 degrees of latitude and 10 degrees of longitude + + reproj - - Macroclass symbology is missing + + <html><head/><body><p>EPSG value</p></body></html> - - Missing bands + + <html><head/><body><p>X resolution</p></body></html> - - No metadata found inside the input directory. Default values will be used + + <html><head/><body><p>Y resolution</p></body></html> - - Select a shapefile + + <html><head/><body><p>Align to raster</p></body></html> - - Set thresholds + + Align to raster - - Are you sure you want to set thresholds for several signatures? + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - Save error matrix raster output + + same extent as reference - - Classification + + Y resolution - - ErrMatrixCode + + X resolution - - Reference + + <html><head/><body><p>NoData value of the output raster</p></body></html> - - PixelSum + + Int32 - - Total + + UInt32 - - Overall accuracy [%] = + + UInt16 - - Kappa hat classification = + + <html><head/><body><p>If checked, set a scale</p></body></html> - - Reset weights + + <html><head/><body><p>Scale</p></body></html> - - Are you sure you want to reset weights? + + <html><head/><body><p>If checked, set an offset</p></body></html> - - Select a HDF file + + Output +NoData value - - Clear rules + + Set +scale - - Are you sure you want to clear the rules? + + Set +offset - - Select a text file of rules + + Calculation process - - Save the rules to file + + Resampling method - - Save raster output + + average - - Select a raster + + sum - - Clear band set + + maximum - - Are you sure you want to clear the band set? + + minimum - - Save the band set to file + + mode - - Select a band set file + + median - - Remove band + + nearest_neighbour - - Are you sure you want to remove the selected bands from band set? + + first_quartile - - Save virtual raster + + third_quartile - - Save raster + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - Build overviews + + Resample pixel factor - - Do you want to build the external overviews of bands? + + <html><head/><body><p>Resample factor</p></body></html> - - Select a batch file + + <html><head/><body><p>Select the resampling method</p></body></html> - - Save the batch to file + + Output type - - Save classification report + + Auto - - Unknown + + <html><head/><body><p>If checked, change output NoData value</p></body></html> - - Class + + Change output NoData value - - Percentage % + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> - - Select a directory where to save clipped rasters + + Dissolve output - - Save output + + Use value as NoData - - Searching ... + + Use value +as NoData - - Download the images in the table (requires internet connection) + + <html><head/><body><p>Set incremental new values</p></body></html> - - Export download links + + Incremental new values - - Reset signature list + + Output NoData value - - Are you sure you want to clear the table? + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - Save land cover change raster output + + C Name field - - ReferenceClass + + MC Name field - - NewClass + + MC Name - - Select a MTL file + + C Name - - Save the point list to file + + <html><head/><body><p>Set the number of CPU threads </p></body></html> - - Principal Components Analysis + + Import vector - - Covariance matrix + + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - Bands + + <html><head/><body><p>C ID field</p></body></html> - - Correlation matrix + + <html><head/><body><p>MC ID field</p></body></html> - - Eigen vectors + + <html><head/><body><p>MC Name field</p></body></html> - - Vector_ + + <html><head/><body><p>C Name field</p></body></html> - - Eigen values + + Vector fields - - Accounted variance + + Import vector - - Cumulative variance + + <html><head/><body><p>Import vector</p></body></html> - - Reset RGB list + + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - Are you sure you want to clear the RGB list? + + <html><head/><body><p>Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)</p></body></html> - - RGB list + + GDAL installation directory - - Calculate all the RGB combinations? + + <html><head/><body><p>Import reclassification table from text file</p></body></html> - - Save the RGB list to file + + <html><head/><body><p>Export reclassification table to text file</p></body></html> - - Select a XML file + + Matrix file (optional) - - Transparency + + Neighbor pixels - - Save Log file + + Neighbor distance in pixels - - Reset field names + + <html><head/><body><p>Distance in pixels</p></body></html> - - Are you sure you want to reset field names? + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - Reset variable name + + Create virtual raster output - - Are you sure you want to reset variable name? + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> - - Reset group name + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - Are you sure you want to reset group name? + + Circular - - Change temporary directory + + Calculation +data type - - Are you sure you want to change the temporary directory? + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - Reset temporary directory + + Virtual download - - Are you sure you want to reset the temporary directory? + + <html><head/><body><p>Sort band sets by date</p></body></html> - - Reset thresholds + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - Are you sure you want to reset thresholds? + + Calculate linear regression - - Delete scatter plot + + Create virtual raster +of band set - - Are you sure you want to delete highlighted scatter plots? + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> - - Save plot to file + + Wavelength unit - - Edit value range + + Wavelength - - Are you sure you want to edit the value range for several signatures? + + Band quick settings - - Add to Signature list + + Band set table - - Are you sure you want to add highlighted signatures to the list? + + Active band set - - Are you sure you want to delete highlighted signatures? + + Root directory - - Values + + Script - - Undo thresholds + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> - - Are you sure you want to undo thresholds? + + Copy - - Multiple ROI creation + + Band dilation - - Import signatures + + Output name - - Export signatures + + dilation_ - - Algorithm band weight + + Virtual output - - Signature threshold + + <html><head/><body><p>Enter output name</p></body></html> - - LCS threshold + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - Landsat + + erosion_ - - Sentinel-2 + + Band erosion - - ASTER + + Band sieve - - Clip multiple rasters + + sieve_ - - Split raster bands + + Script (copy the code in a Python shell) - - PCA + + Script - - Vector to raster + + <html><head/><body><p>Enter an expression</p></body></html> - - Accuracy + + Expression - - Land cover change + + NoData +mask - - Classification report + + UL X - - Classification to vector + + UL Y - - Reclassification + + LR X - - Edit raster + + LR Y - - Classification sieve + + Output +data type - - Classification erosion + + False - - Classification dilation + + True - - About + + None - - Interface + + <html><head/><body><p>Upperleft X</p></body></html> - - Debug + + <html><head/><body><p>Upper-left Y</p></body></html> - - The coordinate system of training input is different from the input image. Please create a new training input + + <html><head/><body><p>Lower-right X</p></body></html> - - Directory error. Check write permission + + <html><head/><body><p>Lower-right Y</p></body></html> - - Value 0 + + Masking bands - - Set value 0 + + Combination - - Value 1 + + Dilation - - Set value 1 + + Erosion - - Value 2 + + Sieve - - Set value 2 + + Neighbor - - Undo edit (only for ROI polygons) + + Band neighbor - - Error accessing training input + + pixel_center - - Rasters appear to be in different projections. Reproject rasters to the same CRS + + all_touched - - Search error HTTP Status 500, reduce the result number + + area_based - - Save cross classification raster output + + Area precision - - CrossClassCode + + Pixel size - - CROSS MATRIX [ + + <html><head/><body><p>If checked, align to reference raster</p></body></html> - - Cross classification + + Minimum extent - - Show plugin + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> - - MODIS + + <html><head/><body><p>Output pixel size</p></body></html> - - Stack raster bands + + Reproject and resample band set - - Please, restart QGIS for executing the Semi-Automatic Classification Plugin + + <html><head/><body><p>Use EPSG code</p></body></html> - - Add required fields + + <html><head/><body><p>If checked, compress raster output</p></body></html> - - Downloading ... + + Compress - - Download products + + <html><head/><body><p>Compression method</p></body></html> - - Select a text file of product table + + LZW - - Export table to file + + <html><head/><body><p>Output prefix</p></body></html> - - Check OK + + mosaic_ - - Calculating. Please wait ... + + <html><head/><body><p>Output name</p></body></html> - - Vector or raster not found + + band_ - - Error saving raster + + Output prefix - - The version of Numpy is outdated + + Clip raster bands - - Unable to perform operation. Possibly OGR is missing drivers. Please repeat QGIS installation + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> - - Memory error. Please, set a lower value of RAM in the tab Settings + + Use coordinates for clipping - - Edge error. Reduce the ROI width or draw a ROI manually + + mask_ - - It appears that SciPy is not correctly installed. Please, check the user manual + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> - - Signature + + product - - C_ID_ + + image - - Calculating classification. Please wait ... + + product_id - - Clustering + + acquisition_date - - Sentinel-3 + + cloud_cover - - SCP: completed process + + zone_path - - Save clustering output + + row - - Band name + + collection - - Center wavelength + + size - - Multiplicative Factor + + uid - - Additive Factor + + preview - - At least one band set is required + + <html><head/><body><p>Landsat / Sentinel</p></body></html> - - Remove band set + + <html><head/><body><p>Sentinel</p></body></html> - - Wavelength unit + + Bands - - Image name + + Image conversion - - Band number + + Directory containing bands - - Weight + + Conversion to reflectance and temperature - - Select at least one raster band + + Select metadata file (optional) - - Please define band sets with matching number of bands + + spacecraft - - Mosaic band sets + + processing_level - - Unable to remove bands from a multiband image + + band_name - - Please add single band rasters to the band set + + product_path - - RasterValue + + scale - - Band combination + + offset - - Spectral distance + + nodata - - Band processing + + date - - Save signature output + + k1 - - Distance + + k2 - - Class signature + + band_number - - Basic tools + + e_sun - - Cloud masking + + earth_sun_distance - - missing parameter + + Create a new Band set - - Memory error, too many combinations. Try to reclassify the values + + Input - - Please restart QGIS for installing the Semi-Automatic Classification Plugin + + Multi-Layer Perceptron - - Create KML + + scikit-learn - - Wi + + PyTorch - - SE area + + Random Forest - - Error, please change stratification parameters + + Support Vector Machine - - Classified + + Save classifier - - ERROR MATRIX (pixel count) + + Macroclass ID - - Area + + Class ID - - SE + + Single threshold - - 95% CI area + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> - - PA [%] + + Save signature raster - - UA [%] + + Linear scaling - - Kappa hat + + <html><head/><body><p>If checked, perform cross validation</p></body></html> - - PA = producer's accuracy + + Cross validation - - UA = user's accuracy + + Use input normalization - - SE = standard error + + <html><head/><body><p>Linear scaling normalization</p></body></html> - - CI = confidence interval + + <html><head/><body><p>Z-score normalizatin</p></body></html> - - AREA BASED ERROR MATRIX + + Z-score - - Save the Band set list to file + + <html><head/><body><p>If checked, use input normalization</p></body></html> - - Band set list + + Use training - - removing + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> - - exporting + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> - - importing + + <html><head/><body><p>Number of steps</p></body></html> - - Please lower the RAM value or thread number in Settings + + Find best estimator with steps - - Select a Sentinel-1 file + + Use framework - - Please set the path to ESA SNAP GPT executable in Settings + + <html><head/><body><p>Use scikit-learn framework</p></body></html> - - Sentinel-1 + + <html><head/><body><p>Use PyTorch framework</p></body></html> - - Save zonal stat raster output + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> - - Zonal stat raster + + Max features - - Error, select a stastistic + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> - - Error calculating accuracy. Possibly vector polygons are outside classification + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> - - Error, extent of vector too large or attribute table error + + Balanced class weight - - Memory error. Please, decrease decimal precision of plot + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - - Processing setting + + Number of trees - - Save classification + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> - - Select a classifier + + Minimum number to split - - Random forest + + <html><head/><body><p>Sets the kernel</p></body></html> - - Save band combination raster output + + rbf - - Cancel + + <html><head/><body><p>Regularization parameter C</p></body></html> - - Please select at least one tool. Band set definition does not require Run + + Regularization parameter C - - Signature bands do not match band set. Calculate the spectral signature again + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> - - Select a directory where to save projected rasters + + Kernel - - Reproject raster bands + + Gamma - - Projection error + + Activation - - Sum method is available only with GDAL version >= 3.1 . Please update GDAL + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> - - Save vector output + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> - - Conversion to vector. Please wait ... + + auto - - Creating ROI + + Training proportion - - ROI creation failed. Possible reason: one or more band of the band set are missing or pixel is NoData + + Batch size - - Signature calculation failed. Possible reason: the raster is not loaded + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> - - Import failed. Possible reason: selected file is not a band set + + Max iter - - Classification failed. It appears the one or more bands of the band set are missing + + <html><head/><body><p>Sets the activation function</p></body></html> - - ROI creation failed. Possible reason: input is a virtual raster or band is not loaded + + relu - - The process could still be running in the background. Please terminate it manually + + <html><head/><body><p>Sets initial learning rate</p></body></html> - - Calculating signature + + Alpha - - Writing file + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> - - Conversion to vector + + Hidden layer sizes - - Sieve + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> - - Building overviews + + 100 - - Reprojecting + + Learning rate init - - Random forest classification + + Calculate classification confidence raster - - Date + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> - - Error line + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - Remove training input + + <html><head/><body><p>Set automatic threshold σ</p></body></html> - - Are you sure you want to remove training input? + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - Downloading + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - Remove rows + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Are you sure you want to remove highlighted rows from the table? + + Record detailed events in a Log file - - Processing + + <html><head/><body><p>Use NoData mask</p></body></html> - - Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin + + Offset - - Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Select an extent</p></body></html> - - Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - - DOS1 calculation + + <html><head/><body><p>Move highlighted band sets down</p></body></html> - - Unique values + + <html><head/><body><p>Remove selected band sets</p></body></html> - - Conversion + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> - - Pansharpening + + RGB composite - - Please define a date range within the same year + + Pixel +size - - Checking ... + + <html><head/><body><p>Pixel size</p></body></html> - - GOES + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> - - Calculation + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - Save distance raster output + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> - - LAND COVER CHANGE MATRIX [ + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<hr /> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> - - Support the SCP + + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> - - Help + + neighbor_ - - Calculate raster values iteration + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - Classification iteration + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> - - Classification iteration + + One-Vs-Rest - - Dilation + + <html><head/><body><p>Number of trees</p></body></html> - - Mask + + Variable name for expressions - - Statistics + + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - Raster statistics + + <html><head/><body><p>Function to Script</p></body></html> - - Test + + <html><head/><body><p>Save classifier to file</p></body></html> - - MC ID + + <html><head/><body><p>Save Script to file</p></body></html> - - C ID + + Save to file - - Name + + sun_elevation + + + SpectralSignaturePlot - - Type + + SCP: Spectral Signature Plot - - Color + + S - - SCPID + + MC ID - - Zoom to highlighted items + + C ID - - Clear selection + + Color - - Collapse/expand all + + <html><head/><body><p >Delete row</p></body></html> - - Merge highlighted items + + Plot - - Calculate signatures for highlighted items + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - Delete highlighted items + + Signature list - - Change MC ID for highlighted items + + <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> - - Add highlighted items to spectral plot + + Band lines - - Add highlighted items to scatter plot + + Max characters - - Change Macroclass ID + + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - Change the Macroclass ID for highlighted items to + + x=0.000000 y=0.000000 - - Properties + + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Zoom to + + <html><head/><body><p>Save the plot to file (jpg, png, pdf)</p></body></html> - - Check/uncheck + + Plot value range - - Check/uncheck highlighted items + + Grid - - Clear selection of highlighted items + + Signature details - - Collapse/expand all macroclasses + + Spectral distances - - Change MC ID + + MC Name - - Change color + + C Name - - Change color for highlighted items + + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> - - Merge items + + <html><head/><body><p>Plot the axis grid</p></body></html> - - Delete items + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + semiautomaticclassificationplugin - - Add to spectral plot + + Delete signatures - - Add to scatter plot + + Delete scatter plot - - Properties for highlighted items + + Are you sure you want to delete highlighted scatter plots? - - Import + + Save plot to file - - Import spectral signatures + + Add to Signature list - - Export + + Are you sure you want to add highlighted signatures to the list? - - Export highlighted items + + Are you sure you want to delete highlighted signatures? - - Select a reclassification file + + Values - - Save the reclassification list to file + + Please, restart QGIS for executing the Semi-Automatic Classification Plugin - - Reclassify + + Please restart QGIS for installing the Semi-Automatic Classification Plugin - - Signatures exported + + Error. Please, install the required Python library remotior_sensus - - Signatures imported + + Transparency - - Are you sure you want to undo? + + Wavelength - - Redo save ROI + + Band - - Are you sure you want to redo? + + Standard deviation - - Neighbor pixels + + Euclidean distance - - Region growing + + Bray-Curtis similarity [%] - - Unable to connect, possibly archived image + + Spectral angle - - Erosion step + + Pixel count - - Unique values + + Error. Python library not found - - Band combination + + Error starting Remotior Sensus diff --git a/dock/__init__.py b/interface/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from dock/__init__.py rename to interface/__init__.py diff --git a/interface/accuracy_tab.py b/interface/accuracy_tab.py new file mode 100755 index 0000000..0882b26 --- /dev/null +++ b/interface/accuracy_tab.py @@ -0,0 +1,150 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Accuracy. + +This tool allows for the calculation of classification accuracy. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# reference layer name +def reference_layer_name(): + reference_layer = cfg.dialog.ui.reference_name_combo.currentText() + cfg.dialog.ui.class_field_comboBox.clear() + layer = cfg.util_qgis.select_layer_by_name(reference_layer) + try: + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + fields = layer.dataProvider().fields() + for field in fields: + if str(field.typeName()).lower() != 'string': + cfg.dialog.class_field_combo(str(field.name())) + except Exception as err: + str(err) + + +# refresh reference layer name +def refresh_reference_layer(): + # noinspection PyArgumentList + ls = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.reference_name_combo.clear() + for layer in sorted(ls, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + if (layer.wkbType() == cfg.util_qgis.get_qgis_wkb_types().Polygon + or layer.wkbType() == + cfg.util_qgis.get_qgis_wkb_types().MultiPolygon): + cfg.dialog.reference_layer_combo(layer.name()) + elif layer.type() == cfg.util_qgis.get_qgis_map_raster(): + if layer.bandCount() == 1: + cfg.dialog.reference_layer_combo(layer.name()) + + +# calculate error matrix if click on button +def calculate_error_matrix(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save error matrix raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + cfg.logger.log.info('calculate_error_matrix: %s' % output_path) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + reference_layer = cfg.dialog.ui.reference_name_combo.currentText() + classification_layer = ( + cfg.dialog.ui.classification_name_combo.currentText()) + reference = cfg.util_qgis.get_file_path(reference_layer) + classification = cfg.util_qgis.get_file_path(classification_layer) + field = cfg.dialog.ui.class_field_comboBox.currentText() + if len(field) == 0: + field = None + if cfg.dialog.ui.nodata_checkBox_11.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_15.value() + else: + nodata = None + cfg.ui_utils.add_progress_bar() + output = cfg.rs.cross_classification( + classification_path=classification, reference_path=reference, + output_path=output_path, + vector_field=field, nodata_value=nodata, error_matrix=True + ) + if output.check: + output_raster, output_table = output.paths + # add raster to layers + raster = cfg.util_qgis.add_raster_layer(output_raster) + unique_values = output.extra['unique_values'] + cfg.utils.raster_symbol_generic( + raster, 'NoData', raster_unique_value_list=unique_values + ) + if cfg.utils.check_file(output_table): + with open(output_table, 'r') as f: + text = f.read() + cfg.dialog.ui.error_matrix_textBrowser.setText( + text.replace(',', '\t') + ) + cfg.dialog.ui.toolBox_accuracy.setCurrentIndex(1) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + reference_layer = cfg.dialog.ui.reference_name_combo.currentText() + classification_layer = ( + cfg.dialog.ui.classification_name_combo.currentText()) + reference = cfg.util_qgis.get_file_path(reference_layer) + classification = cfg.util_qgis.get_file_path(classification_layer) + field = cfg.dialog.ui.class_field_comboBox.currentText() + if len(field) == 0: + field = None + # No data value + if cfg.dialog.ui.nodata_checkBox_11.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_15.value() + else: + nodata = None + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ( + '# accuracy \n' + 'rs.cross_classification(classification_path="%s", ' + 'reference_path="%s", output_path="%s", vector_field="%s", ' + 'nodata_value=%s, error_matrix=True)' + % (str(classification), str(reference), str(output_path), + str(field), str(nodata))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_calc_tab.py b/interface/band_calc_tab.py new file mode 100755 index 0000000..e564ae1 --- /dev/null +++ b/interface/band_calc_tab.py @@ -0,0 +1,489 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band calc. + +This tool allows for calculations between raster bands. +""" + +try: + from remotior_sensus.tools import band_calc as rs_calc +except Exception as error: + str(error) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# fill raster band table +# noinspection PyProtectedMember,PyArgumentList +def raster_band_table(bandset_number=None): + if bandset_number is None or bandset_number is False: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + # get QGIS rasters + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + input_name_list = [] + input_raster_list = [] + for x in sorted(layers, key=lambda layer_x: layer_x.name()): + if (x.type() == cfg.util_qgis.get_qgis_map_raster() + and x.bandCount() == 1): + input_name_list.append(x.name()) + input_raster_list.append(x.source()) + # create list of band names from band sets + cfg.calc_raster_variables = rs_calc._band_names_alias( + input_raster_list=input_raster_list, input_name_list=input_name_list, + bandset_catalog=cfg.bandset_catalog, + bandset_number=bandset_number + ) + table = cfg.dialog.ui.tableWidget_band_calc + table.setSortingEnabled(False) + cfg.util_qt.clear_table(table) + # row counter + b = 0 + # Add band to table + for raster in cfg.calc_raster_variables: + table.insertRow(b) + cfg.util_qt.add_table_item(table, raster[1:-1], b, 0, False) + b += 1 + # add current bandset all bands + if cfg.bandset_catalog.get_bandset_count() > 0: + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item( + table, '%s#b*' % cfg.variable_bandset_name, b, 0, False + ) + b += 1 + # add current bandset bands + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + bands = bandset_x.get_band_alias() + for band in bands: + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item( + table, '%s#%s' % (cfg.variable_bandset_name, band), b, 0, False + ) + b += 1 + # current bandset spectral range bands + try: + (blue_band, green_band, red_band, nir_band, swir_1_band, + swir_2_band) = bandset_x.spectral_range_bands(output_as_number=False) + except Exception as err: + str(err) + blue_band = green_band = red_band = nir_band = swir_1_band = None + swir_2_band = None + spectral_bands = [ + [cfg.rs.configurations.variable_blue_name, blue_band], + [cfg.rs.configurations.variable_green_name, green_band], + [cfg.rs.configurations.variable_red_name, red_band], + [cfg.rs.configurations.variable_nir_name, nir_band], + [cfg.rs.configurations.variable_swir1_name, swir_1_band], + [cfg.rs.configurations.variable_swir2_name, swir_2_band]] + for spectral_band in spectral_bands: + if spectral_band[1] is not None: + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item( + table, '%s' % spectral_band[0], b, 0, False + ) + b += 1 + # add all bandset bands + for bs_number in range(1, cfg.bandset_catalog.get_bandset_count() + 1): + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bs_number) + bands = bandset_x.get_band_alias() + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item( + table, '%s%ib*' % (cfg.variable_bandset_name, bs_number), b, 0, + False + ) + b += 1 + for band in bands: + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item( + table, '%s%i%s' % (cfg.variable_bandset_name, bs_number, band), + b, 0, False + ) + b += 1 + text_changed() + cfg.utils.refresh_raster_extent_combo() + cfg.utils.refresh_raster_align_combo() + + +# text changed +def text_changed(): + expression = cfg.dialog.ui.plainTextEdit_calc.toPlainText() + check_expression(expression=expression) + + +# check the expression and return it +# noinspection PyProtectedMember,PyArgumentList +def check_expression(expression, raster_variables=None, bandset_number=None): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + if raster_variables is None: + raster_variables = cfg.calc_raster_variables + else: + # get QGIS rasters + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + input_name_list = [] + input_raster_list = [] + for x in sorted(layers, key=lambda layer_x: layer_x.name()): + if (x.type() == cfg.util_qgis.get_qgis_map_raster() + and x.bandCount() == 1): + input_name_list.append(x.name()) + input_raster_list.append(x.source()) + raster_variables = rs_calc._band_names_alias( + input_raster_list=input_raster_list, + input_name_list=input_name_list, + bandset_catalog=cfg.bandset_catalog, + bandset_number=bandset_number + ) + if raster_variables is not None: + (exp_list, all_out_name_list, + output_message) = rs_calc._check_expression( + expression_string=expression, raster_variables=raster_variables, + bandset_catalog=cfg.bandset_catalog, + bandset_number=bandset_number + ) + if output_message is not None: + if len(expression) == 0: + cfg.dialog.ui.label_band_calc.setText(' Expression') + else: + message = output_message.split(':') + try: + cfg.dialog.ui.label_band_calc.setText( + ' Expression error [line %s]: %s' + % (int((int(message[0]) - 1) / 2), message[1]) + ) + except Exception as err: + str(err) + cfg.dialog.ui.label_band_calc.setText( + ' Expression error %s' % message + ) + cfg.dialog.ui.plainTextEdit_calc.setStyleSheet('color : black') + cfg.dialog.ui.toolButton_calculate.setEnabled(False) + else: + cfg.dialog.ui.label_band_calc.setText(' Expression') + cfg.dialog.ui.plainTextEdit_calc.setStyleSheet('color : green') + cfg.dialog.ui.toolButton_calculate.setEnabled(True) + output_name_table(name_list=all_out_name_list) + return exp_list + + +# Set output name table +def output_name_table(name_list): + table = cfg.dialog.ui.tableWidget_band_calc + table.blockSignals(True) + table.setSortingEnabled(False) + c = table.rowCount() + # remove items + for i in reversed(range(0, c)): + if table.item(i, 1) is not None: + if cfg.rs.configurations.default_output_name in table.item( + i, 1 + ).text(): + table.removeRow(i) + else: + break + else: + break + b = table.rowCount() + for name in name_list: + if len(name) > 0: + # Add band to table + table.insertRow(b) + cfg.util_qt.add_table_item(table, name, b, 0, False) + cfg.util_qt.add_table_item( + table, cfg.rs.configurations.default_output_name, b, 1, False + ) + b += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + + +# import expressions from file +def import_expression_list(): + function_file = cfg.util_qt.get_open_file( + None, 'Select an expression file', '', 'TXT (*.txt)' + ) + if len(function_file) > 0: + try: + f = open(function_file) + sep = ';' + if cfg.utils.check_file(function_file): + cfg.qgis_registry[cfg.reg_custom_functions] = [] + lines = f.readlines() + if len(lines) > 0: + for line in lines: + try: + splitter = line.split(sep) + # name and expression + name = splitter[0] + expression = splitter[1].strip() + cfg.qgis_registry[ + cfg.reg_custom_functions].append( + [name, expression] + ) + except Exception as err: + str(err) + create_expression_list( + cfg.qgis_registry[cfg.reg_custom_functions] + ) + else: + cfg.util_qt.clear_table( + cfg.dialog.ui.band_calc_function_tableWidget + ) + add_functions_to_table(cfg.band_calc_functions) + cfg.qgis_registry[cfg.reg_custom_functions] = [] + except Exception as err: + str(err) + + +# create expression list +def create_expression_list(expression_list): + cfg.util_qt.clear_table(cfg.dialog.ui.band_calc_function_tableWidget) + add_functions_to_table(cfg.band_calc_functions) + add_functions_to_table(expression_list) + + +# add function list to table +def add_functions_to_table(function_list): + if function_list is not None: + table = cfg.dialog.ui.band_calc_function_tableWidget + # count table rows + c = table.rowCount() + for i in function_list: + table.blockSignals(True) + try: + _check = i[1] + # add list items to table + table.setRowCount(c + 1) + cfg.util_qt.add_table_item(table, i[0], c, 0) + c += 1 + except Exception as err: + str(err) + # add list items to table + table.setRowCount(c + 1) + color = cfg.util_qt.get_color_from_rgb(200, 200, 200) + cfg.util_qt.add_table_item( + table, i[0], c, 0, False, color, bold=True + ) + c += 1 + table.blockSignals(False) + + +# set function +def set_function(index): + cursor = cfg.dialog.ui.plainTextEdit_calc.textCursor() + name = cfg.dialog.ui.band_calc_function_tableWidget.item( + index.row(), 0 + ).text() + if len(cfg.qgis_registry[cfg.reg_custom_functions]) > 0: + functions = cfg.band_calc_functions.extend( + cfg.qgis_registry[cfg.reg_custom_functions] + ) + else: + functions = cfg.band_calc_functions + for i in functions: + if name == i[0]: + try: + cursor.insertHtml(' ' + i[1]) + except Exception as err: + str(err) + return False + + +# double click +def double_click(index): + table = cfg.dialog.ui.tableWidget_band_calc + k = table.item(index.row(), index.column()).text() + cursor = cfg.dialog.ui.plainTextEdit_calc.textCursor() + cursor.insertText('"' + k + '"') + cfg.dialog.ui.plainTextEdit_calc.setFocus() + + +# perform bands filter +def filter_table(): + table = cfg.dialog.ui.tableWidget_band_calc + text = cfg.dialog.ui.bandcalc_filter_lineEdit.text() + items = table.findItems(text, cfg.util_qt.get_match_contains()) + c = table.rowCount() + filtered = [] + for item in items: + if item is not None: + if item.column() == 0: + filtered.append(item.row()) + table.blockSignals(True) + for i in range(0, c): + table.setRowHidden(i, False) + if i not in filtered: + table.setRowHidden(i, True) + table.blockSignals(False) + + +# calculate button +def calculate_button(): + calculate() + + +# calculate +# noinspection PyArgumentList +def calculate(output_path=None): + expression_count = cfg.dialog.ui.plainTextEdit_calc.blockCount() + if output_path is None: + # multiple lines + if expression_count > 1: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is False: + return + else: + if len(output_path) == 0: + return + # one line + else: + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)', None + ) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + if output_path is not False: + cfg.logger.log.info('calculate: %s' % output_path) + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + # get extent + extent_raster = extent_list = xy_resolution_list = align_raster = None + extent_intersection = None + extent_type = cfg.dialog.ui.raster_extent_combo.currentText() + if extent_type == cfg.union_extent: + extent_intersection = False + elif extent_type == cfg.map_extent: + rectangle = cfg.map_canvas.extent() + extent_list = [rectangle.xMinimum(), rectangle.yMaximum(), + rectangle.xMaximum(), rectangle.yMinimum()] + extent_intersection = False + elif extent_type == cfg.intersection_extent: + extent_intersection = True + elif extent_type == cfg.custom_extent: + extent_list = [int(cfg.dialog.ui.UL_X_lineEdit.text()), + int(cfg.dialog.ui.UL_Y_linedit.text()), + int(cfg.dialog.ui.LR_X_lineEdit.text()), + int(cfg.dialog.ui.LR_Y_lineEdit.text())] + else: + # get QGIS rasters + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + for x in sorted(layers, key=lambda layer_x: layer_x.name()): + if (x.type() == cfg.util_qgis.get_qgis_map_raster() + and x.bandCount() == 1): + if extent_type == x.name(): + extent_raster = x.source() + break + # alignment + align_type = cfg.dialog.ui.raster_extent_combo.currentText() + if align_type == cfg.default_align: + align_raster = False + else: + # get QGIS rasters + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + for x in sorted(layers, key=lambda layer_x: layer_x.name()): + if (x.type() == cfg.util_qgis.get_qgis_map_raster() + and x.bandCount() == 1): + if extent_type == x.name(): + align_raster = x.source() + break + # pixel resolution + pixel_resolution = cfg.dialog.ui.resolution_lineEdit.text() + if len(pixel_resolution) > 0: + try: + xy_resolution_list = [float(pixel_resolution), + float(pixel_resolution)] + except Exception as err: + str(err) + cfg.mx.msg_war_1() + # input nodata as value + if cfg.dialog.ui.nodata_as_value_checkBox.isChecked() is True: + input_nodata_as_value = True + else: + input_nodata_as_value = None + # use value as nodata + if cfg.dialog.ui.nodata_checkBox_3.isChecked() is True: + use_value_as_nodata = cfg.dialog.ui.nodata_spinBox_13.value() + else: + use_value_as_nodata = None + # nodata mask + if cfg.dialog.ui.nodata_mask_combo.currentText() == 'False': + any_nodata_mask = False + elif cfg.dialog.ui.nodata_mask_combo.currentText() == 'True': + any_nodata_mask = True + else: + any_nodata_mask = None + # scale + if cfg.dialog.ui.set_scale_checkBox.isChecked() is True: + use_scale = cfg.dialog.ui.scale_doubleSpinBox.value() + else: + use_scale = None + # offset + if cfg.dialog.ui.set_offset_checkBox.isChecked() is True: + use_offset = cfg.dialog.ui.offset_doubleSpinBox.value() + else: + use_offset = None + # output nodata + output_nodata = cfg.dialog.ui.nodata_spinBox_4.value() + # output datatype + output_datatype = cfg.dialog.ui.raster_type_combo.currentText() + # calc data type + calc_datatype = cfg.dialog.ui.calc_type_combo.currentText() + expression = cfg.dialog.ui.plainTextEdit_calc.toPlainText() + cfg.ui_utils.add_progress_bar() + # get QGIS rasters + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + input_name_list = [] + input_raster_list = [] + for x in sorted(layers, key=lambda layer_x: layer_x.name()): + if (x.type() == cfg.util_qgis.get_qgis_map_raster() + and x.bandCount() == 1): + input_name_list.append(x.name()) + input_raster_list.append(x.source()) + # run calculation + output = cfg.rs.band_calc( + expression_string=expression, output_path=output_path, + input_raster_list=input_raster_list, + input_name_list=input_name_list, align_raster=align_raster, + extent_raster=extent_raster, extent_list=extent_list, + extent_intersection=extent_intersection, + xy_resolution_list=xy_resolution_list, + input_nodata_as_value=input_nodata_as_value, + use_value_as_nodata=use_value_as_nodata, + output_nodata=output_nodata, output_datatype=output_datatype, + use_scale=use_scale, use_offset=use_offset, + calc_datatype=calc_datatype, any_nodata_mask=any_nodata_mask, + bandset_catalog=cfg.bandset_catalog, bandset_number=bandset_number + ) + # add output rasters + if output.check: + paths = output.paths + for raster in paths: + cfg.util_qgis.add_raster_layer(raster) + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) diff --git a/interface/band_combination_tab.py b/interface/band_combination_tab.py new file mode 100755 index 0000000..4b850c4 --- /dev/null +++ b/interface/band_combination_tab.py @@ -0,0 +1,136 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band combination. + +This tool allows for calculating band combination. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# calculate band set combination if click on button +def calculate_band_combination(): + band_combination() + + +# band combination +def band_combination(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save error matrix raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + cfg.logger.log.info('band_combination: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + # No data value + if cfg.dialog.ui.nodata_checkBox_12.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_16.value() + else: + nodata = None + column_name_list = [] + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + for band in range(1, bandset_x.get_band_count() + 1): + column_name_list.append('band_%i' % band) + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_combination( + input_bands=bandset_number, output_path=output_path, + nodata_value=nodata, column_name_list=column_name_list, + bandset_catalog=cfg.bandset_catalog + ) + if output.check: + output_raster, output_table = output.paths + # add raster to layers + raster = cfg.util_qgis.add_raster_layer(output_raster) + unique_values = output.extra['combinations']['new_val'].tolist() + cfg.utils.raster_symbol_generic( + raster, 'NoData', raster_unique_value_list=unique_values + ) + if cfg.utils.check_file(output_table): + with open(output_table, 'r') as f: + text = f.read() + cfg.dialog.ui.band_set_comb_textBrowser.setText( + text.replace(',', '\t') + ) + cfg.dialog.ui.toolBox_band_set_combination.setCurrentIndex(1) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox.value() + # No data value + if cfg.dialog.ui.nodata_checkBox_12.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_16.value() + else: + nodata = None + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + column_name_list = '[' + for band in range(1, bandset_x.get_band_count() + 1): + column_name_list += '"band_%i", ' % band + column_name_list = column_name_list[:-2] + ']' + if column_name_list == ']': + column_name_list = '[]' + # get input band paths + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + column_name_list = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band combination (input files from bandset)\n' + 'rs.band_combination(input_bands=%s, output_path="%s", ' + 'nodata_value=%s, column_name_list=%s)' + % (str(paths), str(output_path), str(nodata), + str(column_name_list))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_dilation_tab.py b/interface/band_dilation_tab.py new file mode 100755 index 0000000..507a8e1 --- /dev/null +++ b/interface/band_dilation_tab.py @@ -0,0 +1,148 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band dilation. + +This tool allows for the geometric dilation of pixel values. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# value text changed +def text_changed(): + check_value_list() + + +# check value list +def check_value_list(): + try: + values = cfg.utils.text_to_value_list( + cfg.dialog.ui.dilation_classes_lineEdit.text() + ) + cfg.dialog.ui.dilation_classes_lineEdit.setStyleSheet('color : green') + except Exception as err: + str(err) + cfg.dialog.ui.dilation_classes_lineEdit.setStyleSheet('color : red') + values = [] + return values + + +# dilation classification +def dilation_action(): + band_dilation() + + +# band dilation +def band_dilation(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_16.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + # class value list + values = check_value_list() + if len(values) > 0: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_dilation: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + output_name = cfg.dialog.ui.output_name_lineEdit_2.text() + size = cfg.dialog.ui.dilation_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_1.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox_2.isChecked(): + circular = True + else: + circular = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_dilation( + input_bands=bandset_number, value_list=values, size=size, + output_path=output_path, circular_structure=circular, + prefix=output_name, bandset_catalog=cfg.bandset_catalog, + virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_16.value() + # class value list + values = check_value_list() + if len(values) == 0: + values = '[]' + output_name = cfg.dialog.ui.output_name_lineEdit_2.text() + size = cfg.dialog.ui.dilation_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_1.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox_2.isChecked(): + circular = True + else: + circular = False + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band dilation (input files from bandset)\n' + 'rs.band_dilation(input_bands=%s, value_list=%s, size=%s, ' + 'output_path="%s", circular_structure=%s, prefix="%s", ' + 'virtual_output=%s)' + % (str(paths), str(values), str(size), str(output_path), + str(circular), str(output_name), str(virtual_output))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_erosion_tab.py b/interface/band_erosion_tab.py new file mode 100755 index 0000000..0bb64cd --- /dev/null +++ b/interface/band_erosion_tab.py @@ -0,0 +1,150 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band erosion. + +This tool allows for the geometric erosion of pixel values. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# value text changed +def text_changed(): + check_value_list() + + +# check value list +def check_value_list(): + try: + values = cfg.utils.text_to_value_list( + cfg.dialog.ui.erosion_classes_lineEdit.text() + ) + cfg.dialog.ui.erosion_classes_lineEdit.setStyleSheet('color : green') + except Exception as err: + str(err) + cfg.dialog.ui.erosion_classes_lineEdit.setStyleSheet('color : red') + values = [] + return values + + +# band erosion +def band_erosion_action(): + band_erosion() + + +# band erosion +def band_erosion(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_17.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + # class value list + values = check_value_list() + if len(values) > 0: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_erosion: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + output_name = cfg.dialog.ui.output_name_lineEdit_3.text() + size = cfg.dialog.ui.erosion_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_2.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox_3.isChecked(): + circular = True + else: + circular = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_erosion( + input_bands=bandset_number, value_list=values, size=size, + output_path=output_path, circular_structure=circular, + prefix=output_name, bandset_catalog=cfg.bandset_catalog, + virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + else: + cfg.mx.msg_inf_5() + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_17.value() + # class value list + values = check_value_list() + if len(values) == 0: + values = '[]' + output_name = cfg.dialog.ui.output_name_lineEdit_3.text() + size = cfg.dialog.ui.erosion_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_2.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox_3.isChecked(): + circular = True + else: + circular = False + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band erosion (input files from bandset)\n' + 'rs.band_erosion(input_bands=%s, value_list=%s, size=%s, ' + 'output_path="%s", circular_structure=%s, prefix="%s", ' + 'virtual_output=%s)' + % (str(paths), str(values), str(size), str(output_path), + str(circular), str(output_name), str(virtual_output))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_neighbor_tab.py b/interface/band_neighbor_tab.py new file mode 100755 index 0000000..985b801 --- /dev/null +++ b/interface/band_neighbor_tab.py @@ -0,0 +1,157 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band neighbor. + +This tool allows for neighbor calculation. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# stat combo +def load_statistic_combo(): + cfg.dialog.ui.statistic_name_combobox_2.blockSignals(True) + cfg.dialog.ui.statistic_name_combobox_2.clear() + for i in cfg.rs.configurations.statistics_list: + cfg.dialog.statistic_name_combo2(i[0]) + cfg.dialog.ui.statistic_name_combobox_2.blockSignals(False) + + +# neighbor +def band_neighbor_action(): + band_neighbor() + + +# matrix file +def input_matrix_file(): + m = cfg.util_qt.get_open_file( + None, cfg.translate('Select a XML file'), '', + 'CSV file (*.csv);;Text file (*.txt)' + ) + cfg.dialog.ui.label_287.setText(str(m)) + + +# band neighbor +def band_neighbor(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_15.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_neighbor: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + if cfg.dialog.ui.neighbor_virtual_checkBox.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox.isChecked(): + circular_structure = True + else: + circular_structure = False + size = cfg.dialog.ui.class_neighbor_threshold_spinBox.value() + output_name = cfg.dialog.ui.neighbor_output_name_lineEdit.text() + stat_name = cfg.dialog.ui.statistic_name_combobox_2.currentText() + structure = cfg.dialog.ui.label_287.text() + if len(structure) == 0: + structure = None + stat_percentile = cfg.dialog.ui.statistic_lineEdit_2.text() + if len(stat_percentile) == 0: + stat_percentile = None + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_neighbor_pixels( + input_bands=bandset_number, size=size, structure=structure, + stat_percentile=stat_percentile, output_path=output_path, + prefix=output_name, circular_structure=circular_structure, + stat_name=stat_name, bandset_catalog=cfg.bandset_catalog, + virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_15.value() + output_name = cfg.dialog.ui.neighbor_output_name_lineEdit.text() + size = cfg.dialog.ui.class_neighbor_threshold_spinBox.value() + if cfg.dialog.ui.neighbor_virtual_checkBox.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.circular_structure_checkBox.isChecked(): + circular_structure = True + else: + circular_structure = False + stat_name = cfg.dialog.ui.statistic_name_combobox_2.currentText() + structure = cfg.dialog.ui.label_287.text() + if len(structure) == 0: + structure = None + stat_percentile = cfg.dialog.ui.statistic_lineEdit_2.text() + if len(stat_percentile) == 0: + stat_percentile = None + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band neighbor (input files from bandset)\n' + 'rs.band_neighbor_pixels(input_bands=%s, size=%s, structure=%s,' + ' stat_percentile=%s, output_path="%s", prefix="%s", ' + 'circular_structure="%s", stat_name="%s", virtual_output="%s")' + % (str(paths), str(size), str(structure), str(stat_percentile), + str(output_path), str(output_name), + str(circular_structure), str(stat_name), str(virtual_output)) + ) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_pca_tab.py b/interface/band_pca_tab.py new file mode 100755 index 0000000..65628f6 --- /dev/null +++ b/interface/band_pca_tab.py @@ -0,0 +1,135 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band PCA. + +This tool allows for calculation of principal components. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# calculate PCA action +def calculate_pca_action(): + calculate_pca() + + +# calculate PCA +def calculate_pca(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_4.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + components_number = cfg.dialog.ui.pca_components_spinBox.value() + if cfg.dialog.ui.num_comp_checkBox.isChecked() is True: + if components_number > bandset_x.get_band_count(): + components_number = bandset_x.get_band_count() + else: + components_number = bandset_x.get_band_count() + if cfg.dialog.ui.nodata_checkBox_4.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_5.value() + else: + nodata = None + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save error matrix raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + cfg.logger.log.info('calculate_pca: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_pca( + input_bands=bandset_number, output_path=output_path, + nodata_value=nodata, number_components=components_number, + bandset_catalog=cfg.bandset_catalog + ) + if output.check: + output_paths = output.paths + output_table = output.extra['table'] + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + if cfg.utils.check_file(output_table): + with open(output_table, 'r') as f: + text = f.read() + cfg.dialog.ui.report_textBrowser_2.setText( + text.replace(',', '\t') + ) + cfg.dialog.ui.toolBox_PCA.setCurrentIndex(1) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_4.value() + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + components_number = cfg.dialog.ui.pca_components_spinBox.value() + if cfg.dialog.ui.num_comp_checkBox.isChecked() is True: + if components_number > bandset_x.get_band_count(): + components_number = bandset_x.get_band_count() + else: + components_number = bandset_x.get_band_count() + # get input band paths + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + components_number = None + if cfg.dialog.ui.nodata_checkBox_4.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_5.value() + else: + nodata = None + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band pca (input files from bandset)\n' + 'rs.band_pca(input_bands=%s, output_path="%s", nodata_value=%s,' + ' number_components=%s)' + % (str(paths), str(output_path), str(nodata), + str(components_number))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/band_sieve_tab.py b/interface/band_sieve_tab.py new file mode 100755 index 0000000..895cfd8 --- /dev/null +++ b/interface/band_sieve_tab.py @@ -0,0 +1,121 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band sieve. + +This tool allows for sieve calculation. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# sieve classification +def sieve_classification_action(): + band_sieve() + + +# band sieve +def band_sieve(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_18.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_sieve: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + output_name = cfg.dialog.ui.output_name_lineEdit_4.text() + size = cfg.dialog.ui.sieve_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_3.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.sieve_connection_combo.currentText() == '8': + connection = True + else: + connection = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_sieve( + input_bands=bandset_number, size=size, output_path=output_path, + connected=connection, prefix=output_name, + bandset_catalog=cfg.bandset_catalog, virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_18.value() + output_name = cfg.dialog.ui.output_name_lineEdit_4.text() + size = cfg.dialog.ui.sieve_threshold_spinBox.value() + if cfg.dialog.ui.virtual_output_checkBox_3.isChecked(): + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.sieve_connection_combo.currentText() == '8': + connection = True + else: + connection = False + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band sieve (input files from bandset)\n' + 'rs.band_sieve(input_bands=%s, size=%s, output_path="%s", ' + 'connected=%s, prefix="%s", virtual_output=%s)' + % (str(paths), str(size), str(output_path), str(connection), + str(output_name), str(virtual_output))) + + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/bandset_tab.py b/interface/bandset_tab.py new file mode 100755 index 0000000..a3507a8 --- /dev/null +++ b/interface/bandset_tab.py @@ -0,0 +1,1066 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band set. + +This tool allows for band set definition. +""" + +import numpy +from PyQt5.QtWidgets import ( + QWidget, QGridLayout, QFrame, QAbstractItemView, QTableWidget, + QTableWidgetItem, QListWidgetItem +) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# add satellite list to combo +def add_satellite_to_combo(satellite_list): + for i in satellite_list: + cfg.dialog.ui.wavelength_sat_combo.addItem(i) + + +# add unit list to combo +def add_unit_to_combo(unit_list): + for i in unit_list: + cfg.dialog.ui.unit_combo.addItem(i) + + +def satellite_wavelength(): + set_satellite_wavelength() + + +# set satellite wavelengths +def set_satellite_wavelength(satellite_name=None, bandset_number=None): + cfg.logger.log.debug( + 'set_satellite_wavelength satellite_name: %s' + % str(satellite_name) + ) + if satellite_name is None: + satellite_name = cfg.dialog.ui.wavelength_sat_combo.currentText() + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + cfg.bandset_catalog.set_satellite_wavelength( + satellite_name=satellite_name, bandset_number=bandset_number + ) + # create table + band_set_to_table(bandset_number) + + +def satellite_unit(): + set_band_unit() + + +# set band unit +def set_band_unit(unit_name=None, bandset_number=None): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + bands = bandset_x.bands + if unit_name is None: + unit_name = cfg.dialog.ui.unit_combo.currentText() + for band in bands: + band['wavelength_unit'] = unit_name + # create table + band_set_to_table(bandset_number) + + +# set date +def set_bandset_date(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + q_date = cfg.dialog.ui.bandset_dateEdit.date() + date = q_date.toPyDate().strftime('%Y-%m-%d') + cfg.bandset_catalog.set_date(bandset_number=bandset_number, date=date) + cfg.dialog.ui.bandset_date_lineEdit.setText(date) + + +# edit date +def edit_bandset_date(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + date = cfg.dialog.ui.bandset_date_lineEdit.text() + if len(date) > 0: + try: + date = numpy.array(date, dtype='datetime64[D]') + except Exception as err: + str(err) + date = 'NaT' + cfg.bandset_catalog.set_date(bandset_number=bandset_number, date=date) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(True) + cfg.dialog.ui.bandset_date_lineEdit.setText(str(date)) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(False) + + +# edit root directory +def edit_bandset_root(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + root = cfg.dialog.ui.root_dir_lineEdit.text() + cfg.bandset_catalog.set_root_directory( + bandset_number=bandset_number, root_directory=root + ) + band_set_to_table(bandset_number) + + +# add file to band set action +def add_file_to_band_set_action(): + files = cfg.util_qt.get_open_files( + None, cfg.translate('Select input raster'), '', 'Raster (*.*)' + ) + add_file_to_band_set(files) + + +# add file to band set action +def set_custom_wavelength_action(): + file = cfg.util_qt.get_open_file( + None, cfg.translate('Select csv file'), '', + 'TXT file (*.txt);;CSV file (*.csv)' + ) + if len(file) > 0: + with open(file, 'r') as f: + text = f.read() + if len(text) > 0: + values = text.split(',') + if len(values) == 1: + values = text.split(';') + if len(values) == 1: + values = text.split('\n') + if len(values) == 1: + return + bandset_number = cfg.project_registry[ + cfg.reg_active_bandset_number + ] + cfg.bandset_catalog.set_wavelength( + wavelength_list=values, unit=cfg.rs.configurations.wl_micro, + bandset_number=bandset_number + ) + # create table + band_set_to_table(bandset_number) + + +# change band set tab action +def change_bandset_table_action(index): + # change spinbox value (tabs are connected) + cfg.dialog.ui.bandset_number_spinBox.setValue(int(index.row()) + 1) + + +# change band set tab action +def change_bandset_tab_action(): + change_bandset_tab() + + +# add band set tab +def add_bandset_tab_action(): + add_band_set_tab() + + +# add band set tab +def add_band_set_tab(position=None, create_bandset_in_catalog=True): + cfg.logger.log.debug('add_band_set_tab position: %s' % str(position)) + if len(cfg.bandset_tabs) == 0: + position = 1 + elif position is None or int(position) > (len(cfg.bandset_tabs)): + position = len(cfg.bandset_tabs) + 1 + if create_bandset_in_catalog: + # create bandset + bandset = cfg.rs.bandset.create(catalog=cfg.bandset_catalog) + cfg.bandset_catalog.add_bandset( + bandset=bandset, bandset_number=position, insert=True + ) + try: + assert cfg.bandset_tabs[position] + cfg.logger.log.debug('existing bandset tab') + return + except Exception as err: + str(err) + cfg.bandset_tabs[position] = bandset_uid() + table_w_var = 'cfg.dialog.ui.tableWidget__' + str( + cfg.bandset_tabs[position] + ) + cfg.dialog.ui.bandset_number_spinBox.setMaximum(position) + # noinspection PyArgumentList + band_set_tab = QWidget() + band_set_tab.setObjectName(table_w_var) + grid_layout = QGridLayout(band_set_tab) + grid_layout.setObjectName('grid_layout' + str(position)) + exec(table_w_var + ' = QTableWidget(band_set_tab)') + table_w = eval(table_w_var) + table_w.setFrameShape(QFrame.WinPanel) + table_w.setFrameShadow(QFrame.Sunken) + table_w.setAlternatingRowColors(True) + table_w.setSelectionMode(QAbstractItemView.MultiSelection) + table_w.setSelectionBehavior(QAbstractItemView.SelectRows) + table_w.setColumnCount(7) + table_w.setObjectName(table_w_var) + table_w.setRowCount(0) + table_w.setHorizontalHeaderItem(0, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(1, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(2, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(3, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(4, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(5, QTableWidgetItem()) + table_w.setHorizontalHeaderItem(6, QTableWidgetItem()) + table_w.horizontalHeaderItem(0).setText(cfg.translate('Band name')) + table_w.horizontalHeaderItem(1).setText(cfg.translate('Center wavelength')) + table_w.horizontalHeaderItem(2).setText( + cfg.translate('Multiplicative Factor') + ) + table_w.horizontalHeaderItem(3).setText(cfg.translate('Additive Factor')) + table_w.horizontalHeaderItem(4).setText(cfg.translate('Wavelength unit')) + table_w.horizontalHeaderItem(5).setText(cfg.translate('Path')) + table_w.horizontalHeaderItem(6).setText(cfg.translate('Date')) + table_w.verticalHeader().setDefaultSectionSize(24) + table_w.horizontalHeader().setStretchLastSection(True) + grid_layout.addWidget(table_w, 0, 0, 1, 1) + # connect to edited cell + try: + table_w.cellChanged.disconnect() + except Exception as err: + str(err) + table_w.cellChanged.connect(edited_bandset) + cfg.dialog.ui.Band_set_tabWidget.insertTab( + int(position) - 1, band_set_tab, + '%s %s' % (cfg.bandset_tab_name, str(position)) + ) + cfg.util_qt.set_column_width_list( + table_w, [[0, 350], [1, 150], [2, 150], [3, 150], [4, 150], [5, 150]] + ) + # hide tabs + cfg.dialog.ui.Band_set_tabWidget.setStyleSheet( + 'QTabBar::tab {padding: 0px; max-height: 0px;}' + ) + cfg.dialog.ui.bandset_tableWidget.setRowCount(position) + cfg.util_qt.add_table_item( + cfg.dialog.ui.bandset_tableWidget, '', int(position) - 1, 0 + ) + # change spinbox value (tabs are connected) + cfg.dialog.ui.bandset_number_spinBox.setValue(position) + cfg.project_registry[cfg.reg_bandset_count] = ( + cfg.bandset_catalog.get_bandset_count()) + cfg.logger.log.debug( + 'bandset_count: %s; table count: %s; current index: %s' + % (str(cfg.project_registry[cfg.reg_bandset_count]), + str(cfg.dialog.ui.Band_set_tabWidget.count()), + str(cfg.dialog.ui.Band_set_tabWidget.currentIndex()) + ) + ) + + +# add loaded band to current band set +def add_loaded_band_to_bandset(): + cfg.logger.log.info('add_loaded_band_to_bandset') + # clear the list + cfg.widget_dialog.ui.listWidget.clear() + # add raster list + # noinspection PyArgumentList + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + layer_path_list = [] + for layer in sorted(layers, key=lambda c: c.name()): + if ((layer.type() == cfg.util_qgis.get_qgis_map_raster()) + and layer.bandCount() == 1): + item = QListWidgetItem() + item.setCheckState(cfg.util_qt.get_unchecked()) + item.setText(layer.name()) + layer_path_list.append(layer.source().split("|layername=")[0]) + cfg.widget_dialog.ui.listWidget.addItem(item) + cfg.dialog_accepted = False + cfg.widget_dialog.exec() + if cfg.dialog_accepted is True: + checked_files = [] + for index in range(cfg.widget_dialog.ui.listWidget.count()): + if (cfg.widget_dialog.ui.listWidget.item(index).checkState() + == cfg.util_qt.get_checked()): + checked_files.append(layer_path_list[index]) + add_file_to_band_set(checked_files) + + +# clear the band set +def clear_bandset_action(): + clear_bandset() + + +# clear the bandset +def clear_bandset(question=True, bandset_number=None): + if question: + answer = cfg.util_qt.question_box( + cfg.translate('Clear band set'), + cfg.translate('Are you sure you want to clear the band set?') + ) + else: + answer = True + if answer: + if bandset_number is None: + bandset_number = (cfg.dialog.ui.Band_set_tabWidget.currentIndex() + + 1) + cfg.logger.log.debug('clear_bandset: %s' % str(bandset_number)) + cfg.bandset_catalog.clear_bandset(bandset_number) + # create table + band_set_to_table(bandset_number) + + +# band set edited +def edited_bandset(row, column): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + table_w = eval( + 'cfg.dialog.ui.tableWidget__' + str(cfg.bandset_tabs[bandset_number]) + ) + cfg.logger.log.debug('edited_bandset column: %s' % str(column)) + if column == 0: + band_names = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='name' + ) + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(band_names[row])) + table_w.blockSignals(False) + elif column == 1: + try: + value = float(table_w.item(row, column).text()) + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + bands = bandset_x.bands + bands['wavelength'][bands['band_number'] == row + 1] = value + bandset_x.sort_bands_by_wavelength() + # create table + band_set_to_table(bandset_number) + except Exception as err: + str(err) + band_wavelength = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='wavelength' + ) + value = band_wavelength[row] + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + elif column == 2: + try: + value = float(table_w.item(row, column).text()) + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + bands = bandset_x.bands + bands['multiplicative_factor'][ + bands['band_number'] == row + 1] = value + except Exception as err: + str(err) + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='multiplicative_factor' + ) + value = band_value[row] + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + elif column == 3: + try: + value = float(table_w.item(row, column).text()) + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + bands = bandset_x.bands + bands['additive_factor'][bands['band_number'] == row + 1] = value + except Exception as err: + str(err) + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='additive_factor' + ) + value = band_value[row] + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + elif column == 4: + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='wavelength_unit' + ) + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(band_value[row])) + table_w.blockSignals(False) + elif column == 5: + path = table_w.item(row, column).text() + if len(path) > 0: + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + bands = bandset_x.bands + bands['path'][bands['band_number'] == row + 1] = path + root = cfg.bandset_catalog.get_root_directory(bandset_number) + absolute = cfg.utils.relative_to_absolute_path( + path=path, root=root + ) + bands['absolute_path'][bands['band_number'] == row + 1] = absolute + else: + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='path' + ) + value = band_value[row] + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + elif column == 6: + try: + value = table_w.item(row, column).text() + if len(value) > 0: + numpy.array(value, dtype='datetime64[D]') + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + bands = bandset_x.bands + bands['date'][bands['band_number'] == row + 1] = value + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='date' + ) + value = band_value[row] + if value is None: + value = 'NaT' + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + except Exception as err: + str(err) + band_value = cfg.bandset_catalog.get_bandset( + bandset_number, attribute='date' + ) + value = band_value[row] + if value is None: + value = 'NaT' + table_w.blockSignals(True) + cfg.util_qt.set_table_item(table_w, row, column, str(value)) + table_w.blockSignals(False) + + +# delete bandset +def remove_bandsets(): + answer = cfg.util_qt.question_box( + cfg.translate('Remove band set'), + cfg.translate( + 'Are you sure you want to remove the selected band sets?' + ) + ) + if answer: + table = cfg.dialog.ui.bandset_tableWidget + selected = table.selectedItems() + selected_list = [] + for i in range(0, len(selected)): + selected_list.append(selected[i].row()) + selected_list = list(set(selected_list)) + for index in reversed(selected_list): + delete_bandset_tab(index) + + +# delete bandset +def delete_bandset_tab(index): + table = cfg.dialog.ui.bandset_tableWidget + count = cfg.dialog.ui.Band_set_tabWidget.count() + cfg.logger.log.debug('delete_bandset_tab: %s' % str(index + 1)) + for position in range(index, count - 1): + try: + cfg.bandset_tabs[position + 1] = cfg.bandset_tabs[position + 2] + except Exception as err: + cfg.mx.msg_bar_critical( + title='bandset', message=str(err), smtp=False + ) + cfg.logger.log.error(str(err)) + cfg.bandset_tabs.pop(count, None) + bandset = cfg.bandset_catalog.get_bandset(index + 1) + if bandset is not None: + cfg.bandset_catalog.remove_bandset(index + 1) + cfg.logger.log.debug( + 'bandset_count: %s' % str( + cfg.bandset_catalog.get_bandset_count() + ) + ) + cfg.dialog.ui.Band_set_tabWidget.removeTab(index) + cfg.dialog.ui.bandset_number_spinBox.setMaximum(count) + table.removeRow(index) + + +# export bandset to file +def export_bandset(): + xml_file = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save the bandset to file'), '', '*.xml', 'xml' + ) + if xml_file is not False: + cfg.logger.log.info('export_bandset: %s' % xml_file) + if not xml_file.lower().endswith('.xml'): + xml_file = xml_file + '.xml' + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + cfg.bandset_catalog.export_bandset_as_xml( + bandset_number=bandset_number, output_path=xml_file + ) + + +# import bandset from file +def import_bandset(): + xml_file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a bandset file'), '', 'XML (*.xml)' + ) + if len(xml_file) > 0: + cfg.logger.log.info('import_bandset: %s' % xml_file) + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + try: + cfg.bandset_catalog.import_bandset_from_xml( + bandset_number=bandset_number, xml_path=xml_file + ) + # create table + band_set_to_table(bandset_number) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_5() + + +# move down selected bandset +def move_down_bandset(): + table = cfg.dialog.ui.bandset_tableWidget + selected = table.selectedItems() + selected_list = [] + for i in range(0, len(selected)): + selected_list.append(selected[i].row()) + selected_list = list(set(selected_list)) + if (table.rowCount() - 1) not in selected_list: + for index in reversed(selected_list): + cfg.bandset_catalog.move_bandset( + bandset_number_input=index + 1, bandset_number_output=index + 2 + ) + bandset_1 = cfg.bandset_catalog.get_bandset_by_number(index + 1) + bandset_2 = cfg.bandset_catalog.get_bandset_by_number(index + 2) + # band sets table + table.blockSignals(True) + names = str(bandset_1.get_band_attributes('name')).replace( + "'", '' + ).replace( + '[', '' + ).replace(']', '') + if names == 'None': + names = '' + cfg.util_qt.add_table_item(table, str(names), int(index), 0) + names = str(bandset_2.get_band_attributes('name')).replace( + "'", '' + ).replace( + '[', '' + ).replace(']', '') + if names == 'None': + names = '' + cfg.util_qt.add_table_item(table, str(names), int(index) + 1, 0) + table.blockSignals(False) + # create table + band_set_to_table(index + 1) + band_set_to_table(index + 2) + table.clearSelection() + table.setSelectionMode(QAbstractItemView.MultiSelection) + for i in selected_list: + table.selectRow(i + 1) + table.setSelectionMode(QAbstractItemView.ExtendedSelection) + + +# move up selected bandset +def move_up_bandset(): + table = cfg.dialog.ui.bandset_tableWidget + selected = table.selectedItems() + selected_list = [] + for i in range(0, len(selected)): + selected_list.append(selected[i].row()) + selected_list = list(set(selected_list)) + if 0 not in selected_list: + for index in selected_list: + cfg.bandset_catalog.move_bandset( + bandset_number_input=index + 1, bandset_number_output=index + ) + bandset_1 = cfg.bandset_catalog.get_bandset_by_number(index + 1) + bandset_2 = cfg.bandset_catalog.get_bandset_by_number(index) + # band sets table + table.blockSignals(True) + names = str(bandset_1.get_band_attributes('name')).replace( + "'", '' + ).replace( + '[', '' + ).replace(']', '') + if names == 'None': + names = '' + cfg.util_qt.add_table_item(table, str(names), int(index), 0) + names = str(bandset_2.get_band_attributes('name')).replace( + "'", '' + ).replace( + '[', '' + ).replace(']', '') + if names == 'None': + names = '' + cfg.util_qt.add_table_item(table, str(names), int(index) - 1, 0) + table.blockSignals(False) + # create table + band_set_to_table(index + 1) + band_set_to_table(index) + table.clearSelection() + table.setSelectionMode(QAbstractItemView.MultiSelection) + for i in selected_list: + table.selectRow(i - 1) + table.setSelectionMode(QAbstractItemView.ExtendedSelection) + + +# move down selected band +def move_down_band(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + table = eval( + 'cfg.dialog.ui.tableWidget__' + str(cfg.bandset_tabs[bandset_number]) + ) + selected = table.selectedItems() + selected_list = [] + for i in range(0, len(selected)): + selected_list.append(selected[i].row()) + selected_list = list(set(selected_list)) + if (table.rowCount() - 1) not in selected_list: + for index in reversed(selected_list): + cfg.bandset_catalog.move_band_in_bandset( + bandset_number=bandset_number, + band_number_input=index + 1, band_number_output=index + 2 + ) + # create table + band_set_to_table(bandset_number) + for i in selected_list: + table.selectRow(i + 1) + + +# move up selected band +def move_up_band(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + table = eval( + 'cfg.dialog.ui.tableWidget__' + str(cfg.bandset_tabs[bandset_number]) + ) + selected = table.selectedItems() + selected_list = [] + for i in range(0, len(selected)): + selected_list.append(selected[i].row()) + selected_list = list(set(selected_list)) + if 0 not in selected_list: + for index in selected_list: + cfg.bandset_catalog.move_band_in_bandset( + bandset_number=bandset_number, band_number_input=index + 1, + band_number_output=index + ) + # create table + band_set_to_table(bandset_number) + for i in selected_list: + table.selectRow(i - 1) + + +# sort bands by name +def sort_bands_by_name(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + try: + cfg.bandset_catalog.sort_bands_by_name(bandset_number=bandset_number) + except Exception as err: + str(err) + # create table + band_set_to_table(bandset_number) + + +# remove selected band +def remove_band(): + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + table_w = eval( + 'cfg.dialog.ui.tableWidget__' + str(cfg.bandset_tabs[bandset_number]) + ) + answer = cfg.util_qt.question_box( + cfg.translate('Remove band'), + cfg.translate( + 'Are you sure you want to remove the selected bands from band set?' + ) + ) + if answer: + selected_list = [] + for i in table_w.selectedItems(): + selected_list.append(i.row() + 1) + selected_list = list(set(selected_list)) + for r in reversed(selected_list): + cfg.bandset_catalog.remove_band_in_bandset( + bandset_number=bandset_number, band_number=r + ) + # create table + band_set_to_table(bandset_number) + + +# sort bandsets by date +def sort_bandsets_by_date(): + cfg.bandset_catalog.sort_bandsets_by_date() + for bandset_number in range( + 1, cfg.bandset_catalog.get_bandset_count() + 1 + ): + # create table + band_set_to_table(bandset_number) + + +""" Tools """ + + +# create virtual raster +def virtual_raster_bandset(output_path=None, bandset_number=None): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + if output_path is None: + vrt_file = cfg.util_qt.get_save_file_name( + None, cfg.translate( + 'Save virtual raster' + ), '', '*.vrt', 'vrt' + ) + else: + vrt_file = output_path + if vrt_file is not False: + if not vrt_file.lower().endswith('.vrt'): + vrt_file += '.vrt' + try: + cfg.bandset_catalog.create_virtual_raster( + bandset_number=bandset_number, output_path=vrt_file + ) + except Exception as err: + cfg.mx.msg_err_5() + cfg.logger.log.error(str(err)) + return vrt_file + + +# stack bandset +def stack_bandset(output_path=None, bandset_number=None): + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + if output_path is None: + tif_file = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save raster'), '', '*.tif', 'tif' + ) + else: + tif_file = output_path + if tif_file is not False: + if not tif_file.lower().endswith('.tif'): + tif_file += '.tif' + try: + cfg.bandset_catalog.create_bandset_stack( + bandset_number=bandset_number, output_path=tif_file + ) + except Exception as err: + cfg.mx.msg_err_5() + cfg.logger.log.error(str(err)) + return tif_file + + +# button perform bandset tools +def perform_bandset_tools(): + if (cfg.dialog.ui.overview_raster_bandset_checkBox.isChecked() is False + and cfg.dialog.ui.band_calc_checkBox.isChecked() is False + and cfg.dialog.ui.stack_raster_bandset_checkBox.isChecked() is + False + and cfg.dialog.ui.virtual_raster_bandset_checkBox.isChecked() is + False): + cfg.mx.msg_war_8() + elif (cfg.dialog.ui.overview_raster_bandset_checkBox.isChecked() is True + and cfg.dialog.ui.band_calc_checkBox.isChecked() is False + and cfg.dialog.ui.stack_raster_bandset_checkBox.isChecked() is False + and cfg.dialog.ui.virtual_raster_bandset_checkBox.isChecked() is + False): + # build overview + cfg.bandset_catalog.build_bandset_band_overview( + bandset_number=cfg.project_registry[cfg.reg_active_bandset_number] + ) + else: + directory = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if directory is not False: + cfg.ui_utils.add_progress_bar() + bandset_tools(directory, batch=False) + cfg.ui_utils.remove_progress_bar() + + +# perform bandset tools +def bandset_tools(output_directory, batch=True): + if batch is False: + cfg.ui_utils.add_progress_bar() + cfg.logger.log.info('bandset_tools: %s' % output_directory) + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + name = cfg.bandset_catalog.get_name(bandset_number) + if cfg.rs.configurations.action: + if cfg.dialog.ui.band_calc_checkBox.isChecked() is True: + cfg.band_calc.raster_band_table() + cfg.band_calc.calculate(output_directory) + if cfg.rs.configurations.action: + if cfg.dialog.ui.virtual_raster_bandset_checkBox.isChecked() is True: + virtual_raster_bandset( + ''.join( + [output_directory, '/', name, '_', 'virtual_rast', + '.vrt'] + ) + ) + if cfg.rs.configurations.action: + if cfg.dialog.ui.stack_raster_bandset_checkBox.isChecked() is True: + stack_bandset( + ''.join( + [output_directory, '/', name, '_', 'stack_raster', + '.tif'] + ) + ) + if cfg.rs.configurations.action: + if cfg.dialog.ui.overview_raster_bandset_checkBox.isChecked() is True: + # build overview + cfg.bandset_catalog.build_bandset_band_overview( + bandset_number=cfg.project_registry[ + cfg.reg_active_bandset_number] + ) + if batch is False: + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# perform bands filter +def filter_table(): + text = cfg.dialog.ui.band_set_filter_lineEdit.text() + items = cfg.dialog.ui.bandset_tableWidget.findItems( + text, cfg.util_qt.get_match_contains() + ) + c = cfg.dialog.ui.bandset_tableWidget.rowCount() + rows = [] + for item in items: + rows.append(item.row()) + cfg.dialog.ui.bandset_tableWidget.blockSignals(True) + for i in range(0, c): + cfg.dialog.ui.bandset_tableWidget.setRowHidden(i, False) + if i not in rows: + cfg.dialog.ui.bandset_tableWidget.setRowHidden(i, True) + cfg.dialog.ui.bandset_tableWidget.blockSignals(False) + + +# band set to table +def band_set_to_table(bandset_number): + cfg.logger.log.debug( + 'band_set_to_table bandset_number: %s' % str(bandset_number) + ) + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + # add table without adding bandset in catalog + if bandset_number not in cfg.bandset_tabs: + add_band_set_tab( + position=bandset_number, create_bandset_in_catalog=False + ) + table_w = eval( + 'cfg.dialog.ui.tableWidget__' + str(cfg.bandset_tabs[bandset_number]) + ) + bands = bandset_x.bands + cfg.logger.log.debug('band_count: %s' % str(bandset_x.get_band_count())) + if bands is not None: + bands.sort(order='band_number') + # create table + table_w.blockSignals(True) + cfg.util_qt.clear_table(table_w) + table_w.setRowCount(bandset_x.get_band_count()) + for band in bands: + # table rows + c = band['band_number'] - 1 + cfg.logger.log.debug('band name: %s' % str(band['name'])) + cfg.util_qt.add_table_item(table_w, str(band['name']), c, 0) + cfg.util_qt.add_table_item(table_w, str(band['wavelength']), c, 1) + cfg.util_qt.add_table_item( + table_w, str(band['multiplicative_factor']), c, 2 + ) + cfg.util_qt.add_table_item( + table_w, str(band['additive_factor']), c, 3 + ) + cfg.util_qt.add_table_item( + table_w, str(band['wavelength_unit']), c, 4 + ) + cfg.util_qt.add_table_item(table_w, str(band['path']), c, 5) + cfg.util_qt.add_table_item(table_w, str(band['date']), c, 6) + table_w.blockSignals(False) + # band sets table + cfg.dialog.ui.bandset_tableWidget.blockSignals(True) + names = str(bandset_x.get_band_attributes('name')).replace( + "'", '' + ).replace( + '[', '' + ).replace(']', '') + if names == 'None': + names = '' + cfg.util_qt.add_table_item( + cfg.dialog.ui.bandset_tableWidget, str(names), + int(bandset_number) - 1, 0 + ) + cfg.dialog.ui.bandset_tableWidget.blockSignals(False) + if bandset_number == ( + cfg.dialog.ui.Band_set_tabWidget.currentIndex() + 1): + # set date + date = cfg.bandset_catalog.get_date(bandset_number) + if len(date) > 0: + try: + numpy.array(date, dtype='datetime64[D]') + except Exception as err: + str(err) + date = 'NaT' + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(True) + cfg.dialog.ui.bandset_date_lineEdit.setText(date) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(False) + # set root directory + root = cfg.bandset_catalog.get_root_directory(bandset_number) + if root is None or root == 'None': + root = '' + cfg.dialog.ui.root_dir_lineEdit.blockSignals(True) + cfg.dialog.ui.root_dir_lineEdit.setText(root) + cfg.dialog.ui.root_dir_lineEdit.blockSignals(False) + else: + table_w.blockSignals(True) + cfg.util_qt.clear_table(table_w) + table_w.blockSignals(True) + # band sets table + cfg.dialog.ui.bandset_tableWidget.blockSignals(True) + cfg.util_qt.add_table_item( + cfg.dialog.ui.bandset_tableWidget, '', int(bandset_number) - 1, 0 + ) + cfg.dialog.ui.bandset_tableWidget.blockSignals(False) + if bandset_number == ( + cfg.dialog.ui.Band_set_tabWidget.currentIndex() + 1): + # set date + date = 'NaT' + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(True) + cfg.dialog.ui.bandset_date_lineEdit.setText(date) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(False) + # set root directory + root = '' + cfg.dialog.ui.root_dir_lineEdit.blockSignals(True) + cfg.dialog.ui.root_dir_lineEdit.setText(root) + cfg.dialog.ui.root_dir_lineEdit.blockSignals(False) + + +# change band set tab +def change_bandset_tab(bandset_number=None): + if bandset_number is None: + bandset_number = cfg.dialog.ui.bandset_number_spinBox.value() + cfg.project_registry[cfg.reg_active_bandset_number] = bandset_number + cfg.dialog.ui.Band_set_tabWidget.setCurrentIndex(bandset_number - 1) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(True) + cfg.dialog.ui.wavelength_sat_combo.blockSignals(True) + cfg.dialog.ui.wavelength_sat_combo.setCurrentIndex(0) + cfg.dialog.ui.wavelength_sat_combo.blockSignals(False) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(False) + # set date + date = cfg.bandset_catalog.get_date(bandset_number) + if len(date) > 0: + try: + numpy.array(date, dtype='datetime64[D]') + except Exception as err: + str(err) + date = 'NaT' + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(True) + cfg.dialog.ui.bandset_date_lineEdit.setText(date) + cfg.dialog.ui.bandset_date_lineEdit.blockSignals(False) + # set root directory + root = cfg.bandset_catalog.get_root_directory(bandset_number) + if root is None or root == 'None': + root = '' + cfg.dialog.ui.root_dir_lineEdit.blockSignals(True) + cfg.dialog.ui.root_dir_lineEdit.setText(root) + cfg.dialog.ui.root_dir_lineEdit.blockSignals(False) + + +# add files to band set +def add_file_to_band_set(files): + if len(files) > 0: + cfg.logger.log.debug('add_file_to_band_set files: %s' % str(files)) + cfg.rs.configurations.action = True + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + unit = cfg.dialog.ui.unit_combo.currentText() + satellite = cfg.dialog.ui.wavelength_sat_combo.currentText() + root_directory = cfg.dialog.ui.root_dir_lineEdit.text() + if len(root_directory) == 0: + root_directory = None + if root_directory is not None: + temp_files = [] + for f in files: + temp_files.append( + cfg.utils.absolute_to_relative(f, root_directory) + ) + files = temp_files + if satellite == cfg.rs.configurations.no_satellite: + wavelengths = None + else: + wavelengths = [satellite] + unit = None + # check empty bandset + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + cfg.logger.log.debug('bandset_x: %s' % str(bandset_x)) + if bandset_x is None: + # create bandset + cfg.bandset_catalog.create_bandset( + paths=files, bandset_number=bandset_number, insert=False, + unit=unit, root_directory=root_directory, + wavelengths=wavelengths + ) + else: + bands = bandset_x.bands + if bands is None or bands.shape[0] == 0: + try: + # create bandset + cfg.bandset_catalog.create_bandset( + paths=files, bandset_number=bandset_number, + insert=False, unit=unit, root_directory=root_directory, + wavelengths=wavelengths + ) + except Exception as err: + cfg.mx.msg_err_5() + cfg.logger.log.error(str(err)) + else: + for file in files: + cfg.bandset_catalog.add_band_to_bandset( + path=file, bandset_number=bandset_number, + raster_band=1, root_directory=root_directory + ) + # create table + band_set_to_table(bandset_number) + + +def bandset_uid(): + times = cfg.utils.get_time() + random_int = str(cfg.utils.random_integer(0, 1000)) + uid = '{}_{}'.format(times, random_int) + return uid + + +# check accepted dialog +def check_accepted(): + cfg.dialog_accepted = True + + +# select all +def select_all_bands(): + if cfg.widget_dialog.ui.listWidget.count() > 0: + if (cfg.widget_dialog.ui.listWidget.item(0).checkState() + == cfg.util_qt.get_checked()): + state = cfg.util_qt.get_unchecked() + else: + state = cfg.util_qt.get_checked() + for index in range(cfg.widget_dialog.ui.listWidget.count()): + if (cfg.widget_dialog.ui.listWidget.item(0).checkState() + == cfg.util_qt.get_checked()): + cfg.widget_dialog.ui.listWidget.item(index).setCheckState( + state + ) + else: + cfg.widget_dialog.ui.listWidget.item(index).setCheckState( + state + ) + + +# function to explain import QTableWidget +def explain_q_table_widget(): + assert QTableWidget + + +# add color composite +def add_composite(): + cfg.utils.set_rgb_color_composite(composite='3-2-1') diff --git a/interface/classification_report_tab.py b/interface/classification_report_tab.py new file mode 100755 index 0000000..83672ac --- /dev/null +++ b/interface/classification_report_tab.py @@ -0,0 +1,101 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Classification report. + +This tool allows for the classification report. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# calculate classification report if click on button +def calculate_classification_report(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save classification report'), '', '*.csv', 'csv' + ) + if output_path is not False: + if not output_path.lower().endswith('.csv'): + output_path += '.csv' + cfg.logger.log.info( + 'calculate_classification_report: %s' + % output_path + ) + classification_layer = ( + cfg.dialog.ui.classification_report_name_combo.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + cfg.logger.log.debug('classification: %s' % classification) + # No data value + if cfg.dialog.ui.nodata_checkBox.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_2.value() + else: + nodata = None + cfg.ui_utils.add_progress_bar() + output = cfg.rs.raster_report( + raster_path=classification, output_path=output_path, + nodata_value=nodata + ) + if output.check: + output_table = output.path + if cfg.utils.check_file(output_table): + with open(output_table, 'r') as f: + text = f.read() + cfg.dialog.ui.report_textBrowser.setText( + text.replace(',', '\t') + ) + cfg.dialog.ui.toolBox_class_report.setCurrentIndex(1) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + classification_layer = ( + cfg.dialog.ui.classification_report_name_combo.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + # No data value + if cfg.dialog.ui.nodata_checkBox.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_2.value() + else: + nodata = None + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# classification report \n' + 'rs.raster_report(raster_path="%s", output_path="%s", ' + 'nodata_value=%s)' + % (str(classification), str(output_path), str(nodata))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/classification_tab.py b/interface/classification_tab.py new file mode 100755 index 0000000..d5d3583 --- /dev/null +++ b/interface/classification_tab.py @@ -0,0 +1,764 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Classification. + +This tool allows for classification of band set. +""" + +from copy import deepcopy + +# import the PyQt libraries +from PyQt5.QtGui import QIcon, QPixmap, QCursor + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# set variable for macroclass classification +def macroclass_radio(): + if cfg.dialog.ui.macroclass_radioButton.isChecked() is True: + cfg.dialog.ui.class_radioButton.blockSignals(True) + cfg.dialog.ui.class_radioButton.setChecked(0) + cfg.dialog.ui.class_radioButton.blockSignals(False) + else: + cfg.dialog.ui.macroclass_radioButton.blockSignals(True) + cfg.dialog.ui.macroclass_radioButton.setChecked(1) + cfg.dialog.ui.macroclass_radioButton.blockSignals(False) + + +# set variable for class classification +def class_radio(): + if cfg.dialog.ui.class_radioButton.isChecked() is True: + cfg.dialog.ui.macroclass_radioButton.blockSignals(True) + cfg.dialog.ui.macroclass_radioButton.setChecked(0) + cfg.dialog.ui.macroclass_radioButton.blockSignals(False) + else: + cfg.dialog.ui.class_radioButton.blockSignals(True) + cfg.dialog.ui.class_radioButton.setChecked(1) + cfg.dialog.ui.class_radioButton.blockSignals(False) + + +# set variable for scaling +def z_scaling_radio(): + if cfg.dialog.ui.z_score_radioButton.isChecked() is True: + cfg.dialog.ui.linear_scaling_radioButton.blockSignals(True) + cfg.dialog.ui.linear_scaling_radioButton.setChecked(0) + cfg.dialog.ui.linear_scaling_radioButton.blockSignals(False) + else: + cfg.dialog.ui.z_score_radioButton.blockSignals(True) + cfg.dialog.ui.z_score_radioButton.setChecked(1) + cfg.dialog.ui.z_score_radioButton.blockSignals(False) + + +# set variable for scaling +def linear_scaling_radio(): + if cfg.dialog.ui.linear_scaling_radioButton.isChecked() is True: + cfg.dialog.ui.z_score_radioButton.blockSignals(True) + cfg.dialog.ui.z_score_radioButton.setChecked(0) + cfg.dialog.ui.z_score_radioButton.blockSignals(False) + else: + cfg.dialog.ui.linear_scaling_radioButton.blockSignals(True) + cfg.dialog.ui.linear_scaling_radioButton.setChecked(1) + cfg.dialog.ui.linear_scaling_radioButton.blockSignals(False) + + +# changed tab +def changed_tab(index): + icon = QIcon() + icon.addPixmap( + QPixmap( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_options.svg' + ), QIcon.Normal, QIcon.Off + ) + count = cfg.dialog.ui.toolBox_classification.count() + for position in range(0, count): + cfg.dialog.ui.toolBox_classification.setItemIcon(position, QIcon()) + cfg.dialog.ui.toolBox_classification.setItemIcon(index, icon) + # reset classifier + cfg.classifier_preview = None + + +# load classifier +def open_classifier(): + file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a classifier file'), '', + 'Classifier (*%s)' % cfg.rs.configurations.rsmo_suffix + ) + if len(file) > 0: + cfg.dialog.ui.label_classifier.setText(file) + temp_dir = cfg.rs.configurations.temp.create_temporary_directory() + file_list = cfg.rs.files_directories.unzip_file(file, temp_dir) + # open classification framework + for f in file_list: + f_name = cfg.rs.files_directories.file_name(f) + if f_name == cfg.rs.configurations.classification_framework: + with open(f, 'r') as f_file: + classification_framework = f_file.read() + lines = classification_framework.split( + cfg.rs.configurations.new_line + ) + for line in lines: + variable = line.split('=') + if (variable[0] == + cfg.rs.configurations.algorithm_name_framework): + algorithm_name = variable[1] + cfg.dialog.ui.name_classifier.setText(algorithm_name) + break + break + else: + cfg.dialog.ui.label_classifier.setText('') + cfg.dialog.ui.name_classifier.setText('') + + +# apply symbology to classification +def apply_class_symbology(classification_raster, macroclass): + value_name, value_color = cfg.scp_dock.export_symbology(macroclass) + cfg.utils.classification_raster_symbol( + classification_layer=classification_raster, + value_name_dictionary=value_name, value_color_dictionary=value_color + ) + + +# perform classification +def run_classification_action(): + run_classifier() + + +# save classifier +def save_classifier_action(): + output = run_classifier(save_classifier=True) + return output + + +# perform classification +def run_classifier(save_classifier=None, preview_point=None): + threshold = False + signature_raster = False + cross_validation = True + find_best_estimator = False + classification_confidence = False + input_normalization = load_classifier = class_weight = None + rf_max_features = rf_number_trees = rf_min_samples_split = svm_c = None + svm_gamma = svm_kernel = mlp_hidden_layer_sizes = None + mlp_training_portion = mlp_alpha = mlp_learning_rate_init = None + mlp_max_iter = mlp_batch_size = mlp_activation = None + cfg.rs.configurations.action = True + # if not preview ask for output file + if preview_point is None: + if save_classifier is True: + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save classifier'), '', + 'Classifier file (*%s)' % cfg.rs.configurations.rsmo_suffix + ) + else: + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save classification'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + else: + # path for preview + output_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.vrt' + ) + if output_path is False: + return + else: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + cfg.logger.log.info('run_classifier: %s' % output_path) + # load classifier + if len(cfg.dialog.ui.label_classifier.text()) > 0: + load_classifier = cfg.dialog.ui.label_classifier.text() + # get bandset + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_12.value() + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + classifier_index = cfg.dialog.ui.toolBox_classification.currentIndex() + classifier_list = [ + cfg.rs.configurations.maximum_likelihood, + cfg.rs.configurations.minimum_distance, + cfg.rs.configurations.multi_layer_perceptron, + cfg.rs.configurations.random_forest, + cfg.rs.configurations.spectral_angle_mapping, + cfg.rs.configurations.support_vector_machine + ] + classifier_name = classifier_list[classifier_index] + if cfg.dialog.ui.macroclass_radioButton.isChecked() is True: + macroclass = True + else: + macroclass = False + if cfg.dialog.ui.input_normalization_checkBox.isChecked() is True: + if cfg.dialog.ui.z_score_radioButton.isChecked() is True: + input_normalization = cfg.rs.configurations.z_score + else: + input_normalization = cfg.rs.configurations.linear_scaling + if cfg.scp_training is None: + cfg.mx.msg_war_5() + return False + if (cfg.scp_training.signature_catalog is None + or cfg.scp_training.signature_catalog is False): + cfg.mx.msg_war_5() + return False + else: + signature_catalog = cfg.scp_training.signature_catalog + if save_classifier is True: + only_fit = True + else: + only_fit = False + # maximum likelihood + if classifier_name == cfg.rs.configurations.maximum_likelihood: + if cfg.dialog.ui.single_threshold_checkBox.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_2.value() + if cfg.dialog.ui.single_threshold_checkBox_2.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox_3.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox.isChecked() is True: + classification_confidence = True + # minimum distance + elif classifier_name == cfg.rs.configurations.minimum_distance: + if cfg.dialog.ui.single_threshold_checkBox_4.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_4.value() + if cfg.dialog.ui.single_threshold_checkBox_3.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox_2.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox_2.isChecked() is True: + classification_confidence = True + # multi layer perceptron + elif classifier_name == cfg.rs.configurations.multi_layer_perceptron: + if cfg.dialog.ui.pytorch_radioButton.isChecked() is True: + classifier_name = ( + cfg.rs.configurations.pytorch_multi_layer_perceptron + ) + if cfg.dialog.ui.best_estimator_checkBox_2.isChecked() is True: + find_best_estimator = int(cfg.dialog.ui.steps_SpinBox_2.value()) + if cfg.dialog.ui.cross_validation_checkBox_3.isChecked() is True: + cross_validation = True + else: + cross_validation = False + mlp_training_portion = ( + cfg.dialog.ui.training_proportion_SpinBox.value()) + mlp_learning_rate_init = cfg.dialog.ui.learning_rate_SpinBox.value() + mlp_alpha = cfg.dialog.ui.alpha_SpinBox.value() + mlp_max_iter = int(cfg.dialog.ui.max_iterations_SpinBox.value()) + try: + mlp_batch_size = int(cfg.dialog.ui.batch_size_lineEdit.text()) + except Exception as err: + str(err) + mlp_batch_size = 'auto' + mlp_activation = cfg.dialog.ui.activation_lineEdit.text() + hidden_layers = cfg.dialog.ui.hidden_layers_lineEdit.text() + try: + mlp_hidden_layer_sizes = eval('[%s]' % hidden_layers) + except Exception as err: + mlp_hidden_layer_sizes = [100] + cfg.mx.msg_war_2() + str(err) + if cfg.dialog.ui.confidence_raster_checkBox_3.isChecked() is True: + classification_confidence = True + # random forest + elif classifier_name == cfg.rs.configurations.random_forest: + if cfg.dialog.ui.best_estimator_checkBox.isChecked() is True: + find_best_estimator = int(cfg.dialog.ui.steps_SpinBox.value()) + if cfg.dialog.ui.ovr_checkBox.isChecked() is True: + classifier_name = cfg.rs.configurations.random_forest_ovr + if cfg.dialog.ui.class_weight_checkBox.isChecked() is True: + class_weight = 'balanced' + if cfg.dialog.ui.cross_validation_checkBox_2.isChecked() is True: + cross_validation = True + else: + cross_validation = False + rf_number_trees = int(cfg.dialog.ui.number_trees_SpinBox.value()) + rf_min_samples_split = int(cfg.dialog.ui.min_split_SpinBox.value()) + if len(cfg.dialog.ui.max_features_lineEdit.text()) > 0: + if cfg.dialog.ui.max_features_lineEdit.text() == 'sqrt': + rf_max_features = 'sqrt' + else: + try: + rf_max_features = float( + cfg.dialog.ui.max_features_lineEdit.text() + ) + except Exception as err: + str(err) + if cfg.dialog.ui.confidence_raster_checkBox_4.isChecked() is True: + classification_confidence = True + # spectral angle mapping + elif classifier_name == cfg.rs.configurations.spectral_angle_mapping: + if cfg.dialog.ui.single_threshold_checkBox_6.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_3.value() + if cfg.dialog.ui.single_threshold_checkBox_5.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox_5.isChecked() is True: + classification_confidence = True + # SVM + elif classifier_name == cfg.rs.configurations.support_vector_machine: + svm_c = cfg.dialog.ui.param_c_SpinBox.value() + if len(cfg.dialog.ui.gamma_lineEdit.text()) > 0: + if cfg.dialog.ui.gamma_lineEdit.text() == 'scale': + svm_gamma = 'scale' + elif cfg.dialog.ui.gamma_lineEdit.text() == 'auto': + svm_gamma = 'auto' + else: + try: + svm_gamma = float(cfg.dialog.ui.gamma_lineEdit.text()) + except Exception as err: + str(err) + if len(cfg.dialog.ui.kernel_lineEdit.text()) > 0: + svm_kernel = cfg.dialog.ui.kernel_lineEdit.text() + if cfg.dialog.ui.best_estimator_checkBox_3.isChecked() is True: + find_best_estimator = int(cfg.dialog.ui.steps_SpinBox_3.value()) + if cfg.dialog.ui.cross_validation_checkBox.isChecked() is True: + cross_validation = True + else: + cross_validation = False + if cfg.dialog.ui.class_weight_checkBox_2.isChecked() is True: + class_weight = 'balanced' + if cfg.dialog.ui.confidence_raster_checkBox_6.isChecked() is True: + classification_confidence = True + cfg.logger.log.debug( + 'input_bands: %s; output_path: %s; spectral_signatures: %s;' + 'macroclass: %s; algorithm_name: %s; threshold: %s; ' + 'cross_validation: %s; signature_raster: %s; input_normalization: %s; ' + 'load_classifier: %s; class_weight_ %s; find_best_estimator: %s; ' + 'rf_max_features: %s; rf_number_trees: %s; rf_min_samples_split: %s; ' + 'svm_c: %s; svm_gamma: %s; svm_kernel: %s; mlp_training_portion: %s;' + 'mlp_alpha: %s; mlp_learning_rate_init: %s; mlp_max_iter: %s;' + ' mlp_batch_size: %s; mlp_activation: %s; mlp_hidden_layer_sizes: %s; ' + 'classification_confidence: %s; only_fit: %s; save_classifier: %s' % + (bandset_number, output_path, signature_catalog, macroclass, + classifier_name, threshold, cross_validation, signature_raster, + input_normalization, load_classifier, class_weight, + find_best_estimator, rf_max_features, rf_number_trees, + rf_min_samples_split, svm_c, svm_gamma, svm_kernel, + mlp_training_portion, mlp_alpha, mlp_learning_rate_init, mlp_max_iter, + mlp_batch_size, mlp_activation, mlp_hidden_layer_sizes, + classification_confidence, only_fit, save_classifier) + ) + # get bandset + bandset_x = cfg.bandset_catalog.get(bandset_number) + if bandset_x is None: + cfg.mx.msg_war_6(bandset_number) + return + band_count = bandset_x.get_band_count() + cfg.logger.log.debug('bandset band count: %s' % (str(band_count))) + if band_count == 0: + cfg.mx.msg_war_6(bandset_number) + return + cfg.ui_utils.add_progress_bar() + # classification + if preview_point is None: + bandset = bandset_number + # classification preview + else: + cfg.logger.log.debug( + 'preview_point x: %s; y: %s' + % (str(preview_point.x()), + str(preview_point.y())) + ) + # subset bandset + preview_size = cfg.project_registry[cfg.reg_preview_size] + # prepare virtual raster of input + dummy_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.vrt' + ) + prepared = cfg.rs.shared_tools.prepare_process_files( + input_bands=bandset_number, output_path=dummy_path, + bandset_catalog=cfg.bandset_catalog + ) + temporary_virtual_raster = prepared['temporary_virtual_raster'] + if type(temporary_virtual_raster) is list: + temporary_virtual_raster = temporary_virtual_raster[0] + # get pixel size + x_size, y_size = cfg.util_gdal.get_pixel_size(temporary_virtual_raster) + # calculate preview window + left = preview_point.x() - (x_size * preview_size) / 2 + top = preview_point.y() + (y_size * preview_size) / 2 + right = preview_point.x() + (x_size * preview_size) / 2 + bottom = preview_point.y() - (y_size * preview_size) / 2 + # copy bandset and subset + bandset = deepcopy(bandset_x) + bandset.box_coordinate_list = [left, top, right, bottom] + cfg.logger.log.debug( + 'bandset.box_coordinate_list: %s' + % str([left, top, right, bottom]) + ) + # load classifier + if load_classifier is None: + # classifier path + classifier_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix=cfg.rs.configurations.rsmo_suffix + ) + # calculate from training on the whole bandset + if cfg.classifier_preview is None: + # run classification + fit_classifier = cfg.rs.band_classification( + only_fit=True, save_classifier=True, + input_bands=bandset_number, output_path=classifier_path, + spectral_signatures=signature_catalog, + macroclass=macroclass, algorithm_name=classifier_name, + bandset_catalog=cfg.bandset_catalog, threshold=threshold, + signature_raster=signature_raster, + cross_validation=cross_validation, + input_normalization=input_normalization, + load_classifier=load_classifier, class_weight=class_weight, + find_best_estimator=find_best_estimator, + rf_max_features=rf_max_features, + rf_number_trees=rf_number_trees, + rf_min_samples_split=rf_min_samples_split, + svm_c=svm_c, svm_gamma=svm_gamma, svm_kernel=svm_kernel, + mlp_training_portion=mlp_training_portion, + mlp_alpha=mlp_alpha, + mlp_learning_rate_init=mlp_learning_rate_init, + mlp_max_iter=mlp_max_iter, mlp_batch_size=mlp_batch_size, + mlp_activation=mlp_activation, + mlp_hidden_layer_sizes=mlp_hidden_layer_sizes, + classification_confidence=classification_confidence + ) + if fit_classifier.check: + only_fit = False + save_classifier = False + cfg.classifier_preview = fit_classifier.extra['model_path'] + cfg.logger.log.debug( + 'cfg.classifier_preview: %s' + % cfg.classifier_preview + ) + else: + cfg.mx.msg_err_1() + return + # load classifier + load_classifier = cfg.classifier_preview + # run classification + output = cfg.rs.band_classification( + input_bands=bandset, output_path=output_path, + spectral_signatures=signature_catalog, + macroclass=macroclass, algorithm_name=classifier_name, + bandset_catalog=cfg.bandset_catalog, threshold=threshold, + signature_raster=signature_raster, cross_validation=cross_validation, + input_normalization=input_normalization, + load_classifier=load_classifier, class_weight=class_weight, + find_best_estimator=find_best_estimator, + rf_max_features=rf_max_features, rf_number_trees=rf_number_trees, + rf_min_samples_split=rf_min_samples_split, + svm_c=svm_c, svm_gamma=svm_gamma, svm_kernel=svm_kernel, + mlp_training_portion=mlp_training_portion, + mlp_alpha=mlp_alpha, mlp_learning_rate_init=mlp_learning_rate_init, + mlp_max_iter=mlp_max_iter, mlp_batch_size=mlp_batch_size, + mlp_activation=mlp_activation, + mlp_hidden_layer_sizes=mlp_hidden_layer_sizes, + classification_confidence=classification_confidence, + only_fit=only_fit, save_classifier=save_classifier + ) + if output.check: + if save_classifier is not True and preview_point is None: + output_raster = output.path + # add raster to layers + raster = cfg.util_qgis.add_raster_layer(output_raster) + cfg.util_qgis.move_layer_to_top(raster) + # apply symbology + apply_class_symbology(raster, macroclass) + name = cfg.rs.files_directories.file_name(output_raster) + directory = cfg.rs.files_directories.parent_directory(output_raster) + cfg.util_qgis.save_qml_style( + raster, '%s/%s.qml' % (directory, name) + ) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + return output + + +# create classification preview +def create_preview(preview_point): + point = cfg.utils.check_point_in_image(point=preview_point) + if point is False: + cfg.mx.msg_war_3() + return False + cfg.preview_point = point + output = run_classifier(preview_point=point) + if output.check: + output_raster = output.path + # move previous preview to group + group = cfg.util_qgis.group_index( + cfg.qgis_registry[cfg.reg_group_name] + ) + if group is None: + group = cfg.util_qgis.create_group( + cfg.qgis_registry[cfg.reg_group_name] + ) + if cfg.classification_preview is not None: + cfg.util_qgis.move_layer( + cfg.classification_preview, + cfg.qgis_registry[cfg.reg_group_name] + ) + # add preview + cfg.classification_preview = cfg.util_qgis.add_raster_layer( + output_raster + ) + if cfg.dialog.ui.macroclass_radioButton.isChecked() is True: + macroclass = True + else: + macroclass = False + # apply symbology + apply_class_symbology(cfg.classification_preview, macroclass) + # move to top + cfg.util_qgis.move_layer_to_top(cfg.classification_preview) + cfg.util_qgis.set_group_visible(group, False) + cfg.util_qgis.set_group_expanded(group, False) + cfg.show_preview_radioButton2.setChecked(True) + # enable map canvas render + cfg.map_canvas.setRenderFlag(True) + # enable Redo button + cfg.redoPreviewButton.setEnabled(True) + else: + cfg.mx.msg_err_1() + + +# activate pointer for classification preview +def pointer_classification_preview_active(): + cfg.map_canvas.setMapTool(cfg.classification_preview_pointer) + cursor = QCursor(QPixmap(':/pointer/icons/pointer/ROI_pointer.svg')) + cfg.map_canvas.setCursor(cursor) + + +# left click pointer +def pointer_left_click(point): + create_preview(point) + + +# right click pointer +def pointer_right_click(point): + create_preview(point) + + +# set script button +def set_script(): + output_path = 'output_path' + macroclass = classifier_name = threshold = signature_raster = None + cross_validation = input_normalization = load_classifier = None + class_weight = find_best_estimator = rf_max_features = None + rf_number_trees = rf_min_samples_split = svm_c = svm_gamma = None + svm_kernel = mlp_training_portion = mlp_alpha = None + mlp_learning_rate_init = mlp_max_iter = mlp_batch_size = None + mlp_activation = mlp_hidden_layer_sizes = classification_confidence = None + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_12.value() + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + if cfg.dialog.ui.macroclass_radioButton.isChecked() is True: + macroclass = True + else: + macroclass = False + if cfg.dialog.ui.input_normalization_checkBox.isChecked() is True: + if cfg.dialog.ui.z_score_radioButton.isChecked() is True: + input_normalization = cfg.rs.configurations.z_score + else: + input_normalization = cfg.rs.configurations.linear_scaling + if len(cfg.dialog.ui.label_classifier.text()) > 0: + load_classifier = cfg.dialog.ui.label_classifier.text() + classifier_index = cfg.dialog.ui.toolBox_classification.currentIndex() + classifier_list = [ + cfg.rs.configurations.maximum_likelihood_a, + cfg.rs.configurations.minimum_distance_a, + cfg.rs.configurations.multi_layer_perceptron_a, + cfg.rs.configurations.random_forest_a, + cfg.rs.configurations.spectral_angle_mapping_a, + cfg.rs.configurations.support_vector_machine_a + ] + classifier_name = classifier_list[classifier_index] + # maximum likelihood + if classifier_name == cfg.rs.configurations.maximum_likelihood_a: + if cfg.dialog.ui.single_threshold_checkBox.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_2.value() + if cfg.dialog.ui.single_threshold_checkBox_2.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox_3.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox.isChecked() is True: + classification_confidence = True + # minimum distance + elif classifier_name == cfg.rs.configurations.minimum_distance_a: + if cfg.dialog.ui.single_threshold_checkBox_4.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_4.value() + if cfg.dialog.ui.single_threshold_checkBox_3.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox_2.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox_2.isChecked() is True: + classification_confidence = True + # multi layer perceptron + elif classifier_name == cfg.rs.configurations.multi_layer_perceptron_a: + if cfg.dialog.ui.pytorch_radioButton.isChecked() is True: + classifier_name = ( + cfg.rs.configurations.pytorch_multi_layer_perceptron_a + ) + if cfg.dialog.ui.best_estimator_checkBox_2.isChecked() is True: + find_best_estimator = int( + cfg.dialog.ui.steps_SpinBox_2.value() + ) + if cfg.dialog.ui.cross_validation_checkBox_3.isChecked() is True: + cross_validation = True + else: + cross_validation = False + mlp_training_portion = ( + cfg.dialog.ui.training_proportion_SpinBox.value()) + mlp_learning_rate_init = ( + cfg.dialog.ui.learning_rate_SpinBox.value() + ) + mlp_alpha = cfg.dialog.ui.alpha_SpinBox.value() + mlp_max_iter = int(cfg.dialog.ui.max_iterations_SpinBox.value()) + try: + mlp_batch_size = int(cfg.dialog.ui.batch_size_lineEdit.text()) + except Exception as err: + str(err) + mlp_batch_size = 'auto' + mlp_activation = cfg.dialog.ui.activation_lineEdit.text() + hidden_layers = cfg.dialog.ui.hidden_layers_lineEdit.text() + try: + mlp_hidden_layer_sizes = eval('[%s]' % hidden_layers) + except Exception as err: + mlp_hidden_layer_sizes = [100] + cfg.mx.msg_war_2() + str(err) + if cfg.dialog.ui.confidence_raster_checkBox_3.isChecked() is True: + classification_confidence = True + # random forest + elif classifier_name == cfg.rs.configurations.random_forest_a: + if cfg.dialog.ui.best_estimator_checkBox.isChecked() is True: + find_best_estimator = int(cfg.dialog.ui.steps_SpinBox.value()) + if cfg.dialog.ui.ovr_checkBox.isChecked() is True: + classifier_name = cfg.rs.configurations.random_forest_a_ovr + if cfg.dialog.ui.class_weight_checkBox.isChecked() is True: + class_weight = 'balanced' + if cfg.dialog.ui.cross_validation_checkBox_2.isChecked() is True: + cross_validation = True + else: + cross_validation = False + rf_number_trees = int(cfg.dialog.ui.number_trees_SpinBox.value()) + rf_min_samples_split = int(cfg.dialog.ui.min_split_SpinBox.value()) + if len(cfg.dialog.ui.max_features_lineEdit.text()) > 0: + if cfg.dialog.ui.max_features_lineEdit.text() == 'sqrt': + rf_max_features = 'sqrt' + else: + try: + rf_max_features = float( + cfg.dialog.ui.max_features_lineEdit.text() + ) + except Exception as err: + str(err) + if cfg.dialog.ui.confidence_raster_checkBox_4.isChecked() is True: + classification_confidence = True + # spectral angle mapping + elif classifier_name == cfg.rs.configurations.spectral_angle_mapping_a: + if cfg.dialog.ui.single_threshold_checkBox_6.isChecked() is True: + threshold = cfg.dialog.ui.alg_threshold_SpinBox_3.value() + if cfg.dialog.ui.single_threshold_checkBox_5.isChecked() is True: + threshold = True + if cfg.dialog.ui.signature_raster_checkBox.isChecked() is True: + signature_raster = True + if cfg.dialog.ui.confidence_raster_checkBox_5.isChecked() is True: + classification_confidence = True + # SVM + elif classifier_name == cfg.rs.configurations.support_vector_machine_a: + svm_c = cfg.dialog.ui.param_c_SpinBox.value() + if len(cfg.dialog.ui.gamma_lineEdit.text()) > 0: + if cfg.dialog.ui.gamma_lineEdit.text() == 'scale': + svm_gamma = 'scale' + elif cfg.dialog.ui.gamma_lineEdit.text() == 'auto': + svm_gamma = 'auto' + else: + try: + svm_gamma = float(cfg.dialog.ui.gamma_lineEdit.text()) + except Exception as err: + str(err) + if len(cfg.dialog.ui.kernel_lineEdit.text()) > 0: + svm_kernel = cfg.dialog.ui.kernel_lineEdit.text() + if cfg.dialog.ui.best_estimator_checkBox_3.isChecked() is True: + find_best_estimator = int( + cfg.dialog.ui.steps_SpinBox_3.value() + ) + if cfg.dialog.ui.cross_validation_checkBox.isChecked() is True: + cross_validation = True + else: + cross_validation = False + if cfg.dialog.ui.class_weight_checkBox_2.isChecked() is True: + class_weight = 'balanced' + if cfg.dialog.ui.confidence_raster_checkBox_6.isChecked() is True: + classification_confidence = True + # get input band paths + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + if cfg.scp_training is None: + training_path = 'training_path' + else: + training_path = cfg.scp_training.output_path + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# classification (input files from bandset)\n' + 'rs.band_classification(input_bands=%s, output_path="%s", ' + 'spectral_signatures="%s", macroclass=%s, algorithm_name="%s", ' + 'threshold="%s", signature_raster=%s, cross_validation=%s,' + 'input_normalization="%s", load_classifier="%s", ' + 'class_weight="%s", find_best_estimator=%s, ' + 'rf_max_features=%s, rf_number_trees=%s, ' + 'rf_min_samples_split=%s, svm_c=%s, svm_gamma="%s", ' + 'svm_kernel="%s", mlp_training_portion="%s", ' + 'mlp_alpha=%s, mlp_learning_rate_init=%s, mlp_max_iter=%s, ' + 'mlp_batch_size="%s", mlp_activation="%s", ' + 'mlp_hidden_layer_sizes=%s, classification_confidence=%s)' + % (str(paths), str(output_path), + str(training_path), macroclass, + str(classifier_name), str(threshold), + str(signature_raster), str(cross_validation), + str(input_normalization), str(load_classifier), + str(class_weight), str(find_best_estimator), + str(rf_max_features), str(rf_number_trees), + str(rf_min_samples_split), str(svm_c), str(svm_gamma), + str(svm_kernel), str(mlp_training_portion), str(mlp_alpha), + str(mlp_learning_rate_init), str(mlp_max_iter), + str(mlp_batch_size), str(mlp_activation), + str(mlp_hidden_layer_sizes), str(classification_confidence) + )) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/classification_to_vector_tab.py b/interface/classification_to_vector_tab.py new file mode 100755 index 0000000..f22dc23 --- /dev/null +++ b/interface/classification_to_vector_tab.py @@ -0,0 +1,121 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Classification to vector. + +This tool allows for the conversion from raster to vector. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# convert classification to vector +def convert_classification_to_vector_action(): + convert_classification_to_vector() + + +# convert classification to vector +def convert_classification_to_vector(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save vector output'), '', '*.gpkg', 'gpkg' + ) + if output_path is not False: + if not output_path.lower().endswith('.gpkg'): + output_path += '.gpkg' + cfg.logger.log.info( + 'convert_classification_to_vector: %s' + % output_path + ) + classification_layer = ( + cfg.dialog.ui.classification_vector_name_combo.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + try: + if (cfg.dialog.ui.class_macroclass_comboBox.currentText() + == 'MC_ID'): + macroclass = True + else: + macroclass = False + value_name_dictionary, value_color_dictionary = ( + cfg.scp_dock.export_symbology(macroclass) + ) + except Exception as err: + str(err) + value_name_dictionary = value_color_dictionary = None + if cfg.dialog.ui.dissolve_output_checkBox.isChecked() is True: + dissolve = True + else: + dissolve = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.raster_to_vector( + raster_path=classification, output_path=output_path, + dissolve=dissolve + ) + if output.check: + output_vector = output.path + layer = cfg.util_qgis.add_vector_layer(path=output_vector) + if (cfg.dialog.ui.use_class_code_checkBox.isChecked() is True + and value_name_dictionary is not None): + cfg.utils.vector_symbol( + layer, value_name_dictionary, value_color_dictionary + ) + # save qml file + name = cfg.rs.files_directories.file_name(output_vector) + cfg.util_qgis.save_qml_style( + layer, ''.join( + [cfg.utils.directory_name(output_vector), '/', name, + '.qml'] + ) + ) + cfg.util_qgis.add_layer_to_map(layer) + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + classification_layer = ( + cfg.dialog.ui.classification_vector_name_combo.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + if cfg.dialog.ui.dissolve_output_checkBox.isChecked() is True: + dissolve = True + else: + dissolve = False + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# classification to vector \n' + 'rs.raster_to_vector(raster_path="%s", output_path="%s", ' + 'dissolve=%s)' + % (str(classification), str(output_path), str(dissolve))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/clip_bands_tab.py b/interface/clip_bands_tab.py new file mode 100755 index 0000000..767e436 --- /dev/null +++ b/interface/clip_bands_tab.py @@ -0,0 +1,479 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Band clip. + +This tool allows for clipping bands. +""" + +from PyQt5.QtCore import QPointF +from PyQt5.QtGui import QPolygonF, QColor, QPixmap, QCursor +from qgis.core import QgsGeometry +from qgis.gui import QgsRubberBand + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# add rubber polygon +def add_rubber_polygon(upper_left_point, lower_right_point): + try: + clear_canvas_poly() + except Exception as err: + str(err) + cfg.clip_rubber_poly = QgsRubberBand( + cfg.map_canvas, cfg.util_qgis.get_qgis_wkb_types().LineGeometry + ) + point_f = QPointF() + poly_f = QPolygonF() + point_f.setX(upper_left_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + point_f.setX(lower_right_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + point_f.setX(lower_right_point.x()) + point_f.setY(lower_right_point.y()) + poly_f.append(point_f) + point_f.setX(upper_left_point.x()) + point_f.setY(lower_right_point.y()) + poly_f.append(point_f) + point_f.setX(upper_left_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + geometry = QgsGeometry().fromQPolygonF(poly_f) + # noinspection PyTypeChecker + cfg.clip_rubber_poly.setToGeometry(geometry, None) + clr = QColor("#ff0000") + clr.setAlpha(50) + cfg.clip_rubber_poly.setFillColor(clr) + cfg.clip_rubber_poly.setWidth(3) + + +# clear canvas +def clear_canvas_poly(): + cfg.clip_rubber_poly.reset() + cfg.map_canvas.refresh() + + +# activate pointer +def pointer_active(): + cfg.map_canvas.setMapTool(cfg.clip_bands_pointer) + cursor = QCursor(QPixmap(':/pointer/icons/pointer/ROI_pointer.svg')) + cfg.map_canvas.setCursor(cursor) + + +# left click pointer +def pointer_left_click(point): + pointer_click_ul(point) + + +# right click pointer +def pointer_right_click(point): + pointer_click_lr(point) + + +# set coordinates +def pointer_click_lr(point): + cfg.dialog.ui.LX_lineEdit.setText(str(point.x())) + cfg.dialog.ui.LY_lineEdit.setText(str(point.y())) + show_area() + + +# set coordinates +def pointer_click_ul(point): + cfg.dialog.ui.UX_lineEdit.setText(str(point.x())) + cfg.dialog.ui.UY_lineEdit.setText(str(point.y())) + show_area() + + +# show area +def show_area(): + try: + add_rubber_polygon( + cfg.util_qgis.create_qgis_point( + float(cfg.dialog.ui.UX_lineEdit.text()), + float(cfg.dialog.ui.UY_lineEdit.text()) + ), + cfg.util_qgis.create_qgis_point( + float(cfg.dialog.ui.LX_lineEdit.text()), + float(cfg.dialog.ui.LY_lineEdit.text()) + ) + ) + except Exception as err: + str(err) + + +# refresh shape and training list +def refresh_layers(): + cfg.utils.refresh_vector_layer() + + +# show hide area radio button +def show_hide_area(): + try: + if cfg.dialog.ui.show_area_radioButton_3.isChecked(): + show_area() + else: + clear_canvas_poly() + except Exception as err: + str(err) + + +# radio changed +def vector_changed(): + cfg.dialog.ui.coordinates_radioButton.blockSignals(True) + cfg.dialog.ui.vector_radioButton.blockSignals(True) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(True) + if cfg.dialog.ui.vector_radioButton.isChecked(): + cfg.dialog.ui.coordinates_radioButton.setChecked(0) + cfg.dialog.ui.temporary_ROI_radioButton.setChecked(0) + cfg.dialog.ui.coordinates_radioButton.blockSignals(False) + cfg.dialog.ui.vector_radioButton.blockSignals(False) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(False) + + +# radio changed +def roi_changed(): + cfg.dialog.ui.coordinates_radioButton.blockSignals(True) + cfg.dialog.ui.vector_radioButton.blockSignals(True) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(True) + if cfg.dialog.ui.temporary_ROI_radioButton.isChecked(): + cfg.dialog.ui.vector_radioButton.setChecked(0) + cfg.dialog.ui.coordinates_radioButton.setChecked(0) + cfg.dialog.ui.coordinates_radioButton.blockSignals(False) + cfg.dialog.ui.vector_radioButton.blockSignals(False) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(False) + + +# radio changed +def coordinates_changed(): + cfg.dialog.ui.coordinates_radioButton.blockSignals(True) + cfg.dialog.ui.vector_radioButton.blockSignals(True) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(True) + if cfg.dialog.ui.coordinates_radioButton.isChecked(): + cfg.dialog.ui.vector_radioButton.setChecked(0) + cfg.dialog.ui.temporary_ROI_radioButton.setChecked(0) + cfg.dialog.ui.coordinates_radioButton.blockSignals(False) + cfg.dialog.ui.vector_radioButton.blockSignals(False) + cfg.dialog.ui.temporary_ROI_radioButton.blockSignals(False) + + +# reference layer name +def reference_layer_name(): + reference = cfg.dialog.ui.shapefile_comboBox.currentText() + cfg.dialog.ui.class_field_comboBox_3.clear() + layer = cfg.util_qgis.select_layer_by_name(reference) + try: + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + fields = layer.dataProvider().fields() + for field in fields: + if str(field.typeName()).lower() != 'string': + cfg.dialog.class_field_combo_3(str(field.name())) + except Exception as err: + str(err) + + +# clip bands action +def clip_bands_action(): + clip_bands() + + +# clip bands +def clip_bands(): + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('clip_bands: %s' % output_path) + output_name = cfg.dialog.ui.output_clip_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_2.value() + # nodata value + if cfg.dialog.ui.clip_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + reference = vector_field = extent_list = None + # use vector + if cfg.dialog.ui.vector_radioButton.isChecked() is True: + reference_layer = cfg.dialog.ui.shapefile_comboBox.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + # vector EPSG + if ('Polygon?crs=' in str(reference) + or 'memory?geometry=' in str(reference) + or '(memory)' in str(reference)): + # temporary layer + t_vector = cfg.utils.createTempRasterPath('gpkg') + try: + selected = cfg.utls.select_layer_by_name(reference_layer) + s = cfg.util_qgis.save_qgis_memory_layer_to_file( + selected, t_vector, file_format='GPKG' + ) + except Exception as err: + str(err) + s = cfg.util_qgis.save_qgis_memory_layer_to_file( + reference, t_vector, file_format='GPKG' + ) + reference = cfg.util_qgis.qgis_layer_source(s) + elif 'QgsVectorLayer' in str(reference): + # temporary layer + date_time = cfg.utils.get_time() + t_vector_name = cfg.temp_roi_name + date_time + '.shp' + t_vector = cfg.temp_dir + '/' + date_time + t_vector_name + # get layer crs + crs = cfg.util_gdal.get_crs_gdal(reference) + # create a temp shapefile with a field + cfg.util_gdal.create_empty_shapefile_ogr(crs, t_vector) + added_vector = cfg.util_qgis.add_vector_layer( + t_vector, t_vector_name + ) + layer = cfg.util_qgis.select_layer_by_name(reference_layer) + for f in layer.getFeatures(): + # copy ROI to temp shapefile + cfg.util_qgis.copy_feature_to_qgis_layer( + layer, f.id(), added_vector + ) + reference = t_vector + if cfg.dialog.ui.vector_field_checkBox.isChecked() is True: + vector_field = ( + cfg.dialog.ui.class_field_comboBox_3.currentText()) + # use temporary ROI + elif cfg.dialog.ui.temporary_ROI_radioButton.isChecked() is True: + if cfg.temporary_roi is not None: + # get vector from ROI + t_vector = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.shp' + ) + cfg.util_qgis.save_qgis_memory_layer_to_file( + cfg.temporary_roi, t_vector + ) + reference = t_vector + else: + return False + # use coordinates + else: + upper_x = cfg.dialog.ui.UX_lineEdit.text() + upper_y = cfg.dialog.ui.UY_lineEdit.text() + lower_x = cfg.dialog.ui.LX_lineEdit.text() + lower_y = cfg.dialog.ui.LY_lineEdit.text() + try: + clear_canvas_poly() + upper_left = cfg.util_qgis.create_qgis_point( + float(upper_x), float(upper_y) + ) + lower_right = cfg.util_qgis.create_qgis_point( + float(lower_x), float(lower_y) + ) + upper_x = lower_right.x() + upper_y = lower_right.y() + lower_x = upper_left.x() + lower_y = upper_left.y() + if float(upper_x) > float(lower_x): + upper_x = upper_left.x() + lower_x = lower_right.x() + if float(upper_y) < float(lower_y): + upper_y = upper_left.y() + lower_y = lower_right.y() + except Exception as err: + str(err) + bandset_x = cfg.bandset_catalog.get(bandset_number) + crs = bandset_x.crs + qgis_crs = cfg.util_qgis.get_qgis_crs() + if crs is None: + crs = qgis_crs + # projection of input point to bandset crs + if cfg.util_gdal.compare_crs(crs, qgis_crs) is False: + upper_left_point = cfg.util_qgis.create_qgis_point( + upper_x, upper_y + ) + lower_right_point = cfg.util_qgis.create_qgis_point( + lower_x, lower_y + ) + try: + point_1 = cfg.utils.project_qgis_point_coordinates( + upper_left_point, qgis_crs, crs + ) + point_2 = cfg.utils.project_qgis_point_coordinates( + lower_right_point, qgis_crs, crs + ) + upper_x = point_1.x() + upper_y = point_1.y() + lower_x = point_2.x() + lower_y = point_2.y() + except Exception as err: + str(err) + extent_list = [upper_x, upper_y, lower_x, lower_y] + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + cfg.logger.log.debug('reference: %s' % reference) + cfg.logger.log.debug('extent_list: %s' % extent_list) + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_clip( + input_bands=bandset_number, output_path=output_path, + vector_path=reference, vector_field=vector_field, + prefix=output_name, bandset_catalog=cfg.bandset_catalog, + extent_list=extent_list, virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + output_name = cfg.dialog.ui.output_clip_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_2.value() + # nodata value + if cfg.dialog.ui.clip_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + reference = vector_field = extent_list = None + # use vector + if cfg.dialog.ui.vector_radioButton.isChecked() is True: + reference_layer = cfg.dialog.ui.shapefile_comboBox.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + # vector EPSG + if ('Polygon?crs=' in str(reference) + or 'memory?geometry=' in str(reference) + or '(memory)' in str(reference)): + # temporary layer + t_vector = cfg.utils.createTempRasterPath('gpkg') + try: + selected = cfg.utls.select_layer_by_name(reference_layer) + s = cfg.util_qgis.save_qgis_memory_layer_to_file( + selected, t_vector, file_format='GPKG' + ) + except Exception as err: + str(err) + s = cfg.util_qgis.save_qgis_memory_layer_to_file( + reference, t_vector, file_format='GPKG' + ) + reference = cfg.util_qgis.qgis_layer_source(s) + elif 'QgsVectorLayer' in str(reference): + # temporary layer + date_time = cfg.utils.get_time() + t_vector_name = cfg.temp_roi_name + date_time + '.shp' + t_vector = cfg.temp_dir + '/' + date_time + t_vector_name + # get layer crs + crs = cfg.util_gdal.get_crs_gdal(reference) + # create a temp shapefile with a field + cfg.util_gdal.create_empty_shapefile_ogr(crs, t_vector) + added_vector = cfg.util_qgis.add_vector_layer( + t_vector, t_vector_name + ) + layer = cfg.util_qgis.select_layer_by_name(reference_layer) + for f in layer.getFeatures(): + # copy ROI to temp shapefile + cfg.util_qgis.copy_feature_to_qgis_layer( + layer, f.id(), added_vector + ) + reference = t_vector + if cfg.dialog.ui.vector_field_checkBox.isChecked() is True: + vector_field = cfg.dialog.ui.class_field_comboBox_3.currentText() + # use temporary ROI + elif cfg.dialog.ui.temporary_ROI_radioButton.isChecked() is True: + if cfg.temporary_roi is not None: + # temporary layer + t_vector = cfg.utils.createTempRasterPath('gpkg') + cfg.util_gdal.create_vector_ogr( + cfg.temporary_roi.crs(), t_vector, vector_format='GPKG' + ) + added_vector = cfg.util_qgis.add_vector_layer(t_vector) + cfg.util_qgis.copy_feature_to_qgis_layer( + cfg.temporary_roi, 1, added_vector + ) + reference = t_vector + else: + return False + # use coordinates + else: + upper_x = cfg.dialog.ui.UX_lineEdit.text() + upper_y = cfg.dialog.ui.UY_lineEdit.text() + lower_x = cfg.dialog.ui.LX_lineEdit.text() + lower_y = cfg.dialog.ui.LY_lineEdit.text() + try: + clear_canvas_poly() + upper_left = cfg.util_qgis.create_qgis_point( + float(upper_x), + float(upper_y) + ) + lower_right = cfg.util_qgis.create_qgis_point( + float(lower_x), + float(lower_y) + ) + upper_x = lower_right.x() + upper_y = lower_right.y() + lower_x = upper_left.x() + lower_y = upper_left.y() + if float(upper_x) > float(lower_x): + upper_x = upper_left.x() + lower_x = lower_right.x() + if float(upper_y) < float(lower_y): + upper_y = upper_left.y() + lower_y = lower_right.y() + except Exception as err: + str(err) + extent_list = [upper_x, upper_y, lower_x, lower_y] + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# clip raster bands (input files from bandset)\n' + 'rs.band_clip(input_bands=%s, output_path="%s", ' + 'vector_path="%s", vector_field="%s", prefix="%s", ' + 'extent_list=%s, virtual_output=%s)' + % (str(paths), str(output_path), str(reference), + str(vector_field), str(output_name), + str(extent_list), str(virtual_output))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/cross_classification_tab.py b/interface/cross_classification_tab.py new file mode 100755 index 0000000..e7b5ee3 --- /dev/null +++ b/interface/cross_classification_tab.py @@ -0,0 +1,172 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Cross classification. + +This tool allows for calculation of cross classification. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# reference layer name +def reference_layer_name(): + reference_layer = cfg.dialog.ui.reference_name_combo_2.currentText() + cfg.dialog.ui.class_field_comboBox_2.clear() + layer = cfg.util_qgis.select_layer_by_name(reference_layer) + try: + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + fields = layer.dataProvider().fields() + for field in fields: + if str(field.typeName()).lower() != 'string': + cfg.dialog.class_field_combo_2(str(field.name())) + except Exception as err: + str(err) + + +# refresh reference layer name +def refresh_reference_layer(): + # noinspection PyArgumentList + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.reference_name_combo_2.clear() + for layer in sorted(layers, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_vector(): + if (layer.wkbType() == cfg.util_qgis.get_qgis_wkb_types().Polygon + or layer.wkbType() == + cfg.util_qgis.get_qgis_wkb_types().MultiPolygon): + cfg.dialog.reference_layer_combo_2(layer.name()) + elif layer.type() == cfg.util_qgis.get_qgis_map_raster(): + if layer.bandCount() == 1: + cfg.dialog.reference_layer_combo_2(layer.name()) + + +# calculate cross classification if click on button +def cross_classification_action(): + cross_classification() + + +# cross classification calculation +def cross_classification(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save cross classification raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + cfg.logger.log.info('band_sieve: %s' % output_path) + reference_layer = cfg.dialog.ui.reference_name_combo_2.currentText() + classification_layer = ( + cfg.dialog.ui.classification_name_combo_2.currentText()) + reference = cfg.util_qgis.get_file_path(reference_layer) + classification = cfg.util_qgis.get_file_path(classification_layer) + field = cfg.dialog.ui.class_field_comboBox_2.currentText() + if len(field) == 0: + field = None + # No data value + if cfg.dialog.ui.nodata_checkBox_6.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_7.value() + else: + nodata = None + # regression + if cfg.dialog.ui.regression_raster_checkBox.isChecked() is True: + regression = True + else: + regression = None + cfg.ui_utils.add_progress_bar() + output = cfg.rs.cross_classification( + classification_path=classification, reference_path=reference, + output_path=output_path, vector_field=field, nodata_value=nodata, + regression_raster=regression + ) + if output.check: + output_raster, output_table = output.paths + # add raster to layers + raster = cfg.util_qgis.add_raster_layer(output_raster) + unique_values = output.extra['unique_values'] + cfg.utils.raster_symbol_generic( + raster, 'NoData', raster_unique_value_list=unique_values + ) + if cfg.utils.check_file(output_table): + with open(output_table, 'r') as f: + text = f.read() + cfg.dialog.ui.cross_matrix_textBrowser.setText( + text.replace(',', '\t') + ) + cfg.dialog.ui.toolBox_cross_classification.setCurrentIndex(1) + if regression: + regression_raster_b0 = output.extra['regression_raster_b0'] + regression_raster_b1 = output.extra['regression_raster_b1'] + if cfg.utils.check_file(regression_raster_b0): + cfg.util_qgis.add_raster_layer(regression_raster_b0) + if cfg.utils.check_file(regression_raster_b1): + cfg.util_qgis.add_raster_layer(regression_raster_b1) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + reference_layer = cfg.dialog.ui.reference_name_combo_2.currentText() + classification_layer = ( + cfg.dialog.ui.classification_name_combo_2.currentText()) + reference = cfg.util_qgis.get_file_path(reference_layer) + classification = cfg.util_qgis.get_file_path(classification_layer) + field = cfg.dialog.ui.class_field_comboBox_2.currentText() + if len(field) == 0: + field = None + # No data value + if cfg.dialog.ui.nodata_checkBox_6.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_7.value() + else: + nodata = None + # regression + if cfg.dialog.ui.regression_raster_checkBox.isChecked() is True: + regression = True + else: + regression = None + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# cross classification \n' + 'rs.cross_classification(classification_path="%s", ' + 'reference_path="%s", output_path="%s", ' + 'vector_field="%s", nodata_value=%s, regression_raster=%s)' + % (str(classification), str(reference), str(output_path), + str(field), str(nodata), str(regression))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/download_products_tab.py b/interface/download_products_tab.py new file mode 100755 index 0000000..fc8e66c --- /dev/null +++ b/interface/download_products_tab.py @@ -0,0 +1,914 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Download products. + +Allows for downloading products such as Landsat and Sentinel-2 datasets. +""" + +import subprocess +from re import sub +from shlex import split + +from PyQt5.QtCore import QPointF +from PyQt5.QtGui import QPolygonF, QColor, QPixmap, QCursor +from qgis.core import ( + QgsGeometry, QgsCoordinateReferenceSystem, QgsRectangle +) +from qgis.gui import QgsRubberBand + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + +""" Login data """ + + +# Earthdata user +def remember_user_earthdata(): + if cfg.dialog.ui.remember_user_checkBox_3.isChecked(): + user = cfg.dialog.ui.user_earthdata_lineEdit.text() + password = cfg.utils.encrypt_password( + cfg.dialog.ui.password_earthdata_lineEdit.text() + ) + cfg.qgis_registry[cfg.reg_earthdata_user] = user + cfg.qgis_registry[cfg.reg_earthdata_pass] = password + + +# Earthdata user checkbox +def remember_user_earthdata_checkbox(): + if cfg.dialog.ui.remember_user_checkBox_3.isChecked(): + cfg.mx.msg_box_warning( + cfg.translate('WARNING'), + cfg.translate('Password is stored unencrypted') + ) + remember_user_earthdata() + else: + cfg.qgis_registry[cfg.reg_earthdata_user] = '' + cfg.qgis_registry[cfg.reg_earthdata_pass] = '' + + +""" Interface """ + + +# add rubber polygon +def add_rubber_polygon(upper_left_point, lower_right_point): + try: + clear_canvas_poly() + except Exception as err: + str(err) + cfg.download_rubber_poly = QgsRubberBand( + cfg.map_canvas, cfg.util_qgis.get_qgis_wkb_types().LineGeometry + ) + point_f = QPointF() + poly_f = QPolygonF() + point_f.setX(upper_left_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + point_f.setX(lower_right_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + point_f.setX(lower_right_point.x()) + point_f.setY(lower_right_point.y()) + poly_f.append(point_f) + point_f.setX(upper_left_point.x()) + point_f.setY(lower_right_point.y()) + poly_f.append(point_f) + point_f.setX(upper_left_point.x()) + point_f.setY(upper_left_point.y()) + poly_f.append(point_f) + geometry = QgsGeometry().fromQPolygonF(poly_f) + # noinspection PyTypeChecker + cfg.download_rubber_poly.setToGeometry(geometry, None) + clr = QColor('#ff0000') + clr.setAlpha(50) + cfg.download_rubber_poly.setFillColor(clr) + cfg.download_rubber_poly.setWidth(3) + + +# clear canvas +def clear_canvas_poly(): + try: + cfg.download_rubber_poly.reset() + except Exception as err: + str(err) + cfg.map_canvas.refresh() + + +# activate pointer +def pointer_active(): + cfg.map_canvas.setMapTool(cfg.download_products_pointer) + cursor = QCursor(QPixmap(':/pointer/icons/pointer/ROI_pointer.svg')) + cfg.map_canvas.setCursor(cursor) + + +# left click pointer +def pointer_left_click(point): + pointer_click_ul(point) + + +# right click pointer +def pointer_right_click(point): + pointer_click_lr(point) + + +# set coordinates +def pointer_click_lr(point): + qgis_crs = cfg.util_qgis.get_qgis_crs() + # WGS84 EPSG 4326 + target_crs = QgsCoordinateReferenceSystem('EPSG:4326') + point_proj = cfg.utils.project_qgis_point_coordinates( + point, qgis_crs, + target_crs + ) + if point_proj is not False: + try: + if float(cfg.dialog.ui.UX_lineEdit_3.text()) < point_proj.x(): + cfg.dialog.ui.LX_lineEdit_3.setText(str(point_proj.x())) + else: + cfg.dialog.ui.LX_lineEdit_3.setText( + str( + cfg.dialog.ui.UX_lineEdit_3.text() + ) + ) + cfg.dialog.ui.UX_lineEdit_3.setText(str(point_proj.x())) + if float(cfg.dialog.ui.UY_lineEdit_3.text()) > point_proj.y(): + cfg.dialog.ui.LY_lineEdit_3.setText(str(point_proj.y())) + else: + cfg.dialog.ui.LY_lineEdit_3.setText( + str( + cfg.dialog.ui.UY_lineEdit_3.text() + ) + ) + cfg.dialog.ui.UY_lineEdit_3.setText(str(point_proj.y())) + except Exception as err: + str(err) + cfg.dialog.ui.LX_lineEdit_3.setText(str(point_proj.x())) + cfg.dialog.ui.LY_lineEdit_3.setText(str(point_proj.y())) + show_area() + + +# set coordinates +def pointer_click_ul(point): + qgis_crs = cfg.util_qgis.get_qgis_crs() + # WGS84 EPSG 4326 + target_crs = QgsCoordinateReferenceSystem('EPSG:4326') + point_proj = cfg.utils.project_qgis_point_coordinates( + point, qgis_crs, target_crs + ) + if point_proj is not False: + try: + if float(cfg.dialog.ui.LX_lineEdit_3.text()) > point_proj.x(): + cfg.dialog.ui.UX_lineEdit_3.setText(str(point_proj.x())) + else: + cfg.dialog.ui.UX_lineEdit_3.setText( + str( + cfg.dialog.ui.LX_lineEdit_3.text() + ) + ) + cfg.dialog.ui.LX_lineEdit_3.setText(str(point_proj.x())) + if float(cfg.dialog.ui.LY_lineEdit_3.text()) < point_proj.y(): + cfg.dialog.ui.UY_lineEdit_3.setText(str(point_proj.y())) + else: + cfg.dialog.ui.UY_lineEdit_3.setText( + str( + cfg.dialog.ui.LY_lineEdit_3.text() + ) + ) + cfg.dialog.ui.LY_lineEdit_3.setText(str(point_proj.y())) + except Exception as err: + str(err) + cfg.dialog.ui.UX_lineEdit_3.setText(str(point_proj.x())) + cfg.dialog.ui.UY_lineEdit_3.setText(str(point_proj.y())) + show_area() + + +# show area +def show_area(): + qgis_crs = cfg.util_qgis.get_qgis_crs() + # WGS84 EPSG 4326 + target_crs = QgsCoordinateReferenceSystem('EPSG:4326') + try: + upper_left = cfg.util_qgis.create_qgis_point( + float(cfg.dialog.ui.UX_lineEdit_3.text()), + float(cfg.dialog.ui.UY_lineEdit_3.text()) + ) + upper_left_proj = cfg.utils.project_qgis_point_coordinates( + upper_left, target_crs, qgis_crs + ) + lower_right = cfg.util_qgis.create_qgis_point( + float(cfg.dialog.ui.LX_lineEdit_3.text()), + float(cfg.dialog.ui.LY_lineEdit_3.text()) + ) + lower_right_proj = cfg.utils.project_qgis_point_coordinates( + lower_right, target_crs, qgis_crs + ) + add_rubber_polygon(upper_left_proj, lower_right_proj) + except Exception as err: + str(err) + + +# show hide area radio button +def show_hide_area(): + try: + if cfg.dialog.ui.show_area_radioButton_2.isChecked(): + show_area() + else: + clear_canvas_poly() + except Exception as err: + str(err) + + +# check all bands +def check_all_bands(): + if cfg.dialog.ui.checkBoxs_band_1.isChecked(): + state = 0 + else: + state = 2 + for band in range(1, 13): + eval( + 'cfg.dialog.ui.checkBoxs_band_%i.setCheckState(%i)' + % (band, state) + ) + cfg.dialog.ui.ancillary_data_checkBox.setCheckState(state) + cfg.dialog.ui.checkBoxs_band_8A.setCheckState(state) + + +""" Table """ + + +# find images +def find_images(): + perform_query() + + +# download image metadata +def perform_query(): + cfg.download_table = None + product_name = cfg.dialog.ui.landsat_satellite_combo.currentText() + date_from_qt = cfg.dialog.ui.dateEdit_from.date() + date_to_qt = cfg.dialog.ui.dateEdit_to.date() + date_from = date_from_qt.toPyDate().strftime('%Y-%m-%d') + date_to = date_to_qt.toPyDate().strftime('%Y-%m-%d') + max_cloud_cover = int(cfg.dialog.ui.cloud_cover_spinBox.value()) + result_number = int(cfg.dialog.ui.result_number_spinBox_2.value()) + cfg.logger.log.info('perform_query product_name: %s' % product_name) + try: + QgsRectangle( + float(cfg.dialog.ui.UX_lineEdit_3.text()), + float(cfg.dialog.ui.UY_lineEdit_3.text()), + float(cfg.dialog.ui.LX_lineEdit_3.text()), + float(cfg.dialog.ui.LY_lineEdit_3.text()) + ) + except Exception as err: + str(err) + cfg.mx.msg_err_3() + return False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.download_products.search( + product=product_name, date_from=date_from, date_to=date_to, + max_cloud_cover=max_cloud_cover, result_number=result_number, + coordinate_list=[float(cfg.dialog.ui.UX_lineEdit_3.text()), + float(cfg.dialog.ui.UY_lineEdit_3.text()), + float(cfg.dialog.ui.LX_lineEdit_3.text()), + float(cfg.dialog.ui.LY_lineEdit_3.text())] + ) + cfg.ui_utils.remove_progress_bar() + if output.check: + product_table = output.extra['product_table'] + cfg.download_table = product_table + else: + return False + table = cfg.dialog.ui.download_images_tableWidget + table.blockSignals(True) + table.setSortingEnabled(False) + if product_table is None: + return False + total_products = product_table.shape[0] + for product in range(total_products): + # add rows + count = table.rowCount() + table.setRowCount(count + 1) + n = 0 + for field in product_table.dtype.names: + if str(product_table[field][product]) != 'None': + cfg.util_qt.add_table_item( + table, str(product_table[field][product]), count, n + ) + n += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + clear_canvas_poly() + + +# clear table +def clear_table(): + answer = cfg.util_qt.question_box( + cfg.translate('Clear the table'), + cfg.translate('Are you sure you want to clear the table?') + ) + if answer: + cfg.util_qt.clear_table(cfg.dialog.ui.download_images_tableWidget) + cfg.download_table = None + + +# perform filter +def filter_table(): + table = cfg.dialog.ui.download_images_tableWidget + text = cfg.dialog.ui.products_filter_lineEdit.text() + items = table.findItems(text, cfg.util_qt.get_match_contains()) + count = table.rowCount() + item_list = [] + for item in items: + item_list.append(item.row()) + table.blockSignals(True) + for i in range(0, count): + table.setRowHidden(i, False) + if i not in item_list: + table.setRowHidden(i, True) + table.blockSignals(False) + + +# remove highlighted images from table +def remove_image_from_table(): + answer = cfg.util_qt.question_box( + cfg.translate('Remove rows'), + cfg.translate( + 'Are you sure you want to remove highlighted rows ' + 'from the table?' + ) + ) + if answer is True: + table = cfg.dialog.ui.download_images_tableWidget + # list of item to remove + rows = [] + for index in table.selectedIndexes(): + rows.append(index.row()) + selected_rows = list(set(rows)) + uid_list = [] + count = table.rowCount() + for row in range(count): + if row not in selected_rows: + uid_list.append(str(table.item(row, 14).text())) + enum_list = [] + for n, uid in enumerate(cfg.download_table.uid): + if str(uid) in uid_list: + enum_list.append(n) + cfg.download_table = cfg.download_table[enum_list] + cfg.util_qt.clear_table(table) + table.blockSignals(True) + table.setSortingEnabled(False) + total_products = cfg.download_table.shape[0] + for product in range(total_products): + # add rows + count = table.rowCount() + table.setRowCount(count + 1) + n = 0 + for field in cfg.download_table.dtype.names: + if str(cfg.download_table[field][product]) != 'None': + cfg.util_qt.add_table_item( + table, str(cfg.download_table[field][product]), + count, n + ) + n += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + clear_canvas_poly() + + +# import table file +def import_table_text(): + file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a text file of product table'), '', + 'XML (*.xml)' + ) + if len(file) > 0: + open_download_table(file) + + +# export table +def export_table_to_text(): + if cfg.dialog.ui.download_images_tableWidget.rowCount() > 0: + saved = cfg.util_qt.get_save_file_name( + None, cfg.translate('Export table to file'), '', '*.xml', 'xml' + ) + if saved is not False: + if not saved.lower().endswith('.xml'): + saved += '.xml' + save_download_table(saved) + + +# save download table +def save_download_table(file=None): + if cfg.download_table is not None: + if file is None: + xml = cfg.rs.download_products.export_product_table_as_xml( + product_table=cfg.download_table + ) + # save to project + cfg.project_registry[cfg.reg_download_product_table] = xml + else: + cfg.rs.download_products.export_product_table_as_xml( + product_table=cfg.download_table, output_path=file + ) + + +# open download table +def open_download_table(file=None): + cfg.logger.log.debug('open_download_table: %s' % str(file)) + cfg.download_table = None + if file is None: + # replace + xml = cfg.project_registry[cfg.reg_download_product_table] + if len(xml) == 0: + return False + temp_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.xml' + ) + with open(temp_path, 'wb') as output_file: + output_file.write(xml) + try: + imported_table = cfg.rs.download_products.import_as_xml( + xml_path=temp_path + ) + cfg.download_table = imported_table.extra['product_table'] + except Exception as err: + cfg.logger.log.error(str(err)) + return False + else: + try: + imported_table = cfg.rs.download_products.import_as_xml( + xml_path=file + ) + cfg.download_table = imported_table.extra['product_table'] + except Exception as err: + cfg.logger.log.error(str(err)) + return False + # add rows to table + table = cfg.dialog.ui.download_images_tableWidget + table.blockSignals(True) + table.setSortingEnabled(False) + total_products = cfg.download_table.shape[0] + for product in range(total_products): + # add rows + count = table.rowCount() + table.setRowCount(count + 1) + n = 0 + for field in cfg.download_table.dtype.names: + if str(cfg.download_table[field][product]) != 'None': + cfg.util_qt.add_table_item( + table, str(cfg.download_table[field][product]), count, n + ) + n += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + + +# display images +def display_images(): + table = cfg.dialog.ui.download_images_tableWidget + ids = [] + for image_id in table.selectedIndexes(): + ids.append(image_id.row()) + image_ids = set(ids) + if len(image_ids) > 0: + progress_step = 100 / len(image_ids) + cfg.ui_utils.add_progress_bar() + # disable map canvas render for speed + cfg.map_canvas.setRenderFlag(False) + progress = 0 + for image_id in image_ids: + sat = str(table.item(image_id, 0).text()) + if sat == cfg.rs.configurations.sentinel2: + display_sentinel2(image_id) + elif (sat == cfg.rs.configurations.landsat_hls + or sat == cfg.rs.configurations.sentinel2_hls): + display_nasa_images(image_id) + progress = progress + progress_step + cfg.ui_utils.update_bar(progress, cfg.translate('Downloading ...')) + cfg.ui_utils.remove_progress_bar() + cfg.map_canvas.setRenderFlag(True) + cfg.map_canvas.refresh() + + +# table click +def table_click(): + table = cfg.dialog.ui.download_images_tableWidget + row = table.currentRow() + selected_ids = [] + for tI in table.selectedIndexes(): + selected_ids.append(tI.row()) + image_ids = set(selected_ids) + if row >= 0 and not len(image_ids) > 1: + cfg.ui_utils.add_progress_bar() + cfg.ui_utils.update_bar(10, cfg.translate('Downloading ...')) + sat = str(table.item(row, 0).text()) + if sat == cfg.rs.configurations.sentinel2: + display_sentinel2(row, True) + elif (sat == cfg.rs.configurations.landsat_hls + or sat == cfg.rs.configurations.sentinel2_hls): + display_nasa_images(row, True) + cfg.ui_utils.remove_progress_bar() + + +""" Download """ + + +# download images in table +def download_images_action(): + download_images(exporter=False) + + +# export links +def export_links(): + download_images(exporter=True) + + +# download images in table +def download_images(exporter=False): + band_list = [] + if cfg.dialog.ui.checkBoxs_band_1.isChecked(): + band_list.append('01') + if cfg.dialog.ui.checkBoxs_band_2.isChecked(): + band_list.append('02') + if cfg.dialog.ui.checkBoxs_band_3.isChecked(): + band_list.append('03') + if cfg.dialog.ui.checkBoxs_band_4.isChecked(): + band_list.append('04') + if cfg.dialog.ui.checkBoxs_band_5.isChecked(): + band_list.append('05') + if cfg.dialog.ui.checkBoxs_band_6.isChecked(): + band_list.append('06') + if cfg.dialog.ui.checkBoxs_band_7.isChecked(): + band_list.append('07') + if cfg.dialog.ui.checkBoxs_band_8.isChecked(): + band_list.append('08') + if cfg.dialog.ui.checkBoxs_band_8.isChecked(): + band_list.append('08') + if cfg.dialog.ui.checkBoxs_band_8A.isChecked(): + band_list.append('8A') + if cfg.dialog.ui.checkBoxs_band_9.isChecked(): + band_list.append('09') + if cfg.dialog.ui.checkBoxs_band_10.isChecked(): + band_list.append('10') + if cfg.dialog.ui.checkBoxs_band_11.isChecked(): + band_list.append('11') + if cfg.dialog.ui.checkBoxs_band_12.isChecked(): + band_list.append('12') + if cfg.dialog.ui.virtual_download_checkBox.isChecked(): + virtual_download = True + try: + left = float(cfg.dialog.ui.UX_lineEdit_3.text()) + top = float(cfg.dialog.ui.UY_lineEdit_3.text()) + right = float(cfg.dialog.ui.LX_lineEdit_3.text()) + bottom = float(cfg.dialog.ui.LY_lineEdit_3.text()) + extent_coordinate_list = [left, top, right, bottom] + # TODO implement coordinate projection + extent_coordinate_list = None + except Exception as err: + str(err) + extent_coordinate_list = None + else: + virtual_download = False + extent_coordinate_list = None + proxy_host = None + proxy_port = None + proxy_user = None + proxy_password = None + cfg.util_qgis.get_qgis_proxy_settings() + if str(cfg.proxy_enabled) == 'true' and len(cfg.proxy_host) > 0: + if len(cfg.proxy_user) > 0: + proxy_user = cfg.proxy_user + proxy_password = cfg.proxy_password + proxy_host = cfg.proxy_host + proxy_port = cfg.proxy_port + else: + proxy_host = cfg.proxy_host + proxy_port = cfg.proxy_port + nasa_user = cfg.dialog.ui.user_earthdata_lineEdit.text() + nasa_password = cfg.dialog.ui.password_earthdata_lineEdit.text() + table = cfg.dialog.ui.download_images_tableWidget + count = table.rowCount() + if count > 0: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate( + 'Download the images in the table ' + '(requires internet connection)' + ) + ) + if output_path is not False: + preview_box = cfg.dialog.ui.download_if_preview_in_legend_checkBox + if preview_box.isChecked(): + uid_list = [] + for row in range(count): + image_id = str(table.item(row, 1).text()) + if cfg.util_qgis.select_layer_by_name( + image_id, True + ) is not None: + uid_list.append(str(table.item(row, 14).text())) + enum_list = [] + for n, uid in enumerate(cfg.download_table.uid): + if str(uid) in uid_list: + enum_list.append(n) + filtered = cfg.download_table[enum_list] + else: + filtered = cfg.download_table + cfg.ui_utils.add_progress_bar() + output = cfg.rs.download_products.download( + product_table=filtered, output_path=output_path, + exporter=exporter, band_list=band_list, + virtual_download=virtual_download, + extent_coordinate_list=extent_coordinate_list, + proxy_host=proxy_host, proxy_port=proxy_port, + proxy_user=proxy_user, proxy_password=proxy_password, + nasa_user=nasa_user, nasa_password=nasa_password + ) + if output.check: + if cfg.dialog.ui.preprocess_checkBox.isChecked(): + preprocess = True + else: + preprocess = False + if cfg.dialog.ui.load_in_QGIS_checkBox.isChecked(): + load_in_qgis = True + else: + load_in_qgis = False + if preprocess: + if output.extra is not None: + # preprocess + directories = output.extra['directory_paths'] + for directory in directories: + cfg.image_conversion.populate_table(directory) + base_directory = cfg.utils.directory_name( + directory + ) + process_directory = '%s/RT_%s' % ( + base_directory, cfg.utils.base_name(directory) + ) + cfg.image_conversion.perform_conversion( + output_path=process_directory, + load_in_qgis=load_in_qgis + ) + cfg.util_qt.clear_table( + cfg.dialog.ui.bands_tableWidget + ) + else: + if load_in_qgis: + if output.paths is not None: + for x_path in output.paths: + cfg.util_qgis.add_raster_layer(x_path) + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +""" Additional functions """ + + +# display granule preview +def display_sentinel2(row, preview=False): + table = cfg.dialog.ui.download_images_tableWidget + image_name = str(table.item(row, 1).text()) + if image_name[0:4] == 'L1C_' or image_name[0:4] == 'L2A_': + image_id = '%s_p.jp2' % image_name + else: + image_id = '%s_p.jp2' % image_name + url = str(table.item(row, 13).text()) + # image preview + image_output = '%s//%s' % (cfg.temp_dir, image_id) + if preview is True and cfg.utils.check_file(image_output): + preview_in_label(image_output) + return image_output + if cfg.utils.check_file('%s.vrt' % image_output) or cfg.utils.check_file( + '%s.vrt' % sub(r'\.jp2$', '.png', str(image_output)) + ): + layer = cfg.util_qgis.select_layer_by_name(image_name) + if layer is not None: + cfg.util_qgis.set_layer_visible(layer, True) + cfg.util_qgis.move_layer_to_top(layer) + else: + cfg.util_qgis.add_raster_layer('%s.vrt' % image_output, image_name) + else: + if 'storage.googleapis.com' in url: + check, output = cfg.rs.download_tools.download_file( + url, image_output, timeout=2 + ) + if check is not False: + if preview is True: + preview_in_label(image_output) + return image_output + min_lat = str(table.item(row, 7).text()) + min_lon = str(table.item(row, 8).text()) + max_lat = str(table.item(row, 9).text()) + max_lon = str(table.item(row, 10).text()) + onthefly_georef_image( + image_output, '%s.vrt' % image_output, min_lon, max_lon, + min_lat, max_lat + ) + if cfg.utils.check_file('%s.vrt' % image_output): + cfg.util_qgis.add_raster_layer( + '%s.vrt' % image_output, image_name + ) + + +# display images +def display_nasa_images(row, preview=False): + table = cfg.dialog.ui.download_images_tableWidget + sat = str(table.item(row, 0).text()) + image_id = str(table.item(row, 1).text()) + min_lat = str(table.item(row, 7).text()) + min_lon = str(table.item(row, 8).text()) + max_lat = str(table.item(row, 9).text()) + max_lon = str(table.item(row, 10).text()) + url = str(table.item(row, 13).text()) + # image preview + image_output = '%s//%s_thumb.jpg' % (cfg.temp_dir, image_id) + if preview is True and cfg.utils.check_file(image_output): + preview_in_label(image_output) + return image_output + elif cfg.utils.check_file('%s//%s.vrt' % (cfg.temp_dir, image_id)): + layer = cfg.util_qgis.select_layer_by_name(image_id) + if layer is not None: + cfg.util_qgis.set_layer_visible(layer, True) + cfg.util_qgis.move_layer_to_top(layer) + else: + r = cfg.util_qgis.add_raster_layer( + '%s//%s.vrt' + % (cfg.temp_dir, image_id) + ) + cfg.util_qgis.set_raster_color_composite(r, 1, 2, 3) + else: + download_nasa_thumbnail( + image_id, min_lat, min_lon, max_lat, max_lon, url, sat, preview + ) + if cfg.utils.check_file('%s//%s.vrt' % (cfg.temp_dir, image_id)): + r = cfg.util_qgis.add_raster_layer( + '%s//%s.vrt' + % (cfg.temp_dir, image_id) + ) + cfg.util_qgis.set_raster_color_composite(r, 1, 2, 3) + + +# display image in label +def preview_in_label(image_path): + temp_image = sub(r'\.jp2$', '.png', str(image_path)) + if image_path.endswith('.jp2') and not cfg.utils.check_file(temp_image): + cfg.utils.get_gdal_path_for_mac() + # georeference thumbnail + com = ('%sgdal_translate %s %s -of PNG' + % (cfg.qgis_registry[cfg.reg_gdal_path], image_path, + temp_image)) + if cfg.system_platform != 'Windows': + com = split(com) + try: + if cfg.system_platform == 'Windows': + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + sub_process = subprocess.Popen( + com, shell=False, startupinfo=startupinfo, + stdin=subprocess.DEVNULL + ) + else: + sub_process = subprocess.Popen(com, shell=False) + sub_process.wait() + except Exception as err: + str(err) + image_path = temp_image + label = cfg.dialog.ui.image_preview_label + pixmap = QPixmap(image_path).scaled(300, 300) + label.setPixmap(pixmap) + return image_path + + +# add OpenStreetMap to the map as described in +# https://wiki.openstreetmap.org/wiki/QGIS +# (© OpenStreetMap contributors. The cartography is licensed as CC BY-SA) +def display_osm(): + temp_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.xml' + ) + xml = """ + + http://tile.openstreetmap.org/${z}/${x}/${y}.png + + + -20037508.34 + 20037508.34 + 20037508.34 + -20037508.34 + 18 + 1 + 1 + top + + EPSG:3857 + 256 + 256 + 3 + + """ + with open(temp_path, 'w') as output_file: + output_file.write(xml) + cfg.util_qgis.add_raster_layer(temp_path, 'OpenStreetMap') + + +# image georeferenced on the fly based on UL and LR +def onthefly_georef_image( + input_image, output_vrt, min_lon, max_lon, min_lat, max_lat +): + center_lon = (float(min_lon) + float(max_lon)) / 2 + center_lat = (float(min_lat) + float(max_lat)) / 2 + # calculate UTM zone (adapted from + # http://stackoverflow.com/questions/9186496/determining-utm-zone-to-convert-from-longitude-latitude) + zone = 1 + int((center_lon + 180) / 6) + # exceptions + if 3.0 <= center_lon < 12.0 and 56.0 <= center_lat < 64.0: + zone = 32 + elif 0.0 <= center_lon < 9.0 and 72.0 <= center_lat < 84.0: + zone = 31 + elif 9.0 <= center_lon < 21.0 and 72.0 <= center_lat < 84.0: + zone = 33 + elif 21.0 <= center_lon < 33.0 and 72.0 <= center_lat < 84.0: + zone = 35 + elif 33.0 <= center_lon < 42.0 and 72.0 <= center_lat < 84.0: + zone = 37 + upper_left = cfg.util_qgis.create_qgis_point( + float(min_lon), + float(max_lat) + ) + lower_right = cfg.util_qgis.create_qgis_point( + float(max_lon), + float(min_lat) + ) + # WGS84 EPSG 4326 + wgs84 = QgsCoordinateReferenceSystem('EPSG:4326') + utm_crs = QgsCoordinateReferenceSystem() + utm_crs.createFromProj4( + '+proj=utm +zone=' + str(zone) + ' +datum=WGS84 +units=m +no_defs' + ) + upper_left_proj = cfg.utils.project_qgis_point_coordinates( + upper_left, wgs84, utm_crs + ) + lower_right_proj = cfg.utils.project_qgis_point_coordinates( + lower_right, wgs84, utm_crs + ) + if upper_left_proj is not False and lower_right_proj is not False: + cfg.utils.get_gdal_path_for_mac() + # georeference thumbnail + com = (('%sgdal_translate -of VRT -a_ullr %s %s %s %s -a_srs ' + '"+proj=utm +zone=%s +datum=WGS84 +units=m +no_defs" %s %s') + % (cfg.qgis_registry[cfg.reg_gdal_path], + str(upper_left_proj.x()), str(upper_left_proj.y()), + str(lower_right_proj.x()), str(lower_right_proj.y()), + str(zone), input_image, output_vrt)) + if cfg.system_platform != 'Windows': + com = split(com) + try: + if cfg.system_platform == 'Windows': + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + process = subprocess.Popen( + com, shell=False, startupinfo=startupinfo, + stdin=subprocess.DEVNULL + ) + else: + process = subprocess.Popen(com, shell=False) + process.wait() + except Exception as err: + str(err) + + +# download thumbnail +def download_nasa_thumbnail( + image_id, min_lat, min_lon, max_lat, max_lon, url, sat, preview=False +): + image_output = '%s//%s_thumb.jpg' % (cfg.temp_dir, image_id) + check = False + if (sat == cfg.rs.configurations.landsat_hls + or sat == cfg.rs.configurations.sentinel2_hls): + check, output = cfg.rs.download_tools.download_file( + url, image_output, timeout=2 + ) + if check is True: + if preview is True: + preview_in_label(image_output) + return image_output + onthefly_georef_image( + image_output, '%s//%s.vrt' % (cfg.temp_dir, image_id), min_lon, + max_lon, min_lat, max_lat + ) diff --git a/interface/image_conversion_tab.py b/interface/image_conversion_tab.py new file mode 100755 index 0000000..23c7e33 --- /dev/null +++ b/interface/image_conversion_tab.py @@ -0,0 +1,247 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Image conversion. + +This tool allows for the conversion of images to reflectance such as Landsat +and Sentinel-2. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# landsat input +def input_image(): + path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if path is False: + cfg.dialog.ui.label_26.setText('') + cfg.util_qt.clear_table(cfg.dialog.ui.bands_tableWidget) + return + cfg.dialog.ui.label_26.setText(str(path)) + # metadata + cfg.dialog.ui.label_27.setText('') + populate_table(input_path=path) + + +# metadata input +def input_metadata(): + metadata = cfg.util_qt.get_open_file( + None, cfg.translate('Select a MTL file'), '', + 'MTL file .txt (*.txt);;MTL file .met (*.met);;MTD file .xml (*.xml)' + ) + cfg.dialog.ui.label_27.setText(str(metadata)) + if len(cfg.dialog.ui.label_26.text()) > 0: + populate_table( + input_path=cfg.dialog.ui.label_26.text(), + metadata_file_path=metadata + ) + + +# populate table +def populate_table(input_path, metadata_file_path=None): + cfg.logger.log.info( + 'populate_table input_path: %s; metadata_file_path: %s' + % (input_path, str(metadata_file_path)) + ) + cfg.preprocess_band_table = None + if cfg.dialog.ui.nodata_checkBox_2.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_3.value() + else: + nodata = None + cfg.preprocess_band_table = ( + cfg.rs.preprocess_products.create_product_table( + input_path=input_path, nodata_value=nodata, + metadata_file_path=metadata_file_path + )) + table = cfg.dialog.ui.bands_tableWidget + cfg.util_qt.set_column_width_list( + table, [[0, 150], [1, 150], [2, 150], + [3, 350], [4, 450]] + ) + cfg.util_qt.clear_table(table) + table.blockSignals(True) + table.setSortingEnabled(False) + total_bands = cfg.preprocess_band_table.shape[0] + if total_bands == 0: + cfg.mx.msg_war_7() + for band in range(total_bands): + # add rows + count = table.rowCount() + table.setRowCount(count + 1) + n = 0 + for field in cfg.preprocess_band_table.dtype.names: + if str(cfg.preprocess_band_table[field][band]) != 'None': + cfg.util_qt.add_table_item( + table, str(cfg.preprocess_band_table[field][band]), + count, n + ) + n += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + + +# perform conversion +def perform_conversion(output_path=None, load_in_qgis=False): + if output_path is None or output_path is False: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False and cfg.preprocess_band_table is not None: + if cfg.dialog.ui.create_bandset_checkBox.isChecked() is True: + if cfg.dialog.ui.add_new_bandset_radioButton_1.isChecked() is True: + # added new bandset + add_bandset = True + else: + # replaced bandset + add_bandset = False + else: + # no added bandset + add_bandset = None + if cfg.dialog.ui.DOS1_checkBox.isChecked() is True: + dos1_correction = True + else: + dos1_correction = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.preprocess_products.perform_preprocess( + product_table=cfg.preprocess_band_table, output_path=output_path, + dos1_correction=dos1_correction, add_bandset=add_bandset, + bandset_catalog=cfg.bandset_catalog, output_prefix='RT_' + ) + if output.check: + if load_in_qgis: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + if add_bandset is True: + for bandset_number in range( + 1, cfg.bandset_catalog.get_bandset_count() + 1 + ): + cfg.bst.band_set_to_table(bandset_number) + cfg.mx.msg_inf_6() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# remove bands +def remove_highlighted_band(): + answer = cfg.util_qt.question_box( + cfg.translate('Remove rows'), + cfg.translate( + 'Are you sure you want to remove highlighted rows from the table?' + ) + ) + if answer is True: + table = cfg.dialog.ui.bands_tableWidget + # list of item to remove + rows = [] + for index in table.selectedIndexes(): + rows.append(index.row()) + selected_rows = list(set(rows)) + band_name_list = [] + count = table.rowCount() + for row in range(count): + if row not in selected_rows: + band_name_list.append(str(table.item(row, 3).text())) + enum_list = [] + for n, band_name in enumerate(cfg.preprocess_band_table.band_name): + if str(band_name) in band_name_list: + enum_list.append(n) + cfg.preprocess_band_table = cfg.preprocess_band_table[enum_list] + cfg.util_qt.clear_table(table) + table.blockSignals(True) + table.setSortingEnabled(False) + total_products = cfg.preprocess_band_table.shape[0] + for product in range(total_products): + # add rows + count = table.rowCount() + table.setRowCount(count + 1) + n = 0 + for field in cfg.preprocess_band_table.dtype.names: + if str(cfg.preprocess_band_table[field][product]) != 'None': + cfg.util_qt.add_table_item( + table, str(cfg.preprocess_band_table[field][product]), + count, n + ) + n += 1 + table.setSortingEnabled(True) + table.blockSignals(False) + + +# set script button +def set_script(): + output_path = 'output_path' + output_prefix = 'RT_' + input_path = cfg.dialog.ui.label_26.text() + metadata_file_path = cfg.dialog.ui.label_27.text() + if len(metadata_file_path) == 0: + metadata_file_path = None + if cfg.dialog.ui.create_bandset_checkBox.isChecked() is True: + create_catalog = ('# crete bandset catalog\n' + 'catalog = rs.bandset_catalog()\n') + catalog = 'catalog' + if cfg.dialog.ui.add_new_bandset_radioButton_1.isChecked() is True: + add_bandset = True + else: + add_bandset = False + else: + create_catalog = '' + catalog = 'None' + add_bandset = None + if cfg.dialog.ui.DOS1_checkBox.isChecked() is True: + dos1_correction = True + else: + dos1_correction = False + if cfg.dialog.ui.nodata_checkBox_2.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_3.value() + else: + nodata = None + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# image conversion\n' + '%s' + 'rs.preprocess_products.preprocess(input_path="%s", ' + 'output_path="%s", metadata_file_path="%s", add_bandset=%s, ' + 'nodata_value=%s, dos1_correction=%s, output_prefix="%s", ' + 'bandset_catalog=%s)' + % (str(create_catalog), str(input_path), str(output_path), + str(metadata_file_path), str(add_bandset), + str(nodata), str(dos1_correction), str(output_prefix), + str(catalog))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, + command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/input_interface.py b/interface/input_interface.py new file mode 100755 index 0000000..b604c7a --- /dev/null +++ b/interface/input_interface.py @@ -0,0 +1,1208 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from inspect import stack +from re import findall + +from PyQt5 import QtCore +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon, QFont, QDesktopServices, QPixmap +from PyQt5.QtWidgets import ( + QComboBox, QRadioButton, QLabel, QAction, QMenu, QTabBar, qApp, + QDoubleSpinBox +) +from requests import get + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + +try: + # noinspection PyUnresolvedReferences + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + # noinspection PyPep8Naming + def _fromUtf8(s): + return s + + +# function dictionaries +def function_dictionaries(): + cfg.first_functions = { + 'Band set': bandset_tab, + 'Download products': download_products_tab + } + cfg.first_icons = { + 'Band set': 'semiautomaticclassificationplugin_bandset_tool.svg', + 'Download products': + 'semiautomaticclassificationplugin_download_arrow.svg' + } + # Basic tools + cfg.basic_tools_functions = { + 'RGB composite': rgb_composite_tab, + 'Multiple ROI creation': multiple_roi_creation_tab, + 'Import signatures': import_signatures_tab, + 'Export signatures': export_signatures_tab, + 'Signature threshold': signature_threshold_tab + } + cfg.basic_tools_icons = { + 'RGB composite': 'semiautomaticclassificationplugin_rgb_tool.svg', + 'Multiple ROI creation': + 'semiautomaticclassificationplugin_roi_multiple.svg', + 'Import signatures': + 'semiautomaticclassificationplugin_import_spectral_library.svg', + 'Export signatures': + 'semiautomaticclassificationplugin_export_spectral_library.svg', + 'Signature threshold': + 'semiautomaticclassificationplugin_threshold_tool.svg' + } + # Preprocessing + cfg.preprocessing_functions = { + 'Clip raster bands': clip_raster_bands_tab, + 'Image conversion': image_conversion_tab, + 'Masking bands': masking_bands_tab, + 'Mosaic band sets': mosaic_bandsets_tab, + 'Reproject raster bands': reproject_bands_tab, + 'Split raster bands': split_bands_tab, + 'Stack raster bands': stack_bands_tab, + 'Vector to raster': vector_to_raster_tab + } + cfg.preprocessing_icons = { + 'Clip raster bands': 'semiautomaticclassificationplugin_clip_tool.svg', + 'Image conversion': + 'semiautomaticclassificationplugin_landsat8_tool.svg', + 'Masking bands': + 'semiautomaticclassificationplugin_cloud_masking_tool.svg', + 'Mosaic band sets': + 'semiautomaticclassificationplugin_mosaic_tool.svg', + 'Reproject raster bands': + 'semiautomaticclassificationplugin_reproject_raster_bands.svg', + 'Split raster bands': + 'semiautomaticclassificationplugin_split_raster.svg', + 'Stack raster bands': + 'semiautomaticclassificationplugin_stack_raster.svg', + 'Vector to raster': + 'semiautomaticclassificationplugin_vector_to_raster_tool.svg' + } + # Band processing + cfg.band_processing_functions = { + 'Classification': classification_tab, + 'PCA': pca_tab, + 'Combination': band_combination_tab, + 'Dilation': band_dilation_tab, + 'Erosion': band_erosion_tab, + 'Neighbor': band_neighbor_tab, + 'Sieve': band_sieve_tab + } + cfg.band_processing_icons = { + 'Classification': + 'semiautomaticclassificationplugin_classification.svg', + 'PCA': 'semiautomaticclassificationplugin_pca_tool.svg', + 'Combination': + 'semiautomaticclassificationplugin_band_combination_tool.svg', + 'Dilation': + 'semiautomaticclassificationplugin_classification_dilation.svg', + 'Neighbor': 'semiautomaticclassificationplugin_neighbor_pixels.svg', + 'Sieve': 'semiautomaticclassificationplugin_classification_sieve.svg', + 'Erosion': + 'semiautomaticclassificationplugin_classification_erosion.svg' + } + cfg.postprocessing_functions = { + 'Accuracy': accuracy_tab, + 'Classification report': classification_report_tab, + 'Cross classification': cross_classification_tab, + 'Classification to vector': classification_to_vector_tab, + 'Reclassification': reclassification_tab + } + cfg.postprocessing_icons = { + 'Accuracy': 'semiautomaticclassificationplugin_accuracy_tool.svg', + 'Classification report': + 'semiautomaticclassificationplugin_report_tool.svg', + 'Cross classification': + 'semiautomaticclassificationplugin_cross_classification.svg', + 'Classification to vector': + 'semiautomaticclassificationplugin_class_to_vector_tool.svg', + 'Reclassification': + 'semiautomaticclassificationplugin_reclassification_tool.svg' + } + cfg.top_tree_functions = { + 'Basic tools': top_tree, + 'Preprocessing': top_tree, + 'Band processing': top_tree, + 'Postprocessing': top_tree, + 'Settings': top_tree + } + cfg.calc_functions = { + 'Band calc': band_calc_tab, + 'Script': script_tab + } + cfg.calc_icons = { + 'Band calc': 'semiautomaticclassificationplugin_bandcalc_tool.svg', + 'Script': 'semiautomaticclassificationplugin_batch.svg' + } + cfg.other_functions = { + 'User manual': quick_guide, + 'Help': ask_help, + 'About': about_tab + } + cfg.other_icons = { + 'User manual': 'guide.svg', + 'Help': 'help.svg', + 'About': 'fromGIStoRS.png' + } + cfg.setting_functions = { + 'Debug': debug_tab, + 'Interface': interface_tab, + 'Processing setting': processing_settings_tab + } + cfg.setting_icons = { + 'Debug': None, + 'Interface': None, + 'Processing setting': None + } + + +""" Interface functions """ + + +def load_input_toolbar(): + cfg.working_toolbar = cfg.iface.addToolBar('SCP Working Toolbar') + cfg.working_toolbar.setObjectName('SCP Working Toolbar') + load_working_toolbar() + set_dock_tabs() + + +# SCP Working Toolbar +# noinspection PyUnresolvedReferences +def load_working_toolbar(): + add_toolbar_action( + show_plugin, 'semiautomaticclassificationplugin.svg', + cfg.translate('Semi-Automatic Classification Plugin') + ) + # button zoom to image + add_toolbar_action( + cfg.util_qgis.zoom_to_bandset, + 'semiautomaticclassificationplugin_zoom_to_Image.svg', + cfg.translate('Zoom to input image extent') + ) + # radio button show hide input image + cfg.inputImageRadio = add_toolbar_radio( + show_hide_input_mage, cfg.translate('RGB = '), + cfg.translate('Show/hide the input image') + ) + # combo RGB composite + cfg.rgb_combo = QComboBox(cfg.iface.mainWindow()) + cfg.rgb_combo.setFixedWidth(80) + cfg.rgb_combo.setEditable(True) + cfg.working_toolbar.addWidget(cfg.rgb_combo) + cfg.rgb_combo.setToolTip(cfg.translate('Select a RGB color composite')) + cfg.rgb_combo.currentIndexChanged.connect(rgb_combo_changed) + # local cumulative cut stretch button + cfg.local_cumulative_stretch_toolButton = add_toolbar_action( + cfg.util_qgis.set_raster_cumulative_stretch, + 'semiautomaticclassificationplugin_bandset_cumulative_stretch_tool' + '.svg', + cfg.translate('Local cumulative cut stretch of band set') + ) + # local standard deviation stretch button + cfg.local_std_dev_stretch_toolButton = add_toolbar_action( + cfg.util_qgis.set_raster_std_dev_stretch, + 'semiautomaticclassificationplugin_bandset_std_dev_stretch_tool.svg', + cfg.translate('Local standard deviation stretch of band set') + ) + # button zoom to ROI + cfg.zoom_to_temp_roi = add_toolbar_action( + zoom_to_temp_roi, 'semiautomaticclassificationplugin_zoom_to_ROI.svg', + cfg.translate('Zoom to temporary ROI') + ) + # radio button show hide ROI + cfg.show_ROI_radioButton = add_toolbar_radio( + cfg.scp_dock.show_hide_roi, cfg.translate('ROI '), + cfg.translate('Show/hide the temporary ROI') + ) + # manual ROI pointer + cfg.polygonROI_Button = add_toolbar_action( + cfg.scp_dock.pointer_manual_roi_active, + 'semiautomaticclassificationplugin_manual_ROI.svg', + cfg.translate('Create a ROI polygon') + ) + # pointer button + cfg.pointerButton = add_toolbar_action( + cfg.scp_dock.pointer_region_growing_roi_active, + 'semiautomaticclassificationplugin_roi_single.svg', + cfg.translate('Activate ROI pointer') + ) + # redo button + cfg.redo_ROI_Button = add_toolbar_action( + cfg.scp_dock.redo_roi, + 'semiautomaticclassificationplugin_roi_redo.svg', + cfg.translate('Redo the ROI at the same point') + ) + cfg.redo_ROI_Button.setEnabled(False) + style = ( + 'background-color : qlineargradient(spread:pad, x1:0, y1:0, x2:1,' + ' y2:0, stop:0 #535353, stop:1 #535353); color : white' + ) + # spinbox spectral distance + lbl_spectral_distance = add_toolbar_label( + cfg.translate(' Dist'), 'Yes' + ) + lbl_spectral_distance.setStyleSheet(_fromUtf8(style)) + cfg.Range_radius_spin = add_toolbar_spin( + cfg.scp_dock.range_radius, + cfg.translate('Similarity of pixels (distance in radiometry unit)'), + 6, 1e-06, 10000.0, 0.001, 0.01 + ) + # spinbox min size + label_min = add_toolbar_label(cfg.translate(' Min'), 'Yes') + label_min.setStyleSheet(_fromUtf8(style)) + cfg.roi_min_size_spin = add_toolbar_spin( + cfg.scp_dock.roi_min_size, + cfg.translate('Minimum area of ROI (in pixel unit)'), 0, 1, 10000, + 1, 60, 60 + ) + # spinbox max size + label_max = add_toolbar_label(cfg.translate(' Max'), 'Yes') + label_max.setStyleSheet(_fromUtf8(style)) + cfg.max_roi_width_spin = add_toolbar_spin( + cfg.scp_dock.max_roi_width, + cfg.translate( + 'Side of a square which inscribes the ROI, ' + 'defining the maximum width thereof (in pixel unit)' + ), + 0, 1, 10000, 1, int(cfg.project_registry[cfg.reg_roi_max_width]), 60 + ) + # button zoom to preview + add_toolbar_action( + zoom_to_preview, + 'semiautomaticclassificationplugin_zoom_to_preview.svg', + cfg.translate('Zoom to the classification preview') + ) + # radio button show hide preview + cfg.show_preview_radioButton2 = add_toolbar_radio( + show_hide_preview, cfg.translate('Preview '), + cfg.translate('Show/hide the classification preview') + ) + # preview pointer button + add_toolbar_action( + cfg.classification.pointer_classification_preview_active, + 'semiautomaticclassificationplugin_preview.svg', + cfg.translate('Activate classification preview pointer') + ) + cfg.redoPreviewButton = add_toolbar_action( + redo_preview, 'semiautomaticclassificationplugin_preview_redo.svg', + cfg.translate('Redo the classification preview at the same point') + ) + cfg.redoPreviewButton.setEnabled(False) + # spinbox transparency + lbl_t = add_toolbar_label(cfg.translate(' T'), 'Yes') + lbl_t.setStyleSheet(_fromUtf8(style)) + add_toolbar_spin( + change_transparency, cfg.translate('Set preview transparency'), 0, 0, + 100, 10, 0, 50 + ) + # spinbox size + lbl_s = add_toolbar_label(cfg.translate(' S'), 'Yes') + lbl_s.setStyleSheet(_fromUtf8(style)) + cfg.preview_size_spinBox = add_toolbar_spin( + preview_size, cfg.translate('Set the preview size (in pixel unit)'), + 0, 1, 1000000, 100, int(cfg.project_registry[cfg.reg_preview_size]), + 60 + ) + add_toolbar_action( + cfg.utils.create_kml_from_map, + 'semiautomaticclassificationplugin_kml_add.svg', + cfg.translate('Create KML') + ) + + +# menu index +def menu_index(): + function_dictionaries() + dictionaries = [ + cfg.first_functions, cfg.basic_tools_functions, + cfg.preprocessing_functions, cfg.band_processing_functions, + cfg.postprocessing_functions, cfg.top_tree_functions, + cfg.calc_functions, cfg.other_functions, cfg.setting_functions + ] + try: + # translate + n_dict = {} + for menu_dict in dictionaries: + for val in menu_dict: + n_dict[cfg.translate(val)] = menu_dict[val] + s = cfg.dialog.ui.menu_treeWidget.selectedItems() + n = s[0].text(0) + t = cfg.dialog.ui.menu_treeWidget + t.blockSignals(True) + cfg.dialog.ui.SCP_tabs.blockSignals(True) + n_dict[n]() + s[0].setExpanded(True) + cfg.dialog.ui.SCP_tabs.blockSignals(False) + t.blockSignals(False) + except Exception as err: + str(err) + cfg.dialog.ui.SCP_tabs.blockSignals(False) + t = cfg.dialog.ui.menu_treeWidget + t.blockSignals(False) + + +# add spinbox +# noinspection PyUnresolvedReferences +def add_toolbar_spin( + function, tooltip, decimals, minimum, maximum, step, value, width=100 +): + spin = QDoubleSpinBox(cfg.iface.mainWindow()) + spin.setFixedWidth(width) + spin.setDecimals(decimals) + spin.setMinimum(minimum) + spin.setMaximum(maximum) + spin.setSingleStep(step) + spin.setProperty('value', value) + spin.setToolTip(cfg.translate(tooltip)) + cfg.working_toolbar.addWidget(spin) + spin.valueChanged.connect(function) + return spin + + +# add radio button +def add_toolbar_radio(function, text, tooltip): + radio = QRadioButton(cfg.iface.mainWindow()) + radio.setToolTip(cfg.translate(tooltip)) + radio.setStyleSheet(_fromUtf8('background-color : #656565; color : white')) + radio.setText(cfg.translate(text)) + radio.setChecked(True) + radio.setAutoExclusive(False) + cfg.working_toolbar.addWidget(radio) + radio.clicked.connect(function) + return radio + + +# add label to toolbar +def add_toolbar_label(text, black=None, width=None): + font = QFont() + font.setFamily(_fromUtf8('FreeSans')) + font.setBold(True) + font.setWeight(75) + lbl = QLabel(cfg.iface.mainWindow()) + lbl.setFont(font) + if black is None: + lbl.setStyleSheet( + _fromUtf8('background-color : #656565; color : white') + ) + else: + lbl.setStyleSheet(_fromUtf8('color : black')) + lbl.setObjectName(_fromUtf8('lbl')) + if width is not None: + lbl.setFixedWidth(width) + lbl.setMaximumHeight(18) + lbl.setText(cfg.translate(text)) + cfg.working_toolbar.addWidget(lbl) + return lbl + + +# Add toolbar action +def add_toolbar_action(function, icon_name, tooltip): + action = QAction( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/%s' % icon_name + ), tooltip, cfg.iface.mainWindow() + ) + action.setToolTip(tooltip) + action.triggered.connect(function) + cfg.working_toolbar.addAction(action) + return action + + +# show plugin +def show_plugin(): + # close the dialog + cfg.dialog.close() + activate_docks() + # show the dialog + cfg.dialog.show() + cfg.ui_utils.set_interface(True) + cfg.rs.configurations.action = True + + +# activate docks +def activate_docks(): + cfg.dock_class_dlg.show() + cfg.working_toolbar.show() + + +# connect resize event +def resize_event(event): + size = event.size() + cfg.qgis_registry[cfg.reg_window_size_w] = str(size.width()) + cfg.qgis_registry[cfg.reg_window_size_h] = str(size.height()) + + +# user manual +def quick_guide(): + QDesktopServices().openUrl( + QtCore.QUrl( + 'https://fromgistors.blogspot.com/p/user-manual.html?spref=scp' + ) + ) + + +# help +def ask_help(): + QDesktopServices().openUrl( + QtCore.QUrl( + 'https://fromgistors.blogspot.com/p/online-help.html?spref=scp' + ) + ) + + +# add item to menu +def add_menu_item(menu, function, icon_name, name): + try: + action = QAction( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/%s' + % icon_name + ), name, cfg.iface.mainWindow() + ) + except Exception as err: + str(err) + action = QAction(name, cfg.iface.mainWindow()) + action.setObjectName('action') + action.triggered.connect(function) + menu.addAction(action) + return action + + +# load SCP menu +def load_menu(): + menu_bar = cfg.iface.mainWindow().menuBar() + main_menu = QMenu(cfg.iface.mainWindow()) + main_menu.setObjectName('semiautomaticclassificationplugin') + main_menu.setTitle(cfg.translate('SCP')) + menu_bar.insertMenu( + cfg.iface.firstRightStandardMenu().menuAction(), main_menu + ) + function_dictionaries() + for b in cfg.first_functions: + add_menu_item( + main_menu, cfg.first_functions[b], cfg.first_icons[b], + cfg.translate(b) + ) + # Basic tools + basic_tools_menu = main_menu.addMenu( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_roi_tool.svg' + ), cfg.translate('Basic tools') + ) + # Preprocessing + preprocessing_menu = main_menu.addMenu( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_class_tool.svg' + ), cfg.translate('Preprocessing') + ) + # Band processing + band_processing_menu = main_menu.addMenu( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_band_processing.svg' + ), cfg.translate('Band processing') + ) + # Postprocessing + postprocessing_menu = main_menu.addMenu( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_post_process.svg' + ), cfg.translate('Postprocessing') + ) + for b in cfg.calc_functions: + add_menu_item( + main_menu, cfg.calc_functions[b], cfg.calc_icons[b], + cfg.translate(b) + ) + # Spectral plot + add_menu_item( + main_menu, spectral_plot_tab, + 'semiautomaticclassificationplugin_sign_tool.svg', + cfg.translate('Spectral plot') + ) + # Scatter plot + add_menu_item( + main_menu, scatter_plot_tab, + 'semiautomaticclassificationplugin_scatter_tool.svg', + cfg.translate('Scatter plot') + ) + # Settings + settings_menu = main_menu.addMenu( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/' + 'semiautomaticclassificationplugin_settings_tool.svg' + ), cfg.translate('Settings') + ) + for b in cfg.other_functions: + add_menu_item( + main_menu, cfg.other_functions[b], cfg.other_icons[b], + cfg.translate(b) + ) + for b in cfg.basic_tools_functions: + add_menu_item( + basic_tools_menu, cfg.basic_tools_functions[b], + cfg.basic_tools_icons[b], cfg.translate(b) + ) + for b in cfg.preprocessing_functions: + add_menu_item( + preprocessing_menu, cfg.preprocessing_functions[b], + cfg.preprocessing_icons[b], cfg.translate(b) + ) + for b in cfg.band_processing_functions: + add_menu_item( + band_processing_menu, cfg.band_processing_functions[b], + cfg.band_processing_icons[b], + cfg.translate(b) + ) + for b in cfg.postprocessing_functions: + add_menu_item( + postprocessing_menu, cfg.postprocessing_functions[b], + cfg.postprocessing_icons[b], + cfg.translate(b) + ) + for b in cfg.setting_functions: + add_menu_item( + settings_menu, cfg.setting_functions[b], cfg.setting_icons[b], + cfg.translate(b) + ) + # Show plugin + add_menu_item( + main_menu, show_plugin, 'semiautomaticclassificationplugin_docks.svg', + cfg.translate('Show plugin') + ) + + +# set SCP dock tabs buttons +def set_dock_tabs(): + source = ':/plugins/semiautomaticclassificationplugin/icons' + icons = [ + '%s/semiautomaticclassificationplugin_bandset_tool' % source, + '%s/semiautomaticclassificationplugin_download_arrow' % source, + '%s/semiautomaticclassificationplugin_roi_tool' % source, + '%s/semiautomaticclassificationplugin_class_tool' % source, + '%s/semiautomaticclassificationplugin_band_processing' % source, + '%s/semiautomaticclassificationplugin_post_process' % source, + '%s/semiautomaticclassificationplugin_bandcalc_tool' % source] + for i in range(3, 10): + label = QLabel() + label.setStyleSheet(_fromUtf8('color : black')) + label.setObjectName(_fromUtf8('label')) + label.setPixmap( + QPixmap(icons[i - 3]).scaled(24, 24, Qt.KeepAspectRatio) + ) + label.setAlignment(Qt.AlignCenter) + cfg.dock_class_dlg.ui.tabWidget_dock.tabBar().setTabButton( + i, QTabBar.LeftSide, label + ) + + +# dock tab index +def dock_tab_changed(index): + if index > 2: + cfg.dialog.ui.SCP_tabs.setCurrentIndex(index - 3) + tree = cfg.dialog.ui.menu_treeWidget + root = tree.invisibleRootItem() + tree.blockSignals(True) + # unselect all + for i in range(0, root.childCount()): + child = root.child(i) + child.setHidden(False) + child.setSelected(False) + for x in range(0, child.childCount()): + child.child(x).setHidden(False) + child.child(x).setSelected(False) + child = root.child(index - 3) + child.setSelected(True) + child.setExpanded(True) + tree.blockSignals(False) + cfg.dock_class_dlg.ui.tabWidget_dock.blockSignals(True) + cfg.dock_class_dlg.ui.tabWidget_dock.setCurrentIndex( + cfg.settings_tab_index + ) + cfg.dock_class_dlg.ui.tabWidget_dock.blockSignals(False) + cfg.dialog.close() + cfg.dialog.show() + else: + cfg.settings_tab_index = ( + cfg.dock_class_dlg.ui.tabWidget_dock.currentIndex() + ) + + +# menu tab +def tree_menu_tab(): + tree = cfg.dialog.ui.menu_treeWidget + root = tree.invisibleRootItem() + tree.blockSignals(True) + # unselect all + for i in range(0, root.childCount()): + child = root.child(i) + child.setHidden(False) + if child.text(0).lower().replace(' ', '').replace( + '-', '' + ) == cfg.current_tab[0:-3].lower(): + child.setSelected(True) + child.setExpanded(True) + else: + child.setSelected(False) + for x in range(0, child.childCount()): + child.child(x).setHidden(False) + if child.child(x).text(0).lower().replace(' ', '').replace( + '-', '' + ) == cfg.current_tab[0:-3].lower(): + child.child(x).setSelected(True) + child.setExpanded(True) + else: + child.child(x).setSelected(False) + tree.blockSignals(False) + cfg.dialog.ui.main_tabWidget.setCurrentIndex(0) + cfg.dialog.show() + + +# SCP tab index +def scp_tab_changed(_index): + cfg.dialog.close() + cfg.dialog.show() + + +# main tab index +def main_tab_changed(index): + if index == 1 and cfg.current_tab != 'about_tab': + cfg.dialog.ui.help_textBrowser.clear() + cfg.dialog.ui.help_textBrowser.setPlainText('Loading ...') + # for user manual + cfg.rs.files_directories.create_directory('%s/_images/' % cfg.temp_dir) + base_url = ( + 'https://semiautomaticclassificationmanual.readthedocs.io/en/' + 'latest/%s.html' % cfg.current_tab + ) + cfg.logger.log.debug('help tab: %s' % base_url) + qApp.processEvents() + if not cfg.utils.check_file( + '%s/%s.html' % (cfg.temp_dir, cfg.current_tab) + ): + response = get(base_url) + with open( + '%s/%s.html' + % (cfg.temp_dir, cfg.current_tab), 'wb' + ) as file: + file.write(response.content) + with open('%s/%s.html' % (cfg.temp_dir, cfg.current_tab), 'r') as h: + html = h.read() + images = findall('src="_images/(.+?)"', str(html)) + for image in images: + if not cfg.utils.check_file(cfg.temp_dir + '/_images/' + image): + try: + response = get( + 'https://semiautomaticclassificationmanual.' + 'readthedocs.io/en/latest/_images/%s' % image + ) + with open( + '%s/_images/%s' % (cfg.temp_dir, image), 'wb' + ) as file: + file.write(response.content) + except Exception as err: + str(err) + if len(html) > 0: + cfg.dialog.ui.help_textBrowser.clear() + cfg.dialog.ui.help_textBrowser.setHtml(html) + + +# top tree +def top_tree(): + pass + + +def moved_splitter(_index, _pos): + cfg.qgis_registry[cfg.reg_splitter_sizes] = str( + cfg.dialog.ui.splitter.sizes() + ) + + +# filter tree +def filter_tree(): + try: + text = cfg.dialog.ui.f_filter_lineEdit.text() + tree = cfg.dialog.ui.menu_treeWidget + root = tree.invisibleRootItem() + tree.blockSignals(True) + if len(text) > 0: + tree.expandAll() + tree.findItems(text, cfg.util_qt.get_match_contains()) + for i in range(0, root.childCount()): + child = root.child(i) + child.setHidden(False) + for x in range(0, child.childCount()): + if text.lower() in child.child(x).text(0).lower(): + child.child(x).setHidden(False) + else: + child.child(x).setHidden(True) + else: + tree.collapseAll() + for i in range(0, root.childCount()): + child = root.child(i) + child.setHidden(False) + for x in range(0, child.childCount()): + if text in child.child(x).text(0): + child.child(x).setHidden(False) + tree.blockSignals(False) + except Exception as err: + str(err) + + +# welcome text +def welcome_text(input_url, input_url2=None): + html_text_f = open('%s/ui/welcome.html' % cfg.plugin_dir, 'r') + html_text = html_text_f.read() + cfg.dock_class_dlg.ui.main_textBrowser.clear() + cfg.dock_class_dlg.ui.main_textBrowser.setHtml(html_text) + html_text_f.close() + if cfg.qgis_registry[cfg.reg_download_news] == 2: + cfg.utils.download_html(input_url, input_url2) + cfg.utils.check_remotior_sensus_version() + + +""" Classification preview """ + + +# set preview transparency +def change_transparency(value): + try: + if cfg.classification_preview is not None: + cfg.map_canvas.setRenderFlag(False) + cfg.classification_preview.renderer().setOpacity( + float(1) - float(value) / 100 + ) + if hasattr(cfg.classification_preview, 'setCacheImage'): + cfg.classification_preview.setCacheImage(None) + cfg.classification_preview.triggerRepaint() + cfg.map_canvas.setRenderFlag(True) + cfg.map_canvas.refresh() + except Exception as err: + str(err) + + +# show hide preview radio button +def show_hide_preview(): + try: + if cfg.classification_preview is not None: + if cfg.show_preview_radioButton2.isChecked(): + cfg.util_qgis.set_layer_visible( + cfg.classification_preview, + True + ) + cfg.util_qgis.move_layer_to_top(cfg.classification_preview) + else: + cfg.util_qgis.set_layer_visible( + cfg.classification_preview, + False + ) + except Exception as err: + str(err) + + +# set preview size +def preview_size(): + cfg.project_registry[cfg.reg_preview_size] = int( + cfg.preview_size_spinBox.value() + ) + + +# redo preview +def redo_preview(): + if cfg.preview_point is not None: + cfg.classification.create_preview(cfg.preview_point) + + +# zoom to ROI +def zoom_to_temp_roi(): + if cfg.temporary_roi is not None: + cfg.util_qgis.set_map_extent_from_layer(cfg.temporary_roi) + + +# zoom to preview +def zoom_to_preview(): + if cfg.classification_preview is not None: + cfg.util_qgis.set_map_extent_from_layer(cfg.classification_preview) + + cfg.classification_preview.triggerRepaint() + cfg.map_canvas.refresh() + + +# show hide input image +def show_hide_input_mage(): + i = None + try: + i = cfg.virtual_bandset_dict[cfg.project_registry[ + cfg.reg_active_bandset_number]] + except Exception as err: + str(err) + try: + if i is not None: + if cfg.inputImageRadio.isChecked(): + cfg.util_qgis.set_layer_visible(i, True) + cfg.util_qgis.move_layer_to_top(i) + else: + cfg.util_qgis.set_layer_visible(i, False) + except Exception as err: + str(err) + + +""" tab selection functions """ + + +# select band set tab +def bandset_tab(): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 1 +def select_download_products_tab(): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(1) + dock_tab_changed(4) + + +# select preprocessing tab +def download_products_tab(): + select_download_products_tab() + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 2 from Main Interface +def select_tab_2_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(2) + if second_tab is not None: + cfg.dialog.ui.tabWidget_5.setCurrentIndex(second_tab) + + +# select basic tools tab +def basic_tools_tab(): + select_tab_2_main_interface() + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# RGB composite tab +def rgb_composite_tab(): + select_tab_2_main_interface(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select multiple roi tab +def multiple_roi_creation_tab(): + select_tab_2_main_interface(1) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# import library signatures tab +def import_signatures_tab(): + select_tab_2_main_interface(2) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# export library signatures tab +def export_signatures_tab(): + select_tab_2_main_interface(3) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# signature threshold tab +def signature_threshold_tab(): + select_tab_2_main_interface(4) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 3 from Main Interface +def select_tab_3_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(3) + if second_tab is not None: + cfg.dialog.ui.tabWidget_preprocessing.setCurrentIndex(second_tab) + + +# select preprocessing tab +def pre_processing_tab(): + select_tab_3_main_interface() + dock_tab_changed(6) + + +# select Landsat tab +def image_conversion_tab(): + select_tab_3_main_interface(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# Vector to raster tab +def vector_to_raster_tab(): + select_tab_3_main_interface(1) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Clip raster bands tab +def clip_raster_bands_tab(): + select_tab_3_main_interface(2) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Reproject raster bands tab +def reproject_bands_tab(): + select_tab_3_main_interface(3) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Split raster bands tab +def split_bands_tab(): + select_tab_3_main_interface(4) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Stack raster bands tab +def stack_bands_tab(): + select_tab_3_main_interface(5) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# Mosaic tab +def mosaic_bandsets_tab(): + select_tab_3_main_interface(6) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# cloud masking tab +def masking_bands_tab(): + select_tab_3_main_interface(7) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 4 from Main Interface +def select_tab_4_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(4) + if second_tab is not None: + cfg.dialog.ui.tabWidget_4.setCurrentIndex(second_tab) + + +# select band processing tab +def band_processing_tab(): + select_tab_4_main_interface() + dock_tab_changed(7) + + +# select Band combination tab +def band_combination_tab(): + select_tab_4_main_interface(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select band dilation tab +def band_dilation_tab(): + select_tab_4_main_interface(1) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# band erosion tab +def band_erosion_tab(): + select_tab_4_main_interface(2) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# band sieve tab +def band_sieve_tab(): + select_tab_4_main_interface(3) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# PCA tab +def pca_tab(): + select_tab_4_main_interface(4) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select classification tab +def classification_tab(): + select_tab_4_main_interface(5) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select neighbor pixels tab +def band_neighbor_tab(): + select_tab_4_main_interface(6) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 5 from Main Interface +def select_tab_5_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(5) + if second_tab is not None: + cfg.dialog.ui.tabWidget_2.setCurrentIndex(second_tab) + + +# select postprocessing tab +def post_processing_tab(): + select_tab_5_main_interface() + dock_tab_changed(8) + + +# select Accuracy tab +def accuracy_tab(): + select_tab_5_main_interface(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Classification report tab +def classification_report_tab(): + select_tab_5_main_interface(1) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Cross classification tab +def cross_classification_tab(): + select_tab_5_main_interface(2) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Classification to vector tab +def classification_to_vector_tab(): + select_tab_5_main_interface(3) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Reclassification tab +def reclassification_tab(): + select_tab_5_main_interface(4) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select Band calc tab +def band_calc_tab(): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(6) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 7 from Main Interface +def select_tab_7_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(7) + if second_tab is not None: + cfg.dialog.ui.toolBox.setCurrentIndex(second_tab) + + +# select batch tab +def script_tab(): + select_tab_7_main_interface() + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select tab 8 from Main Interface +def select_tab_8_main_interface(second_tab=None): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(8) + if second_tab is not None: + cfg.dialog.ui.settings_tabWidget.setCurrentIndex(second_tab) + + +# select settings tab +def settings_tab(): + select_tab_8_main_interface() + + +# select settings Processing tab +def processing_settings_tab(): + select_tab_8_main_interface(0) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select settings interface tab +def interface_tab(): + select_tab_8_main_interface(1) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select settings debug tab +def debug_tab(): + select_tab_8_main_interface(2) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# select about tab +def about_tab(): + cfg.dialog.ui.SCP_tabs.setCurrentIndex(9) + cfg.current_tab = str(stack()[0][3]) + tree_menu_tab() + + +# spectral signature plot tab +def spectral_plot_tab(): + cfg.spectral_plot_dlg.close() + cfg.spectral_plot_dlg.show() + + +# select tab in signature plot tab +def select_spectral_plot_settings_tab(second_tab=None): + if second_tab is not None: + cfg.spectral_plot_dlg.ui.tabWidget.setCurrentIndex(second_tab) + + +# scatter plot tab +def scatter_plot_tab(): + cfg.scatter_plot_dlg.close() + cfg.scatter_plot_dlg.show() + + +# rgb changed +def rgb_combo_changed(): + cfg.utils.set_rgb_color_composite(cfg.rgb_combo.currentText()) diff --git a/interface/masking_bands_tab.py b/interface/masking_bands_tab.py new file mode 100755 index 0000000..835ba32 --- /dev/null +++ b/interface/masking_bands_tab.py @@ -0,0 +1,156 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Masking bands. + +This tool allows for masking bands. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# value text changed +def text_changed(): + check_value_list() + + +# check value list +def check_value_list(): + try: + # class value list + values = cfg.utils.text_to_value_list( + cfg.dialog.ui.cloud_mask_classes_lineEdit.text() + ) + cfg.dialog.ui.cloud_mask_classes_lineEdit.setStyleSheet( + 'color : green' + ) + except Exception as err: + str(err) + cfg.dialog.ui.cloud_mask_classes_lineEdit.setStyleSheet('color : red') + values = [] + return values + + +# mask band sets +def mask_action(): + masking_bandset() + + +# bandset masking +def masking_bandset(): + # class value list + values = check_value_list() + if len(values) > 0: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('masking_bandset: %s' % output_path) + output_name = cfg.dialog.ui.mask_output_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_9.value() + classification_layer = ( + cfg.dialog.ui.classification_name_combo_4.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + nodata = cfg.dialog.ui.nodata_spinBox_11.value() + if cfg.dialog.ui.cloud_buffer_checkBox.isChecked() is True: + buffer = cfg.dialog.ui.cloud_buffer_spinBox.value() + else: + buffer = None + if cfg.dialog.ui.mask_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_mask( + input_bands=bandset_number, input_mask=classification, + mask_values=values, output_path=output_path, + prefix=output_name, buffer=buffer, nodata_value=nodata, + bandset_catalog=cfg.bandset_catalog, + virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + values = check_value_list() + output_name = cfg.dialog.ui.mask_output_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_9.value() + classification_layer = ( + cfg.dialog.ui.classification_name_combo_4.currentText()) + classification = cfg.util_qgis.get_file_path(classification_layer) + nodata = cfg.dialog.ui.nodata_spinBox_11.value() + if cfg.dialog.ui.cloud_buffer_checkBox.isChecked() is True: + buffer = cfg.dialog.ui.cloud_buffer_spinBox.value() + else: + buffer = None + if cfg.dialog.ui.mask_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# masking bands (input files from bandset)\n' + 'rs.band_mask(input_bands=%s, input_mask="%s", mask_values=%s, ' + 'output_path="%s", prefix="%s", buffer=%s, nodata_value=%s, ' + 'virtual_output=%s)' + % (str(paths), str(classification), str(values), + str(output_path), str(output_name), str(buffer), + str(nodata), str(virtual_output))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/mosaic_bandsets_tab.py b/interface/mosaic_bandsets_tab.py new file mode 100755 index 0000000..1ca4332 --- /dev/null +++ b/interface/mosaic_bandsets_tab.py @@ -0,0 +1,179 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Mosaic band sets. + +This tool allows for the mosaic of band sets. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# list band sets +def text_changed(): + check_bandset_list() + + +# check bandset list +def check_bandset_list(): + try: + text = cfg.dialog.ui.mosaic_band_sets_lineEdit.text() + if text == '*': + values = list( + range(1, cfg.bandset_catalog.get_bandset_count() + 1) + ) + else: + values = text.split(',') + bandset_list = [] + for value in values: + bandset_list.append(int(value)) + cfg.dialog.ui.mosaic_band_sets_lineEdit.setStyleSheet('color : green') + except Exception as err: + str(err) + cfg.dialog.ui.mosaic_band_sets_lineEdit.setStyleSheet('color : red') + bandset_list = [] + return bandset_list + + +# mosaic band sets +def mosaic_action(): + mosaic_bandsets() + + +# mosaic multiple bandsets +def mosaic_bandsets(): + bandset_list = check_bandset_list() + if len(bandset_list) > 0: + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_sieve: %s' % output_path) + output_name = cfg.dialog.ui.mosaic_output_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + prefix = cfg.dialog.ui.mosaic_output_prefix.text() + if len(prefix) == 0: + prefix = None + if cfg.dialog.ui.mosaic_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.nodata_checkBox_9.isChecked(): + nodata_value = cfg.dialog.ui.nodata_spinBox_10.value() + else: + nodata_value = None + cfg.ui_utils.add_progress_bar() + output = cfg.rs.mosaic( + input_bands=bandset_list, output_path=output_path, + nodata_value=nodata_value, prefix=prefix, + output_name=output_name, bandset_catalog=cfg.bandset_catalog, + virtual_output=virtual_output + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_list = check_bandset_list() + output_name = cfg.dialog.ui.mosaic_output_name_lineEdit.text() + if len(output_name) == 0: + output_name = None + prefix = cfg.dialog.ui.mosaic_output_prefix.text() + if len(prefix) == 0: + prefix = None + if cfg.dialog.ui.mosaic_virtual_checkBox.isChecked() is True: + virtual_output = True + else: + virtual_output = False + if cfg.dialog.ui.nodata_checkBox_9.isChecked(): + nodata_value = cfg.dialog.ui.nodata_spinBox_10.value() + else: + nodata_value = None + # get input band paths + if len(bandset_list) == 1: + # get input band paths + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_list[0]) + absolute_paths = bandset_x.get_absolute_paths() + path_list = '[' + for file in absolute_paths: + path_list += '"%s", ' % file + path_list = path_list[:-2] + ']' + if path_list == ']': + path_list = '[]' + elif len(bandset_list) > 0: + try: + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_list[0] + ) + absolute_paths = bandset_x.get_absolute_paths() + path_list = '[' + for n in range(0, len(absolute_paths)): + paths = '[' + for bandset_number in bandset_list: + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + bandset_number + ) + files = bandset_x.get_absolute_paths() + paths += '"%s", ' % files[n] + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + path_list += paths + ', ' + path_list = path_list[:-2] + ']' + if path_list == ']': + path_list = '[]' + except Exception as err: + str(err) + path_list = '[]' + else: + path_list = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# band sets mosaic (input files from bandset)\n' + 'rs.mosaic(input_bands=%s, output_path="%s", nodata_value=%s, ' + 'prefix="%s", output_name="%s", virtual_output=%s)' + % (str(path_list), str(output_path), str(nodata_value), + str(prefix), str(output_name), str(virtual_output)) + ) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/multiple_roi_tab.py b/interface/multiple_roi_tab.py new file mode 100755 index 0000000..46ba0ac --- /dev/null +++ b/interface/multiple_roi_tab.py @@ -0,0 +1,418 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Multiple ROI. + +This tool allows for the creation of multiple ROIs. +""" + +import numpy +from PyQt5.QtWidgets import qApp + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# add point +def add_row_to_table(): + table = cfg.dialog.ui.point_tableWidget + table.setRowCount(table.rowCount() + 1) + + +# add random point +def add_point_to_table(point): + table = cfg.dialog.ui.point_tableWidget + count = table.rowCount() + table.setRowCount(count + 1) + if cfg.dock_class_dlg.ui.rapid_ROI_checkBox.isChecked() is True: + band = str(cfg.project_registry[cfg.reg_roi_main_band]) + else: + band = '' + cfg.util_qt.add_table_item(table, str(point[0]), count, 0) + cfg.util_qt.add_table_item(table, str(point[1]), count, 1) + cfg.util_qt.add_table_item( + table, str( + cfg.project_registry[cfg.reg_roi_macroclass_id] + ), count, 2 + ) + cfg.util_qt.add_table_item( + table, str( + cfg.project_registry[cfg.reg_roi_macroclass_name] + ), count, 3 + ) + cfg.util_qt.add_table_item( + table, str(cfg.project_registry[cfg.reg_roi_class_id]), count, 4 + ) + cfg.util_qt.add_table_item( + table, str( + cfg.project_registry[cfg.reg_roi_class_name] + ), count, 5 + ) + cfg.util_qt.add_table_item( + table, str(cfg.project_registry[cfg.reg_roi_min_size]), count, 6 + ) + cfg.util_qt.add_table_item( + table, str( + cfg.project_registry[cfg.reg_roi_max_width] + ), count, 7 + ) + cfg.util_qt.add_table_item( + table, str( + cfg.project_registry[cfg.reg_roi_range_radius] + ), count, 8 + ) + cfg.util_qt.add_table_item(table, band, count, 9) + + +# text changed +def expression_text_edited(): + expression = cfg.dialog.ui.stratified_lineEdit.text() + expression_split = expression.split(';') + check = True + for condition in expression_split: + try: + cfg.dialog.ui.stratified_lineEdit.setStyleSheet('color : green') + eval( + condition.replace( + cfg.qgis_registry[cfg.reg_raster_variable_name], '1' + ) + ) + if (condition.strip() + == cfg.qgis_registry[cfg.reg_raster_variable_name]): + cfg.dialog.ui.stratified_lineEdit.setStyleSheet('color : red') + check = False + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.dialog.ui.stratified_lineEdit.setStyleSheet('color : red') + check = False + return check + + +# create random point +def create_random_point(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_10.value() + bandset_x = cfg.bandset_catalog.get(bandset_number) + cfg.logger.log.debug( + 'create_random_point bandset_number: %s' % bandset_number + ) + if bandset_x is None: + cfg.mx.msg_war_6(bandset_number) + return False + band_count = bandset_x.get_band_count() + if band_count == 0: + cfg.mx.msg_war_6(bandset_number) + return False + band_left = bandset_x.bands[0].left + band_top = bandset_x.bands[0].top + band_right = bandset_x.bands[0].right + band_bottom = bandset_x.bands[0].bottom + raster_path = bandset_x.bands[0].path + point_number = int(cfg.dialog.ui.point_number_spinBox.value()) + if cfg.dialog.ui.point_distance_checkBox.isChecked() is True: + min_distance = int(cfg.dialog.ui.point_distance_spinBox.value()) + else: + min_distance = None + stratified = None + stratified_expression = None + if cfg.dialog.ui.stratified_point_checkBox.isChecked() is True: + check = expression_text_edited() + if check is True: + stratified = True + stratified_expression = cfg.dialog.ui.stratified_lineEdit.text() + else: + cfg.mx.msg_err_7() + return False + points = new_points = None + cfg.ui_utils.add_progress_bar() + # points inside grid + if cfg.dialog.ui.point_grid_checkBox.isChecked() is True: + grid_size = int(cfg.dialog.ui.point_grid_spinBox.value()) + x_range = list(range(int(band_left), int(band_right), grid_size)) + y_range = list(range(int(band_bottom), int(band_top), grid_size)) + x_count = 1 + for x in x_range: + if x_count < len(x_range): + y_count = 1 + for y in y_range: + if y_count < len(y_range): + new_points = cfg.utils.random_points_in_grid( + point_number=point_number, x_min=x, + x_max=x + x_range[x_count], + y_min=y, y_max=y + y_range[y_count] + ) + if points is None: + points = new_points + else: + points.extend(new_points) + y_count += 1 + x_count += 1 + elif stratified is not None: + expression_split = stratified_expression.split(';') + for expression in expression_split: + new_points = cfg.utils.random_points_with_condition( + raster_path=raster_path, point_number=point_number, + condition=expression, x_min=band_left, y_top=band_top + ) + if points is None: + points = new_points + else: + points.extend(new_points) + else: + points = cfg.utils.random_points_in_grid( + point_number=point_number, x_min=band_left, + x_max=band_right, y_min=band_bottom, y_max=band_top + ) + # check distance + if min_distance is not None: + while True: + point_array = numpy.array(points) + distance = cfg.utils.pair_point_distance(point_array) + distance = distance * numpy.tril(numpy.ones(distance.shape), k=-1) + rows, cols = numpy.where( + (distance > 0) & (distance < min_distance) + ) + if rows.shape[0] == 0: + break + else: + points.pop(int(rows[0])) + if points is not None: + for point in points: + add_point_to_table(point) + cfg.ui_utils.remove_progress_bar() + + +# create ROIs +def create_roi_from_points(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_10.value() + table = cfg.dialog.ui.point_tableWidget + count = table.rowCount() + cfg.logger.log.debug( + 'create_roi_from_points bandset_number: %s' % bandset_number + ) + if count > 0: + cfg.ui_utils.add_progress_bar() + for i in range(0, count): + qApp.processEvents() + if cfg.rs.configurations.action: + cfg.ui_utils.update_bar((i + 1) * 100 / (count + 1)) + try: + x_coordinate = table.item(i, 0).text() + y_coordinate = table.item(i, 1).text() + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_6() + break + try: + point = cfg.util_qgis.create_qgis_point( + float(x_coordinate), float(y_coordinate) + ) + point = cfg.utils.check_point_in_image(point=point) + if point is False: + cfg.mx.msg_war_3() + return False + # get ROI parameters + if len(table.item(i, 6).text()) > 0: + v = int(table.item(i, 6).text()) + cfg.project_registry[cfg.reg_roi_min_size] = v + if len(table.item(i, 7).text()) > 0: + v = int(table.item(i, 7).text()) + cfg.project_registry[cfg.reg_roi_max_width] = v + if len(table.item(i, 8).text()) > 0: + v = float(table.item(i, 8).text()) + cfg.project_registry[cfg.reg_roi_range_radius] = v + if len(table.item(i, 9).text()) > 0: + v = int(table.item(i, 9).text()) + cfg.project_registry[cfg.reg_roi_main_band] = v + cfg.project_registry[ + cfg.reg_rapid_roi_check] = 2 + cfg.scp_dock.create_region_growing_roi( + point=point, bandset_number=bandset_number + ) + # get ROI attributes + v = int(table.item(i, 2).text()) + cfg.project_registry[cfg.reg_roi_macroclass_id] = v + cfg.project_registry[cfg.reg_roi_macroclass_name] = ( + table.item(i, 3).text() + ) + v = int(table.item(i, 4).text()) + cfg.project_registry[cfg.reg_roi_class_id] = v + cfg.project_registry[cfg.reg_roi_class_name] = ( + table.item(i, 5).text() + ) + cfg.scp_dock.save_roi_to_training( + bandset_number=bandset_number + ) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_6() + break + # restore settings for single ROI + cfg.scp_dock.roi_macroclass_id_value() + cfg.scp_dock.roi_macroclass_name_info() + cfg.scp_dock.roi_class_id_value() + cfg.scp_dock.roi_class_name_info() + cfg.scp_dock.roi_min_size() + cfg.scp_dock.max_roi_width() + cfg.scp_dock.range_radius() + cfg.scp_dock.rapid_roi_band() + cfg.scp_dock.rapid_roi_checkbox() + cfg.ui_utils.remove_progress_bar() + + +# export point list to file +def export_point_list(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save the point list to file'), '', '*.csv', 'csv' + ) + separator = ';' + if output_path is not False: + cfg.logger.log.debug('export_point_list: %s' % output_path) + if output_path.lower().endswith('.csv'): + pass + else: + output_path = output_path + '.csv' + text = ( + 'X' + separator + 'Y' + separator + 'MC_ID' + separator + + 'MC_Info' + separator + 'C_ID' + separator + 'C_Info' + + separator + 'Min' + separator + 'Max' + separator + 'Dist' + + separator + 'Rapid_ROI_band\n' + ) + table = cfg.dialog.ui.point_tableWidget + count = table.rowCount() + for i in range(0, count): + x_coordinate = table.item(i, 0).text() + y_coordinate = table.item(i, 1).text() + mc_id = table.item(i, 2).text() + mc_info = table.item(i, 3).text() + c_id = table.item(i, 4).text() + c_info = table.item(i, 5).text() + min_size = '' + max_width = '' + range_rad = '' + roi_band = '' + try: + min_size = table.item(i, 6).text() + max_width = table.item(i, 7).text() + range_rad = table.item(i, 8).text() + roi_band = table.item(i, 9).text() + except Exception as err: + str(err) + text += ( + x_coordinate + separator + y_coordinate + separator + mc_id + + separator + mc_info + separator + c_id + separator + + c_info + separator + min_size + separator + max_width + + separator + range_rad + separator + roi_band + '\n' + ) + with open(output_path, 'w') as f: + f.write(text) + + +# import points from file +def import_points_csv(): + point_file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a point list file'), '', + 'CSV (*.csv);; Point SHP .shp (*.shp);; Point GPKG .shp (*.gpkg)' + ) + if len(point_file) > 0: + if point_file.lower().endswith('.csv'): + try: + f = open(point_file) + if cfg.utils.check_file(point_file): + lines = f.readlines() + if '\t' in lines[0]: + separator = '\t' + else: + separator = ';' + table = cfg.dialog.ui.point_tableWidget + for line in range(1, len(lines)): + # point list + split_line = lines[line].strip().split(separator) + min_size = cfg.project_registry[cfg.reg_roi_min_size] + max_width = cfg.project_registry[cfg.reg_roi_max_width] + range_rad = cfg.project_registry[ + cfg.reg_roi_range_radius + ] + roi_band = '' + try: + min_size = split_line[6] + max_width = split_line[7] + range_rad = split_line[8] + roi_band = split_line[9] + except Exception as err: + str(err) + # add item to table + count = table.rowCount() + # add list items to table + table.setRowCount(count + 1) + cfg.util_qt.add_table_item( + table, split_line[0], count, 0 + ) + cfg.util_qt.add_table_item( + table, split_line[1], count, 1 + ) + cfg.util_qt.add_table_item( + table, split_line[2], count, 2 + ) + cfg.util_qt.add_table_item( + table, split_line[3], count, 3 + ) + cfg.util_qt.add_table_item( + table, split_line[4], count, 4 + ) + cfg.util_qt.add_table_item( + table, split_line[5], count, 5 + ) + cfg.util_qt.add_table_item(table, min_size, count, 6) + cfg.util_qt.add_table_item(table, max_width, count, 7) + cfg.util_qt.add_table_item(table, range_rad, count, 8) + cfg.util_qt.add_table_item(table, roi_band, count, 9) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_5() + elif (point_file.lower().endswith('.shp') + or point_file.lower().endswith('.gpkg')): + try: + _vector = cfg.util_gdal.open_vector(point_file) + _layer = _vector.GetLayer() + _feature = _layer.GetNextFeature() + while _feature: + geometry = _feature.GetGeometryRef() + point = [geometry.GetX(), geometry.GetY()] + _feature.Destroy() + _feature = _layer.GetNextFeature() + add_point_to_table(point) + _layer = None + _vector = None + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_5() + + +def remove_row_from_table(): + cfg.util_qt.remove_rows_from_table(cfg.dialog.ui.point_tableWidget) + + +# Activate signature calculation checkbox2 +def signature_checkbox_2(): + if cfg.dialog.ui.signature_checkBox2.isChecked() is True: + # connected checkbox + cfg.dock_class_dlg.ui.signature_checkBox.setCheckState(2) + else: + cfg.dock_class_dlg.ui.signature_checkBox.setCheckState(0) diff --git a/interface/reclassification_tab.py b/interface/reclassification_tab.py new file mode 100755 index 0000000..1bbe4b5 --- /dev/null +++ b/interface/reclassification_tab.py @@ -0,0 +1,336 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Reclassification. + +This tool allows for raster reclassification. +""" + +import numpy + +try: + from remotior_sensus.core.processor_functions import ( + raster_unique_values_with_sum + ) +except Exception as error: + str(error) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# reclassify +def reclassify_action(): + reclassify() + + +# reclassify +def reclassify(): + reference_layer = cfg.dialog.ui.reclassification_name_combo.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + value_list = get_values_table() + if reference is not None and len(value_list) > 0: + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + cfg.logger.log.info('reclassify: %s' % output_path) + cfg.ui_utils.add_progress_bar() + reclassification_list = create_reclassification_string_from_list( + value_list + ) + output = cfg.rs.raster_reclassification( + raster_path=reference, output_path=output_path, + reclassification_table=reclassification_list + ) + if output.check: + # add raster to layers + raster = cfg.util_qgis.add_raster_layer(output.path) + unique_values = [value[1] for value in reclassification_list] + cfg.utils.raster_symbol_generic( + raster, 'NoData', raster_unique_value_list=unique_values + ) + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +def calculate_unique_values(): + input_name = cfg.dialog.ui.reclassification_name_combo.currentText() + i = cfg.util_qgis.select_layer_by_name(input_name, True) + try: + input_path = cfg.util_qgis.qgis_layer_source(i) + except Exception as err: + str(err) + cfg.mx.msg_err_5() + cfg.utils.refresh_raster_layer() + return False + cfg.ui_utils.add_progress_bar() + cfg.rs.configurations.multiprocess.run( + raster_path=input_path, function=raster_unique_values_with_sum, + keep_output_argument=True, dummy_bands=2 + ) + cfg.rs.configurations.multiprocess.multiprocess_unique_values() + cmb = cfg.rs.configurations.multiprocess.output + values = numpy.unique(numpy.asarray(cmb[0])).tolist() + if cfg.dialog.ui.CID_MCID_code_checkBox.isChecked() is True: + if cfg.scp_training is not None: + unique = cfg.scp_training.calculate_unique_c_id_mc_id() + else: + unique = create_value_list(values) + else: + unique = create_value_list(values) + add_values_to_table(unique) + cfg.ui_utils.remove_progress_bar() + + +def incremental_new_values(): + input_name = cfg.dialog.ui.reclassification_name_combo.currentText() + i = cfg.util_qgis.select_layer_by_name(input_name, True) + try: + input_path = cfg.util_qgis.qgis_layer_source(i) + except Exception as err: + str(err) + cfg.mx.msg_err_5() + cfg.utils.refresh_raster_layer() + return False + cfg.ui_utils.add_progress_bar() + cfg.rs.configurations.multiprocess.run( + raster_path=input_path, function=raster_unique_values_with_sum, + keep_output_argument=True, dummy_bands=2 + ) + cfg.rs.configurations.multiprocess.multiprocess_unique_values() + cmb = cfg.rs.configurations.multiprocess.output + values = numpy.unique(numpy.asarray(cmb[0])).tolist() + unique = create_value_list(values, True) + add_values_to_table(unique) + cfg.ui_utils.remove_progress_bar() + + +def create_value_list(values, incremental=False): + value_list = [] + if incremental is False: + for i in sorted(values): + g = str(i).split('.0') + try: + _t = g[1] + p = i + except Exception as err: + str(err) + p = g[0] + value_list.append([p, p]) + else: + v = 1 + for i in sorted(values): + g = str(i).split('.0') + try: + t = g[1] + if len(t) > 0: + p = i + else: + p = g[0] + except Exception as err: + str(err) + p = g[0] + value_list.append([p, str(v)]) + v = v + 1 + return value_list + + +def add_values_to_table(value_list): + table = cfg.dialog.ui.reclass_values_tableWidget + table.blockSignals(True) + cfg.util_qt.clear_table(table) + c = table.rowCount() + for i in value_list: + table.setRowCount(c + 1) + cfg.util_qt.add_table_item(table, str(i[0]), c, 0) + cfg.util_qt.add_table_item(table, str(i[1]), c, 1) + c += 1 + table.blockSignals(False) + + +def get_values_table(): + table = cfg.dialog.ui.reclass_values_tableWidget + c = table.rowCount() + values = [] + for row in range(0, c): + old = table.item(row, 0).text() + new = table.item(row, 1).text() + values.append([old, new]) + return values + + +def create_reclassification_string_from_list(value_list): + reclass_list = [] + for i in value_list: + try: + cond = float(i[0]) + except Exception as err: + str(err) + cond = str(i[0]) + reclass_list.append([cond, float(i[1])]) + return reclass_list + + +def add_row(): + table = cfg.dialog.ui.reclass_values_tableWidget + c = table.rowCount() + table.blockSignals(True) + table.setRowCount(c + 1) + cfg.util_qt.add_table_item(table, '0', c, 0) + cfg.util_qt.add_table_item(table, '0', c, 1) + table.blockSignals(False) + + +def remove_row(): + cfg.util_qt.remove_rows_from_table( + cfg.dialog.ui.reclass_values_tableWidget + ) + + +def edited_cell(row, column): + table = cfg.dialog.ui.reclass_values_tableWidget + val = table.item(row, column).text() + if column == 1: + try: + float(val) + except Exception as err: + str(err) + table.blockSignals(True) + cfg.util_qt.set_table_item(table, row, column, '0') + table.blockSignals(False) + elif column == 0: + c = val.replace( + cfg.qgis_registry[cfg.reg_raster_variable_name], '_array' + ) + _array = numpy.arange(9).reshape(3, 3) + try: + eval('numpy.where(' + c + ', 1, _array)') + except Exception as err: + str(err) + table.blockSignals(True) + cfg.util_qt.set_table_item(table, row, column, '0') + table.blockSignals(False) + cfg.mx.msgWar16() + + +# import reclass from file +def import_reclass(): + file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a reclassification file'), '', + 'CSV (*.csv)' + ) + if len(file) > 0: + import_reclass_file(file) + + +# import reclass +def import_reclass_file(file): + try: + f = open(file) + if cfg.utils.check_file(file): + file = f.readlines() + if '\t' in file[0]: + sep = '\t' + else: + sep = ',' + table = cfg.dialog.ui.reclass_values_tableWidget + for b in range(0, len(file)): + p = file[b].strip().split(sep) + old_value = 0 + new_value = 0 + try: + old_value = p[0] + new_value = p[1] + except Exception as err: + str(err) + c = table.rowCount() + table.setRowCount(c + 1) + cfg.util_qt.add_table_item(table, old_value, c, 0) + cfg.util_qt.add_table_item(table, new_value, c, 1) + except Exception as err: + str(err) + + +# export reclass list to file +def export_reclass(): + list_file = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save the reclassification list to file'), '', + '*.csv', 'csv' + ) + try: + if list_file.lower().endswith('.csv'): + pass + else: + list_file = list_file + '.csv' + table = cfg.dialog.ui.reclass_values_tableWidget + c = table.rowCount() + f = open(list_file, 'w') + txt = '' + sep = ',' + old_value = new_value = None + for i in range(0, c): + try: + old_value = table.item(i, 0).text() + new_value = table.item(i, 1).text() + except Exception as err: + str(err) + txt += '%s%s%s\n' % (old_value, sep, new_value) + f.write(txt) + f.close() + except Exception as err: + str(err) + + +# set script button +def set_script(): + output_path = 'output_path' + reference_layer = cfg.dialog.ui.reclassification_name_combo.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + value_list = get_values_table() + reclassification_list = create_reclassification_string_from_list( + value_list + ) + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# reclassification \n' + 'rs.raster_reclassification(raster_path="%s", output_path="%s",' + ' reclassification_table=%s)' + % (str(reference), str(output_path), str(reclassification_list)) + ) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/reproject_bandset_tab.py b/interface/reproject_bandset_tab.py new file mode 100755 index 0000000..ebd0fe7 --- /dev/null +++ b/interface/reproject_bandset_tab.py @@ -0,0 +1,235 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Reproject band set. + +This tool allows for reprojecting band sets. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# checkbox changed +def radio_align_changed(): + cfg.dialog.ui.align_radioButton.blockSignals(True) + cfg.dialog.ui.epsg_radioButton.blockSignals(True) + if cfg.dialog.ui.align_radioButton.isChecked(): + cfg.dialog.ui.epsg_radioButton.setChecked(0) + cfg.dialog.ui.align_radioButton.blockSignals(False) + cfg.dialog.ui.epsg_radioButton.blockSignals(False) + + +# checkbox changed +def radio_epsg_changed(): + cfg.dialog.ui.align_radioButton.blockSignals(True) + cfg.dialog.ui.epsg_radioButton.blockSignals(True) + if cfg.dialog.ui.epsg_radioButton.isChecked(): + cfg.dialog.ui.align_radioButton.setChecked(0) + cfg.dialog.ui.align_radioButton.blockSignals(False) + cfg.dialog.ui.epsg_radioButton.blockSignals(False) + + +# refresh reference layer name +def refresh_reference_layer(): + # noinspection PyArgumentList + ls = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.raster_align_comboBox.clear() + for layer in sorted(ls, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_raster(): + if layer.bandCount() == 1: + cfg.dialog.project_raster_combo(layer.name()) + + +def reproject_bands_action(): + reproject_bands() + + +def reproject_bands(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_14.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('band_sieve: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + output_name = cfg.dialog.ui.reproj_output_name_lineEdit.text() + if cfg.dialog.ui.virtual_output_checkBox_4.isChecked(): + virtual_output = True + else: + virtual_output = False + align_raster = epsg = nodata_value = resample_pixel_factor = None + x_y_resolution = None + same_extent = False + if cfg.dialog.ui.align_radioButton.isChecked() is True: + reference_layer = cfg.dialog.ui.raster_align_comboBox.currentText() + align_raster = cfg.util_qgis.get_file_path(reference_layer) + if cfg.dialog.ui.same_extent_raster_checkBox.isChecked() is True: + same_extent = True + # use EPSG + elif cfg.dialog.ui.epsg_radioButton.isChecked() is True: + try: + epsg = int(cfg.dialog.ui.epsg_code_lineEdit.text()) + except Exception as err: + str(err) + if cfg.dialog.ui.change_nodata_checkBox.isChecked() is True: + nodata_value = cfg.dialog.ui.nodata_spinBox_14.value() + if cfg.dialog.ui.resample_checkBox.isChecked() is True: + try: + resample_pixel_factor = float( + cfg.dialog.ui.resample_lineEdit.text() + ) + except Exception as err: + str(err) + x_resolution = cfg.dialog.ui.x_resolution_lineEdit.text() + y_resolution = cfg.dialog.ui.y_resolution_lineEdit.text() + if len(x_resolution) > 0 and len(y_resolution) > 0: + try: + x_y_resolution = [float(x_resolution), float(y_resolution)] + except Exception as err: + str(err) + # resampling method + resampling = cfg.dialog.ui.resampling_method_comboBox.currentText() + # raster type + raster_type = cfg.dialog.ui.raster_type_combo_2.currentText() + if raster_type == 'Auto': + raster_type = None + compress_format = cfg.dialog.ui.resample_lineEdit_2.text() + if cfg.dialog.ui.compress_checkBox.isChecked() is True: + compress = True + else: + compress = False + # resample + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_resample( + input_bands=bandset_number, output_path=output_path, + prefix=output_name, epsg_code=epsg, align_raster=align_raster, + resampling=resampling, nodata_value=nodata_value, + x_y_resolution=x_y_resolution, + resample_pixel_factor=resample_pixel_factor, + output_data_type=raster_type, + same_extent=same_extent, virtual_output=virtual_output, + bandset_catalog=cfg.bandset_catalog, + compress=compress, compress_format=compress_format + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + output_name = cfg.dialog.ui.reproj_output_name_lineEdit.text() + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_14.value() + if cfg.dialog.ui.virtual_output_checkBox_4.isChecked(): + virtual_output = True + else: + virtual_output = False + align_raster = epsg = same_extent = nodata_value = None + resample_pixel_factor = x_y_resolution = None + if cfg.dialog.ui.align_radioButton.isChecked() is True: + reference_layer = cfg.dialog.ui.raster_align_comboBox.currentText() + align_raster = cfg.util_qgis.get_file_path(reference_layer) + if cfg.dialog.ui.same_extent_raster_checkBox.isChecked() is True: + same_extent = True + # use EPSG + elif cfg.dialog.ui.epsg_radioButton.isChecked() is True: + try: + epsg = int(cfg.dialog.ui.epsg_code_lineEdit.text()) + except Exception as err: + str(err) + if cfg.dialog.ui.change_nodata_checkBox.isChecked() is True: + nodata_value = cfg.dialog.ui.nodata_spinBox_14.value() + if cfg.dialog.ui.resample_checkBox.isChecked() is True: + try: + resample_pixel_factor = float( + cfg.dialog.ui.resample_lineEdit.text() + ) + except Exception as err: + str(err) + x_resolution = cfg.dialog.ui.x_resolution_lineEdit.text() + y_resolution = cfg.dialog.ui.y_resolution_lineEdit.text() + if len(x_resolution) > 0 and len(y_resolution) > 0: + try: + x_y_resolution = [float(x_resolution), float(y_resolution)] + except Exception as err: + str(err) + # resampling method + resampling = cfg.dialog.ui.resampling_method_comboBox.currentText() + # raster type + raster_type = cfg.dialog.ui.raster_type_combo_2.currentText() + if raster_type == 'Auto': + raster_type = None + compress_format = cfg.dialog.ui.resample_lineEdit_2.text() + if cfg.dialog.ui.compress_checkBox.isChecked() is True: + compress = True + else: + compress = False + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + # get input band paths + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# reproject band set (input files from bandset)\n' + 'rs.band_resample(input_bands=%s, output_path="%s", ' + 'prefix="%s", epsg_code="%s", align_raster="%s", ' + 'resampling="%s", nodata_value=%s, x_y_resolution=%s, ' + 'resample_pixel_factor=%s, output_data_type="%s", ' + 'same_extent=%s, virtual_output=%s, compress=%s, ' + 'compress_format="%s")' + % (str(paths), str(output_path), str(output_name), str(epsg), + str(align_raster), str(resampling), str(nodata_value), + str(x_y_resolution), str(resample_pixel_factor), + str(raster_type), str(same_extent), str(virtual_output), + str(compress), str(compress_format)) + ) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/rgb_composite_tab.py b/interface/rgb_composite_tab.py new file mode 100755 index 0000000..c42aa2c --- /dev/null +++ b/interface/rgb_composite_tab.py @@ -0,0 +1,286 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""RGB composite. + +This tool allows for managing RGB composites. +""" + +from itertools import permutations + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# Create RGB table +def rgb_table_from_list(rgb_list): + table = cfg.dialog.ui.RGB_tableWidget + table.blockSignals(True) + cfg.util_qt.clear_table(table) + x = 0 + for rgb in rgb_list: + if rgb != '-': + cfg.util_qt.insert_table_row(table, x) + cfg.util_qt.add_table_item(table, rgb, x, 0) + x += 1 + table.blockSignals(False) + + +# edited table +def edited_table(row, column): + table = cfg.dialog.ui.RGB_tableWidget + rgb_item = table.item(row, column).text() + try: + check = cfg.utils.create_rgb_color_composite(rgb_item) + except Exception as err: + str(err) + rgb_table_from_list(cfg.project_registry[cfg.reg_rgb_list]) + return False + if check is True: + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + # update combo + rgb_id = cfg.rgb_combo.findText(rgb_item) + cfg.rgb_combo.setCurrentIndex(rgb_id) + else: + rgb_table_from_list(cfg.project_registry[cfg.reg_rgb_list]) + + +# read RGB table +def read_rgb_table(): + table = cfg.dialog.ui.RGB_tableWidget + count = table.rowCount() + rgb_list = ['-'] + for row in range(0, count): + item = table.item(row, 0).text() + rgb_list.append(item) + return rgb_list + + +# add RGB +def add_composite_to_table(): + table = cfg.dialog.ui.RGB_tableWidget + count = table.rowCount() + table.setRowCount(count + 1) + cfg.util_qt.add_table_item(table, '0-0-0', count, 0) + + +# remove RGB +def remove_composite_from_table(): + cfg.util_qt.remove_rows_from_table(cfg.dialog.ui.RGB_tableWidget) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +# sort RGB +def sort_composite_names(): + rgb_list = cfg.project_registry[cfg.reg_rgb_list] + sorted_list = sorted(rgb_list) + cfg.project_registry[cfg.reg_rgb_list] = sorted_list + rgb_table_from_list(cfg.project_registry[cfg.reg_rgb_list]) + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +def clear_table_action(): + clear_table() + + +# clear table +def clear_table(question=True): + if question is True: + answer = cfg.util_qt.question_box( + cfg.translate('Reset RGB composites'), + cfg.translate('Are you sure you want to clear the RGB list?') + ) + else: + answer = True + if answer is True: + table = cfg.dialog.ui.RGB_tableWidget + cfg.util_qt.clear_table(table) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +# move up selected composite +def move_up_composite(): + table = cfg.dialog.ui.RGB_tableWidget + table.blockSignals(True) + count = table.rowCount() + selected = table.selectedItems() + selected_rows = [] + for item in range(0, len(selected)): + selected_rows.append(selected[item].row() - 1) + try: + for row in range(0, count): + if table.item(row, 0).isSelected(): + selected_item = table.item(row, 0).text() + previous_item = table.item(row - 1, 0).text() + table.item(row, 0).setText(str(previous_item)) + table.item(row - 1, 0).setText(str(selected_item)) + table.clearSelection() + values = list(set(selected_rows)) + for item in range(0, len(values)): + table.selectRow(values[item]) + except Exception as err: + str(err) + table.clearSelection() + table.blockSignals(False) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +# move down selected composite +def move_down_composite(): + table = cfg.dialog.ui.RGB_tableWidget + table.blockSignals(True) + count = table.rowCount() + selected = table.selectedItems() + selected_rows = [] + for i in range(0, len(selected)): + selected_rows.append(selected[i].row() + 1) + try: + for row in reversed(list(range(0, count))): + if table.item(row, 0).isSelected(): + selected_item = table.item(row, 0).text() + next_item = table.item(row + 1, 0).text() + table.item(row, 0).setText(str(next_item)) + table.item(row + 1, 0).setText(str(selected_item)) + table.clearSelection() + values = list(set(selected_rows)) + for i in range(0, len(values)): + table.selectRow(values[i]) + except Exception as err: + str(err) + table.clearSelection() + table.blockSignals(False) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +# calculate all RGB composites +def calculate_all_composites_action(): + calculate_all_composites() + + +# all RGB List +def calculate_all_composites(question=True, bandset_number=None): + if question is True: + answer = cfg.util_qt.question_box( + cfg.translate('RGB composite'), + cfg.translate('Calculate all the RGB color composites?') + ) + else: + answer = True + if answer is True: + if bandset_number is None: + bandset_number = cfg.project_registry[ + cfg.reg_active_bandset_number + ] + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return False + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + rgb_permutations = list( + permutations(list(range(1, band_count + 1)), 3) + ) + table = cfg.dialog.ui.RGB_tableWidget + table.blockSignals(True) + cfg.util_qt.clear_table(table) + for combination in rgb_permutations: + count = table.rowCount() + table.setRowCount(count + 1) + cfg.util_qt.add_table_item( + table, '%s-%s-%s' % combination, count, 0 + ) + table.blockSignals(False) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + + +# export RGB list to file +def export_rgb_list(): + file = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save the RGB list to file'), '', '*.csv', 'csv' + ) + if file is not False: + if file.lower().endswith('.csv'): + pass + else: + file += '.csv' + try: + rgb_file = open(file, 'w') + rgb_file.write('') + rgb_file.close() + rgb_file = open(file, 'a') + for composite in cfg.project_registry[cfg.reg_rgb_list]: + if composite != '-': + txt = composite + '\n' + rgb_file.write(txt) + rgb_file.close() + except Exception as err: + cfg.logger.log.error(str(err)) + + +# import RGB from file +def import_rgb_list_from_file(): + file = cfg.util_qt.get_open_file( + None, cfg.translate('Select a RGB list file'), '', 'CSV (*.csv)' + ) + table = cfg.dialog.ui.RGB_tableWidget + try: + rgb_file = open(file) + if cfg.utils.check_file(file): + file = rgb_file.readlines() + table.blockSignals(True) + for row in range(1, len(file)): + count = table.rowCount() + table.setRowCount(count + 1) + cfg.util_qt.add_table_item(table, file[row].strip(), count, 0) + table.blockSignals(False) + rgb_list = read_rgb_table() + cfg.project_registry[cfg.reg_rgb_list] = rgb_list + cfg.util_qt.set_combobox_items( + cfg.rgb_combo, cfg.project_registry[cfg.reg_rgb_list] + ) + except Exception as err: + cfg.logger.log.error(str(err)) + table.blockSignals(False) + cfg.mx.msg_err_5() diff --git a/interface/scp_dock.py b/interface/scp_dock.py new file mode 100755 index 0000000..94ab59b --- /dev/null +++ b/interface/scp_dock.py @@ -0,0 +1,2685 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from copy import deepcopy +from datetime import datetime, timedelta +import shutil +import zipfile + +import numpy +from PyQt5.QtCore import Qt, QVariant, QPoint, QPointF +from PyQt5.QtGui import ( + QColor, QFont, QCursor, QIcon, QPixmap, QPainter, QPolygonF +) +from PyQt5.QtWidgets import ( + QTreeWidget, QTreeWidgetItem, QAbstractItemView, QCompleter, QMenu, QAction +) +from qgis.core import QgsGeometry, QgsFeature, QgsField +from qgis.gui import QgsVertexMarker, QgsHighlight + +try: + from remotior_sensus.core.spectral_signatures import ( + SpectralSignaturesCatalog, SpectralSignaturePlot, generate_signature_id + ) + from remotior_sensus.tools import band_calc + from remotior_sensus.util import raster_vector +except Exception as error: + SpectralSignaturesCatalog = str + str(error) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + +""" Class to manage signature catalog buffer """ + + +class SignatureCatalogBuffer: + + def __init__(self, signature_catalog, max_size): + cfg.logger.log.debug( + 'SignatureCatalogBuffer max_size: %s' % str(max_size) + ) + self.max_size = max_size + self.buffer = {} + for key in range(-max_size, max_size + 1): + self.buffer[key] = None + self.buffer[0] = signature_catalog + + def set_catalog(self, signature_catalog): + # delete files of undo max size that will be replaced + if -self.max_size in self.buffer: + if self.buffer[-self.max_size] is not None: + try: + cfg.utils.remove_file( + self.buffer[-self.max_size].geometry_file + ) + cfg.utils.remove_file( + self.buffer[-self.max_size].temporary_file + ) + except Exception as err: + str(err) + self.buffer[-self.max_size] = None + # remove redo keys + for i in range(1, self.max_size + 1): + if i in self.buffer: + if self.buffer[i] is not None: + # delete temporary signature file + try: + cfg.utils.remove_file( + self.buffer[i].geometry_file + ) + cfg.utils.remove_file( + self.buffer[i].temporary_file + ) + except Exception as err: + str(err) + # remove redo keys + self.buffer[i] = None + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # replace undo keys + for key in sorted(self.buffer): + if key < 0: + self.buffer[key] = self.buffer[key + 1] + self.buffer[0] = signature_catalog + + def undo(self): + for key in reversed(range(-self.max_size, self.max_size)): + self.buffer[key + 1] = self.buffer[key] + if self.buffer[key + 1] is not None: + cfg.logger.log.debug( + 'self.buffer[%s].geometry_file: %s' + % ((key + 1), str(self.buffer[key + 1].geometry_file)) + ) + cfg.logger.log.debug('self.buffer: %s' % self.buffer) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(False) + if self.buffer[-1] is not None: + cfg.logger.log.debug('self.buffer[-1]: %s' % self.buffer[-1]) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + return self.buffer[0] + + def redo(self): + for key in range(-self.max_size + 1, self.max_size + 1): + self.buffer[key - 1] = self.buffer[key] + if self.buffer[key - 1] is not None: + cfg.logger.log.debug( + 'self.buffer[%s].geometry_file: %s' + % ((key - 1), str(self.buffer[key - 1].geometry_file)) + ) + cfg.logger.log.debug('self.buffer: %s' % self.buffer) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + if self.buffer[1] is not None: + cfg.logger.log.debug('self.buffer[1]: %s' % self.buffer[1]) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(True) + return self.buffer[0] + + def set_max_size(self, max_size): + self.max_size = max_size + signature_catalog = self.buffer[0] + self.buffer = {} + for key in range(-max_size, max_size + 1): + self.buffer[key] = None + self.buffer[0] = signature_catalog + + +""" Class to manage signature catalog and vector input in QGIS """ + + +class TrainingVectorLayer: + + # noinspection PyArgumentList + def __init__( + self, signature_catalog: SpectralSignaturesCatalog, + output_path: str + ): + # vector layer + self.vector = None + self.layer = None + # layer editing + self.editing = False + # dictionary of items of ROI and signatures in dock tree + self.class_dock_tree = {} + # dictionary of items of macroclasses in dock tree + self.macroclass_dock_tree = {} + self.collapse_tree = True + # reset classification preview classifier + cfg.classifier_preview = None + cfg.dock_class_dlg.ui.button_Save_ROI.setEnabled(False) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(False) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # reset + if signature_catalog is False: + # reset table tree + self.tree = self.clear_tree() + project = cfg.util_qgis.get_qgis_project() + # remove training input + if cfg.scp_training is not None: + try: + project.removeMapLayer(cfg.scp_training.layer) + except Exception as err: + str(err) + cfg.scp_training = None + cfg.project_registry[cfg.reg_training_input_path] = '' + cfg.dock_class_dlg.ui.trainingFile_lineEdit.setText('') + # init + else: + cfg.logger.log.debug( + 'TrainingVectorLayer output_path: %s' % str(output_path) + ) + # create buffer + self.signature_catalog_buffer = SignatureCatalogBuffer( + signature_catalog, + max_size=cfg.qgis_registry[cfg.reg_max_train_buffer] + ) + self.signature_catalog = signature_catalog + cfg.logger.log.debug( + 'signature_catalog %s' + % str(signature_catalog) + ) + self.temporary_file = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.scpx' + ) + ) + cfg.logger.log.debug( + 'self.temporary_file: %s' + % str(self.temporary_file) + ) + # define output path + self.output_path = output_path + cfg.logger.log.debug( + 'self.output_path: %s' + % str(self.output_path) + ) + cfg.project_registry[cfg.reg_training_input_path] = output_path + cfg.dock_class_dlg.ui.trainingFile_lineEdit.setText(output_path) + # create self.layer in map + self.add_vector_to_map() + # connect project saved + cfg.util_qgis.get_qgis_project().projectSaved.connect( + self.project_saved + ) + # connect to table tree + self.tree = self.roi_signature_table_tree() + + # disable editing + # noinspection PyPep8Naming + def beforeEditingStarted(self): + if self.editing is False: + self.layer.commitChanges(stopEditing=True) + cfg.mx.msg_inf_1() + + # set max size buffer + def set_max_size_buffer(self, max_size): + self.signature_catalog_buffer.max_size(max_size) + + # save signature catalog to file + def signature_catalog_copy(self): + cfg.logger.log.debug('signature_catalog_copy') + signature_catalog = deepcopy(self.signature_catalog) + # copy geometry file to temporary file + geometry_temp_path = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + ) + cfg.rs.files_directories.copy_file( + signature_catalog.geometry_file, geometry_temp_path + ) + signature_catalog.geometry_file = geometry_temp_path + return signature_catalog + + # save signature catalog to file + def project_saved(self): + self.save_signature_catalog(path=self.output_path) + # save backup + self.save_signature_catalog( + path='%s%s' % (self.output_path, cfg.backup_name) + ) + + # reset signature catalog + def reset_signature_catalog(self): + cfg.logger.log.debug('reset_signature_catalog') + project = cfg.util_qgis.get_qgis_project() + try: + project.removeMapLayer(self.layer) + except Exception as err: + str(err) + cfg.map_canvas.setRenderFlag(False) + cfg.map_canvas.setRenderFlag(True) + self.signature_catalog_buffer = None + self.signature_catalog = None + self.vector = None + self.layer = None + self.output_path = '' + cfg.dock_class_dlg.ui.trainingFile_lineEdit.setText('') + cfg.project_registry[cfg.reg_training_input_path] = '' + # reset table tree + self.tree = self.clear_tree() + self.macroclass_dock_tree = {} + cfg.dock_class_dlg.ui.label_48.setText( + cfg.translate(' ROI & Signature list') + ) + + # save signature catalog to file + def save_signature_catalog(self, path=None, signature_id_list=None): + if path is None: + path = self.output_path + if self.signature_catalog is not None: + self.signature_catalog.save( + output_path=path, signature_id_list=signature_id_list + ) + cfg.logger.log.debug('save_signature_catalog: %s' % str(path)) + else: + cfg.logger.log.debug('save_signature_catalog: catalog is None') + + # save signature catalog to temporary file + def save_temporary_signature_catalog(self): + cfg.logger.log.debug('save_temporary_signature_catalog') + if self.signature_catalog is not None: + self.signature_catalog.save(self.temporary_file) + cfg.logger.log.debug( + 'save_temporary_signature_catalog: %s' + % str(self.temporary_file) + ) + else: + cfg.logger.log.debug('save_signature_catalog: catalog is None') + + # set new signature catalog + # noinspection PyArgumentList + def set_signature_catalog(self, signature_catalog): + cfg.logger.log.debug('set_signature_catalog') + self.signature_catalog_buffer.set_catalog(signature_catalog) + self.signature_catalog = signature_catalog + # create self.layer in map + self.add_vector_to_map() + + # edit vector + def edit_vector(self, expression, field_name, value): + self.editing = True + cfg.util_qgis.edit_layer_features( + layer=self.layer, expression=expression, field_name=field_name, + value=value + ) + self.editing = False + + # undo signature catalog + def undo(self): + cfg.logger.log.debug('undo') + if self.signature_catalog is not None: + cfg.logger.log.debug( + 'self.signature_catalog.geometry_file: %s' + % str(self.signature_catalog.geometry_file) + ) + self.signature_catalog = self.signature_catalog_buffer.undo() + # connect to table tree + self.tree = self.roi_signature_table_tree() + # create self.layer in map + self.add_vector_to_map() + + # redo signature catalog + def redo(self): + cfg.logger.log.debug('redo') + if self.signature_catalog is not None: + cfg.logger.log.debug( + 'self.signature_catalog.geometry_file: %s' + % str(self.signature_catalog.geometry_file) + ) + self.signature_catalog = self.signature_catalog_buffer.redo() + # connect to table tree + self.tree = self.roi_signature_table_tree() + # create self.layer in map + self.add_vector_to_map() + + # add vector to map + def add_vector_to_map(self): + project = cfg.util_qgis.get_qgis_project() + cfg.map_canvas.setRenderFlag(False) + if self.layer is not None: + try: + project.removeMapLayer(self.layer) + self.vector = None + except Exception as err: + str(err) + if self.signature_catalog is not None: + cfg.logger.log.debug( + 'self.signature_catalog.geometry_file: %s' + % str(self.signature_catalog.geometry_file) + ) + self.vector = cfg.util_qgis.add_vector_layer( + self.signature_catalog.geometry_file, cfg.scp_layer_name, 'ogr' + ) + self.layer = project.addMapLayer(self.vector) + table_config = self.layer.attributeTableConfig() + try: + table_config.setColumnHidden(0, True) + table_config.setColumnHidden(1, True) + self.layer.setAttributeTableConfig(table_config) + cfg.util_qgis.training_symbol(self.layer) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.map_canvas.setRenderFlag(True) + # disable layer editing + self.layer.editingStarted.connect(self.beforeEditingStarted) + + # edit signature value + def edit_signature_value(self, signature_id, field, value): + self.signature_catalog.table[field][ + self.signature_catalog.table['signature_id'] == signature_id + ] = value + + # create ROI and signature table tree + def roi_signature_table_tree(self, tree=None): + cfg.logger.log.debug('roi_signature_table_tree') + # reset classification preview classifier + cfg.classifier_preview = None + self.tree = self.clear_tree(tree) + self.tree.blockSignals(True) + self.tree.setSortingEnabled(False) + macroclass_list = [] + # macroclasses + for macroclass in self.signature_catalog.macroclasses: + macroclass_name = self.signature_catalog.macroclasses[macroclass] + macroclass_list.append(macroclass_name) + if macroclass in self.signature_catalog.macroclasses_color_string: + macroclass_color = ( + self.signature_catalog.macroclasses_color_string[ + macroclass + ] + ) + else: + macroclass_color = cfg.rs.shared_tools.random_color() + self.signature_catalog.macroclasses_color_string[ + macroclass] = macroclass_color + # add macroclass items + self.add_macroclass_tree_item( + macroclass=macroclass, macroclass_info=macroclass_name, + color=macroclass_color, checkbox_state=None + ) + cfg.logger.log.debug('macroclass_list: %s' % str(macroclass_list)) + # add spectral signatures and ROIs + if self.signature_catalog.table is None: + signatures = [] + else: + signatures = self.signature_catalog.table.signature_id.tolist() + class_name_list = [] + for signature in signatures: + signature_array = self.signature_catalog.table[ + self.signature_catalog.table['signature_id'] == signature] + macroclass_id = signature_array.macroclass_id[0] + class_id = signature_array.class_id[0] + class_name = signature_array.class_name[0] + class_name_list.append(class_name) + selected = signature_array.selected[0] + geometry_check = signature_array.geometry[0] + signature_check = signature_array.signature[0] + color = signature_array.color[0] + if signature_check == 1 and geometry_check == 1: + type_info = cfg.roi_and_signature_type + elif geometry_check == 1: + type_info = cfg.roi_type + elif signature_check == 1: + type_info = cfg.signature_type + else: + type_info = '' + cfg.logger.log.error('type_info empty') + # replace for checkbox state + if selected == 1: + selected = 2 + self.add_class_tree_item( + macroclass_id=macroclass_id, class_id=class_id, + class_info=class_name, type_info=type_info, + signature_id=signature, color=color, checkbox_state=selected + ) + cfg.logger.log.debug('class_name_list: %s' % str(class_name_list)) + self.tree.show() + self.tree.setSortingEnabled(True) + self.tree.blockSignals(False) + # info completer + class_info_completer(class_name_list) + macroclass_info_completer(macroclass_list) + # filter + filter_tree() + # connect signature threshold table + cfg.signature_threshold.signature_thresholds_to_table() + cfg.scp_training = self + return self.tree + + # add signature item + def add_class_tree_item( + self, macroclass_id, class_id, class_info, + type_info, signature_id, color=None, checkbox_state=None + ): + self.class_dock_tree[str(signature_id)] = QTreeWidgetItem() + try: + self.macroclass_dock_tree[macroclass_id].addChild( + self.class_dock_tree[str(signature_id)] + ) + except Exception as err: + cfg.logger.log.error(str(err)) + self.add_macroclass_tree_item( + macroclass=macroclass_id, macroclass_info='' + ) + self.class_dock_tree[str(signature_id)].setFlags( + Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | + Qt.ItemIsSelectable | Qt.ItemIsDragEnabled + ) + if checkbox_state is not None: + self.class_dock_tree[str(signature_id)].setCheckState( + 0, int(checkbox_state) + ) + self.class_dock_tree[str(signature_id)].setData( + 0, 0, int(macroclass_id) + ) + self.class_dock_tree[str(signature_id)].setData( + 1, 0, int(class_id) + ) + self.class_dock_tree[str(signature_id)].setData( + 2, 0, str(class_info) + ) + self.class_dock_tree[str(signature_id)].setData( + 3, 0, str(type_info) + ) + self.class_dock_tree[str(signature_id)].setData( + 5, 0, str(signature_id) + ) + if color is not None: + self.class_dock_tree[str(signature_id)].setBackground( + 4, QColor(color) + ) + + # add macroclass item + def add_macroclass_tree_item( + self, macroclass, macroclass_info, color=None, checkbox_state=None + ): + row = self.tree.topLevelItemCount() + self.macroclass_dock_tree[macroclass] = QTreeWidgetItem(row) + self.tree.addTopLevelItem(self.macroclass_dock_tree[macroclass]) + self.macroclass_dock_tree[macroclass].setFlags( + Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable | + Qt.ItemIsDropEnabled + ) + self.macroclass_dock_tree[macroclass].setExpanded(True) + self.macroclass_dock_tree[macroclass].setData( + 0, 0, int(macroclass) + ) + self.macroclass_dock_tree[macroclass].setData( + 2, 0, str(macroclass_info) + ) + self.macroclass_dock_tree[macroclass].setData( + 5, 0, int(macroclass) + ) + font = QFont() + font.setBold(True) + self.macroclass_dock_tree[macroclass].setFont(0, font) + self.macroclass_dock_tree[macroclass].setFont(2, font) + if checkbox_state is not None: + self.macroclass_dock_tree[macroclass].setCheckState( + 0, checkbox_state + ) + if color is not None: + self.macroclass_dock_tree[macroclass].setBackground( + 4, QColor(color) + ) + + # clear tree + # noinspection PyUnresolvedReferences + def clear_tree(self, tree=None): + cfg.logger.log.debug('clear_tree') + self.class_dock_tree = {} + self.macroclass_dock_tree = {} + if tree is None: + order = 0 + sorter = Qt.AscendingOrder + else: + order = tree.header().sortIndicatorOrder() + sorter = tree.header().sortIndicatorSection() + tree.deleteLater() + cfg.dock_class_dlg.ui.signature_list_treeWidget = ( + QTreeWidget(cfg.dock_class_dlg.ui.tab_2) + ) + tree_widget = cfg.dock_class_dlg.ui.signature_list_treeWidget + tree_widget.setEditTriggers( + QAbstractItemView.AnyKeyPressed | QAbstractItemView.SelectedClicked + ) + tree_widget.setAlternatingRowColors(True) + tree_widget.setSelectionMode( + QAbstractItemView.MultiSelection + ) + tree_widget.setIndentation(5) + tree_widget.setExpandsOnDoubleClick(False) + tree_widget.setObjectName('signature_list_treeWidget') + cfg.dock_class_dlg.ui.gridLayout.addWidget(tree_widget, 1, 1, 1, 1) + tree_widget.setSortingEnabled(True) + tree_widget.headerItem().setText(0, cfg.translate('MC ID')) + tree_widget.headerItem().setText(1, cfg.translate('C ID')) + tree_widget.headerItem().setText(2, cfg.translate('Name')) + tree_widget.headerItem().setText(3, cfg.translate('Type')) + tree_widget.headerItem().setText(4, cfg.translate('Color')) + tree_widget.headerItem().setText(5, 'signature_id') + # tree list + tree_widget.header().hideSection(5) + tree_widget.header().setSortIndicator(sorter, order) + cfg.util_qt.set_tree_column_width_list( + tree_widget, [[0, 60], [1, 30], [2, 100], [3, 40], [4, 30]] + ) + # connect to edited cell + tree_widget.itemChanged.connect(self.edited_cell_tree) + # connect to signature list double click + tree_widget.itemDoubleClicked.connect(self.signature_tree_double_click) + # context menu + tree_widget.setContextMenuPolicy(Qt.CustomContextMenu) + tree_widget.customContextMenuRequested.connect(context_menu) + return tree_widget + + # edit macroclass value + def edit_macroclass(self, macroclass_value): + ids = self.get_highlighted_ids() + for signature_id in ids: + # set macroclass in table + old_value = self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table['signature_id'] == signature_id + ] + self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = macroclass_value + # add macroclass in dictionary + if macroclass_value not in self.signature_catalog.macroclasses: + self.signature_catalog.macroclasses[macroclass_value] = ( + 'macroclass' + ) + macroclass_color = ( + cfg.rs.shared_tools.random_color() + ) + self.signature_catalog.macroclasses_color_string[ + macroclass_value] = macroclass_color + # check if isolated macroclass + check_id = self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'macroclass_id'] == old_value] + if len(check_id) == 0: + try: + del self.signature_catalog.macroclasses[ + old_value] + del self.macroclass_dock_tree[old_value] + cat = self.signature_catalog + del cat.macroclasses_color_string[old_value] + except Exception as err: + str(err) + # set macroclass in geometry + expression = '"%s" = \'%s\'' % ( + cfg.rs.configurations.uid_field_name, signature_id + ) + self.edit_vector( + expression=expression, field_name='macroclass_id', + value=macroclass_value + ) + + # edited cell + def edited_cell_tree(self, item, column): + table = cfg.dock_class_dlg.ui.signature_list_treeWidget + table.setSortingEnabled(False) + table.blockSignals(True) + reload = False + # items + try: + signature_id = list(self.class_dock_tree.keys())[ + list(self.class_dock_tree.values()).index(item)] + macroclass_id = False + except Exception as err: + str(err) + try: + macroclass_id = list(self.macroclass_dock_tree.keys())[ + list(self.macroclass_dock_tree.values()).index(item)] + signature_id = False + except Exception as err: + cfg.logger.log.error(str(err)) + self.roi_signature_table_tree() + return + # item value + value = item.text(column) + cfg.logger.log.debug( + 'edited_cell_tree column: %s; value: %s' + % (str(column), str(value)) + ) + cfg.logger.log.debug( + 'signature_id: %s; macroclass_id: %s' + % (str(signature_id), str(macroclass_id)) + ) + # macroclass column + if column == 0: + # signature item + if signature_id is not False: + # get old value from table + old_value = self.signature_catalog.table[ + self.signature_catalog.table[ + 'signature_id'] == signature_id].macroclass_id[0] + try: + value = int(value) + except Exception as err: + str(err) + item.setData(column, old_value) + value = old_value + if old_value != value: + if value < 0: + item.setData(column, old_value) + else: + # set macroclass in table + self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = value + # add macroclass in dictionary + if value not in self.signature_catalog.macroclasses: + self.signature_catalog.macroclasses[value] = ( + 'macroclass' + ) + macroclass_color = ( + cfg.rs.shared_tools.random_color() + ) + self.signature_catalog.macroclasses_color_string[ + value] = macroclass_color + # check if isolated macroclass + check_id = self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'macroclass_id'] == old_value] + if len(check_id) == 0: + try: + del self.signature_catalog.macroclasses[ + old_value] + del self.macroclass_dock_tree[old_value] + cat = self.signature_catalog + del cat.macroclasses_color_string[old_value] + except Exception as err: + str(err) + # set macroclass in geometry + expression = '"%s" = \'%s\'' % ( + cfg.rs.configurations.uid_field_name, signature_id + ) + self.edit_vector( + expression=expression, field_name='macroclass_id', + value=value + ) + # set selected in table + checked = item.checkState(0) + if checked == 2: + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = 1 + else: + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = 0 + reload = True + # macroclass item + elif macroclass_id is not False: + # get old value from table + old_value = macroclass_id + try: + value = int(value) + except Exception as err: + str(err) + item.setData(column, old_value) + value = old_value + if old_value != value: + if value < 0: + item.setData(column, old_value) + value = old_value + # add macroclass in dictionary + if value not in self.signature_catalog.macroclasses: + self.signature_catalog.macroclasses[value] = ( + 'macroclass' + ) + macroclass_color = cfg.rs.shared_tools.random_color() + self.signature_catalog.macroclasses_color_string[ + value] = macroclass_color + # change signature macroclass + self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'macroclass_id'] == old_value] = value + # check if isolated macroclass + check_id = self.signature_catalog.table.macroclass_id[ + self.signature_catalog.table[ + 'macroclass_id'] == old_value] + if len(check_id) == 0: + try: + del self.signature_catalog.macroclasses[ + old_value] + del self.macroclass_dock_tree[old_value] + cat = self.signature_catalog + del cat.macroclasses_color_string[old_value] + except Exception as err: + str(err) + # set macroclass in geometry + expression = '"%s" = \'%s\'' % ( + 'macroclass_id', old_value + ) + self.edit_vector( + expression=expression, field_name='macroclass_id', + value=value + ) + reload = True + else: + reload = True + # class column + elif column == 1: + # signature item + if signature_id is not False: + # get old value from table + old_value = self.signature_catalog.table[ + self.signature_catalog.table[ + 'signature_id'] == signature_id].class_id[0] + try: + value = int(value) + except Exception as err: + str(err) + item.setData(column, old_value) + value = old_value + if old_value != value: + if value < 0: + item.setData(column, old_value) + else: + # set class in table + self.signature_catalog.table.class_id[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = value + # set class in geometry + expression = '"%s" = \'%s\'' % ( + cfg.rs.configurations.uid_field_name, signature_id + ) + self.edit_vector( + expression=expression, field_name='class_id', + value=value + ) + # set selected in table + checked = item.checkState(0) + if checked == 2: + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = 1 + else: + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = 0 + reload = True + # info column + elif column == 2: + # signature item + if signature_id is not False: + # set class in table + self.signature_catalog.table.class_name[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = str(value) + # macroclass item + elif macroclass_id is not False: + self.signature_catalog.macroclasses[ + macroclass_id] = str(value) + # type column + elif column == 3: + item.setData(column, '') + # color column + elif column == 4: + item.setData(column, '') + table.clearSelection() + table.setSortingEnabled(True) + table.blockSignals(False) + if reload is True: + self.roi_signature_table_tree() + else: + # info completer + class_info = self.signature_catalog.table.class_name.tolist() + class_info_completer(class_info) + macroclass_info = self.signature_catalog.macroclasses.values() + macroclass_info_completer(macroclass_info) + + # signature table double click + def signature_tree_double_click(self, item, column): + table = cfg.dock_class_dlg.ui.signature_list_treeWidget + table.setSortingEnabled(False) + table.blockSignals(True) + reload = False + # items + try: + signature_id = list(self.class_dock_tree.keys())[ + list(self.class_dock_tree.values()).index(item)] + macroclass_id = False + except Exception as err: + str(err) + macroclass_id = list(self.macroclass_dock_tree.keys())[ + list(self.macroclass_dock_tree.values()).index(item)] + signature_id = False + cfg.logger.log.debug( + 'signature_id: %s; macroclass_id: %s' + % (str(signature_id), str(macroclass_id)) + ) + if column == 0 or column == 1 or column == 2 or column == 3: + if macroclass_id is not False: + item.setExpanded(not item.isExpanded()) + # color column + elif column == 4: + color = cfg.util_qt.select_color() + if color is not None: + # signature item + if signature_id is not False: + for selected in table.selectedItems(): + signature = selected.text(5) + # set color in table + self.signature_catalog.table.color[ + self.signature_catalog.table[ + 'signature_id'] == signature] = str( + color.toRgb().name() + ) + # macroclass item + elif macroclass_id is not False: + self.signature_catalog.macroclasses_color_string[ + macroclass_id] = color.toRgb().name() + reload = True + table.setSortingEnabled(True) + table.blockSignals(False) + if reload is True: + self.roi_signature_table_tree() + + # select all signatures + def select_all_signatures(self, check=None, selected=None): + # select all + if check is True: + self.all_items_set_state(1, selected) + # unselect all + else: + self.all_items_set_state(0, selected) + + # set all items to state 0 or 2 + def all_items_set_state(self, value, only_selected=None): + tree = cfg.dock_class_dlg.ui.signature_list_treeWidget + if only_selected is False: + # set same state for all + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] != '0'] = value + else: + for row in tree.selectedItems(): + # classes + if len(row.text(1)) > 0: + signature = row.text(5) + # set selected + # noinspection PyUnresolvedReferences + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature] = value + # macroclasses + else: + count = row.childCount() + for selected_row in range(0, count): + signature = row.child(selected_row).text(5) + # set selected + # noinspection PyUnresolvedReferences + self.signature_catalog.table.selected[ + self.signature_catalog.table[ + 'signature_id'] == signature] = value + self.roi_signature_table_tree() + + # change color + def change_color(self, color): + tree = cfg.dock_class_dlg.ui.signature_list_treeWidget + if len(tree.selectedItems()) > 0: + for item in tree.selectedItems(): + try: + signature_id = list(self.class_dock_tree.keys())[ + list(self.class_dock_tree.values()).index(item)] + macroclass_id = False + except Exception as err: + str(err) + macroclass_id = list(self.macroclass_dock_tree.keys())[ + list(self.macroclass_dock_tree.values()).index(item)] + signature_id = False + # set color in table + # signature item + if signature_id is not False: + # set color in table + self.signature_catalog.table.color[ + self.signature_catalog.table[ + 'signature_id'] == signature_id] = str( + color.toRgb().name() + ) + # macroclass item + elif macroclass_id is not False: + self.signature_catalog.macroclasses_color_string[ + macroclass_id] = color.toRgb().name() + self.roi_signature_table_tree() + + # add signature + def add_spectral_signature_to_catalog( + self, values, wavelengths, standard_deviations, + macroclass_id=None, macroclass_name=None, class_id=None, + class_name=None + ): + color_string = cfg.rs.shared_tools.random_color() + unit = self.signature_catalog.bandset.get_wavelength_units()[0] + if macroclass_id is None: + macroclass_id = cfg.project_registry[cfg.reg_roi_macroclass_id] + if macroclass_name is None: + macroclass_name = cfg.project_registry[cfg.reg_roi_macroclass_name] + if class_id is None: + class_id = int(cfg.project_registry[cfg.reg_roi_class_id]) + if class_name is None: + class_name = cfg.project_registry[cfg.reg_roi_class_name] + value_list = [] + wavelength_list = [] + standard_deviation_list = [] + bandset_wavelength = self.signature_catalog.bandset.bands['wavelength'] + wavelength = numpy.array(wavelengths) + for b in bandset_wavelength.tolist(): + arg_min = numpy.abs(wavelength - b).argmin() + wavelength_list.append(b) + value_list.append(values[arg_min]) + standard_deviation_list.append(standard_deviations[arg_min]) + self.signature_catalog.add_spectral_signature( + value_list=value_list, macroclass_id=macroclass_id, + class_id=class_id, macroclass_name=macroclass_name, + class_name=class_name, wavelength_list=wavelength_list, + standard_deviation_list=standard_deviation_list, geometry=0, + signature=1, color_string=color_string, pixel_count=0, + unit=unit + ) + self.roi_signature_table_tree() + + # delete highlighted signatures + def delete_selected_signatures(self): + ids = self.get_highlighted_ids() + for signature in ids: + self.signature_catalog.remove_signature_by_id( + signature_id=signature + ) + + # merge highlighted signatures + def merge_selected_signatures(self): + ids = self.get_highlighted_ids() + random_color = cfg.rs.shared_tools.random_color() + try: + self.signature_catalog.merge_signatures_by_id( + signature_id_list=ids, calculate_signature=True, + macroclass_id=int( + cfg.project_registry[cfg.reg_roi_macroclass_id] + ), + class_id=int(cfg.project_registry[cfg.reg_roi_class_id]), + macroclass_name=cfg.project_registry[ + cfg.reg_roi_macroclass_name + ], + class_name=cfg.project_registry[cfg.reg_roi_class_name], + color_string=random_color + ) + except Exception as err: + str(err) + cfg.mx.msg_err_6() + cfg.logger.log.error('signature ids: %s' % (str(ids))) + + # import spectral signature file + def import_file(self, file_path): + self.signature_catalog.import_file(file_path=file_path) + self.roi_signature_table_tree() + + # import spectral signature file old version + def import_scp_file(self, scp_file_path): + with zipfile.ZipFile(scp_file_path) as open_file: + for file_name in open_file.namelist(): + if file_name.endswith('.gpkg'): + unzip_file = open_file.open(file_name) + file_path = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + ) + try: + unzip_temp_text = open(file_path, 'wb') + with unzip_file, unzip_temp_text: + shutil.copyfileobj( + unzip_file, unzip_temp_text + ) + unzip_temp_text.close() + except Exception as err: + str(err) + break + self.signature_catalog.import_vector( + file_path=file_path, + macroclass_field='MC_ID', + macroclass_name_field='MC_name', + class_field='C_ID', class_name_field='C_name', + calculate_signature=True + ) + self.roi_signature_table_tree() + + # import csv file to catalog + def import_csv_file(self, file_path): + random_color = cfg.rs.shared_tools.random_color() + try: + self.signature_catalog.import_spectral_signature_csv( + csv_path=file_path, + macroclass_id=int( + cfg.project_registry[cfg.reg_roi_macroclass_id] + ), + class_id=int(cfg.project_registry[cfg.reg_roi_class_id]), + macroclass_name=cfg.project_registry[ + cfg.reg_roi_macroclass_name], + class_name=cfg.project_registry[cfg.reg_roi_class_name], + color_string=random_color + ) + self.roi_signature_table_tree() + except Exception as err: + str(err) + cfg.mx.msg_err_6() + cfg.logger.log.error('import_csv_file: %s' % (str(file_path))) + + # import vector file + def import_vector( + self, file_path, macroclass_field, macroclass_name_field, + class_field, class_name_field, calculate_signature + ): + self.signature_catalog.import_vector( + file_path=file_path, macroclass_field=macroclass_field, + macroclass_name_field=macroclass_name_field, + class_field=class_field, class_name_field=class_name_field, + calculate_signature=calculate_signature + ) + self.roi_signature_table_tree() + + # calculate signature of highlighted signatures + def calculate_signature_of_selected_signatures(self): + ids = self.get_highlighted_ids() + for _id in ids: + signature_array = self.signature_catalog.table[ + self.signature_catalog.table['signature_id'] == _id] + geometry_check = signature_array.geometry[0] + if geometry_check == 1: + macroclass_id = signature_array.macroclass_id[0] + class_id = signature_array.class_id[0] + class_name = signature_array.class_name[0] + color = signature_array.color[0] + macroclass_name = self.signature_catalog.macroclasses[ + macroclass_id + ] + try: + # calculate signature as merging one ROI + self.signature_catalog.merge_signatures_by_id( + signature_id_list=[_id], calculate_signature=True, + macroclass_id=macroclass_id, class_id=class_id, + macroclass_name=macroclass_name, class_name=class_name, + color_string=color + ) + # remove original signature + self.signature_catalog.remove_signature_by_id( + signature_id=_id + ) + except Exception as err: + str(err) + cfg.mx.msg_err_6() + cfg.logger.log.error('signature id: %s' % (str(_id))) + + # get highlighted IDs + def get_highlighted_ids(self, select_all=None, signatures=None): + tree = cfg.dock_class_dlg.ui.signature_list_treeWidget + if select_all is True: + # get only signature + if signatures is True: + ids = self.signature_catalog.table.signature_id[ + self.signature_catalog.table['signature'] == 1 + ].tolist() + else: + ids = self.signature_catalog.table.signature_id.tolist() + else: + ids = [] + for row in tree.selectedItems(): + # classes + if len(row.text(1)) > 0: + signature = row.text(5) + # set selected + # noinspection PyUnresolvedReferences + ids.append( + self.signature_catalog.table.signature_id[ + self.signature_catalog.table[ + 'signature_id'] == signature][0] + ) + # macroclasses + else: + count = row.childCount() + for selected_row in range(0, count): + signature = row.child(selected_row).text(5) + # set selected + # noinspection PyUnresolvedReferences + ids.append( + self.signature_catalog.table.signature_id[ + self.signature_catalog.table[ + 'signature_id'] == signature][0] + ) + cfg.logger.log.debug('get_highlighted_ids: %s' % (str(ids))) + return ids + + # collapse menu + def collapse(self): + if self.collapse_tree is True: + cfg.dock_class_dlg.ui.signature_list_treeWidget.collapseAll() + self.collapse_tree = False + else: + cfg.dock_class_dlg.ui.signature_list_treeWidget.expandAll() + self.collapse_tree = True + + # calculate unique class id to macroclass id + def calculate_unique_c_id_mc_id(self): + value_list = [] + for macroclass in self.signature_catalog.macroclasses: + class_value = self.signature_catalog.table.class_id[ + self.signature_catalog.table['macroclass_id'] == macroclass][0] + value_list.append([class_value, macroclass]) + return value_list + + +""" Interface functions """ + + +# reset input +def reset_input(): + answer = cfg.util_qt.question_box( + cfg.translate('Remove training input'), + cfg.translate('Are you sure you want to remove training input?') + ) + if answer is True: + reset_input_dock() + + +# reset input +def reset_input_dock(): + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(False) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + if cfg.scp_training is not None: + cfg.scp_training.reset_signature_catalog() + + +# calculate signatures +def calculate_signatures(): + ids = cfg.scp_training.get_highlighted_ids(select_all=False) + if len(ids) == 0: + return 0 + answer = cfg.util_qt.question_box( + cfg.translate('Calculate signatures'), + cfg.translate('Calculate signatures for highlighted items?') + ) + if answer is True: + # save previous catalog file + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + cfg.ui_utils.add_progress_bar() + cfg.scp_training.calculate_signature_of_selected_signatures() + cfg.ui_utils.remove_progress_bar() + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # create table tree + cfg.scp_training.roi_signature_table_tree() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + + +# merge highlighted signatures +def merge_signatures(): + table = cfg.dock_class_dlg.ui.signature_list_treeWidget + selected = table.selectedItems() + if len(selected) > 0: + answer = cfg.util_qt.question_box( + cfg.translate('Merge signatures'), + cfg.translate('Merge highlighted signatures?') + ) + if answer is True: + # save previous catalog file + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + cfg.ui_utils.add_progress_bar() + cfg.scp_training.merge_selected_signatures() + cfg.ui_utils.remove_progress_bar() + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # create table tree + cfg.scp_training.roi_signature_table_tree() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + + +# remove selected signatures +def remove_selected_signatures(): + table = cfg.dock_class_dlg.ui.signature_list_treeWidget + selected = table.selectedItems() + if len(selected) > 0: + answer = cfg.util_qt.question_box( + cfg.translate('Delete signatures'), + cfg.translate( + 'Are you sure you want to delete highlighted ROIs ' + 'and signatures?' + ) + ) + if answer is True: + # save previous catalog file + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + cfg.scp_training.delete_selected_signatures() + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # create table tree + cfg.scp_training.roi_signature_table_tree() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + + +# zoom to clicked ROI +def zoom_to_roi_polygons(expression): + if cfg.scp_training is not None: + cfg.map_canvas.setRenderFlag(False) + zoom_to_selected(cfg.scp_training.layer, expression) + cfg.util_qgis.set_layer_visible(cfg.scp_training.layer, True) + cfg.util_qgis.move_layer_to_top(cfg.scp_training.layer) + cfg.map_canvas.setRenderFlag(True) + + +# Zoom to selected feature of layer +def zoom_to_selected(layer, expression): + layer.removeSelection() + layer.selectByExpression(expression) + cfg.map_canvas.zoomToSelected(layer) + layer.removeSelection() + + +# Activate signature calculation +def signature_checkbox(): + if cfg.dock_class_dlg.ui.signature_checkBox.isChecked() is True: + cfg.project_registry[cfg.reg_signature_calculation_check] = 2 + cfg.dialog.ui.signature_checkBox2.blockSignals(True) + cfg.dialog.ui.signature_checkBox2.setCheckState(2) + cfg.dialog.ui.signature_checkBox2.blockSignals(False) + else: + cfg.project_registry[cfg.reg_signature_calculation_check] = 0 + cfg.dialog.ui.signature_checkBox2.blockSignals(True) + cfg.dialog.ui.signature_checkBox2.setCheckState(0) + cfg.dialog.ui.signature_checkBox2.blockSignals(False) + + +# properties menu +def properties_menu(): + add_signature_to_spectral_plot(1) + + +# collapse menu +def collapse_menu(): + cfg.scp_training.collapse() + + +# change macroclass menu +def change_macroclass_menu(): + dock_tree = cfg.dock_class_dlg.ui.signature_list_treeWidget + if len(dock_tree.selectedItems()) > 0: + answer = cfg.util_qt.question_box( + cfg.translate('Change Macroclass ID'), + cfg.translate( + 'Change the Macroclass ID for highlighted items to' + ) + + ' %s ?' % str(cfg.project_registry[cfg.reg_roi_macroclass_id]) + ) + if answer is True: + cfg.scp_training.edit_macroclass( + cfg.project_registry[cfg.reg_roi_macroclass_id] + ) + cfg.scp_training.roi_signature_table_tree() + + +# change color menu +def change_color_menu(): + color = cfg.util_qt.select_color() + if color is not None: + cfg.scp_training.change_color(color) + + +# clear selection menu +def clear_selection_menu(): + cfg.dock_class_dlg.ui.signature_list_treeWidget.clearSelection() + + +# zoom to menu +def zoom_to_menu(): + ids = cfg.scp_training.get_highlighted_ids( + select_all=False, + signatures=False + ) + expression = '' + for _id in ids: + expression += '"%s" = \'%s\' or ' % ( + cfg.rs.configurations.uid_field_name, _id + ) + expression = expression[:-4] + cfg.logger.log.debug('zoom_to_menu expression: %s' % (str(expression))) + zoom_to_roi_polygons(expression) + + +# select all menu +def select_all_menu(): + checked = None + if len( + cfg.dock_class_dlg.ui.signature_list_treeWidget.selectedItems() + ) > 0: + selected = True + items = cfg.dock_class_dlg.ui.signature_list_treeWidget.selectedItems() + else: + selected = False + items = [] + checked = cfg.scp_training.signature_catalog.table.selected[0] + # get check value + for i in items: + # classes + if len(i.text(1)) > 0: + checked = i.checkState(0) + # macroclasses + else: + count = i.childCount() + for r in range(0, count): + checked = i.child(r).checkState(0) + break + if checked == 2 or checked == 1: + cfg.scp_training.select_all_signatures( + check=False, + selected=selected + ) + elif checked == 0: + cfg.scp_training.select_all_signatures( + check=True, + selected=selected + ) + + +# filter tree +def filter_tree(): + text = cfg.dock_class_dlg.ui.ROI_filter_lineEdit.text() + tree = cfg.dock_class_dlg.ui.signature_list_treeWidget + root = tree.invisibleRootItem() + tree.blockSignals(True) + if len(text) > 0: + tree.expandAll() + tree.findItems(text, cfg.util_qt.get_match_contains()) + for i in range(0, root.childCount()): + child_x = root.child(i) + child_x.setHidden(False) + for child in range(0, child_x.childCount()): + if text.lower() in child_x.child(child).text(2).lower(): + child_x.child(child).setHidden(False) + elif text.lower() in child_x.child(child).text(1).lower(): + child_x.child(child).setHidden(False) + elif text.lower() in child_x.child(child).text(0).lower(): + child_x.child(child).setHidden(False) + else: + child_x.child(child).setHidden(True) + else: + tree.expandAll() + for i in range(0, root.childCount()): + child_x = root.child(i) + child_x.setHidden(False) + for child in range(0, child_x.childCount()): + if text in child_x.child(child).text(0): + child_x.child(child).setHidden(False) + tree.blockSignals(False) + + +""" Context menu """ + + +# add item to menu +def add_menu_item(menu, function, icon_name, name, tooltip=''): + try: + action = QAction( + QIcon( + ':/plugins/semiautomaticclassificationplugin/icons/%s' + % icon_name + ), name, cfg.iface.mainWindow() + ) + except Exception as err: + str(err) + action = QAction(name, cfg.iface.mainWindow()) + action.setObjectName('action') + action.setToolTip(tooltip) + action.triggered.connect(function) + menu.addAction(action) + return action + + +# menu +def context_menu(event): + menu = QMenu() + menu.setToolTipsVisible(True) + add_menu_item( + menu, zoom_to_menu, + 'semiautomaticclassificationplugin_zoom_to_ROI.svg', + cfg.translate('Zoom to') + ) + add_menu_item( + menu, select_all_menu, + 'semiautomaticclassificationplugin_options.svg', + cfg.translate('Check/uncheck') + ) + add_menu_item( + menu, clear_selection_menu, + 'semiautomaticclassificationplugin_select_all.svg', + cfg.translate('Clear selection') + ) + add_menu_item( + menu, collapse_menu, 'semiautomaticclassificationplugin_docks.svg', + cfg.translate('Collapse/expand all') + ) + menu.addSeparator() + add_menu_item( + menu, change_macroclass_menu, + 'semiautomaticclassificationplugin_enter.svg', + cfg.translate('Change MC ID') + ) + add_menu_item( + menu, change_color_menu, 'semiautomaticclassificationplugin_enter.svg', + cfg.translate('Change color') + ) + menu.addSeparator() + add_menu_item( + menu, merge_signatures, + 'semiautomaticclassificationplugin_merge_sign_tool.svg', + cfg.translate('Merge items') + ) + add_menu_item( + menu, calculate_signatures, + 'semiautomaticclassificationplugin_add_sign_tool.svg', + cfg.translate('Calculate signatures') + ) + add_menu_item( + menu, remove_selected_signatures, + 'semiautomaticclassificationplugin_remove.svg', + cfg.translate('Delete items') + ) + menu.addSeparator() + add_menu_item( + menu, add_signature_to_spectral_plot, + 'semiautomaticclassificationplugin_sign_tool.svg', + cfg.translate('Add to spectral plot') + ) + add_menu_item( + menu, add_roi_to_scatter_plot, + 'semiautomaticclassificationplugin_scatter_tool.svg', + cfg.translate('Add to scatter plot') + ) + add_menu_item( + menu, properties_menu, + 'semiautomaticclassificationplugin_accuracy_tool.svg', + cfg.translate('Properties') + ) + menu.addSeparator() + add_menu_item( + menu, cfg.input_interface.import_signatures_tab, + 'semiautomaticclassificationplugin_import_spectral_library.svg', + cfg.translate('Import') + ) + add_menu_item( + menu, cfg.input_interface.export_signatures_tab, + 'semiautomaticclassificationplugin_export_spectral_library.svg', + cfg.translate('Export') + ) + menu.exec_( + cfg.dock_class_dlg.ui.signature_list_treeWidget.mapToGlobal(event) + ) + + +""" Toolbar functions """ + + +# create a ROI in the same point +def redo_roi(): + if cfg.last_roi_point is not None: + roi = create_region_growing_roi(cfg.last_roi_point) + if roi is False: + cfg.redo_ROI_Button.setEnabled(False) + + +# show hide ROI radio button +def show_hide_roi(): + try: + if cfg.show_ROI_radioButton.isChecked(): + # training layer + if cfg.scp_training is not None: + cfg.util_qgis.set_layer_visible(cfg.scp_training.layer, True) + cfg.util_qgis.move_layer_to_top(cfg.scp_training.layer) + # rubber roi polygon + if cfg.scp_dock_rubber_roi is not None: + cfg.scp_dock_rubber_roi.show() + # roi polygon + if cfg.roi_map_polygon is not None: + cfg.roi_map_polygon.show() + # roi center + if cfg.roi_center_vertex is not None: + cfg.roi_center_vertex.show() + else: + # training layer + if cfg.scp_training is not None: + cfg.util_qgis.set_layer_visible(cfg.scp_training.layer, False) + # rubber roi polygon + if cfg.scp_dock_rubber_roi is not None: + cfg.scp_dock_rubber_roi.hide() + # roi polygon + if cfg.roi_map_polygon is not None: + cfg.roi_map_polygon.hide() + # roi center + if cfg.roi_center_vertex is not None: + cfg.roi_center_vertex.hide() + cfg.map_canvas.refresh() + except Exception as err: + str(err) + + +# pointer moved +def moved_pointer(point): + calculate_pixel_expression(point) + + +# calculate pixel expression +def calculate_pixel_expression(point): + cursor = QCursor(QPixmap(':/pointer/icons/pointer/ROI_pointer.svg')) + if cfg.project_registry[cfg.reg_index_calculation_check] == 2: + point = cfg.utils.check_point_in_image(point=point) + if point is not False and point is not None: + bandset_x = cfg.bandset_catalog.get( + cfg.project_registry[cfg.reg_active_bandset_number] + ) + if (cfg.dock_class_dlg.ui.vegetation_index_comboBox.currentText() + == 'NDVI'): + expression = cfg.rs.configurations.variable_ndvi_expression + elif (cfg.dock_class_dlg.ui.vegetation_index_comboBox.currentText() + == 'EVI'): + expression = cfg.rs.configurations.variable_evi_expression + else: + expression = cfg.project_registry[ + cfg.reg_roi_custom_expression + ] + cfg.logger.log.debug( + 'calculate_pixel_expression: %s' % str(expression) + ) + if len(expression) > 0: + bandset_x.calc( + expression_string=expression, + point_coordinates=[point.x(), point.y()] + ) + cfg.rs.configurations.multiprocess.multiprocess_pixel_value() + value = cfg.rs.configurations.multiprocess.output + cfg.rs.configurations.multiprocess.output = False + if value is not False: + cursor = cursor_creation(value) + cfg.map_canvas.setCursor(cursor) + + +def cursor_creation(value): + num = str(value)[0:6] + pmap = QPixmap( + ["48 48 3 1", + " c None", + ". c #ffffff", + "+ c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + " ", + " ++++ ", + " +..+ ", + " +..+ ", + " +..+ ", + " +..+ ", + " +++++++..+++++++ ", + " +..............+ ", + " +..............+ ", + " +++++++..+++++++ ", + " +..+ ", + " +..+ ", + " +..+ ", + " +..+ ", + " ++++ ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + ] + ) + painter = QPainter() + painter.begin(pmap) + painter.setPen(QColor(0, 0, 0)) + painter.setFont(QFont('Monospace', 9)) + painter.drawText(QPoint(2, 12), num) + painter.end() + return QCursor(pmap) + + +# set custom expression +# noinspection PyProtectedMember +def custom_expression_edited(): + custom_expression = str(cfg.dock_class_dlg.ui.custom_index_lineEdit.text()) + # check expression + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + # create list of band names from band sets + raster_variables = band_calc._bandset_names_alias(bandset=bandset_x) + (exp_list, all_out_name_list, + output_message) = band_calc._check_expression_bandset( + custom_expression, raster_variables, bandset_x + ) + if output_message is not None: + cfg.project_registry[cfg.reg_roi_custom_expression] = '' + cfg.dock_class_dlg.ui.custom_index_lineEdit.setStyleSheet( + 'color : red' + ) + else: + cfg.project_registry[cfg.reg_roi_custom_expression] = str( + custom_expression + ) + cfg.dock_class_dlg.ui.custom_index_lineEdit.setStyleSheet( + 'color : green' + ) + + +# Activate pointer for ROI creation +def pointer_manual_roi_active(): + cfg.roi_points = [] + cfg.qgis_vertex_item_list = [] + cfg.map_canvas.setMapTool(cfg.manual_roi_pointer) + cursor = QCursor() + cursor.setShape(Qt.CrossCursor) + cfg.map_canvas.setCursor(cursor) + + +# Activate pointer for ROI creation +def pointer_region_growing_roi_active(): + cfg.map_canvas.setMapTool(cfg.region_growing_pointer) + cursor = QCursor(QPixmap(':/pointer/icons/pointer/ROI_pointer.svg')) + cfg.map_canvas.setCursor(cursor) + + +# set min ROI size +def roi_min_size(): + cfg.project_registry[cfg.reg_roi_min_size] = int( + cfg.roi_min_size_spin.value() + ) + # auto refresh ROI + if cfg.roi_time is None: + cfg.roi_time = datetime.now() - timedelta(seconds=2) + if cfg.dock_class_dlg.ui.auto_refresh_ROI_checkBox.isChecked(): + if datetime.now() > ( + cfg.roi_time + timedelta(seconds=1)): + cfg.roi_time = datetime.now() + redo_roi() + + +# set Range radius +def range_radius(): + cfg.project_registry[cfg.reg_roi_range_radius] = float( + cfg.Range_radius_spin.value() + ) + # auto refresh ROI + if cfg.roi_time is None: + cfg.roi_time = datetime.now() - timedelta(seconds=2) + if cfg.dock_class_dlg.ui.auto_refresh_ROI_checkBox.isChecked(): + if datetime.now() > ( + cfg.roi_time + timedelta(seconds=1)): + cfg.roi_time = datetime.now() + redo_roi() + + +# set Max ROI size +def max_roi_width(): + cfg.project_registry[cfg.reg_roi_max_width] = int( + cfg.max_roi_width_spin.value() + ) + # auto refresh ROI + if cfg.roi_time is None: + cfg.roi_time = datetime.now() - timedelta(seconds=2) + if cfg.dock_class_dlg.ui.auto_refresh_ROI_checkBox.isChecked(): + if datetime.now() > ( + cfg.roi_time + timedelta(seconds=1)): + cfg.roi_time = datetime.now() + redo_roi() + + +# set rapid ROI band +def rapid_roi_band(): + cfg.project_registry[cfg.reg_roi_main_band] = ( + cfg.dock_class_dlg.ui.rapidROI_band_spinBox.value() + ) + # auto refresh ROI + if cfg.dock_class_dlg.ui.auto_refresh_ROI_checkBox.isChecked(): + if datetime.now() > ( + cfg.roi_time + timedelta(seconds=1)): + cfg.roi_time = datetime.now() + redo_roi() + + +# Activate rapid ROI creation +def rapid_roi_checkbox(): + if cfg.dock_class_dlg.ui.rapid_ROI_checkBox.isChecked() is True: + cfg.project_registry[cfg.reg_rapid_roi_check] = 2 + else: + cfg.project_registry[cfg.reg_rapid_roi_check] = 0 + # auto refresh ROI + if cfg.dock_class_dlg.ui.auto_refresh_ROI_checkBox.isChecked(): + if datetime.now() > ( + cfg.roi_time + timedelta(seconds=1)): + cfg.roi_time = datetime.now() + redo_roi() + + +# Activate vegetation index checkbox +def vegetation_index_checkbox(): + if cfg.dock_class_dlg.ui.display_cursor_checkBox.isChecked() is True: + cfg.project_registry[cfg.reg_index_calculation_check] = 2 + else: + cfg.project_registry[cfg.reg_index_calculation_check] = 0 + + +# ROI macroclass ID +def roi_macroclass_id_value(): + value = cfg.dock_class_dlg.ui.ROI_Macroclass_ID_spin.value() + cfg.project_registry[cfg.reg_roi_macroclass_id] = value + # set macroclass name if existing + if cfg.scp_training is not None: + if value in cfg.scp_training.signature_catalog.macroclasses: + macroclass = cfg.scp_training.signature_catalog.macroclasses[value] + cfg.dock_class_dlg.ui.ROI_Macroclass_line.setText(macroclass) + cfg.project_registry[cfg.reg_roi_macroclass_name] = macroclass + + +def roi_macroclass_name_info(): + cfg.project_registry[cfg.reg_roi_macroclass_name] = str( + cfg.dock_class_dlg.ui.ROI_Macroclass_line.text() + ) + + +# set ROI class ID +def roi_class_id_value(): + cfg.project_registry[ + cfg.reg_roi_class_id] = cfg.dock_class_dlg.ui.ROI_ID_spin.value() + + +# set ROI class info +def roi_class_name_info(): + cfg.project_registry[cfg.reg_roi_class_name] = str( + cfg.dock_class_dlg.ui.ROI_Class_line.text() + ) + + +# class info completer +def class_info_completer(class_info_list): + try: + # class names + completer_class_name = QCompleter(class_info_list) + cfg.dock_class_dlg.ui.ROI_Class_line.setCompleter( + completer_class_name + ) + except Exception as err: + str(err) + + +# macroclass info completer +def macroclass_info_completer(macroclass_list): + # class names + completer_macroclass_name = QCompleter(macroclass_list) + cfg.dock_class_dlg.ui.ROI_Macroclass_line.setCompleter( + completer_macroclass_name + ) + + +# Activate save input file +def save_input_checkbox(): + if cfg.dock_class_dlg.ui.save_input_checkBox.isChecked() is True: + cfg.project_registry[cfg.reg_save_training_input_check] = 2 + else: + cfg.project_registry[cfg.reg_save_training_input_check] = 0 + + +# max buffer checkbox +def max_buffer(): + value = cfg.dock_class_dlg.ui.max_buffer_spinBox.value() + cfg.qgis_registry[cfg.max_train_buffer_default] = value + if cfg.scp_training is not None: + cfg.scp_training.set_max_size_buffer(value) + + +""" Map functions """ + + +# add roi polygon +def add_roi_polygon_to_map(source_layer, feature_id): + color = QColor(cfg.qgis_registry[cfg.reg_roi_color]) + try: + value = 255 - int( + int(cfg.qgis_registry[cfg.reg_roi_transparency]) * 255 / 100 + ) + color.setAlpha(value) + except Exception as err: + str(err) + color.setAlpha(100) + feature = cfg.util_qgis.get_feature_by_id(source_layer, feature_id) + cfg.roi_map_polygon = QgsHighlight( + cfg.map_canvas, feature.geometry(), source_layer + ) + cfg.roi_map_polygon.setWidth(2) + cfg.roi_map_polygon.setColor(QColor('#53d4e7')) + try: + cfg.roi_map_polygon.setFillColor(color) + except Exception as err: + str(err) + cfg.map_canvas.refresh() + cfg.roi_map_polygon.show() + cfg.show_ROI_radioButton.setChecked(True) + cfg.ctrl_click = None + + +# clear scp dock rubber +def clear_scp_dock_rubber(): + for point in cfg.roi_points: + try: + cfg.map_canvas.scene().removeItem(point) + except Exception as err: + str(err) + cfg.roi_points = [] + cfg.scp_dock_rubber_roi.hide() + cfg.scp_dock_rubber_roi.reset() + if cfg.roi_map_polygon is not None: + cfg.roi_map_polygon.hide() + if cfg.roi_map_polygon is not None: + cfg.map_canvas.scene().removeItem(cfg.roi_map_polygon) + cfg.roi_map_polygon = None + for point in cfg.qgis_vertex_item_list: + cfg.map_canvas.scene().removeItem(point) + del point + if cfg.roi_center_vertex is not None: + cfg.roi_center_vertex.hide() + cfg.qgis_vertex_item_list = [] + cfg.map_canvas.refresh() + + +""" Training input functions """ + + +# Save last ROI to training +def save_roi_to_training(bandset_number=None): + # bandset_number is False when triggered by action + if bandset_number is None or bandset_number is False: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + if cfg.scp_training is None or cfg.scp_training.signature_catalog is None: + cfg.mx.msg_war_5() + return False + elif cfg.temporary_roi is None: + cfg.mx.msg_war_4() + else: + cfg.ui_utils.add_progress_bar() + # get vector from ROI + roi_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + cfg.util_qgis.save_memory_layer_to_geopackage( + cfg.temporary_roi, roi_path + ) + # calculate signature + if cfg.project_registry[cfg.reg_signature_calculation_check] == 2: + calculate_signature = True + else: + calculate_signature = False + cfg.logger.log.debug( + 'bandset number: %s; bandset catalog: %s; ' + 'bandset count: %s; bandset: %s' + % (str(bandset_number), str(cfg.bandset_catalog), + str(cfg.bandset_catalog.get_bandset_count()), + str(cfg.bandset_catalog.get(bandset_number)) + ) + ) + # save previous catalog file + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + # save roi to new catalog + signature_catalog.import_vector( + file_path=roi_path, macroclass_value=int( + cfg.project_registry[cfg.reg_roi_macroclass_id] + ), + class_value=int(cfg.project_registry[cfg.reg_roi_class_id]), + macroclass_name=cfg.project_registry[cfg.reg_roi_macroclass_name], + class_name=cfg.project_registry[cfg.reg_roi_class_name], + calculate_signature=calculate_signature + ) + if cfg.rs.configurations.action: + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + clear_scp_dock_rubber() + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + # increase C_ID + cfg.dock_class_dlg.ui.ROI_ID_spin.setValue( + int(cfg.project_registry[cfg.reg_roi_class_id]) + 1 + ) + # create table tree + cfg.scp_training.roi_signature_table_tree() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + cfg.ui_utils.remove_progress_bar() + + +# undo training modifications +def undo_saved_roi(): + answer = cfg.util_qt.question_box( + cfg.translate('Undo save ROI'), cfg.translate( + 'Are you sure you want to undo?' + ) + ) + if answer is True: + cfg.logger.log.debug('undo') + # training input undo + cfg.scp_training.undo() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + + +# restore training buffered +def redo_saved_roi(): + answer = cfg.util_qt.question_box( + cfg.translate('Redo save ROI'), cfg.translate( + 'Are you sure you want to redo?' + ) + ) + if answer is True: + cfg.logger.log.debug('redo') + # training input redo + cfg.scp_training.redo() + # save training input + if cfg.project_registry[cfg.reg_save_training_input_check] == 2: + cfg.scp_training.save_signature_catalog() + + +# left click +def left_click_manual(point): + qgis_crs = cfg.util_qgis.get_qgis_crs() + point = cfg.utils.check_point_in_image(point=point, output_crs=qgis_crs) + if point is False: + cfg.mx.msg_war_3() + return False + time = cfg.utils.get_time() + name = '%s%s' % (cfg.temp_roi_name, time) + # crs + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + if band_count == 0: + return False + memory_layer = cfg.util_qgis.add_vector_layer( + 'MultiPolygon?crs=%s' % qgis_crs.toWkt(), name, 'memory' + ) + memory_layer.setCrs(qgis_crs) + cfg.roi_points.append(point) + # rubber band polygon to store vertices + cfg.scp_dock_rubber_roi.addPoint(point) + geometry = cfg.scp_dock_rubber_roi.asGeometry() + vertex = QgsVertexMarker(cfg.map_canvas) + vertex.setCenter(point) + cfg.qgis_vertex_item_list.append(vertex) + cfg.scp_dock_rubber_roi.setToGeometry(geometry, qgis_crs) + cfg.scp_dock_rubber_roi.show() + + +# right click +def right_click_manual(point): + qgis_crs = cfg.util_qgis.get_qgis_crs() + left_click_manual(point) + feature = QgsFeature() + time = cfg.utils.get_time() + name = '%s%s' % (cfg.temp_roi_name, time) + # crs + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + if band_count == 0: + return False + memory_layer = cfg.util_qgis.add_vector_layer( + 'MultiPolygon?crs=%s' % qgis_crs.toWkt(), name, 'memory' + ) + memory_layer.setCrs(qgis_crs) + if not len(cfg.roi_points) >= 3: + cfg.mx.msg_inf_2() + clear_scp_dock_rubber() + return + q_point = QPointF() + f_polygon = QPolygonF() + for v in cfg.roi_points: + q_point.setX(v.x()) + q_point.setY(v.y()) + f_polygon.append(q_point) + q_point.setX(cfg.roi_points[0].x()) + q_point.setY(cfg.roi_points[0].y()) + f_polygon.append(q_point) + q_geometry = QgsGeometry().fromQPolygonF(f_polygon) + memory_layer.addTopologicalPoints(q_geometry) + data_provider = memory_layer.dataProvider() + # create temp ROI + memory_layer.startEditing() + # add fields + data_provider.addAttributes( + [QgsField(cfg.empty_field_name, QVariant.Int)] + ) + # add a feature + if cfg.ctrl_click is not None: + q_geometry = add_part_to_roi(q_geometry) + feature.setGeometry(q_geometry) + feature.setAttributes([1]) + data_provider.addFeatures([feature]) + memory_layer.commitChanges() + memory_layer.updateExtents() + cfg.temporary_roi = memory_layer + clear_scp_dock_rubber() + add_roi_polygon_to_map(cfg.temporary_roi, 1) + # calculate temporary spectral signature + if cfg.dock_class_dlg.ui.auto_calculate_ROI_signature_checkBox.isChecked(): + temporary_roi_spectral_signature() + cfg.dock_class_dlg.ui.button_Save_ROI.setEnabled(True) + + +# add multipart ROI +def add_part_to_roi(part): + if cfg.temporary_roi is not None and cfg.ctrl_click is True: + features = cfg.temporary_roi.getFeatures() + feature = QgsFeature() + features.nextFeature(feature) + geometry = QgsGeometry(feature.geometry()) + geometry.convertToMultiType() + part.convertToMultiType() + geometry.addPartGeometry(part) + cfg.second_temporary_roi = cfg.temporary_roi + return geometry + else: + return part + + +def delete_last_roi(): + cfg.temporary_roi = cfg.second_temporary_roi + try: + add_roi_polygon_to_map(cfg.temporary_roi, 1) + except Exception as err: + str(err) + + +# left click +def left_click_region_growing(point): + point = cfg.utils.check_point_in_image(point=point) + cfg.last_roi_point = point + if point is False: + cfg.mx.msg_war_3() + return False + create_region_growing_roi(point) + + +# left click +def right_click_region_growing(point): + point = cfg.utils.check_point_in_image(point=point) + if point is False: + cfg.mx.msg_war_3() + return False + calculate_pixel_signature(point) + + +# right click to calculate point (pixel) signature +# noinspection PyArgumentList +def calculate_pixel_signature(point, bandset_number=None): + if point is not None: + if bandset_number is None: + bandset_number = cfg.project_registry[ + cfg.reg_active_bandset_number] + cfg.rs.configurations.action = True + cfg.ui_utils.add_progress_bar() + try: + # region growing to get pixel + roi_path = cfg.rs.shared_tools.region_growing_polygon( + coordinate_x=point.x(), coordinate_y=point.y(), + input_bands=bandset_number, + max_width=1, max_spectral_distance=1000000, + minimum_size=1, bandset_catalog=cfg.bandset_catalog + ) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_6() + cfg.ui_utils.remove_progress_bar() + return False + bandset = cfg.bandset_catalog.get(bandset_number) + if bandset is None: + return False + else: + band_list = bandset.get_absolute_paths() + temp_bandset = deepcopy(bandset) + bands = temp_bandset.bands + # create virtual raster of input + vrt_check = raster_vector.create_temporary_virtual_raster(band_list) + if bands is not None: + for band in bands: + if cfg.rs.configurations.action is False: + break + path = raster_vector.create_temporary_virtual_raster( + [vrt_check], band_number_list=[[int(band['band_number'])]] + ) + + band['path'] = path + temp_bandset.root_directory = None + signature_catalog = cfg.rs.spectral_signatures_catalog( + bandset=temp_bandset + ) + (value_list, standard_deviation_list, wavelength_list, + pixel_count) = signature_catalog.calculate_signature(roi_path) + cfg.ui_utils.remove_progress_bar() + plot_catalog = cfg.spectral_signature_plotter.plot_catalog + signature_id = generate_signature_id() + color_string = cfg.rs.shared_tools.random_color() + vector_plot = SpectralSignaturePlot( + value=value_list, wavelength=wavelength_list, pixel_count=pixel_count, + standard_deviation=standard_deviation_list, signature_id=signature_id, + macroclass_name=cfg.temp_roi_name, + class_name='point (X=%s; Y=%s)' % (str(point.x()), str(point.y())), + color_string=color_string, selected=1 + ) + plot_catalog.catalog[signature_id] = vector_plot + cfg.spectral_signature_plotter.signature_list_plot_table() + cfg.input_interface.spectral_plot_tab() + + +# create a region growing ROI +# noinspection PyArgumentList +def create_region_growing_roi(point, bandset_number=None): + if point is not None: + cfg.rs.configurations.action = True + if bandset_number is None: + bandset_number = cfg.project_registry[ + cfg.reg_active_bandset_number] + # bands + if cfg.project_registry[cfg.reg_rapid_roi_check] == 2: + bands = int(cfg.project_registry[cfg.reg_roi_main_band]) + else: + bands = None + cfg.ui_utils.add_progress_bar() + # region growing + try: + region_path = cfg.rs.shared_tools.region_growing_polygon( + coordinate_x=point.x(), coordinate_y=point.y(), + input_bands=bandset_number, band_number=bands, + max_width=int(cfg.project_registry[cfg.reg_roi_max_width]), + max_spectral_distance=float( + cfg.project_registry[cfg.reg_roi_range_radius] + ), + minimum_size=int(cfg.project_registry[cfg.reg_roi_min_size]), + bandset_catalog=cfg.bandset_catalog + ) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_6() + cfg.ui_utils.remove_progress_bar() + return False + # create memory temp ROI + region_crs = cfg.util_gdal.get_crs_gdal(region_path) + d_t = cfg.utils.get_time() + temp_name = cfg.temp_roi_name + d_t + memory_layer = cfg.util_qgis.add_vector_layer( + 'MultiPolygon?crs=%s' % str(region_crs), temp_name, 'memory' + ) + crs = cfg.util_qgis.create_qgis_reference_system_from_wkt(region_crs) + memory_layer.setCrs(crs) + memory_layer.startEditing() + # add fields + provider = memory_layer.dataProvider() + provider.addAttributes( + [QgsField(cfg.empty_field_name, QVariant.Int)] + ) + roi_layer = cfg.util_qgis.add_vector_layer(region_path) + # add a feature + feature_id = cfg.util_qgis.get_last_feature_id(roi_layer) + feature_x = cfg.util_qgis.get_feature_by_id(roi_layer, feature_id) + # get geometry + geometry = feature_x.geometry() + # add a feature + if cfg.ctrl_click is not None: + geometry = add_part_to_roi(geometry) + else: + cfg.second_temporary_roi = cfg.temporary_roi + copied_feature = QgsFeature() + copied_feature.setGeometry(geometry) + copied_feature.setAttributes([1]) + provider.addFeatures([copied_feature]) + memory_layer.commitChanges() + memory_layer.updateExtents() + # add ROI layer + clear_scp_dock_rubber() + cfg.temporary_roi = memory_layer + add_roi_polygon_to_map(cfg.temporary_roi, 1) + cfg.roi_center_vertex = QgsVertexMarker(cfg.map_canvas) + cfg.roi_center_vertex.setCenter(point) + cfg.roi_center_vertex.setIconType(1) + cfg.roi_center_vertex.setColor(QColor(0, 255, 255)) + cfg.roi_center_vertex.setIconSize(12) + cfg.roi_points.append(cfg.roi_center_vertex) + # calculate temporary spectral signature + button = cfg.dock_class_dlg.ui.auto_calculate_ROI_signature_checkBox + if button.isChecked(): + temporary_roi_spectral_signature(bandset_number=bandset_number) + cfg.dock_class_dlg.ui.button_Save_ROI.setEnabled(True) + cfg.redo_ROI_Button.setEnabled(True) + cfg.ui_utils.remove_progress_bar() + + +# calculate temporary ROI spectral signature +def temporary_roi_spectral_signature(bandset_number=None, roi_path=None): + cfg.rs.configurations.action = True + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + # get ROI polygons + if roi_path is None: + # get vector from ROI + roi_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + cfg.util_qgis.save_memory_layer_to_geopackage( + cfg.temporary_roi, roi_path + ) + signature_catalog = cfg.rs.spectral_signatures_catalog( + bandset=cfg.bandset_catalog.get(bandset_number) + ) + cfg.ui_utils.add_progress_bar() + # add signature to plot + (value_list, standard_deviation_list, wavelength_list, + pixel_count) = signature_catalog.calculate_signature(roi_path) + cfg.ui_utils.remove_progress_bar() + plot_catalog = cfg.spectral_signature_plotter.plot_catalog + signature_id = generate_signature_id() + color_string = cfg.rs.shared_tools.random_color() + vector_plot = SpectralSignaturePlot( + value=value_list, wavelength=wavelength_list, pixel_count=pixel_count, + standard_deviation=standard_deviation_list, signature_id=signature_id, + macroclass_name=cfg.temp_roi_name, class_name=cfg.temp_roi_name, + color_string=color_string, selected=1 + ) + plot_catalog.catalog[signature_id] = vector_plot + cfg.spectral_signature_plotter.signature_list_plot_table() + cfg.input_interface.spectral_plot_tab() + + +""" Training input """ + + +# Create new input +def create_training_input(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Create training input'), '', '*.scpx', 'scpx' + ) + if output_path is not False: + if output_path.lower().endswith('.scpx'): + pass + elif not output_path.lower().endswith('.scpx'): + output_path += '.scpx' + reset_input_dock() + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + cfg.project_registry[cfg.reg_training_bandset_number] = bandset_number + cfg.dock_class_dlg.ui.label_48.setText( + cfg.translate(' ROI & Signature list') + ' (' + + cfg.translate('band set') + ' ' + str(bandset_number) + ')' + ) + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + cfg.logger.log.debug('bandset band count: %s' % (str(band_count))) + if band_count == 0: + cfg.mx.msg_war_6(bandset_number) + return + signature_catalog = cfg.rs.spectral_signatures_catalog( + bandset=cfg.bandset_catalog.get(bandset_number) + ) + # load vector in QGIS + cfg.scp_training = TrainingVectorLayer( + signature_catalog=signature_catalog, output_path=output_path + ) + cfg.scp_training.save_signature_catalog() + # connect signature threshold table + cfg.signature_threshold.signature_thresholds_to_table() + + +# import training file +def import_library_file(path=None): + if path is None or path is False: + file_path = cfg.util_qt.get_open_file( + None, cfg.translate('Select a training input'), '', + 'Signature catalog package (*.scpx);; ' + 'Signature catalog package old version (*.scp);;' + 'USGS library (*.zip);;ASTER library (*.txt);;CSV file (*.csv)' + ) + else: + file_path = path + if len(file_path) > 0: + cfg.ui_utils.add_progress_bar() + # save previous catalog file + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + if file_path.endswith('.scpx'): + cfg.scp_training.import_file(file_path) + elif file_path.endswith('.scp'): + cfg.scp_training.import_scp_file(file_path) + elif file_path.endswith('.zip'): + cfg.signature_importer.import_usgs_library(file_path) + elif file_path.endswith('.csv'): + cfg.scp_training.import_csv_file(file_path) + elif file_path.endswith('.txt'): + cfg.signature_importer.aster_library(file_path) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + cfg.ui_utils.remove_progress_bar() + + +# open training file +def open_training_input_file(path=None): + if path is None or path is False: + file_path = cfg.util_qt.get_open_file( + None, cfg.translate('Select a training input'), '', + 'Signature catalog package (*.scpx)' + ) + else: + file_path = path + if len(file_path) > 0: + open_signature_catalog_file(file_path) + + +# open signature file +def open_signature_catalog_file(file_path=None, bandset_number=None): + cfg.logger.log.info('open_signature_catalog_file: %s' % (str(file_path))) + if bandset_number is None: + bandset_number = cfg.project_registry[cfg.reg_active_bandset_number] + bandset_x = cfg.bandset_catalog.get(bandset_number) + band_count = bandset_x.get_band_count() + cfg.project_registry[cfg.reg_training_bandset_number] = bandset_number + cfg.logger.log.debug('bandset band count: %s' % (str(band_count))) + if band_count == 0: + cfg.mx.msg_war_6(bandset_number) + # copy file to temporary file + temp_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.scpx' + ) + cfg.rs.files_directories.copy_file(file_path, temp_path) + signature_catalog = cfg.rs.spectral_signatures_catalog( + bandset=cfg.bandset_catalog.get(bandset_number) + ) + cfg.dock_class_dlg.ui.label_48.setText( + cfg.translate(' ROI & Signature list') + ' (' + + cfg.translate('band set') + ' ' + str(bandset_number) + ')' + ) + signature_catalog.load(file_path=temp_path) + # remove training input + project = cfg.util_qgis.get_qgis_project() + if cfg.scp_training is not None: + try: + project.removeMapLayer(cfg.scp_training.layer) + except Exception as err: + str(err) + # load vector in QGIS + cfg.scp_training = TrainingVectorLayer( + signature_catalog=signature_catalog, output_path=file_path + ) + # connect signature threshold table + cfg.signature_threshold.signature_thresholds_to_table() + + +# export signature to vector +def export_signature_vector(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Export SCP training input'), '', + 'SHP file (*.shp);;GPKG file (*.gpkg)' + ) + if output_path is not False: + if str(output_path).endswith('.shp'): + vector_format = 'ESRI Shapefile' + elif str(output_path).endswith('.gpkg'): + vector_format = 'GPKG' + else: + output_path += '.gpkg' + vector_format = 'GPKG' + ids = cfg.scp_training.get_highlighted_ids() + if len(ids) > 0: + cfg.ui_utils.add_progress_bar() + cfg.scp_training.signature_catalog.export_vector( + signature_id_list=ids, output_path=output_path, + vector_format=vector_format + ) + cfg.ui_utils.remove_progress_bar() + cfg.mx.msg_inf_4() + + +# export signature file +def export_signature_file(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Export SCP training input'), '', + 'Training file (*.scpx)' + ) + if output_path is not False: + if output_path.lower().endswith('.scpx'): + pass + elif not output_path.lower().endswith('.scpx'): + output_path += '.scpx' + ids = cfg.scp_training.get_highlighted_ids() + if len(ids) > 0: + cfg.ui_utils.add_progress_bar() + cfg.scp_training.save_signature_catalog( + path=output_path, signature_id_list=ids + ) + cfg.ui_utils.remove_progress_bar() + + +# export signature file +def export_signature_as_csv(): + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + ids = cfg.scp_training.get_highlighted_ids() + if len(ids) > 0: + cfg.ui_utils.add_progress_bar() + cfg.scp_training.signature_catalog.export_signatures_as_csv( + signature_id_list=ids, output_directory=output_path + ) + cfg.ui_utils.remove_progress_bar() + cfg.mx.msg_inf_4() + + +# open a vector +def open_vector(): + vector = cfg.util_qt.get_open_file( + None, cfg.translate('Select a vector'), '', + 'SHP file (*.shp);;GPKG file (*.gpkg)' + ) + if len(vector) > 0: + cfg.dialog.ui.select_shapefile_label.setText(vector) + fields = cfg.util_gdal.vector_fields(vector) + cfg.dialog.ui.MC_ID_combo.clear() + cfg.dialog.ui.MC_ID_combo.addItems(fields) + cfg.dialog.ui.MC_Info_combo.clear() + cfg.dialog.ui.MC_Info_combo.addItems(fields) + cfg.dialog.ui.C_ID_combo.clear() + cfg.dialog.ui.C_ID_combo.addItems(fields) + cfg.dialog.ui.C_Info_combo.clear() + cfg.dialog.ui.C_Info_combo.addItems(fields) + else: + cfg.dialog.ui.select_shapefile_label.setText('') + cfg.dialog.ui.MC_ID_combo.clear() + cfg.dialog.ui.MC_Info_combo.clear() + cfg.dialog.ui.C_ID_combo.clear() + cfg.dialog.ui.C_Info_combo.clear() + + +# import vector file from selected path in cfg.dialog.ui.select_shapefile_label +def import_vector(): + if len(cfg.dialog.ui.select_shapefile_label.text()) > 0: + macroclass_field = cfg.dialog.ui.MC_ID_combo.currentText() + macroclass_name_field = cfg.dialog.ui.MC_Info_combo.currentText() + class_field = cfg.dialog.ui.C_ID_combo.currentText() + class_name_field = cfg.dialog.ui.C_Info_combo.currentText() + if cfg.dialog.ui.signature_checkBox_2.isChecked() is True: + calculate_signature = True + else: + calculate_signature = False + cfg.ui_utils.add_progress_bar() + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = cfg.scp_training.signature_catalog_copy() + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + cfg.scp_training.import_vector( + file_path=cfg.dialog.ui.select_shapefile_label.text(), + macroclass_field=macroclass_field, + macroclass_name_field=macroclass_name_field, + class_field=class_field, class_name_field=class_name_field, + calculate_signature=calculate_signature + ) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + cfg.ui_utils.remove_progress_bar() + + +""" Plot """ + + +# add signatures to spectral plot +def add_signature_to_spectral_plot(tab_index=0): + if cfg.scp_training is not None: + ids = cfg.scp_training.get_highlighted_ids( + select_all=False, signatures=True + ) + if len(ids) > 0: + plot_catalog = cfg.spectral_signature_plotter.plot_catalog + signature_catalog = cfg.scp_training.signature_catalog + cfg.ui_utils.add_progress_bar() + for _id in ids: + if cfg.rs.configurations.action: + signature_catalog.export_signature_values_for_plot( + signature_id=_id, plot_catalog=plot_catalog + ) + cfg.ui_utils.remove_progress_bar() + cfg.spectral_signature_plotter.signature_list_plot_table() + cfg.input_interface.spectral_plot_tab() + cfg.input_interface.select_spectral_plot_settings_tab(tab_index) + else: + cfg.input_interface.spectral_plot_tab() + cfg.input_interface.select_spectral_plot_settings_tab(tab_index) + + +# add ROI to scatter plot +def add_roi_to_scatter_plot(): + cfg.logger.log.debug('add_roi_to_scatter_plot') + ids = cfg.scp_training.get_highlighted_ids(select_all=False) + if len(ids) > 0: + plot_catalog = cfg.scatter_plotter.plot_catalog + signature_catalog = cfg.scp_training.signature_catalog + cfg.ui_utils.add_progress_bar() + for _id in ids: + geometry = signature_catalog.table[ + signature_catalog.table['signature_id'] == _id].geometry[0] + if geometry == 1: + signature_catalog.export_signature_values_for_plot( + signature_id=_id, plot_catalog=plot_catalog + ) + temp_path = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + # export geometry + cfg.util_gdal.get_polygon_from_vector( + vector_path=signature_catalog.geometry_file, + output=temp_path, attribute_filter="%s = '%s'" % ( + cfg.rs.configurations.uid_field_name, _id + ) + ) + plot_catalog.catalog[_id].attributes[ + 'geometry_path'] = temp_path + else: + cfg.logger.log.debug( + 'no geometry for signature_id: %s' % str(_id) + ) + cfg.scatter_plotter.scatter_plot_list_table() + cfg.input_interface.scatter_plot_tab() + else: + cfg.input_interface.scatter_plot_tab() + + +# export symbology +def export_symbology(macroclass=True): + if macroclass is True: + value_color_dictionary = ( + cfg.scp_training.signature_catalog.macroclasses_color_string + ) + value_name_dictionary = ( + cfg.scp_training.signature_catalog.macroclasses + ) + else: + classes = cfg.scp_training.signature_catalog.table.class_id.tolist() + names = cfg.scp_training.signature_catalog.table.class_name.tolist() + colors = cfg.scp_training.signature_catalog.table.color.tolist() + value_name_dictionary = {} + value_color_dictionary = {} + for class_i in range(len(classes)): + value_name_dictionary[classes[class_i]] = names[class_i] + value_color_dictionary[classes[class_i]] = colors[class_i] + return value_name_dictionary, value_color_dictionary diff --git a/interface/script_tab.py b/interface/script_tab.py new file mode 100755 index 0000000..f29c455 --- /dev/null +++ b/interface/script_tab.py @@ -0,0 +1,59 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from PyQt5.QtWidgets import qApp + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# clear text +def clear_text(): + answer = cfg.util_qt.question_box( + cfg.translate('Clear script'), + cfg.translate('Are you sure you want to clear the script?') + ) + if answer is True: + cfg.dialog.ui.plainTextEdit_batch.setPlainText('') + + +# copy text +def copy_text(): + text = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + clipboard = qApp.clipboard() + clipboard.setText(text) + + +# save script to file +def save_script(): + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save script'), '', + 'Python file (*.py)' + ) + if output_path is not False: + if output_path.lower().endswith('.py'): + pass + else: + output_path = output_path + '.py' + text = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + with open(output_path, 'w') as output_file: + output_file.write(text) diff --git a/interface/settings.py b/interface/settings.py new file mode 100755 index 0000000..0b0568f --- /dev/null +++ b/interface/settings.py @@ -0,0 +1,470 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +import sys +from shutil import copy + +from PyQt5.QtCore import QDir + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# Change ROI color +def change_roi_color(): + c = cfg.QtWidgetsSCP.QColorDialog.getColor() + if c.isValid(): + cfg.qgis_registry[cfg.reg_roi_color] = c.name() + cfg.dialog.ui.change_color_Button.setStyleSheet( + 'background-color :' + cfg.qgis_registry[cfg.reg_roi_color] + ) + + +# ROI transparency +def change_roi_transparency(): + cfg.qgis_registry[cfg.reg_roi_transparency] = ( + cfg.dialog.ui.transparency_Slider.value() + ) + cfg.dialog.ui.transparency_Label.setText( + cfg.translate('Transparency ') + + str(cfg.qgis_registry[cfg.reg_roi_transparency]) + '%' + ) + + +# variable name +def raster_variable_name_change(): + cfg.qgis_registry[cfg.reg_raster_variable_name] = ( + cfg.dialog.ui.variable_name_lineEdit.text() + ) + + +# group name +def group_name_change(): + cfg.qgis_registry[cfg.reg_group_name] = ( + cfg.dialog.ui.group_name_lineEdit.text() + ) + + +# download news +def download_news_change(): + if cfg.dialog.ui.download_news_checkBox.isChecked() is True: + cfg.qgis_registry[cfg.reg_download_news] = 2 + elif cfg.dialog.ui.download_news_checkBox.isChecked() is False: + cfg.qgis_registry[cfg.reg_download_news] = 0 + + +# checkbox switch sound +def sound_checkbox_change(): + # sound setting + if cfg.dialog.ui.sound_checkBox.isChecked() is True: + cfg.qgis_registry[cfg.reg_sound] = 2 + elif cfg.dialog.ui.sound_checkBox.isChecked() is False: + cfg.qgis_registry[cfg.reg_sound] = 0 + + +# RAM setting +def ram_setting_change(): + cfg.qgis_registry[cfg.reg_ram_value] = cfg.dialog.ui.RAM_spinBox.value() + cfg.rs.set(available_ram=int(cfg.qgis_registry[cfg.reg_ram_value])) + + +# thread setting +def threads_setting_change(): + cfg.qgis_registry[ + cfg.reg_threads_value] = cfg.dialog.ui.CPU_spinBox.value() + cfg.rs.set(n_processes=int(cfg.qgis_registry[cfg.reg_threads_value])) + + +# reset raster variable names +def reset_raster_variable_name(): + answer = cfg.util_qt.question_box( + cfg.translate('Reset variable name'), + cfg.translate('Are you sure you want to reset variable name?') + ) + if answer is True: + cfg.qgis_registry[ + cfg.reg_raster_variable_name] = cfg.raster_variable_name_def + cfg.dialog.ui.variable_name_lineEdit.setText( + cfg.qgis_registry[cfg.reg_raster_variable_name] + ) + + +# reset group name +def reset_group_name(): + answer = cfg.util_qt.question_box( + cfg.translate('Reset group name'), + cfg.translate('Are you sure you want to reset group name?') + ) + if answer is True: + cfg.qgis_registry[cfg.reg_group_name] = cfg.group_name_def + cfg.dialog.ui.group_name_lineEdit.setText( + cfg.qgis_registry[cfg.reg_group_name] + ) + + +# change temporary directory +def change_temp_dir(): + answer = cfg.util_qt.question_box( + cfg.translate('Change temporary directory'), + cfg.translate( + 'Are you sure you want to change the temporary directory?' + ) + ) + if answer is True: + output = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output is not False: + if QDir(output).exists(): + date_time = cfg.utils.get_time() + output_dir = cfg.rs.files_directories.create_directory( + '%s/%s' % (output, date_time) + ) + if output_dir is False: + return False + cfg.temp_dir = '%s/%s' % (output, date_time) + cfg.dialog.ui.temp_directory_label.setText(output) + cfg.util_qt.write_registry_keys(cfg.reg_temp_dir, output) + cfg.rs.set(temporary_directory=cfg.temp_dir) + + +# reset temporary directory +def reset_temp_dir(): + answer = cfg.util_qt.question_box( + cfg.translate('Reset temporary directory'), + cfg.translate( + 'Are you sure you want to reset the temporary directory?' + ) + ) + if answer is True: + # noinspection PyArgumentList + cfg.temp_dir = '%s/%s' % (QDir.tempPath(), cfg.temp_dir_name) + cfg.util_qt.write_registry_keys(cfg.reg_temp_dir, cfg.temp_dir) + cfg.dialog.ui.temp_directory_label.setText(cfg.temp_dir) + cfg.rs.set(temporary_directory=cfg.temp_dir) + + +# Reset ROI style +def reset_roi_style(): + cfg.qgis_registry[cfg.reg_roi_color] = cfg.roi_color_default + cfg.qgis_registry[cfg.reg_roi_transparency] = cfg.roi_transparency_default + cfg.dialog.ui.change_color_Button.setStyleSheet( + 'background-color :' + cfg.qgis_registry[cfg.reg_roi_color] + ) + cfg.dialog.ui.transparency_Label.setText( + cfg.translate('Transparency ') + + str(cfg.qgis_registry[cfg.reg_roi_transparency]) + '%' + ) + cfg.dialog.ui.transparency_Slider.setValue( + cfg.qgis_registry[cfg.reg_roi_transparency] + ) + + +# set variable for raster compression +def raster_compression_checkbox(): + if cfg.dialog.ui.raster_compression_checkBox.isChecked() is True: + cfg.qgis_registry[cfg.reg_raster_compression] = 2 + else: + cfg.qgis_registry[cfg.reg_raster_compression] = 0 + + +# smtp server +def smtp_server_change(): + cfg.qgis_registry[ + cfg.reg_smtp_server] = cfg.dialog.ui.smtp_server_lineEdit.text() + cfg.smtp_server = cfg.qgis_registry[cfg.reg_smtp_server] + + +# smtp to emails +def smtp_to_emails_change(): + cfg.qgis_registry[ + cfg.reg_smtp_emails] = cfg.dialog.ui.to_email_lineEdit.text() + cfg.smtp_recipients = cfg.qgis_registry[ + cfg.reg_smtp_emails] + + +# user +def remember_user(): + if cfg.dialog.ui.remeber_settings_checkBox.isChecked(): + cfg.qgis_registry[ + cfg.reg_smtp_user] = cfg.dialog.ui.smtp_user_lineEdit.text() + cfg.qgis_registry[cfg.reg_smtp_password] = cfg.utils.encrypt_password( + cfg.dialog.ui.smtp_password_lineEdit.text() + ) + cfg.smtp_user = cfg.dialog.ui.smtp_user_lineEdit.text() + cfg.smtp_password = ( + cfg.dialog.ui.smtp_password_lineEdit.text() + ) + + +# checkbox remember user +def remember_user_checkbox(): + if cfg.dialog.ui.remeber_settings_checkBox.isChecked(): + remember_user() + else: + cfg.qgis_registry[cfg.reg_smtp_user] = '' + cfg.qgis_registry[cfg.reg_smtp_password] = '' + + +# checkbox SMTP +def smtp_checkbox(): + # sound setting + if cfg.dialog.ui.smtp_checkBox.isChecked() is True: + cfg.qgis_registry[cfg.reg_smtp_check] = 2 + cfg.smtp_notification = True + elif cfg.dialog.ui.smtp_checkBox.isChecked() is False: + cfg.qgis_registry[cfg.reg_smtp_check] = 0 + cfg.smtp_notification = False + + +# GDAL setting +def gdal_path_change(): + if len(cfg.dialog.ui.gdal_path_lineEdit.text()) == 0: + cfg.qgis_registry[cfg.reg_gdal_path] = '' + else: + cfg.qgis_registry[cfg.reg_gdal_path] = ( + cfg.dialog.ui.gdal_path_lineEdit.text().rstrip('/') + '/') + + +# checkbox switch log +def log_checkbox_change(): + if cfg.dialog.ui.log_checkBox.isChecked() is True: + cfg.qgis_registry[cfg.reg_log_key] = 2 + if cfg.rs is not None: + cfg.rs.set(log_level=10) + elif cfg.dialog.ui.log_checkBox.isChecked() is False: + cfg.qgis_registry[cfg.reg_log_key] = 0 + if cfg.rs is not None: + cfg.rs.set(log_level=20) + + +# copy the Log file +def copy_log_file(): + out = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save Log file'), '', '*.txt', 'txt' + ) + if out is not False: + if not out.lower().endswith('.txt'): + out += '.txt' + if cfg.utils.check_file(cfg.rs.configurations.logger.file_path): + try: + copy(cfg.rs.configurations.logger.file_path, out) + except Exception as err: + str(err) + + +""" Tests """ + + +# test required dependencies +def test_dependencies(): + message = '
    ' + test_numpy_a = test_numpy() + if test_numpy_a: + message += '
  • NumPy: %s
  • ' % cfg.translate('Success') + else: + message += '
  • NumPy: %s
  • ' % ( + cfg.translate('Fail') + ) + test_scipy_a = test_scipy() + if test_scipy_a: + message += '
  • SciPy: %s
  • ' % cfg.translate('Success') + else: + message += '
  • SciPy: %s
  • ' % ( + cfg.translate('Fail')) + test_matplotlib_a = test_matplotlib() + if test_matplotlib_a: + message += '
  • Matplotlib: %s
  • ' % cfg.translate('Success') + else: + message += '
  • Matplotlib: %s' % ( + cfg.translate('Fail')) + test_gdal_a = test_gdal() + if test_gdal_a: + message += '
  • GDAL: %s
  • ' % cfg.translate('Success') + else: + message += '
  • GDAL: %s
  • ' % ( + cfg.translate('Fail')) + test_pytorch_a = test_pytorch() + if test_pytorch_a: + message += '
  • PyTorch: %s
  • ' % cfg.translate('Success') + else: + message += '
  • PyTorch: %s
  • ' % ( + cfg.translate('Fail') + ) + test_sklearn_a = test_sklearn() + if test_sklearn_a: + message += '
  • scikit-learn: %s
  • ' % cfg.translate('Success') + else: + message += '
  • scikit-learn: %s
  • ' % ( + cfg.translate('Fail')) + test_remotior_sensus_a = test_remotior_sensus() + if test_remotior_sensus_a: + message += '
  • Remotior Sensus: %s
  • ' % cfg.translate('Success') + else: + message += ( + '
  • Remotior Sensus: %s. ' + 'Please read the %s
  • ' % ( + cfg.translate('Fail'), + 'installation manual' + ) + ) + test_multiprocess_a = test_multiprocess() + if test_multiprocess_a: + message += '
  • Multiprocess: %s
  • ' % cfg.translate('Success') + else: + message += '
  • Multiprocess: %s
  • ' % ( + cfg.translate('Fail') + ) + message += '
  • sys.exec_prefix: %s
  • ' % str(sys.exec_prefix) + test_internet_a = test_internet_connection() + if test_internet_a: + message += '
  • Internet connection: %s
  • ' % cfg.translate( + 'Success' + ) + else: + message += '
  • Internet connection: %s
  • ' % ( + cfg.translate('Fail') + ) + message += '
' + cfg.dialog.ui.test_textBrowser.clear() + cfg.dialog.ui.test_textBrowser.setHtml(message) + try: + cfg.logger.log.debug('tests: %s' % message) + except Exception as err: + str(err) + + +# test Remotior Sensus +def test_remotior_sensus(): + test = True + try: + import remotior_sensus + remotior_sensus.Session(n_processes=2, available_ram=10) + except Exception as err: + str(err) + test = False + return test + + +# test multiprocess +def test_multiprocess(): + test = True + try: + import remotior_sensus + from remotior_sensus.core.processor_functions import ( + raster_unique_values_with_sum + ) + rs = remotior_sensus.Session(n_processes=2, available_ram=10) + raster_path = '%s/debug/raster.tif' % cfg.plugin_dir + rs.configurations.multiprocess.run( + raster_path=raster_path, function=raster_unique_values_with_sum, + n_processes=2, available_ram=100, keep_output_argument=True + ) + except Exception as err: + str(err) + test = False + return test + + +# test GDAL +def test_gdal(): + test = True + try: + from osgeo import gdal, ogr, osr + assert gdal.Translate + except Exception as err: + str(err) + test = False + return test + + +# test GDAL +def test_pytorch(): + test = True + try: + # noinspection PyUnresolvedReferences + import torch + except Exception as err: + str(err) + test = False + return test + + +# test scikit-learn +def test_sklearn(): + test = True + try: + from sklearn import svm + except Exception as err: + str(err) + test = False + return test + + +# test internet connection +def test_internet_connection(): + test = True + try: + from remotior_sensus.util import download_tools + url = 'https://www.python.org' + temp = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.html' + ) + download_tools.download_file(url=url, output_path=temp) + except Exception as err: + str(err) + test = False + return test + + +# test Numpy +def test_numpy(): + test = True + try: + import numpy + numpy.count_nonzero([1, 1, 0]) + except Exception as err: + str(err) + test = False + return test + + +# test Scipy +def test_scipy(): + test = True + try: + import scipy + except Exception as err: + str(err) + test = False + return test + + +# test Matplotlib +def test_matplotlib(): + test = True + try: + from matplotlib.ticker import MaxNLocator + except Exception as err: + str(err) + test = False + return test diff --git a/interface/signature_threshold_tab.py b/interface/signature_threshold_tab.py new file mode 100755 index 0000000..aa47887 --- /dev/null +++ b/interface/signature_threshold_tab.py @@ -0,0 +1,229 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Signature thresholds. + +Allows for setting signature thresholds. +""" + +from remotior_sensus.util import shared_tools + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# Create signature threshold table +def signature_thresholds_to_table(): + if cfg.scp_training is not None: + table = cfg.dialog.ui.signature_threshold_tableWidget + table.blockSignals(True) + cfg.util_qt.clear_table(table) + if cfg.scp_training.signature_catalog is not None: + if cfg.scp_training.signature_catalog.table is not None: + sig_table = cfg.scp_training.signature_catalog.table + ids = sig_table.signature_id.tolist() + row = 0 + for signature_id in ids: + signature_array = cfg.scp_training.signature_catalog.table[ + cfg.scp_training.signature_catalog.table[ + 'signature_id'] == signature_id] + macroclass_id = signature_array.macroclass_id[0] + class_id = signature_array.class_id[0] + class_name = signature_array.class_name[0] + macroclass_name = ( + cfg.scp_training.signature_catalog.macroclasses[ + macroclass_id + ] + ) + min_dist_thr = signature_array.min_dist_thr[0] + max_like_thr = signature_array.max_like_thr[0] + spec_angle_thr = signature_array.spec_angle_thr[0] + cfg.util_qt.insert_table_row(table, row) + cfg.util_qt.add_table_item( + table, int(macroclass_id), row, 0, False + ) + cfg.util_qt.add_table_item( + table, str(macroclass_name), row, 1, False + ) + cfg.util_qt.add_table_item( + table, int(class_id), row, 2, False + ) + cfg.util_qt.add_table_item( + table, str(class_name), row, 3, False + ) + cfg.util_qt.add_table_item( + table, str(min_dist_thr), row, 4 + ) + cfg.util_qt.add_table_item( + table, str(max_like_thr), row, 5 + ) + cfg.util_qt.add_table_item( + table, str(spec_angle_thr), row, 6 + ) + cfg.util_qt.add_table_item( + table, str(signature_id), row, 7, False + ) + row += 1 + table.blockSignals(False) + cfg.util_qt.sort_table_column(table, 7) + + +# reset thresholds +def reset_thresholds(): + answer = cfg.util_qt.question_box( + cfg.translate('Reset thresholds'), + cfg.translate('Are you sure you want to reset thresholds?') + ) + if answer is True: + table = cfg.dialog.ui.signature_threshold_tableWidget + count = table.rowCount() + for row in range(0, count): + cfg.util_qt.set_table_item(table, row, 4, '0') + cfg.util_qt.set_table_item(table, row, 5, '0') + cfg.util_qt.set_table_item(table, row, 6, '0') + + +# set thresholds +def set_thresholds(): + table = cfg.dialog.ui.signature_threshold_tableWidget + selection = [] + for selected in table.selectedIndexes(): + selection.append([selected.row(), selected.column()]) + if len(selection) > 0: + value = cfg.dialog.ui.threshold_doubleSpinBox.value() + table.setSortingEnabled(False) + for item in reversed(selection): + if item[1] == 6: + if value > 90: + value = 90 + try: + cfg.util_qt.set_table_item(table, item[0], 6, str(value)) + except Exception as err: + str(err) + elif item[1] == 5: + if value > 100: + value = 100 + try: + cfg.util_qt.set_table_item( + table, item[0], 5, + str(value) + ) + except Exception as err: + str(err) + else: + try: + cfg.util_qt.set_table_item(table, item[0], 4, str(value)) + except Exception as err: + str(err) + table.setSortingEnabled(True) + + +# set weights based on variance +def set_all_weights_from_variance(): + table = cfg.dialog.ui.signature_threshold_tableWidget + selection = [] + for selected in table.selectedIndexes(): + selection.append([selected.row(), selected.column()]) + if len(selection) > 0: + table.setSortingEnabled(False) + for item in reversed(selection): + signature_id = table.item(item[0], 7).text() + values = cfg.scp_training.signature_catalog.signatures[ + signature_id].value + standard_deviation = cfg.scp_training.signature_catalog.signatures[ + signature_id].standard_deviation + mean_plus = [] + mean_minus = [] + for n in range(0, len(values)): + mean_plus.append(values[n] + standard_deviation[n]) + mean_minus.append(values[n] - standard_deviation[n]) + # multiplicative factor + fact = cfg.dialog.ui.multiplicative_threshold_doubleSpinBox.value() + if item[1] == 6: + angle_plus = shared_tools.calculate_spectral_angle( + values_x=cfg.utils.numpy_array_from_list(values), + values_y=cfg.utils.numpy_array_from_list(mean_plus) + ) + angle_minus = shared_tools.calculate_spectral_angle( + values_x=cfg.utils.numpy_array_from_list(values), + values_y=cfg.utils.numpy_array_from_list(mean_minus) + ) + try: + sam_value = fact * max([angle_plus, angle_minus]) + except Exception as err: + str(err) + sam_value = 0 + if sam_value > 90: + sam_value = 90 + cfg.scp_training.edit_signature_value( + signature_id=signature_id, field='spec_angle_thr', + value=sam_value + ) + cfg.util_qt.set_table_item(table, item[0], 6, str(sam_value)) + elif item[1] == 4: + distance_plus = shared_tools.calculate_euclidean_distance( + values_x=values, values_y=mean_plus + ) + distance_minus = shared_tools.calculate_euclidean_distance( + values_x=values, values_y=mean_minus + ) + try: + distance = fact * max([distance_plus, distance_minus]) + except Exception as err: + str(err) + distance = 0 + cfg.scp_training.edit_signature_value( + signature_id=signature_id, field='min_dist_thr', + value=distance + ) + cfg.util_qt.set_table_item(table, item[0], 4, str(distance)) + table.setSortingEnabled(True) + + +# edited threshold table +def edited_threshold_table(row, column): + table = cfg.dialog.ui.signature_threshold_tableWidget + text = table.item(row, column).text() + signature_id = table.item(row, 7).text() + try: + value = float(text) + except Exception as err: + str(err) + value = 0 + if column == 4: + cfg.scp_training.edit_signature_value( + signature_id=signature_id, field='min_dist_thr', value=value + ) + elif column == 5: + if value > 100: + table.blockSignals(True) + cfg.util_qt.set_table_item(table, row, column, '100') + table.blockSignals(False) + cfg.scp_training.edit_signature_value( + signature_id=signature_id, field='max_like_thr', value=value + ) + elif column == 6: + if value > 90: + table.blockSignals(True) + cfg.util_qt.set_table_item(table, row, column, '90') + table.blockSignals(False) + cfg.scp_training.edit_signature_value( + signature_id=signature_id, field='spec_angle_thr', value=value + ) diff --git a/interface/split_bands_tab.py b/interface/split_bands_tab.py new file mode 100755 index 0000000..1a3d16c --- /dev/null +++ b/interface/split_bands_tab.py @@ -0,0 +1,97 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Split bands. + +This tool allows for slitting bands of multiband raster. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# refresh reference layer name +def refresh_reference_layer(): + # noinspection PyArgumentList + layers = cfg.util_qgis.get_qgis_project().mapLayers().values() + cfg.dialog.ui.raster_name_combo.clear() + for layer in sorted(layers, key=lambda c: c.name()): + if layer.type() == cfg.util_qgis.get_qgis_map_raster(): + if layer.bandCount() > 1: + cfg.dialog.raster_layer_combo(layer.name()) + + +# split raster button +def split_raster(): + split_raster_to_bands() + + +# split raster to bands +def split_raster_to_bands(): + output_path = cfg.util_qt.get_existing_directory( + None, cfg.translate('Select a directory') + ) + if output_path is not False: + cfg.logger.log.info('split_raster_to_bands: %s' % output_path) + reference_layer = cfg.dialog.ui.raster_name_combo.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + if reference is not None: + prefix = cfg.dialog.ui.output_name_lineEdit.text() + cfg.ui_utils.add_progress_bar() + output = cfg.rs.raster_split( + raster_path=reference, prefix=prefix, output_path=output_path + ) + if output.check: + output_paths = output.paths + for raster in output_paths: + # add raster to layers + cfg.util_qgis.add_raster_layer(raster) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + reference_layer = cfg.dialog.ui.raster_name_combo.currentText() + reference = cfg.util_qgis.get_file_path(reference_layer) + prefix = cfg.dialog.ui.output_name_lineEdit.text() + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# split bands \n' + 'rs.raster_split(raster_path="%s", prefix="%s", ' + 'output_path="%s")' + % (str(reference), str(prefix), str(output_path))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/stack_bandset_tab.py b/interface/stack_bandset_tab.py new file mode 100755 index 0000000..10ee03b --- /dev/null +++ b/interface/stack_bandset_tab.py @@ -0,0 +1,99 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Stack band set. + +This tool allows for stacking bands. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# stack bandset +def stack_action(): + stack_bands() + + +# stack multiple rasters +def stack_bands(): + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_3.value() + if bandset_number > cfg.bandset_catalog.get_bandset_count(): + cfg.mx.msg_err_2() + return + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save error matrix raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + if output_path.lower().endswith('.vrt'): + pass + elif not output_path.lower().endswith('.tif'): + output_path += '.tif' + cfg.logger.log.info('band_sieve: %s' % output_path) + cfg.logger.log.debug('bandset_number: %s' % bandset_number) + cfg.ui_utils.add_progress_bar() + output = cfg.rs.band_stack( + input_bands=bandset_number, output_path=output_path, + bandset_catalog=cfg.bandset_catalog + ) + if output.check: + cfg.util_qgis.add_raster_layer(output.path) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + bandset_number = cfg.dialog.ui.band_set_comb_spinBox_3.value() + bandset_x = cfg.bandset_catalog.get_bandset_by_number(bandset_number) + if bandset_x is not None: + # get input band paths + files = bandset_x.get_absolute_paths() + paths = '[' + for file in files: + paths += '"%s", ' % file + paths = paths[:-2] + ']' + if paths == ']': + paths = '[]' + else: + paths = '[]' + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# stack bands (input files from bandset)\n' + 'rs.band_stack(input_bands=%s, output_path="%s")' + % (str(paths), str(output_path))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/interface/vector_to_raster_tab.py b/interface/vector_to_raster_tab.py new file mode 100755 index 0000000..9d3ef6d --- /dev/null +++ b/interface/vector_to_raster_tab.py @@ -0,0 +1,174 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . +"""Vector to raster. + +This tool allows for the conversion of vector to raster. +""" + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# reload vector list +def reload_vector_list(): + cfg.utils.refresh_vector_layer() + + +# convert to raster +def convert_to_raster_action(): + convert_to_raster() + + +# convert to raster +def convert_to_raster(): + vector = cfg.dialog.ui.vector_name_combo.currentText() + layer = cfg.util_qgis.select_layer_by_name(vector) + references = cfg.dialog.ui.reference_raster_name_combo.currentText() + reference = cfg.util_qgis.select_layer_by_name(references) + if layer is None or reference is None: + cfg.utils.refresh_vector_layer() + cfg.utils.refresh_raster_layer() + return + vector_source = cfg.util_qgis.qgis_layer_source(layer) + reference_source = cfg.util_qgis.qgis_layer_source(reference) + field = cfg.dialog.ui.field_comboBox.currentText() + if cfg.dialog.ui.field_radioButton.isChecked(): + constant = None + else: + constant = cfg.dialog.ui.constant_value_spinBox.value() + if len(field) == 0 and cfg.dialog.ui.field_radioButton.isChecked(): + cfg.utils.refresh_vector_layer() + return + if cfg.dialog.ui.conversion_type_combo.currentText() == 'pixel_center': + conversion_type = 'pixel_center' + elif cfg.dialog.ui.conversion_type_combo.currentText() == 'all_touched': + conversion_type = 'all_touched' + else: + conversion_type = 'area_based' + if cfg.dialog.ui.extent_checkBox_2.isChecked(): + minimum_extent = True + else: + minimum_extent = None + try: + area_precision = float(cfg.dialog.ui.area_precision_lineEdit.text()) + except Exception as err: + str(err) + area_precision = 20 + try: + pixel_size = float(cfg.dialog.ui.pixel_size_lineEdit.text()) + except Exception as err: + str(err) + pixel_size = None + if cfg.dialog.ui.nodata_checkBox_10.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_12.value() + else: + nodata = None + output_path = cfg.util_qt.get_save_file_name( + None, cfg.translate('Save raster output'), '', + 'TIF file (*.tif);;VRT file (*.vrt)' + ) + if output_path is not False: + if output_path.lower().endswith('.tif'): + pass + else: + output_path += '.tif' + cfg.logger.log.info('convert_to_raster: %s' % output_path) + cfg.ui_utils.add_progress_bar() + output = cfg.rs.vector_to_raster( + vector_path=vector_source, align_raster=reference_source, + vector_field=field, constant=constant, pixel_size=pixel_size, + output_path=output_path, method=conversion_type, + area_precision=area_precision, nodata_value=nodata, + minimum_extent=minimum_extent + ) + if output.check: + # add raster to layer + cfg.util_qgis.add_raster_layer(output.path) + else: + cfg.mx.msg_err_1() + cfg.ui_utils.remove_progress_bar(smtp=str(__name__)) + + +# set script button +def set_script(): + output_path = 'output_path' + vector = cfg.dialog.ui.vector_name_combo.currentText() + layer = cfg.util_qgis.select_layer_by_name(vector) + references = cfg.dialog.ui.reference_raster_name_combo.currentText() + reference = cfg.util_qgis.select_layer_by_name(references) + vector_source = cfg.util_qgis.qgis_layer_source(layer) + reference_source = cfg.util_qgis.qgis_layer_source(reference) + field = cfg.dialog.ui.field_comboBox.currentText() + if cfg.dialog.ui.field_radioButton.isChecked(): + constant = None + else: + constant = cfg.dialog.ui.constant_value_spinBox.value() + if cfg.dialog.ui.conversion_type_combo.currentText() == 'pixel_center': + conversion_type = 'pixel_center' + elif cfg.dialog.ui.conversion_type_combo.currentText() == 'all_touched': + conversion_type = 'all_touched' + else: + conversion_type = 'area_based' + if cfg.dialog.ui.extent_checkBox_2.isChecked(): + minimum_extent = True + else: + minimum_extent = None + try: + area_precision = float(cfg.dialog.ui.area_precision_lineEdit.text()) + except Exception as err: + str(err) + area_precision = 20 + try: + pixel_size = float(cfg.dialog.ui.area_precision_lineEdit.text()) + except Exception as err: + str(err) + pixel_size = None + if cfg.dialog.ui.nodata_checkBox_10.isChecked() is True: + nodata = cfg.dialog.ui.nodata_spinBox_12.value() + else: + nodata = None + + # copy the command + session = ('rs = remotior_sensus.Session(n_processes=%s, available_ram=%s)' + % (cfg.qgis_registry[cfg.reg_threads_value], + cfg.qgis_registry[cfg.reg_ram_value])) + command = ('# vector to raster \n' + 'rs.vector_to_raster(vector_path="%s", align_raster="%s", ' + 'vector_field="%s", constant=%s, pixel_size=%s, ' + 'output_path="%s", method="%s", area_precision=%s, ' + 'nodata_value=%s, minimum_extent=%s)' + % (str(vector_source), str(reference_source), str(field), + str(constant), str(pixel_size), str(output_path), + str(conversion_type), str(area_precision), str(nodata), + str(minimum_extent))) + previous = cfg.dialog.ui.plainTextEdit_batch.toPlainText() + if 'import remotior_sensus' in previous: + text = '\n'.join([previous, command]) + else: + text = '\n'.join( + ['import remotior_sensus', session, previous, command] + ) + cfg.dialog.ui.plainTextEdit_batch.setPlainText( + text.replace('"None"', 'None').replace('"False"', 'False').replace( + '"True"', 'True' + ) + ) + cfg.input_interface.script_tab() diff --git a/maininterface/GOESTab.py b/maininterface/GOESTab.py deleted file mode 100644 index 51fc6bc..0000000 --- a/maininterface/GOESTab.py +++ /dev/null @@ -1,313 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class GOESTab: - - def __init__(self): - pass - - # GOES input - def inputGOES(self): - i = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - cfg.ui.GOES_label.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - sat = 'GOES' - cfg.ui.GOES_satellite_lineEdit.setText(sat) - l = cfg.ui.GOES_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 450]]) - cfg.utls.clearTable(l) - inp = input - if len(inp) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - cfg.ui.GOES_satellite_lineEdit.setText(sat) - # bands - dBs = {} - bandNames = [] - for f in cfg.osSCP.listdir(inp): - if f.lower().endswith('.nc'): - f = f[0:-3] - # check band number - bNmb = str(f[-2:]) - try: - if int(bNmb) in range(1,7): - bandNames.append(f) - except: - pass - cfg.uiUtls.updateBar(50) - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0) - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - # remove band - def removeHighlightedBand(self): - l = cfg.ui.GOES_tableWidget - cfg.utls.removeRowsFromTable(l) - - # edited cell - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.GOES_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText('') - - # GOES output - def performGOESConversion(self): - if len(cfg.ui.GOES_label.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.GOES(cfg.ui.GOES_label.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform GOES conversion: ' + str(cfg.ui.GOES_label.text())) - - # GOES conversion - def GOES(self, inputDirectory, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - if batch == 'No': - cfg.cnvs.setRenderFlag(False) - # Esun - dEsunB = {} - # Esun from GOES-R, 2017. PRODUCT DEFINITION AND USER’S GUIDE (PUG) VOLUME 3: LEVEL 1B PRODUCTS - dEsunB = {'ESUN_BAND01': 2041.6865234375, 'ESUN_BAND02': 1628.080078125, 'ESUN_BAND03': 955.5531005859375, 'ESUN_BAND04': 361.5187683105469, 'ESUN_BAND05': 242.64404296875, 'ESUN_BAND06': 77.00672149658203} - # output raster list - outputRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - bandNumberList = [] - sat = cfg.ui.GOES_satellite_lineEdit.text() - if str(sat) == '': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No satellite error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - cfg.uiUtls.updateBar(5, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion')) - l = cfg.ui.GOES_tableWidget - inp = inputDirectory - out = outputDirectory - # input - for f in cfg.osSCP.listdir(inp): - cfg.QtWidgetsSCP.qApp.processEvents() - cfg.uiUtls.updateBar(20) - # name prefix - pre = 'RT_' - oDir = cfg.utls.makeDirectory(out) - l = cfg.ui.GOES_tableWidget - # input bands - c = l.rowCount() - # output raster list - outputRasterList = [] - convInputList = [] - tempRasterList1 = [] - # No data value - if cfg.ui.GOES_nodata_checkBox.isChecked() is True: - nD = cfg.ui.GOES_nodata_spinBox.value() - else: - nD = cfg.NoDataVal - threadNumber = cfg.threads - sez = list(range(0, c, threadNumber)) - sez.append(c) - cfg.subprocDictProc = {} - for s in range(0, len(sez)-1): - for p in range(sez[s], sez[s+1]): - iBand = l.item(p,0).text() - iBandN = iBand[-2:] - sBand = inp + '/' + iBand + '.nc' - # temp files - tPMD = cfg.utls.createTempRasterPath('tif') - tempRasterList1.append(tPMD) - gD = 'gdalwarp --config GDAL_DISABLE_READDIR_ON_OPEN TRUE -co BIGTIFF=YES -r near -co COMPRESS=LZW -t_srs ' + 'EPSG:4326 -ot Float32 -dstnodata ' + str(nD) + ' -of GTiff' - cfg.utls.getGDALForMac() - a = cfg.gdalPath + gD - b = 'NETCDF:"' +sBand + '":Rad' - g = '"' + tPMD + '" ' - d = a + ' ' + b + ' ' + g - if cfg.sysSCPNm != 'Windows': - d = cfg.shlexSCP.split(d) - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(p)] = cfg.subprocessSCP.Popen(d, shell=False, startupinfo = startupinfo, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(p)] = cfg.subprocessSCP.Popen(d, shell=False) - while True: - polls = [] - for p in range(sez[s], sez[s+1]): - polls.append(cfg.subprocDictProc['proc_'+ str(p)].poll()) - if polls.count(None) == 0: - break - else: - try: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(message = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reprojecting') + dots) - except: - pass - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - break - cfg.timeSCP.sleep(1) - for i in range(0, c): - iBand = l.item(i,0).text() - iBandN = iBand[-2:] - sBand = inp + '/' + iBand + '.nc' - # open input with GDAL - rDB = cfg.gdalSCP.Open('NETCDF:"' +sBand + '":Rad', cfg.gdalSCP.GA_ReadOnly) - gBand = rDB.GetRasterBand(1) - offs = gBand.GetOffset() - scl = gBand.GetScale() - rDMeta = rDB.GetMetadata_List() - # get metadata - for metadata in rDMeta: - if 'time_coverage_start' in metadata: - dt = metadata.split('=')[1].split('T')[0] - gBand = None - rDB = None - eSun = float(dEsunB['ESUN_BAND' + str(iBandN)]) - # date format - dFmt = '%Y-%m-%d' - eSD = float(cfg.utls.calculateEarthSunDistance(dt, dFmt)) - m = float(scl) - a = float(offs) - e = 'cfg.np.clip(cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ( "raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % eSD) + ' * ' + str('%.16f' % eSD) + '/ (' + str('%.16f' % eSun)+ ' ) ), 0, 1)' - outputRaster = oDir + '/' + pre + iBand + '.tif' - convInputList.append([tempRasterList1[i], e, outputRaster]) - # band list - bandSetList.append(iBandN) - bandSetNameList.append(pre + iBand) - outputRasterList.append(outputRaster) - if len(convInputList) > 0: - # conversion - inputList = [] - functionList = [] - variableList = [] - bandList = [] - for inP in convInputList: - inputList.append(inP[0]) - functionList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - bandList.append(1) - tPMDN = cfg.utls.createTempVirtualRaster(inputList, 'No', 'Yes', 'Yes', 0, 'No', 'No') - tempRasterList = cfg.utls.createTempRasterList(len(outputRasterList)) - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, tempRasterList, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = 'Yes', compressFormat = 'LZW') - rD = None - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - # No data value - if cfg.ui.GOES_nodata_checkBox.isChecked() is True: - NoData = cfg.ui.GOES_nodata_spinBox.value() - else: - NoData = cfg.NoDataVal - argumentList = functionList - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = tempRasterList, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(tempRasterList[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - # create band set - if cfg.ui.GOES_create_bandset_checkBox.isChecked() is True: - if cfg.ui.add_new_bandset_checkBox_7.isChecked() is True: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, dt) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - cfg.bst.setSatelliteWavelength(cfg.satGOES, bandSetList, bandSetNumber) - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - tW.clearSelection() - cfg.bst.bandSetTools(oDir) - # remove temporary files - try: - for t in tempRasterList1: - cfg.osSCP.remove(t) - except: - pass - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - diff --git a/maininterface/LCSignaturePixel.py b/maininterface/LCSignaturePixel.py deleted file mode 100644 index e4a568d..0000000 --- a/maininterface/LCSignaturePixel.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class LCSigPixel(QgsMapTool): - - MaprightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - MapleftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(point) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.MaprightClicked.emit(pnt) - else: - self.MapleftClicked.emit(pnt) diff --git a/maininterface/LCSignaturePixel2.py b/maininterface/LCSignaturePixel2.py deleted file mode 100644 index f7c682d..0000000 --- a/maininterface/LCSignaturePixel2.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class LCSigPixel2(QgsMapTool): - - MaprightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - MapleftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(point) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.MaprightClicked.emit(pnt) - else: - self.MapleftClicked.emit(pnt) diff --git a/maininterface/LCSignatureThresholdTab.py b/maininterface/LCSignatureThresholdTab.py deleted file mode 100644 index dff8a0c..0000000 --- a/maininterface/LCSignatureThresholdTab.py +++ /dev/null @@ -1,627 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class LCSigThresholdTab: - - def __init__(self): - pass - - # Create signature list table - def LCSignatureThresholdListTable(self): - l = cfg.ui.LCS_tableWidget - self.tableEdited = 'No' - l.blockSignals(True) - l.setSortingEnabled(False) - # column width - try: - wid0 = l.columnWidth(0) - wid1 = l.columnWidth(1) - wid2 = l.columnWidth(2) - wid3 = l.columnWidth(3) - wid4 = l.columnWidth(4) - except: - wid0 = 40 - wid1 = 70 - wid2 = 40 - wid3 = 70 - wid4 = 70 - v = 5 - wid = [] - try: - for i in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - try: - if l.columnWidth(v) == 0: - wid.append(70) - else: - wid.append(l.columnWidth(v)) - except: - wid.append(70) - v = v +1 - try: - if l.columnWidth(v) == 0: - wid.append(70) - else: - wid.append(l.columnWidth(v)) - except: - wid.append(70) - v = v +1 - except: - pass - cfg.utls.clearTable(l) - l.setColumnCount(0) - cfg.utls.insertTableColumn(l, 0, cfg.tableMCID, 40) - cfg.utls.insertTableColumn(l, 1, cfg.tableMCInfo, 70) - cfg.utls.insertTableColumn(l, 2, cfg.tableCID, 30) - cfg.utls.insertTableColumn(l, 3, cfg.tableCInfo, 70) - cfg.utls.insertTableColumn(l, 4, cfg.tableColor, 70) - v = 5 - try: - for i in range(1, cfg.bandSetsList[cfg.bndSetNumber][2] + 1): - cfg.utls.insertTableColumn(l, v, cfg.tableMin + str(i), wid[v-5]) - v = v +1 - cfg.utls.insertTableColumn(l, v, cfg.tableMax + str(i), wid[v-5]) - v = v +1 - except: - pass - # signature ID column - cfg.utls.insertTableColumn(l, v, cfg.tableColString, 60, 'Yes') - x = 0 - try: - for k in list(cfg.signIDs.values()): - cfg.utls.insertTableRow(l, x) - cfg.utls.addTableItem(l, int(cfg.signList["MACROCLASSID_" + str(k)]), x, 0, 'No') - cfg.utls.addTableItem(l, str(cfg.signList["MACROCLASSINFO_" + str(k)]), x, 1, 'No') - cfg.utls.addTableItem(l, int(cfg.signList["CLASSID_" + str(k)]), x, 2, 'No') - cfg.utls.addTableItem(l, str(cfg.signList["CLASSINFO_" + str(k)]), x, 3, 'No') - c = cfg.signList["COLOR_" + str(k)] - cfg.utls.addTableItem(l, str(""), x, 4, 'No', c) - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - cfg.utls.addTableItem(l, str(cfg.signList["LCS_MIN_" + str(k)][b]), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(l, str(cfg.signList["LCS_MAX_" + str(k)][b]), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(l, str(cfg.signIDs["ID_" + str(k)]), x, v, 'No') - x = x + 1 - except Exception as err: - cfg.utls.clearTable(l) - cfg.mx.msgErr57("MC" +str(cfg.signList["MACROCLASSID_" + str(k)]) + ";C" + str(cfg.signList["CLASSID_" + str(k)]) + ";" + str(cfg.signList["CLASSINFO_" + str(k)]) ) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - cfg.utls.setColumnWidthList(l, [[0, 40]]) - try: - vOrd = self.orderColumn - order = l.horizontalHeader().sortIndicatorOrder() - except: - vOrd = 2 - order = 0 - cfg.utls.sortTableColumn(l, vOrd, order) - l.setSortingEnabled(True) - l.blockSignals(False) - self.tableEdited = 'Yes' - self.orderedTable(vOrd) - intersect = cfg.LCSignT.checkIntersections() - cfg.LCSignT.higlightRowsByID(intersect) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " signature list threshold created") - - # read threshold table - def readThresholdTable(self): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - tW = cfg.ui.LCS_tableWidget - c = tW.rowCount() - for b in range(0, c): - try: - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(b, v).text() - vb = 5 - min = [] - max = [] - for n in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - min.append(float(tW.item(b, vb).text())) - vb = vb + 1 - max.append(float(tW.item(b, vb).text())) - vb = vb + 1 - cfg.signList["LCS_MIN_" + str(id)] = min - cfg.signList["LCS_MAX_" + str(id)] = max - cfg.spectrPlotList["LCS_MIN_" + str(id)] = min - cfg.spectrPlotList["LCS_MAX_" + str(id)] = max - except: - pass - intersect = cfg.LCSignT.checkIntersections() - cfg.LCSignT.higlightRowsByID(intersect) - - # check in thresholds are intersecting - def checkIntersections(self): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - intersect = [] - cmb = list(cfg.itertoolsSCP.combinations(list(cfg.signIDs.values()), 2)) - for a in cmb: - id0 = a[0] - minA = cfg.np.array(cfg.signList["LCS_MIN_" + str(id0)]) - maxA = cfg.np.array(cfg.signList["LCS_MAX_" + str(id0)]) - id1 = a[1] - minB = cfg.np.array(cfg.signList["LCS_MIN_" + str(id1)]) - maxB= cfg.np.array(cfg.signList["LCS_MAX_" + str(id1)]) - if cfg.macroclassCheck == 'Yes': - class0 = cfg.signList["MACROCLASSID_" + str(id0)] - class1 = cfg.signList["MACROCLASSID_" + str(id1)] - else: - class0 = cfg.signList["CLASSID_" + str(id0)] - class1 = cfg.signList["CLASSID_" + str(id1)] - if class0 != class1: - test = [] - tW = cfg.ui.LCS_tableWidget - if int((tW.columnCount() - 6)/2) != len(cfg.signList["LCS_MIN_" + str(id0)]): - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - for i in range(0, len(cfg.signList["LCS_MIN_" + str(id0)])): - if max(cfg.signList["LCS_MIN_" + str(id0)][i], cfg.signList["LCS_MIN_" + str(id1)][i]) <= min(cfg.signList["LCS_MAX_" + str(id1)][i], cfg.signList["LCS_MAX_" + str(id0)][i]): - test.append(1) - sum = cfg.np.array(test).sum() - if sum == len(cfg.signList["LCS_MIN_" + str(id0)]): - intersect.append(a) - return intersect - - # ordered table - def orderedTable(self, column): - self.orderColumn = column - tW = cfg.ui.LCS_tableWidget - count = tW.rowCount() - v = list(range(0, count)) - try: - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 5 - for x in v: - id = tW.item(x, vx).text() - cfg.signList["LCS_ROW_" + str(id)] = x - except: - pass - - # highlight rows by ID - def higlightRowsByID(self, IDComb): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - tW = cfg.ui.LCS_tableWidget - c = tW.rowCount() - self.tableEdited = 'No' - tW.setSortingEnabled(False) - tW.blockSignals(True) - for b in range(0, c): - tW.item(b, 4).setText("") - for x in range(0, 4): - tW.item(b, x).setBackground(cfg.QtGuiSCP.QColor(255,255,255)) - for ids in IDComb: - try: - row0 = cfg.signList["LCS_ROW_" + str(ids[0])] - row1 = cfg.signList["LCS_ROW_" + str(ids[1])] - except: - cfg.mx.msgWar27() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - for x in range(0, 4): - tW.item(row0, x).setBackground(cfg.QtGuiSCP.QColor(255,203,69)) - tW.item(row1, x).setBackground(cfg.QtGuiSCP.QColor(255,203,69)) - text0 = tW.item(row1, 4).text() - text1 = tW.item(row0, 4).text() - mcId0 = str(cfg.signList["MACROCLASSID_" + str(ids[0])]) - cId0 = str(cfg.signList["CLASSID_" + str(ids[0])]) - mcId1 = str(cfg.signList["MACROCLASSID_" + str(ids[1])]) - cId1 = str(cfg.signList["CLASSID_" + str(ids[1])]) - text0 = text0 + mcId0 + "-" + cId0 + ";" - text1 = text1 + mcId1 + "-" + cId1 + ";" - tW.item(row0, 4).setText(text1) - tW.item(row1, 4).setText(text0) - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - - # edited threshold table - def editedThresholdTable(self, row, column): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - if self.tableEdited == 'Yes': - tW = cfg.ui.LCS_tableWidget - t = tW.item(row, column).text() - if tW.columnCount() != cfg.bandSetsList[cfg.bndSetNumber][2]: - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - try: - tr = float(t) - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(row, v).text() - values = cfg.signList["VALUES_" + str(id)] - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - if column == vb: - if tr >= values[b * 2]: - val = str(values[b * 2]) - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - self.tableEdited = 'Yes' - break - vb = vb + 1 - if column == vb: - if tr <= values[b * 2]: - val = str(values[b * 2]) - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - self.tableEdited = 'Yes' - break - vb = vb + 1 - except: - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(row, v).text() - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - if column == vb: - val = str(cfg.signList["LCS_MIN_" + str(id)][b]) - break - vb = vb + 1 - if column == vb: - val = str(cfg.signList["LCS_MAX_" + str(id)][b]) - break - vb = vb + 1 - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - self.tableEdited = 'Yes' - cfg.LCSignT.readThresholdTable() - cfg.spSigPlot.refreshPlot() - return 0 - cfg.LCSignT.readThresholdTable() - #cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget, 'Yes') - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.spSigPlot.refreshPlot() - - # set weights based on variance - def setAllWeightsVariance(self): - tW = cfg.ui.LCS_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.setSortingEnabled(False) - tW.blockSignals(True) - progrStep = 0 - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - cfg.QtWidgetsSCP.qApp.processEvents() - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(x, idCol).text() - # values - val = cfg.signList["VALUES_" + str(id)] - vb = 5 - try: - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - sd = val[b * 2 +1] - cfg.utls.addTableItem(tW, str(val[b * 2] - (sd * cfg.ui.multiplicative_threshold_doubleSpinBox_2.value())), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(val[b * 2] + (sd * cfg.ui.multiplicative_threshold_doubleSpinBox_2.value())), x, vb) - vb = vb + 1 - except: - pass - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - cfg.LCSignT.readThresholdTable() - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget, 'Yes') - #cfg.spSigPlot.refreshPlot() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - # Activate pointer for pixel threshold - def pointerActive(self): - # connect to click - t = cfg.LCSPixel - cfg.cnvs.setMapTool(t) - px = cfg.QtGuiSCP.QPixmap(":/pointer/icons/pointer/ROI_pointer.svg") - c = cfg.QtGuiSCP.QCursor(px) - cfg.cnvs.setCursor(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "pointer active: LCS pixel") - - # left click ROI pointer for pixel signature - def pointerLeftClick(self, point): - point = cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if cfg.pntCheck == 'Yes': - sig = cfg.utls.calculatePixelSignature(point, cfg.bandSetsList[cfg.bndSetNumber][8], cfg.bndSetNumber, "Pixel", 'No') - tW = cfg.ui.LCS_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - progrStep = 0 - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(x, idCol).text() - # values - val = cfg.signList["VALUES_" + str(id)] - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - sigVal = sig[b] - valMax = float(cfg.signList["LCS_MAX_" + str(id)][b]) - valMin = float(cfg.signList["LCS_MIN_" + str(id)][b]) - if sigVal >= val[b * 2]: - if cfg.ui.LCS_include_checkBox.isChecked(): - if sigVal >= valMax: - #max = valMax + (sigVal - valMax) * cfg.ui.multiplicative_threshold_doubleSpinBox_2.value() - max = sigVal - else: - max = valMax - else: - max = sigVal - 1e-10 - min = valMin - else: - if cfg.ui.LCS_include_checkBox.isChecked(): - if sigVal <= valMin: - #min = valMin - (valMin - sigVal) * cfg.ui.multiplicative_threshold_doubleSpinBox_2.value() - min = sigVal - else: - min = valMin - else: - min = sigVal + 1e-10 - max = valMax - cfg.utls.addTableItem(tW, str(min), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(max), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - cfg.LCSignT.readThresholdTable() - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget, 'Yes') - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "pointer") - - # include checkbox - def includeCheckbox(self): - cfg.ui.LCS_cut_checkBox.blockSignals(True) - cfg.uisp.LCS_include_checkBox_2.blockSignals(True) - cfg.uisp.LCS_cut_checkBox_2.blockSignals(True) - if cfg.ui.LCS_include_checkBox.isChecked(): - cfg.ui.LCS_cut_checkBox.setCheckState(0) - cfg.uisp.LCS_include_checkBox_2.setCheckState(2) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(0) - else: - cfg.ui.LCS_cut_checkBox.setCheckState(2) - cfg.uisp.LCS_include_checkBox_2.setCheckState(0) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(2) - cfg.ui.LCS_cut_checkBox.blockSignals(False) - cfg.uisp.LCS_include_checkBox_2.blockSignals(False) - cfg.uisp.LCS_cut_checkBox_2.blockSignals(False) - - # cut checkbox - def cutCheckbox(self): - cfg.ui.LCS_include_checkBox.blockSignals(True) - cfg.uisp.LCS_include_checkBox_2.blockSignals(True) - cfg.uisp.LCS_cut_checkBox_2.blockSignals(True) - if cfg.ui.LCS_cut_checkBox.isChecked(): - cfg.ui.LCS_include_checkBox.setCheckState(0) - cfg.uisp.LCS_include_checkBox_2.setCheckState(0) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(2) - else: - cfg.ui.LCS_include_checkBox.setCheckState(2) - cfg.uisp.LCS_include_checkBox_2.setCheckState(2) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(0) - cfg.ui.LCS_include_checkBox.blockSignals(False) - cfg.uisp.LCS_include_checkBox_2.blockSignals(False) - cfg.uisp.LCS_cut_checkBox_2.blockSignals(False) - - # set minimum and maximum - def setMinimumMaximum(self): - tW = cfg.ui.LCS_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.setSortingEnabled(False) - tW.blockSignals(True) - progrStep = 0 - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(x, idCol).text() - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - min = float(cfg.signList["MIN_VALUE_" + str(id)][b]) - max = float(cfg.signList["MAX_VALUE_" + str(id)][b]) - cfg.utls.addTableItem(tW, str(min), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(max), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - cfg.LCSignT.readThresholdTable() - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget, 'Yes') - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - def ROIThreshold(self): - if cfg.lstROI is not None: - tW = cfg.ui.LCS_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.setSortingEnabled(False) - tW.blockSignals(True) - progrStep = 0 - # calculate ROI - fID = cfg.utls.getLastFeatureID(cfg.lstROI) - cfg.utls.calculateSignature(cfg.lstROI, cfg.bandSetsList[cfg.bndSetNumber][8], [fID], 0, cfg.tmpROINm, 0, 0, 0, 20, "MinMax", "MinMax", None) - progrStep = 20 - for x in reversed(v): - progrStep = progrStep +80/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(x, idCol).text() - # values - val = cfg.signList["VALUES_" + str(id)] - vb = 5 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - stats = cfg.tblOut["BAND_" + str(b + 1)] - min = stats[0] - max = stats[1] - if cfg.ui.LCS_include_checkBox.isChecked(): - if cfg.np.around(float(tW.item(x, vb).text()), 11) > cfg.np.around(min, 11): - cfg.utls.addTableItem(tW, str(min), x, vb) - else: - if cfg.np.around(float(tW.item(x, vb).text()), 11) < cfg.np.around(min, 11): - if min >= val[b * 2]: - cfg.utls.addTableItem(tW, str(min + 1e-10), x, vb + 1) - else: - cfg.utls.addTableItem(tW, str(min + 1e-10), x, vb) - vb = vb + 1 - if cfg.ui.LCS_include_checkBox.isChecked(): - if cfg.np.around(float(tW.item(x, vb).text()), 11) < cfg.np.around(max, 11): - cfg.utls.addTableItem(tW, str(max), x, vb) - else: - if cfg.np.around(float(tW.item(x, vb).text()), 11) > cfg.np.around(max, 11): - if max <= val[b * 2]: - cfg.utls.addTableItem(tW, str(max - 1e-10), x, vb - 1) - else: - cfg.utls.addTableItem(tW, str(max - 1e-10), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - cfg.LCSignT.readThresholdTable() - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget, 'Yes') - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - # add signatures to spectral plot - def addSignatureToSpectralPlot(self): - tW = cfg.ui.LCS_tableWidget - r = [] - check = 'Yes' - for i in tW.selectedIndexes(): - r.append(i.row()) - v = list(set(r)) - if len(v) > 0: - progresStep = 100 / len(v) - progress = 0 - cfg.uiUtls.addProgressBar() - for x in v: - progress = progress * progresStep - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 +5 - id = tW.item(x, idCol).text() - if id in list(cfg.signIDs.values()): - if id not in list(cfg.signPlotIDs.values()): - cfg.SCPD.sigListToPlot(id) - else: - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(id)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[cfg.bndSetNumber][8], rId, cfg.ROI_MC_ID[id], cfg.ROI_MC_Info[id], cfg.ROI_C_ID[id], cfg.ROI_C_Info[id], progress, progresStep, 'No', 'No', id) - cfg.SCPD.sigListToPlot(id) - check = 'No' - cfg.uiUtls.removeProgressBar() - if check == 'No': - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.utls.spectralPlotTab() - else: - cfg.utls.spectralPlotTab() - \ No newline at end of file diff --git a/maininterface/accuracy.py b/maininterface/accuracy.py deleted file mode 100644 index dee0c27..0000000 --- a/maininterface/accuracy.py +++ /dev/null @@ -1,653 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Accuracy: - - def __init__(self): - self.clssfctnNm = None - - # calculate error matrix if click on button - def calculateErrorMatrix(self): - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' calculate Error Matrix') - # No data value - if cfg.ui.nodata_checkBox_11.isChecked() is True: - nD = cfg.ui.nodata_spinBox_15.value() - else: - nD = None - self.errorMatrix(self.clssfctnNm, cfg.referenceLayer, NoDataValue = nD) - - # classification name - def classificationLayerName(self): - self.clssfctnNm = cfg.ui.classification_name_combo.currentText() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification name: ' + str(self.clssfctnNm)) - - # error matrix calculation - def errorMatrix(self, classification, reference, batch = 'No', shapefileField = None, rasterOutput = None, NoDataValue = None): - # check if numpy is updated - try: - cfg.np.count_nonzero([1,1,0]) - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - rstrCheck = 'No' - cfg.mx.msgErr26() - if batch == 'No': - errorRstPath = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save error matrix raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - errorRstPath = rasterOutput - # virtual raster - vrtR = 'No' - if errorRstPath is not False: - if errorRstPath.lower().endswith('.vrt'): - vrtR = 'Yes' - elif errorRstPath.lower().endswith('.tif'): - pass - else: - errorRstPath = errorRstPath + '.tif' - if batch == 'No': - iClass = cfg.utls.selectLayerbyName(classification, 'Yes') - l = cfg.utls.selectLayerbyName(reference) - else: - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(reference, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - l = cfg.utls.addVectorLayer(reference, cfg.utls.fileName(reference), 'ogr') - else: - l = cfg.utls.addRasterLayer(reference) - reml = l - rD = None - if cfg.osSCP.path.isfile(classification): - iClass = cfg.utls.addRasterLayer(classification) - remiClass = iClass - else: - return 'No' - except: - return 'No' - # date time for temp name - dT = cfg.utls.getTime() - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(errorRstPath)) - if iClass is not None and l is not None: - # if not reference shapefile - if l.type() != 0: - # check projections - rCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(l)) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - eCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(iClass)) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(cfg.utls.layerSource(iClass), tPMD, str(rCrs)) - cfg.mx.msg9() - remiClass2 = cfg.utls.addRasterLayer(tPMD) - iClass = remiClass2 - else: - # vector EPSG - ql = cfg.utls.layerSource(l) - if 'Polygon?crs=' in str(ql) or 'memory?geometry=' in str(ql): - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - l = cfg.utls.saveMemoryLayerToShapefile(l, tSHP, format = 'GPKG') - vCrs = cfg.utls.getCrsGDAL(tSHP) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - else: - ql = cfg.utls.layerSource(l) - vCrs = cfg.utls.getCrsGDAL(ql) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - # in case of reprojection - qll = cfg.utls.layerSource(l) - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileName(qll) - qlll = cfg.utls.layerSource(iClass) - rCrs = cfg.utls.getCrsGDAL(qlll) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if vEPSG.IsSame(rEPSG) != 1: - if cfg.osSCP.path.isfile(reprjShapefile): - pass - else: - try: - qllll = cfg.utls.layerSource(l) - cfg.utls.repojectShapefile(qllll, vEPSG, reprjShapefile, rEPSG) - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - l = cfg.utls.addVectorLayer(reprjShapefile, cfg.utls.fileName(reprjShapefile) , 'ogr') - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.QtWidgetsSCP.qApp.processEvents() - # temp raster layer - tRC= cfg.utls.createTempRasterPath('tif') - # error matrix - eMN = dT + cfg.errMatrixNm - cfg.reportPth = str(cfg.tmpDir + '/' + eMN) - tblOut = cfg.osSCP.path.dirname(errorRstPath) + '/' + cfg.utls.fileNameNoExt(errorRstPath) + '.csv' - cfg.uiUtls.updateBar(10) - # if reference shapefile - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - if batch == 'No': - fd = cfg.ui.class_field_comboBox.currentText() - else: - fd = shapefileField - if batch == 'No': - # convert reference layer to raster - qlllll = cfg.utls.layerSource(l) - qllllll = cfg.utls.layerSource(iClass) - vect = cfg.utls.vectorToRaster(fd, str(qlllll), classification, str(tRC), str(qllllll), extent = 'Yes') - else: - qlllllll = cfg.utls.layerSource(l) - vect = cfg.utls.vectorToRaster(fd, str(qlllllll), classification, str(tRC), classification, extent = 'Yes') - if vect == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - referenceRaster = tRC - # if reference raster - elif l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer: - if batch == 'No': - referenceRaster = cfg.utls.layerSource(l) - else: - referenceRaster = reference - qllllllll = cfg.utls.layerSource(iClass) - # combination finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = referenceRaster, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), nodataValue = NoDataValue) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # calculate unique values - valuesA = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - valuesA = cfg.np.append(valuesA, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - valuesA = valuesA.astype(int) - try: - cmbA = cfg.np.unique(valuesA, axis = 0).tolist() - refRasterBandUniqueVal = sorted(cmbA) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - # new raster - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = qllllllll, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), nodataValue = NoDataValue) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # calculate unique values - valuesB = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - valuesB = cfg.np.append(valuesB, ar[0][0, ::]) - sumVal = cfg.np.append(sumVal, ar[0][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - reclRasterBandUniqueVal = {} - valuesB = valuesB.astype(int) - for v in range(0, len(valuesB)): - try: - reclRasterBandUniqueVal[valuesB[v]] = reclRasterBandUniqueVal[valuesB[v]] + sumVal[v] - except: - reclRasterBandUniqueVal[valuesB[v]] = sumVal[v] - newRasterBandUniqueVal = [] - pixelTotal = {} - totPixelClass = 0 - for i in sorted(reclRasterBandUniqueVal): - if NoDataValue != i: - newRasterBandUniqueVal.append(i) - pixelTotal[i] = reclRasterBandUniqueVal[i] - totPixelClass = totPixelClass + reclRasterBandUniqueVal[i] - bandsUniqueVal = [refRasterBandUniqueVal, newRasterBandUniqueVal] - if 0 in refRasterBandUniqueVal: - k0 = 1 - else: - k0 = 0 - if 0 in newRasterBandUniqueVal: - k1 = 1 - else: - k1 = 0 - try: - cmb = list(cfg.itertoolsSCP.product(*bandsUniqueVal)) - testCmb = cmb[0] - except Exception as err: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr63() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # expression builder - check = 'No' - t = 0 - while t < 100: - t = t + 1 - rndVarList = [] - calcDataType = cfg.np.uint32 - # first try fixed list - if t == 1: - coT = 333 - for cmbI in range(0, len(cmb[0])): - rndVarList.append(coT) - coT = coT + 1 - # random list - else: - for cmbI in range(0, len(cmb[0])): - rndVarList.append(int(999 * cfg.np.random.random())) - newValueList = [] - reclassDict = {} - for i in cmb: - newVl = (i[0] + k0) * (rndVarList[0]) + (i[1] + k1) * (rndVarList[1]) - reclassDict[newVl] = i - newValueList.append(newVl) - if i[0] < 0 or i[1] < 0 : - calcDataType = cfg.np.int32 - uniqueValList = cfg.np.unique(newValueList) - if int(uniqueValList.shape[0]) == len(newValueList): - n = 1 - col = [] - row = [] - reclassList = [] - cmbntns = {} - for newVl in sorted(reclassDict.keys()): - i = reclassDict[newVl] - reclassList.append(newVl) - cmbntns['combination_' + str(i[0]) + '_'+ str(i[1])] = n - col.append(i[1]) - row.append(i[0]) - n = n + 1 - check = 'Yes' - break - if check == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - e = '(rasterSCPArrayfunctionBand[::, ::, 0] + ' + str(k0) +' ) * ' + str(rndVarList[0]) + ' + (rasterSCPArrayfunctionBand[::, ::, 1] + ' + str(k1) +' ) * ' + str(rndVarList[1]) - # calculation - bList = [referenceRaster, qllllllll] - bandNumberList = [1, 1] - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.crossRasters, outputRasterList = [errorRstPath], functionBandArgument = reclassList, functionVariable = e, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Accuracy'), compress = cfg.rasterCompression, nodataValue = NoDataValue, outputNoDataValue = cfg.NoDataValUInt32, virtualRaster = vrtR, dataType = 'UInt32', calcDataType = calcDataType) - # check projections - left, right, top, bottom, cRPX, cRPY, rP, un = cfg.utls.imageGeoTransform(errorRstPath) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'land cover change raster output: ' + str(errorRstPath)) - # calculate unique values - values = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[1][0, ::]) - sumVal = cfg.np.append(sumVal, ar[1][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - rasterBandUniqueVal = {} - values = values.astype(int) - for v in range(0, len(values)): - try: - rasterBandUniqueVal[values[v]] = rasterBandUniqueVal[values[v]] + sumVal[v] - except: - rasterBandUniqueVal[values[v]] = sumVal[v] - cfg.uiUtls.updateBar(80) - cols = sorted(cfg.np.unique(col).tolist()) - rows = sorted(cfg.np.unique(row).tolist()) - totX = cols - totX.extend(rows) - total = sorted(cfg.np.unique(totX).tolist()) - errMatrix = cfg.np.zeros((len(total), len(total) + 1)) - errMatrixUnbias = cfg.np.zeros((len(total), len(total) + 2)) - cList = 'V_' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classified') + '\t' - try: - l = open(tblOut, 'w') - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - cfg.utls.removeLayerByLayer(remiClass) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # error raster table - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ErrMatrixCode') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reference') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classified') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + '\n' - l.write(t) - for c in total: - cList = cList + str(int(c)) + '\t' - for r in total: - try: - v = cmbntns['combination_' + str(c) + '_'+ str(r)] - t = str(v) + '\t' + str(int(c)) + '\t' + str(int(r)) + '\t' + str(int(rasterBandUniqueVal[v])) + str('\n') - l.write(t) - errMatrix[total.index(r), total.index(c)] = rasterBandUniqueVal[v] - errMatrixUnbias[total.index(r), total.index(c)] = rasterBandUniqueVal[v] - except: - errMatrix[total.index(r), total.index(c)] = 0 - errMatrixUnbias[total.index(r), total.index(c)] = 0 - # sum without totals - totMat = int(errMatrix.sum()) - # add totals to matrices - for r in total: - errMatrix[total.index(r), len(total)] = int(errMatrix[total.index(r), :].sum()) - try: - errMatrixUnbias[total.index(r), len(total)] = pixelTotal[r] * cRPX * cRPY - except: - errMatrixUnbias[total.index(r), len(total)] = 0 - try: - errMatrixUnbias[total.index(r), len(total) + 1] = pixelTotal[r] / totPixelClass - except: - errMatrixUnbias[total.index(r), len(total) + 1] = 0 - for c in total: - for r in total: - try: - errMatrixUnbias[total.index(r), total.index(c)] = errMatrixUnbias[total.index(r), len(total) + 1] * (errMatrix[total.index(r), total.index(c)] ) / errMatrix[total.index(r), len(total) ] - except: - errMatrixUnbias[total.index(r), total.index(c)] = 0 - errMatrix[cfg.np.isnan(errMatrix)] = 0 - errMatrixUnbias[cfg.np.isnan(errMatrixUnbias)] = 0 - # save combination to table - l.write(str('\n')) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ERROR MATRIX (pixel count)') + '\n' - l.write(tStr) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reference') + '\n' - l.write(tStr) - tStr = cList + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') + '\n' - l.write(tStr) - # temp matrix - tmpMtrx= cfg.utls.createTempRasterPath('txt') - cfg.np.savetxt(tmpMtrx, errMatrix, delimiter='\t', fmt='%i') - tM = open(tmpMtrx, 'r') - # write matrix - ix = 0 - for j in tM: - tMR = str(int(total[ix])) + '\t' + j - l.write(tMR) - ix = ix + 1 - lL = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') - for c in range(0, len(total)): - lL = lL + '\t' + str(int(errMatrix[:, c].sum())) - lL = lL + '\t' + str(totMat) + str('\n') - l.write(lL) - # area based error matrix (see Olofsson, et al., 2014, Good practices for estimating area and assessing accuracy of land change, Remote Sensing of Environment, 148, 42-57) - l.write(str("\n")) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'AREA BASED ERROR MATRIX') + '\n' - l.write(tStr) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reference') + '\n' - l.write(tStr) - tStr = cList + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area') + '\t' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Wi') + '\n' - l.write(tStr) - # temp matrix - tmpMtrxU= cfg.utls.createTempRasterPath('txt') - cfg.np.savetxt(tmpMtrxU, errMatrixUnbias, delimiter='\t', fmt='%1.4f') - tM = open(tmpMtrxU, 'r') - ix = 0 - for j in tM: - tMR = str(int(total[ix])) + '\t' + j - l.write(tMR) - ix = ix + 1 - # last lines - lL = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') - for c in range(0, len(total)): - lL = lL + '\t' + str('%1.4f ' % errMatrixUnbias[:, c].sum()) - lL = lL + '\t' + str('%1.4f ' % (totPixelClass * cRPX * cRPY)) + str('\n') - l.write(lL) - lL0 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area') - for c in range(0, len(total)): - lL0 = lL0 + '\t' + str( int(round(totPixelClass * cRPX * cRPY * errMatrixUnbias[:, c].sum()))) - lL0 = lL0 + '\t' + str(int(totPixelClass * cRPX * cRPY)) + str('\n') - l.write(lL0) - lL1 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SE') - lL2 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SE area') - lL3 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', '95% CI area') - for c in range(0, len(total)): - se = 0 - for r in range(0, len(total)): - se = se + (errMatrixUnbias[r, len(total) + 1] * errMatrixUnbias[r, c] - errMatrixUnbias[r, c] * errMatrixUnbias[r, c] ) / (errMatrix[r, len(total) ] - 1) - try: - int(se) - except: - se = 0 - lL1 = lL1 + '\t' + str('%1.4f' % cfg.np.sqrt(se)) - try: - lL2 = lL2 + '\t' + str(int(round(cfg.np.sqrt(se) * totPixelClass * cRPX * cRPY))) - except: - lL2 = lL2 + '\t' + '0' - try: - lL3 = lL3 + '\t' + str(int(round(cfg.np.sqrt(se) * totPixelClass * cRPX * cRPY * 1.96))) - except: - lL3 = lL3 + '\t' + '0' - l.write(lL1) - l.write(str('\n')) - l.write(lL2) - l.write(str('\n')) - l.write(lL3) - l.write(str("\n")) - # user and producer's accuracy and kappa hat, equations from Congalton, R. & Green, K. (2009) Assessing the Accuracy of Remotely Sensed Data: Principles and Practices. CRC Press - lL4 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PA [%]') - lL5 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'UA [%]') - lL6 = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Kappa hat') - nipXnpi = 0 - niiTot = 0 - for g in range(0, len(total)): - nii = errMatrixUnbias[g,g] - niiTot = niiTot + nii - nip = errMatrixUnbias[g, 0:len(total)].sum() - npi = errMatrixUnbias[0:len(total), g].sum() - nipXnpi = nipXnpi + (nip * npi) - p = 100 * nii / npi - u = 100 * nii / nip - khatI = ((1 * nii) - (nip * npi)) / ((1 * nip) - (nip * npi)) - lL4 = lL4 + '\t' + str('%1.4f' % p) - lL5 = lL5 + '\t' + str('%1.4f' % u) - lL6 = lL6 + '\t' + str('%1.4f' % khatI) - l.write(lL4) - l.write(str('\n')) - l.write(lL5) - l.write(str('\n')) - l.write(lL6) - l.write(str('\n')) - # overall accuracy - l.write(str('\n')) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Overall accuracy [%] = ') + str('%1.4f' % (niiTot * 100)) + '\n' - l.write(t) - khat = ((1 * niiTot) - nipXnpi) / ((1 * 1) - nipXnpi) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Kappa hat classification = ') + str('%1.4f' % khat) + str('\n') - l.write(t) - l.write(str('\n')) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area unit = ' + un + '^2') + str('\n') - l.write(t) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'SE = standard error') + str('\n') - l.write(t) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'CI = confidence interval') + str('\n') - l.write(t) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', "PA = producer's accuracy") + str('\n') - l.write(t) - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', "UA = user's accuracy") + str('\n') - l.write(t) - l.close() - # add raster to layers - rstr = cfg.utls.addRasterLayer(errorRstPath) - cfg.utls.rasterSymbolGeneric(rstr, 'NoData', rasterUniqueValueList = sorted(rasterBandUniqueVal.keys())) - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.error_matrix_textBrowser.setText(eM) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error matrix calculated') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(100) - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.ui.toolBox_accuracy.setCurrentIndex(1) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'finished') - else: - self.refreshReferenceLayer() - cfg.utls.refreshClassificationLayer() - - # reference layer name - def referenceLayerName(self): - cfg.referenceLayer = cfg.ui.reference_name_combo.currentText() - cfg.ui.class_field_comboBox.clear() - l = cfg.utls.selectLayerbyName(cfg.referenceLayer) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != 'string': - cfg.dlg.class_field_combo(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reference layer name: ' + str(cfg.referenceLayer)) - - # refresh reference layer name - def refreshReferenceLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.reference_name_combo.clear() - # reference layer name - cfg.referenceLayer = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer): - if (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.Polygon) or (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon): - cfg.dlg.reference_layer_combo(l.name()) - elif (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.reference_layer_combo(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "reference layers refreshed") diff --git a/maininterface/algorithmWeightTab.py b/maininterface/algorithmWeightTab.py deleted file mode 100644 index a334ed5..0000000 --- a/maininterface/algorithmWeightTab.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class AlgWeightTab: - - def __init__(self): - pass - - # reset algorithm table - def resetAlgorithmTable(self): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' reset Algorithm Table') - for index in range(0, len(cfg.bandSetsList)): - self.tableEdited = 'No' - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(index)) - cfg.utls.clearTable(tW) - bandNameList = cfg.bandSetsList[index][3] - for bd in bandNameList: - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, str(c + 1), c, 0, 'No') - cfg.utls.addTableItem(tW, bd, c, 1, 'No') - cfg.utls.addTableItem(tW, '1', c, 2) - self.tableEdited = 'Yes' - self.readAlgorithmTable() - - # load algorithm table - def loadAlgorithmTable(self, index): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' load Algorithm Table') - if cfg.bndSetNumber >= 0: - self.tableEdited = 'No' - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(index)) - cfg.utls.clearTable(tW) - bandNameList = cfg.bandSetsList[index][3] - for bd in bandNameList: - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, str(c + 1), c, 0, 'No') - cfg.utls.addTableItem(tW, bd, c, 1, 'No') - cfg.utls.addTableItem(tW, '1', c, 2) - self.tableEdited = 'Yes' - self.readAlgorithmTable() - - # read algorithm table - def readAlgorithmTable(self): - if cfg.bndSetNumber >= 0: - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(cfg.bndSetNumber)) - w = [] - c = tW.rowCount() - for b in range(0, c): - wI = tW.item(b, 2).text() - w.append(float(wI)) - cfg.algBandWeigths = w - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # add tab - def addBandSetWeigthTab(self, refresh = 'Yes'): - t = cfg.ui.alg_band_weight_tabWidget.count() - band_set_tab = cfg.QtWidgetsSCP.QWidget() - band_set_tab.setObjectName(cfg.bandSetName + str(t + 1)) - gridLayout = cfg.QtWidgetsSCP.QGridLayout(band_set_tab) - gridLayout.setObjectName('gridLayout' + str(t + 1)) - exec('cfg.ui.alg_weight_tableWidget_' + str(t) + ' = cfg.QtWidgetsSCP.QTableWidget(band_set_tab)') - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(t)) - tW.setFrameShape(cfg.QtWidgetsSCP.QFrame.WinPanel) - tW.setFrameShadow(cfg.QtWidgetsSCP.QFrame.Sunken) - tW.setAlternatingRowColors(True) - tW.setSelectionMode(cfg.QtWidgetsSCP.QAbstractItemView.MultiSelection) - tW.setSelectionBehavior(cfg.QtWidgetsSCP.QAbstractItemView.SelectRows) - tW.setColumnCount(3) - tW.setObjectName(cfg.bandSetName + str(t + 1)) - tW.setRowCount(0) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(0, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(1, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(2, item) - item = tW.horizontalHeaderItem(0) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band number')) - item = tW.horizontalHeaderItem(1) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band name')) - item = tW.horizontalHeaderItem(2) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Weight')) - tW.verticalHeader().setDefaultSectionSize(24) - tW.horizontalHeader().setDefaultSectionSize(200) - tW.horizontalHeader().setStretchLastSection(True) - gridLayout.addWidget(tW, 0, 0, 1, 1) - # connect to edited cell - try: - tW.cellChanged.disconnect() - except: - pass - tW.cellChanged.connect(cfg.algWT.editedWeightTable) - cfg.ui.alg_band_weight_tabWidget.addTab(band_set_tab, cfg.bandSetName + str(t + 1)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' added band set weight tab ' + str(t + 1)) - - # delete Band set Weigth tab - def deleteBandSetWeigthTab(self, index): - cfg.ui.alg_band_weight_tabWidget.removeTab(index) - for i in range(0, index): - cfg.ui.alg_band_weight_tabWidget.setTabText(i, cfg.bandSetName + str(i + 1)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' closed band set weigth ' + str(index + 1)) - - # table edited - def editedWeightTable(self, row, column): - bandSetNumber = cfg.ui.alg_band_weight_tabWidget.currentIndex() - if self.tableEdited == 'Yes': - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(bandSetNumber)) - t = tW.item(row, column).text() - try: - float(t) - except: - cfg.utls.setTableItem(tW, row, 2, '1') - cfg.algWT.readAlgorithmTable() - - def resetWeights(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset weights'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset weights?')) - if a == 'Yes': - bandSetNumber = cfg.ui.alg_band_weight_tabWidget.currentIndex() - self.loadAlgorithmTable(bandSetNumber) - - # set weights - def setWeights(self): - self.tableEdited = 'No' - bandSetNumber = cfg.ui.alg_band_weight_tabWidget.currentIndex() - tW = eval('cfg.ui.alg_weight_tableWidget_' + str(bandSetNumber)) - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - wv = cfg.ui.weight_doubleSpinBox.value() - if len(v) > 0: - for c in v: - cfg.utls.setTableItem(tW, c, 2, str(wv)) - else: - v = tW.rowCount() - for c in range(0, v): - cfg.utls.setTableItem(tW, c, 2, str(wv)) - self.tableEdited = 'Yes' - self.readAlgorithmTable() diff --git a/maininterface/asterTab.py b/maininterface/asterTab.py deleted file mode 100644 index a7ddb06..0000000 --- a/maininterface/asterTab.py +++ /dev/null @@ -1,676 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ASTERTab: - - def __init__(self): - pass - - # ASTER input - def inputASTER(self): - i = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a HDF file'), '', 'file .hdf (*.hdf)') - cfg.ui.label_143.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # ASTER conversion to reflectance and temperature - def ASTER(self, inputFile, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - self.sA = '' - self.eSD = '' - ulm = cfg.ui.ulm_lineEdit.text() - lrm = cfg.ui.lrm_lineEdit.text() - try: - uLY = float(ulm.split(',')[0]) - uLX = float(ulm.split(',')[1]) - lRY = float(lrm.split(',')[0]) - lRX = float(lrm.split(',')[1]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No earth sun distance error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - utmZone = int(cfg.ui.utm_zone_lineEdit.text()) - # reference system - rSrc = cfg.osrSCP.SpatialReference() - rSrc.SetProjCS('proj') - rSrc.SetWellKnownGeogCS('WGS84') - if utmZone > 0: - rSrc.SetUTM(utmZone, True) - else: - rSrc.SetUTM(utmZone, False) - self.rSr = rSrc.ExportToWkt() - if len(cfg.ui.sun_elev_lineEdit_2.text()) > 0: - sE = float(cfg.ui.sun_elev_lineEdit_2.text()) - # sine sun elevation - self.sA = cfg.np.sin(sE * cfg.np.pi / 180) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No sun elevation error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr37() - return 'No' - # earth sun distance - if len(cfg.ui.earth_sun_dist_lineEdit_2.text()) > 0: - try: - self.eSD = float(cfg.ui.earth_sun_dist_lineEdit_2.text()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No earth sun distance error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - dt = cfg.ui.date_lineEdit_2.text() - if len(str(self.eSD)) == 0: - dFmt = '%Y%m%d' - try: - self.eSD = cfg.utls.calculateEarthSunDistance(dt, dFmt) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - cfg.uiUtls.updateBar(5) - l = cfg.ui.ASTER_tableWidget - # input - if inputFile.lower().endswith('.hdf'): - fileNm = cfg.utls.fileNameNoExt(inputFile) - # open input with GDAL - rD = cfg.gdalSCP.Open(inputFile, cfg.gdalSCP.GA_ReadOnly) - rDSub = rD.GetSubDatasets() - out = outputDirectory - oDir = cfg.utls.makeDirectory(out) - # name prefix - pre = 'RT_' - # input bands - c = l.rowCount() - # output raster list - outputRasterList = [] - outputRasterList2 = [] - outputRasterListT = [] - bandSetNameList = [] - convInputList = [] - convInputList2 = [] - # temperature - tempInputList = [] - pSize = '' - pSize2 = '' - for i in range(0, c): - if cfg.actionCheck == 'Yes': - iBand = l.item(i,0).text() - iBandN = iBand[-2:] - # aster bands - for sb in rDSub: - inputRaster = None - nm = sb[0] - if 'VNIR' in str(nm): - if '0' + nm[-1:] == iBandN: - bandName = fileNm + '_' + iBandN - inputRaster = nm - elif nm[-2:] == '3N' and iBandN in ['03']: - bandName = fileNm + '_03' - inputRaster = nm - elif 'SWIR' in str(nm): - if '0' + nm[-1:] == iBandN: - bandName = fileNm + '_' + iBandN - inputRaster = nm - elif 'TIR' in str(nm): - if nm[-2:] == iBandN: - bandName = fileNm + '_' + iBandN - inputRaster = nm - if inputRaster is not None: - oNm = pre + iBand + '.tif' - outputRaster = out + '/' + oNm - tempRaster = cfg.utls.createTempRasterPath('tif') - try: - coeff = float(l.item(i,1).text()) - except: - coeff = '' - if bandName[-2:] not in ['10', '11', '12', '13', '14']: - # conversion - e = self.ASTER_reflectance(bandName[-2:], coeff) - if e != 'No': - bandSetNameList.append(pre + bandName) - if bandName[-2:] in ['04', '05', '06', '07', '08', '09']: - try: - pSize2 = int(l.item(i,2).text()) - except: - pSize2 = '' - convInputList2.append([inputRaster, e, outputRaster]) - outputRasterList2.append(outputRaster) - geotransform2 = (uLX, pSize2, 0, uLY, 0, -pSize2) - else: - try: - pSize = int(l.item(i,2).text()) - except: - pSize = '' - convInputList.append([inputRaster, e, outputRaster]) - outputRasterList.append(outputRaster) - geotransform = (uLX, pSize, 0, uLY, 0, -pSize) - # thermal bands - else: - e = self.ASTERTemperature(bandName[-2:], coeff) - try: - pSizeT = int(l.item(i,2).text()) - except: - pSizeT = '' - geotransformT = (uLX, pSizeT, 0, uLY, 0, -pSizeT) - if e != 'No': - tempInputList.append([inputRaster, e, outputRaster]) - outputRasterListT.append(outputRaster) - # close GDAL rasters - rDSub = None - rD = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(outputRasterList)) - # conversion - inputList = [] - functionList = [] - variableList = [] - bandList = [] - for inP in convInputList: - inputList.append(inP[0]) - functionList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - bandList.append(1) - if len(inputList) > 0: - tPMDN = cfg.utls.createTempVirtualRaster(inputList, bandList, 'Yes', 'Yes', 0, self.rSr, 'No', xyResList = [pSize, pSize, float(uLX), float(uLY), float(lRX), float(lRY)], aster = 'Yes') - # No data value - if cfg.ui.nodata_checkBox_5.isChecked() is True: - NoData = cfg.ui.nodata_spinBox_6.value() - else: - NoData = cfg.NoDataVal - # DOS 1 - if cfg.ui.DOS1_checkBox_2.isChecked() is True: - LDNmList = cfg.utls.findDNmin(tPMDN, NoData) - argumentList = [] - for dnM in range(0, len(LDNmList)): - e = functionList[dnM].replace('LDNm', str(LDNmList[dnM])) - argumentList.append(e) - else: - argumentList = functionList - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = cfg.rasterCompression, compressFormat = 'LZW', projection = self.rSr, geotransform = geotransform) - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(oM[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - if len(convInputList2) > 0: - # conversion - inputList = [] - functionList = [] - variableList = [] - bandList = [] - for inP in convInputList2: - inputList.append(inP[0]) - functionList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - bandList.append(1) - tPMDN = cfg.utls.createTempVirtualRaster(inputList, bandList, 'Yes', 'Yes', 0, self.rSr, 'No', xyResList = [pSize2, pSize2, float(uLX), float(uLY), float(lRX), float(lRY)], aster = 'Yes') - # No data value - if cfg.ui.nodata_checkBox_5.isChecked() is True: - NoData = cfg.ui.nodata_spinBox_6.value() - else: - NoData = cfg.NoDataVal - # DOS 1 - if cfg.ui.DOS1_checkBox_2.isChecked() is True: - LDNmList = cfg.utls.findDNmin(tPMDN, NoData) - argumentList = [] - for dnM in range(0, len(LDNmList)): - e = functionList[dnM].replace('LDNm', str(LDNmList[dnM])) - argumentList.append(e) - else: - argumentList = functionList - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = cfg.rasterCompression, compressFormat = 'LZW', projection = self.rSr, geotransform = geotransform2) - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList2)): - cfg.shutilSCP.move(oM[t], outputRasterList2[t]) - # load raster bands - for outR in outputRasterList2: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - if len(tempInputList) > 0: - # conversion - inputList = [] - functionList = [] - variableList = [] - bandList = [] - for inP in tempInputList: - inputList.append(inP[0]) - functionList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - bandList.append(1) - tPMDN = cfg.utls.createTempVirtualRaster(inputList, bandList, 'Yes', 'Yes', 0, self.rSr, 'No', xyResList = [pSizeT, pSizeT, float(uLX), float(uLY), float(lRX), float(lRY)], aster = 'Yes') - # No data value - if cfg.ui.nodata_checkBox_5.isChecked() is True: - NoData = cfg.ui.nodata_spinBox_6.value() - else: - NoData = cfg.NoDataVal - argumentList = functionList - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = cfg.rasterCompression, compressFormat = 'LZW', projection = self.rSr, geotransform = geotransformT) - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterListT)): - cfg.shutilSCP.move(oM[t], outputRasterListT[t]) - # load raster bands - for outR in outputRasterListT: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - # create band set - if cfg.ui.create_bandset_checkBox.isChecked() is True: - if cfg.ui.add_new_bandset_checkBox_4.isChecked() is True: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, dt[:4]+'-'+dt[4:6]+'-'+dt[6:8]) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - cfg.bst.setSatelliteWavelength(cfg.satASTER, None, bandSetNumber) - cfg.bst.bandSetTools(out) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # conversion to Reflectance - def ASTER_reflectance(self, bandNumber, conversionCoefficient): - m = float(conversionCoefficient) - # Esun - dEsunB = {} - # Esun from Michael P. Finn, Matthew D. Reed, and Kristina H. Yamamoto (2012). A Straight Forward Guide for Processing Radiance and Reflectance for EO-1 ALI, Landsat 5 TM, Landsat 7 ETM+, and ASTER - dEsunB = {'ESUN_BAND01': 1848, 'ESUN_BAND02': 1549, 'ESUN_BAND03': 1114, 'ESUN_BAND04': 225.4, 'ESUN_BAND05': 86.63, 'ESUN_BAND06': 81.85, 'ESUN_BAND07': 74.85, 'ESUN_BAND08': 66.49, 'ESUN_BAND09': 59.85} - eS = float(dEsunB['ESUN_BAND' + str(bandNumber)]) - # No data value - if cfg.ui.nodata_checkBox_5.isChecked() is True: - nD = cfg.ui.nodata_spinBox_6.value() - else: - nD = cfg.NoDataVal - # TOA reflectance - if cfg.ui.DOS1_checkBox_2.isChecked() is False: - e = 'cfg.np.clip(cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ( ("raster" - 1 ) *' + str('%.16f' % m) + ' * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % self.eSD) + ' * ' + str('%.16f' % self.eSD) + ') / ( ' + str('%.16f' % eS)+ ' * (' + str(self.sA) + ') ) ), 0, 1)' - # DOS atmospheric correction - else: - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ( ("raster" - 1) * ' + str('%.16f' % m) + ') )' - # path radiance Lp = ML* DNm + AL – 0.01* ESUN * coss / (π * d^2) - Lp = str(m) + ' * (LDNm - 1) - ' + str(0.01 * eS * self.sA / (cfg.np.pi * self.eSD * self.eSD)) - # land surface reflectance r = [π * (L - Lp) * d^2]/ (ESUN * coss) - e = 'cfg.np.clip(( ' + e +' - (' + str(Lp) + ') ) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % self.eSD) + ' * ' + str('%.16f' % self.eSD) + ' / ( ' + str('%.16f' % eS)+ ' * (' + str(self.sA) + ') ), 0, 1)' - return e - - # ASTER temperature - def ASTERTemperature(self, bandNumber, conversionCoefficient): - # No data value - if cfg.ui.nodata_checkBox_5.isChecked() is True: - nD = cfg.ui.nodata_spinBox_6.value() - else: - nD = cfg.NoDataVal - # K1 = c1 /(lambda^5) and K2 = c2/lambda - # where c1 and c2 are first and second radiation constants from CODATA Recommended Values of the Fundamental Physical Constants: 2014 - if int(bandNumber) == 10: - # k1 and k2 - k1 = 3.0236879000387607831e3 - k2 = 1.73346669879518072289e3 - elif int(bandNumber) == 11: - # k1 and k2 - k1 = 2.45950033786752380082e3 - k2 = 1.66332642774566473988e3 - elif int(bandNumber) == 12: - # k1 and k2 - k1 = 1.9086243591011446439e3 - k2 = 1.58107402197802197802e3 - elif int(bandNumber) == 13: - # k1 and k2 - k1 = 8.90016580863773201879e2 - k2 = 1.35733713207547169811e3 - elif int(bandNumber) == 14: - # k1 and k2 - k1 = 6.4645039694287387514e2 - k2 = 1.27325430088495575221e3 - # Kelvin or cs - cs = 0 - if cfg.ui.celsius_checkBox_2.isChecked() is True: - cs = 273.15 - # At-Satellite Brightness Temperature - m = float(conversionCoefficient) - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ((' + str('%.16f' % k2) + ') / ( ln( (' + str('%.16f' % k1) + ' / ( ("raster" - 1 ) * ' + str('%.16f' % m) + ') ) + 1)) - ' + str(cs) + ') )' - return e - - # ASTER correction button - def performASTERCorrection(self): - if len(cfg.ui.label_143.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.ASTER(cfg.ui.label_143.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform ASTER correction: ' + str(cfg.ui.label_143.text())) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - dt = '' - sE = '' - esd = '' - cfg.ui.date_lineEdit_2.setText(dt) - cfg.ui.sun_elev_lineEdit_2.setText(sE) - cfg.ui.earth_sun_dist_lineEdit_2.setText(esd) - l = cfg.ui.ASTER_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 250]]) - cfg.utls.clearTable(l) - if len(input) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - # bands - dBs = {} - dGains = {} - bandNames = [] - # input - if input.lower().endswith('.hdf'): - fileNm = cfg.utls.fileNameNoExt(input) - # open input with GDAL - rD = cfg.gdalSCP.Open(input, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - pass - else: - # get metadata - rDMeta = rD.GetMetadata_List() - for metadata in rDMeta: - if 'CALENDARDATE' in metadata: - dt = metadata.split('=')[1] - elif 'SOLARDIRECTION' in metadata: - sD = metadata.split('=')[1] - sE = sD.split(',')[1] - elif 'UTMZONECODE' in metadata: - utm = metadata.split('=')[1] - elif 'UPPERLEFTM' in metadata: - uLM = metadata.split('=')[1] - elif 'LOWERRIGHTM' in metadata: - lRM = metadata.split('=')[1] - elif 'GAIN' in metadata: - g = metadata.split('=')[1] - if g.split(',')[0] == '01': - if g.split(',')[1].strip() == 'HGH': - v = 0.676 - elif g.split(',')[1].strip() == 'NOR': - v = 1.688 - elif g.split(',')[1].strip() == 'LOW': - v = 2.25 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '02': - if g.split(',')[1].strip() == 'HGH': - v = 0.708 - elif g.split(',')[1].strip() == 'NOR': - v = 1.415 - elif g.split(',')[1].strip() == 'LOW': - v = 1.89 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '3N': - if g.split(',')[1].strip() == 'HGH': - v = 0.423 - elif g.split(',')[1].strip() == 'NOR': - v = 0.862 - elif g.split(',')[1].strip() == 'LOW': - v = 1.15 - else: - v = 'No' - dGains['BAND_03'] = v - elif g.split(',')[0] == '04': - if g.split(',')[1].strip() == 'HGH': - v = 0.1087 - elif g.split(',')[1].strip() == 'NOR': - v = 0.2174 - elif g.split(',')[1].strip() == 'LO1': - v = 0.290 - elif g.split(',')[1].strip() == 'LO2': - v = 0.290 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '05': - if g.split(',')[1].strip() == 'HGH': - v = 0.0348 - elif g.split(',')[1].strip() == 'NOR': - v = 0.0696 - elif g.split(',')[1].strip() == 'LO1': - v = 0.0925 - elif g.split(',')[1].strip() == 'LO2': - v = 0.409 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '06': - if g.split(',')[1].strip() == 'HGH': - v = 0.0313 - elif g.split(',')[1].strip() == 'NOR': - v = 0.0625 - elif g.split(',')[1].strip() == 'LO1': - v = 0.0830 - elif g.split(',')[1].strip() == 'LO2': - v = 0.390 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '07': - if g.split(',')[1].strip() == 'HGH': - v = 0.0299 - elif g.split(',')[1].strip() == 'NOR': - v = 0.0597 - elif g.split(',')[1].strip() == 'LO1': - v = 0.0795 - elif g.split(',')[1].strip() == 'LO2': - v = 0.332 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '08': - if g.split(',')[1].strip() == 'HGH': - v = 0.0209 - elif g.split(',')[1].strip() == 'NOR': - v = 0.0417 - elif g.split(',')[1].strip() == 'LO1': - v = 0.0556 - elif g.split(',')[1].strip() == 'LO2': - v = 0.245 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - elif g.split(',')[0] == '09': - if g.split(',')[1].strip() == 'HGH': - v = 0.0159 - elif g.split(',')[1].strip() == 'NOR': - v = 0.0318 - elif g.split(',')[1].strip() == 'LO1': - v = 0.0424 - elif g.split(',')[1].strip() == 'LO2': - v = 0.265 - else: - v = 'No' - dGains['BAND_' + g.split(',')[0]] = v - dGains['BAND_' + '10'] = 0.006822 - dGains['BAND_' + '11'] = 0.006780 - dGains['BAND_' + '12'] = 0.006590 - dGains['BAND_' + '13'] = 0.005693 - dGains['BAND_' + '14'] = 0.005225 - # date format - dFmt = '%Y%m%d' - try: - esd = str(cfg.utls.calculateEarthSunDistance(dt, dFmt)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - cfg.ui.date_lineEdit_2.setText(dt) - cfg.ui.sun_elev_lineEdit_2.setText(sE) - cfg.ui.earth_sun_dist_lineEdit_2.setText(esd) - cfg.ui.utm_zone_lineEdit.setText(utm) - cfg.ui.ulm_lineEdit.setText(uLM) - cfg.ui.lrm_lineEdit.setText(lRM) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return - rDSub = rD.GetSubDatasets() - # aster bands - for sb in rDSub: - nm = sb[0] - if 'VNIR' in str(nm): - sbD = cfg.gdalSCP.Open(str(nm)) - if nm[-1:].isdigit() : - dBs['BAND_0{0}'.format(nm[-1:])] = 15 - bandNames.append(fileNm + '_0' + nm[-1:]) - elif nm[-2:] == '3N': - dBs['BAND_03'] = 15 - bandNames.append(fileNm + '_03') - elif 'SWIR' in str(nm): - sbD = cfg.gdalSCP.Open(str(nm)) - if nm[-1:].isdigit() : - dBs['BAND_0{0}'.format(nm[-1:])] = 30 - bandNames.append(fileNm + '_0' + nm[-1:]) - elif 'TIR' in str(nm): - sbD = cfg.gdalSCP.Open(str(nm)) - if nm[-2:].isdigit() : - dBs['BAND_{0}'.format(nm[-2:])] = 90 - bandNames.append(fileNm + '_' + nm[-2:]) - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0, 'No') - try: - cfg.utls.addTableItem(l, str(dGains['BAND_' + band[-2:]]), b, 1) - cfg.utls.addTableItem(l, dBs['BAND_' + band[-2:]], b, 2) - except: - pass - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.ASTER_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText('') - - # earth sun distance - def editedEarthSunDist(self): - try: - float(cfg.ui.earth_sun_dist_lineEdit_2.text()) - except: - cfg.ui.earth_sun_dist_lineEdit_2.setText('') - - # sun elevation - def editedSunElevation(self): - try: - float(cfg.ui.sun_elev_lineEdit_2.text()) - except: - cfg.ui.sun_elev_lineEdit_2.setText('') - - def editedDate(self): - dFmt = '%Y%m%d' - dt = cfg.ui.date_lineEdit_2.text() - try: - cfg.utls.calculateEarthSunDistance(dt, dFmt) - cfg.ui.date_lineEdit_2.setStyleSheet('color : black') - except: - cfg.ui.date_lineEdit_2.setStyleSheet('color : red') - - def removeHighlightedBand(self): - l = cfg.ui.ASTER_tableWidget - cfg.utls.removeRowsFromTable(l) - \ No newline at end of file diff --git a/maininterface/bandcalcTab.py b/maininterface/bandcalcTab.py deleted file mode 100644 index 6c583b1..0000000 --- a/maininterface/bandcalcTab.py +++ /dev/null @@ -1,1769 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class BandCalcTab: - - def __init__(self): - self.expressionButton = False - self.decisionRulesButton = False - - # toolbox changed - def tabChanged(self, index): - cfg.bandCalcIndex = index - if cfg.bandCalcIndex == 0: - cfg.ui.toolButton_calculate.setEnabled(self.expressionButton) - elif cfg.bandCalcIndex == 1: - cfg.ui.toolButton_calculate.setEnabled(self.decisionRulesButton) - - # add row to table - def addRowToTable(self): - tW = cfg.ui.decision_rules_tableWidget - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - tW.blockSignals(True) - cfg.utls.addTableItem(tW, str(c + 1), c, 0) - cfg.utls.addTableItem(tW, '', c, 1) - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "added row " + str(c + 1)) - e = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(e) - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # remove row - def removeHighlightedRule(self): - tW = cfg.ui.decision_rules_tableWidget - cfg.utls.removeRowsFromTable(tW) - e = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(e) - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # clear the rules - def clearRulesAction(self): - self.clearRules() - expression = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(expression) - tW = cfg.ui.decision_rules_tableWidget - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # clear the rules - def clearRules(self, question = 'Yes'): - if question == 'Yes': - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clear rules'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to clear the rules?')) - else: - a = 'Yes' - if a == 'Yes': - tW = cfg.ui.decision_rules_tableWidget - tW.blockSignals(True) - cfg.utls.clearTable(tW) - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - - # edited table - def editedDecisionRulesTable(self, row, column): - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - tW = cfg.ui.decision_rules_tableWidget - if column == 0: - try: - tr = int(tW.item(row, 0).text()) - except: - tr = 1 - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, 0, str(tr)) - tW.blockSignals(False) - try: - value = tW.item(row, 0).text() - except: - value = 'No' - try: - t = tW.item(row, 1).text() - except: - tW.setStyleSheet('color : red') - self.decisionRulesButton = False - cfg.ui.toolButton_calculate.setEnabled(self.decisionRulesButton) - return 'No' - e = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(e) - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # create decision rule expression - def decisionRulesExpression(self): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - tW = cfg.ui.decision_rules_tableWidget - NoDataValue = cfg.ui.nodata_spinBox_13.value() - c = tW.rowCount() - if c > 0: - for row in range(0, c): - try: - w = e - except: - pass - try: - value = tW.item(row, 0).text() - t = tW.item(row, 1).text() - except: - return 'No' - tSplit = t.split(';') - e = 'cfg.np.where( ' - for b in tSplit: - if len(b) > 0: - e = e + '(' + b + ') & ' - e = e[:-4] + '), ' + str(value) + ',' + 'str(NoDataValue)' + ')' - try: - e = w.replace('str(NoDataValue)', str(e)) - except: - pass - e = e.replace('str(NoDataValue)', str(NoDataValue)) - return e - - # import rules from text file - def importRules(self): - file = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a text file of rules'), '', 'txt (*.txt)') - if len(file) > 0: - self.clearRules('No') - tW = cfg.ui.decision_rules_tableWidget - text = open(file, 'r') - lines = text.readlines() - tW.blockSignals(True) - for b in lines: - v = b.split(';', 1) - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - try: - cfg.utls.addTableItem(tW, v[0].strip(), c, 0) - cfg.utls.addTableItem(tW, v[1].strip(), c, 1) - except: - tW.blockSignals(False) - self.clearRules('No') - cfg.mx.msgErr19() - return 'No' - tW.blockSignals(False) - expression = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(expression) - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # export rules to text file - def exportRules(self): - tW = cfg.ui.decision_rules_tableWidget - c = tW.rowCount() - if c > 0: - file = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save the rules to file'), '', '*.txt', 'txt') - if file is not False: - if file.lower().endswith('.txt'): - pass - else: - file = file + '.txt' - f = self.rulesToCSV() - o = open(file, 'w') - o.write(f) - o.close() - - # convert rules to CSV - def rulesToCSV(self): - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - tW = cfg.ui.decision_rules_tableWidget - c = tW.rowCount() - if c > 0: - e = '' - for row in range(0, c): - try: - value = tW.item(row, 0).text() - t = tW.item(row, 1).text() - except: - return 'No' - e = e + value + ';' + t + '\n' - return e - - # Set output name table - def outputNameTable(self, nameList = None): - if nameList is None: - pass - l = cfg.ui.tableWidget_band_calc - l.blockSignals(True) - l.setSortingEnabled(False) - c = l.rowCount() - # remove items - for i in reversed(range(0, c)): - if cfg.variableOutName in l.item(i, 0).text(): - l.removeRow(i) - else: - break - b = l.rowCount() - z = 0 - for bN in nameList: - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableOutName + str(z + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN[0].replace('"', ''), b, 1, 'No') - z = z + 1 - b = b + 1 - l.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " output name table created") - - # Set raster band table - def rasterBandName(self, bandSetNumber = None): - if bandSetNumber is None or bandSetNumber is False: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - cfg.utls.refreshRasterExtent() - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - l = cfg.ui.tableWidget_band_calc - l.setSortingEnabled(False) - cfg.utls.clearTable(l) - check = 'Yes' - b = 0 - for x in sorted(ls, key=lambda c: c.name()): - if x.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer and x.bandCount() == 1: - # band name - bN = x.name() - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - # test empty band set - try: - cfg.bandSetsList[bandSetNumber][0] - except: - return - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - if len(cfg.bandSetsList[bandSetNumber][3]) > 0 : - # variable band set - bN = cfg.variableBandsetName + '#b*' - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - for x in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - # band name - bN = cfg.variableBandsetName + '#b' + str(x + 1) - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - else: - try: - r = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - iR = cfg.utls.layerSource(r) - except: - check = 'No' - if check == 'Yes': - x = cfg.utls.getNumberBandRaster(iR) - for c in range(1, x + 1): - # band name - bN = cfg.variableBandsetName + '#b' + str(c) - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if check == 'Yes': - bNList = [] - for bNum in range(0, len(cfg.bandSetsList)): - if len(cfg.bandSetsList[bNum][3]) > 0 : - for x in range(0, len(cfg.bandSetsList[bNum][3])): - # band name - bN = cfg.variableBandsetName + str(bNum + 1) + 'b' + str(x + 1) - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - # band name - bN = cfg.variableBandsetName + '*b' + str(x + 1) - if bN not in bNList: - bNList.append(bN) - # variable band set - bN = cfg.variableBandsetName + str(bNum + 1) + 'b*' - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - for bN in bNList: - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if len(cfg.bandSetsList[bandSetNumber][3]) > 0: - cfg.utls.findBandNumber() - if cfg.BLUEBand is not None: - # band name - bN = cfg.variableBlueName - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if cfg.GREENBand is not None: - # band name - bN = cfg.variableGreenName - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if cfg.REDBand is not None: - # band name - bN = cfg.variableRedName - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if cfg.NIRBand is not None: - # band name - bN = cfg.variableNIRName - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if cfg.SWIR1Band is not None: - # band name - bN = cfg.variableSWIR1Name - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - if cfg.SWIR2Band is not None: - # band name - bN = cfg.variableSWIR2Name - # Add band to table - l.insertRow(b) - cfg.utls.addTableItem(l, cfg.variableName + str(b + 1), b, 0, 'No') - cfg.utls.addTableItem(l, bN, b, 1, 'No') - b = b + 1 - cfg.bCalc.textChanged() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " raster band name checklist created") - - # set raster type - def setRasterType(self): - cfg.rasterBandCalcType = cfg.ui.raster_type_combo.currentText() - - # import expressions from file - def importExpressionList(self): - funcFile = cfg.utls.getOpenFileName(None , 'Select an expression file', '', 'TXT (*.txt)') - if len(funcFile) > 0: - try: - f = open(funcFile) - sep = ';' - if cfg.osSCP.path.isfile(funcFile): - cfg.expressionListBC = [] - lines = f.readlines() - tW = cfg.ui.point_tableWidget - if len(lines) > 0: - for b in lines: - try: - v = b.split(sep) - # name and expression - n = v[0] - e = v[1].strip() - cfg.expressionListBC.append([n, e]) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " expressions imported") - # save in registry - cfg.utls.setQGISRegSetting(cfg.regExpressionListBC, cfg.expressionListBC) - cfg.bCalc.createExpressionList(cfg.expressionListBC) - else: - # save in registry - lbase=[] - cfg.utls.setQGISRegSetting(cfg.regExpressionListBC, str(lbase)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - - # create expression list - def createExpressionList(self, expressionList): - cfg.utls.clearTable(cfg.ui.band_calc_function_tableWidget) - cfg.bCalc.addFunctionsToTable(cfg.bandCalcFunctionNames) - cfg.bCalc.addFunctionsToTable(expressionList) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " expressions created") - - # add function list to table - def addFunctionsToTable(self, functionList): - if functionList is not None: - tW = cfg.ui.band_calc_function_tableWidget - for i in functionList: - tW.blockSignals(True) - # count table rows - c = tW.rowCount() - try: - # name of item of list - itN = i[0] - itF = i[1] - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0) - except: - itN = i[0] - # add list items to table - tW.setRowCount(c + 1) - co = cfg.QtGuiSCP.QColor(200, 200, 200) - cfg.utls.addTableItem(tW, itN, c, 0, 'No', co, bold = 'Yes') - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - - # set function - def setFunction(self, index): - cursor = cfg.ui.plainTextEdit_calc.textCursor() - tW = cfg.ui.band_calc_function_tableWidget - nm = tW.item(index.row(), 0).text() - text = self.replaceFunctionNames(nm) - if text != 'No': - cursor.insertHtml(' ' + text) - - # replace function names - def replaceFunctionNames(self, name): - if cfg.expressionListBC is not None: - cF = cfg.bandCalcFunctionNames + cfg.expressionListBC - else: - cF = cfg.bandCalcFunctionNames - for i in cF: - if name == i[0]: - try: - return i[1] - except: - return 'No' - return 'No' - - # calculate button - def calculateButton(self): - # band calc - if cfg.bandCalcIndex == 0: - cfg.bCalc.calculate() - # decision rules - elif cfg.bandCalcIndex == 1: - e = cfg.bCalc.decisionRulesExpression() - cfg.bCalc.calculate(None, 'No', e) - - # calculate - def calculate(self, outFile = None, batch = 'No', expressionString = None, extentRaster = None, extentList = None, inputNoDataAsValue = None, useNoDataValue = None, outputNoData = None, rasterDataType = None, useScale = None, useOffset = None, align = None, extentIntersection = None, extentSameAs = None, quiet = 'No', bandSetNumber = None, calcDataType = None, nodataMask = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - pass - else: - self.rasterBandName(bandSetNumber) - tW = cfg.ui.tableWidget_band_calc - c = tW.rowCount() - if c > 0: - if outFile is None and batch == 'No': - # band calc - if cfg.bandCalcIndex == 0: - textCount = cfg.ui.plainTextEdit_calc.blockCount() - # multiple lines - if textCount > 1: - outF = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(outF) > 0: - outF = outF + '/' + cfg.calcRasterNm + '.tif' - else: - return - # one line - else: - try: - # output name defined - nm = cfg.ui.plainTextEdit_calc.toPlainText().split('@')[1] - outF = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(outF) > 0: - outF = outF + '/' + cfg.calcRasterNm + '.tif' - else: - return - except: - outF = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)', None) - # decision rules - elif cfg.bandCalcIndex == 1: - outF = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)', None) - else: - outF = outFile - if outF is not False: - if outFile is None: - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band calc'), message = '') - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band calculation started') - if expressionString is None: - expression = ' ' + cfg.ui.plainTextEdit_calc.toPlainText() + ' ' - else: - expression = expressionString - check = self.checkExpression(expression) - if check == 'No': - cfg.mx.msgErr36() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' check No') - if outFile is None: - cfg.uiUtls.removeProgressBar() - return 'No' - cfg.cnvs.setRenderFlag(False) - it = 1 - nCh = len(check) - for eM in check: - c = tW.rowCount() - e = eM[0] - eN = eM[1] - ePath = eM[2] - eVrt = eM[3] - if batch == 'No': - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band calc') + ' [' + str(it) + '/' + str(nCh) + '] ' + e, message = '') - # do not replace expression - expe = None - # add to band set - try: - eNBS = eN.split('%')[1] - eN = eN.split('%')[0] - except: - eNBS = None - # virtual raster - if eVrt == 'Yes': - vrtR = 'Yes' - else: - vrtR = 'No' - dCheck = 'Yes' - if dCheck == 'Yes': - if eN is None: - n = cfg.utls.fileName(outF) - else: - n = eN - if ePath is not None: - outF = ePath + '/' + n - if ePath == cfg.tmpDir and cfg.outTempRastFormat == 'VRT': - vrtR = 'Yes' - if n.lower().endswith('.tif'): - if eN is None and len(check) == 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n - elif eN is None and len(check) > 1: - out = cfg.osSCP.path.dirname(outF) + '/' + cfg.reSCP.sub(r'\.tif$', '', str(n)) + '_' + str(it) + '.tif' - else: - out = cfg.osSCP.path.dirname(outF) + '/' + n - elif n.lower().endswith('.vrt'): - vrtR = 'Yes' - if eN is None and len(check) == 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n - elif eN is None and len(check) > 1: - out = cfg.osSCP.path.dirname(outF) + '/' + cfg.reSCP.sub(r'\.vrt$', '', str(n)) + '_' + str(it) + '.vrt' - else: - out = cfg.osSCP.path.dirname(outF) + '/' + n - else: - if vrtR == 'Yes': - if eN is None and len(check) == 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '.vrt' - elif eN is None and len(check) > 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '_' + str(it) + '.vrt' - else: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '.vrt' - else: - if eN is None and len(check) == 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '.tif' - elif eN is None and len(check) > 1: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '_' + str(it) + '.tif' - else: - out = cfg.osSCP.path.dirname(outF) + '/' + n + '.tif' - outDir = cfg.osSCP.path.dirname(outF) - # if function - if cfg.calcFunctionNm in e: - nf = e.split(cfg.calcFunctionNm) - ee = nf[1] - ee = ee.replace(cfg.FileNm, out) - ee = ee.replace(cfg.DirNm, outDir) - for b in range(0, c): - bV = tW.item(b, 0).text() - bN = tW.item(b, 1).text() - if str('"' + bV +'"') in ee or str('"' + bN +'"') in ee or str('$' + bV +'$') in ee or str('$' + bN +'$') in ee: - # do not replace expressions - eep = ee.split('expression :') - if len(eep) == 1: - eep = ee.split('expression:') - if len(eep) > 1: - eepd = eep[1].split(';') - expe = eepd[0] - ee = ee.replace(expe, cfg.calcVarReplace) - # variable bandset#b1 - if cfg.variableBandsetName + '#b' in bN: - bandNumber = int(bN.split('#b')[1]) - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - bPath = cfg.bndSetLst[bandNumber - 1] - ee = ee.replace('"' + bV + '"', bPath) - ee = ee.replace('"' + bN +' "', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumber][3][bandNumber] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumber][3][bandNumber] + "'") - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - ee = ee.replace('"' + bV + '"', bPath) - ee = ee.replace('"' + bN +' "', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumber][8] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumber][8] + "'") - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # variable bandset1b1 - elif cfg.variableBandsetName in bN: - bandSetBandNumber = bN.replace(cfg.variableBandsetName, '').split('b') - bandSetNumberX = int(bandSetBandNumber[0]) - 1 - bandNumX = int(bandSetBandNumber[1]) - 1 - if cfg.bandSetsList[bandSetNumberX][0] == 'Yes': - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumberX][3][bandNumX], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - ee = ee.replace('"' + bV +'"', bPath) - ee = ee.replace('"' + bN +'"', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumberX][3][bandNumX] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumberX][3][bandNumX] + "'") - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # single band - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumberX][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - ee = ee.replace('"' + bV +'"', bPath) - ee = ee.replace('"' + bN +'"', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumberX][8] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumberX][8] + "'") - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumberX) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # spectral range bands - elif cfg.variableBlueName in bN or cfg.variableRedName in bN or cfg.variableNIRName in bN or cfg.variableGreenName in bN or cfg.variableSWIR1Name in bN or cfg.variableSWIR2Name in bN : - if bN == cfg.variableRedName : - bandNumber = ['', cfg.REDBand] - elif bN == cfg.variableNIRName : - bandNumber = ['', cfg.NIRBand] - elif bN == cfg.variableBlueName : - bandNumber = ['', cfg.BLUEBand] - elif bN == cfg.variableGreenName : - bandNumber = ['', cfg.GREENBand] - elif bN == cfg.variableSWIR1Name : - bandNumber = ['', cfg.SWIR1Band] - elif bN == cfg.variableSWIR2Name : - bandNumber = ['', cfg.SWIR2Band] - else: - cfg.mx.msg4() - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - bPath = cfg.bndSetLst[int(bandNumber[1]) - 1] - ee = ee.replace('"' + bV +'"', bPath) - ee = ee.replace('"' + bN +'"', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumber][3][bandNumber] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumber][3][bandNumber] + "'") - except: - return 'No' - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - ee = ee.replace('"' + bV +'"', bPath) - ee = ee.replace('"' + bN +'"', bPath) - ee = ee.replace('$' + bV + '$', "'" + cfg.bandSetsList[bandSetNumber][8] + "'") - ee = ee.replace('$' + bN + '$', "'" + cfg.bandSetsList[bandSetNumber][8] + "'") - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - else: - i = cfg.utls.selectLayerbyName(bN, 'Yes') - try: - bPath = cfg.utls.layerSource(i) - ee = ee.replace('"' + bV +'"', bPath) - ee = ee.replace('"' + bN +'"', bPath) - ee = ee.replace('$' + bV + '$', '\'' + bN + '\'') - ee = ee.replace('$' + bN + '$', '\'' + bN + '\'') - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # do not replace expression - if expe is not None: - ee = ee.replace(cfg.calcVarReplace, expe) - ee = ee.replace('$', '\'').replace('!!', ';') - dCheck, function = cfg.batchT.checkExpressionLine(ee) - try: - eval(function) - except Exception as err: - cfg.mx.msgErr36() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # not function - else: - # variable list - variableList = [] - # band list - bList = [] - refCRS = None - bandNumberList = [] - for b in range(0, c): - try: - bV = tW.item(b, 0).text() - bN = tW.item(b, 1).text() - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err) + ' bandset' + str(bandSetNumberX+1) + ' band' + str(bandNumX+1) + ' layer ' + str(cfg.bandSetsList[bandSetNumberX][3][bandNumX])) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if str('"' + bV +'"') in e or str('"' + bN +'"') in e: - variableList.append(['"' + bV + '"', '"' + bN + '"']) - # variable bandset#b1 - if cfg.variableBandsetName + '#b' in bN: - bandNumber = bN.split('#b') - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - rPath = cfg.bndSetLst[int(bandNumber[1]) - 1] - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - except Exception as err: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bandNumberList.append(int(bandNumber[1])) - bList.append(bPath) - # variable bandset1b1 - elif cfg.variableBandsetName in bN: - bandSetBandNumber = bN.replace(cfg.variableBandsetName, '').split('b') - bandSetNumberX = int(bandSetBandNumber[0]) - 1 - bandNumX = int(bandSetBandNumber[1]) - 1 - if cfg.bandSetsList[bandSetNumberX][0] == 'Yes': - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumberX][3][bandNumX], 'Yes') - try: - rPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err) + " bandset" + str(bandSetNumberX+1) + " band" + str(bandNumX+1) + " layer " + str(cfg.bandSetsList[bandSetNumberX][3][bandNumX])) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumberX][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumberX) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bandNumberList.append(int(bandNumX)+1) - bList.append(bPath) - # spectral range bands - elif cfg.variableBlueName in bN or cfg.variableRedName in bN or cfg.variableNIRName in bN or cfg.variableGreenName in bN or cfg.variableSWIR1Name in bN or cfg.variableSWIR2Name in bN : - if bN == cfg.variableRedName : - bandNumber = ['', cfg.REDBand] - elif bN == cfg.variableNIRName : - bandNumber = ['', cfg.NIRBand] - elif bN == cfg.variableBlueName : - bandNumber = ['', cfg.BLUEBand] - elif bN == cfg.variableGreenName : - bandNumber = ['', cfg.GREENBand] - elif bN == cfg.variableSWIR1Name : - bandNumber = ['', cfg.SWIR1Band] - elif bN == cfg.variableSWIR2Name : - bandNumber = ['', cfg.SWIR2Band] - else: - cfg.mx.msg4() - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - rPath = cfg.bndSetLst[int(bandNumber[1]) - 1] - except: - return 'No' - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bandNumberList.append(int(bandNumber[1])) - bList.append(bPath) - else: - i = cfg.utls.selectLayerbyName(bN, 'Yes') - try: - rPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - try: - gdalRaster2 = cfg.gdalSCP.Open(bPath, cfg.gdalSCP.GA_ReadOnly) - gBand2 = gdalRaster2.GetRasterBand(int(1)) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - noData = gBand2.GetNoDataValue() - # close band - gBand2 = None - # close raster - gdalRaster2 = None - if inputNoDataAsValue is None: - if cfg.ui.nodata_as_value_checkBox.isChecked() is True: - skipReplaceNoDT = 1 - else: - skipReplaceNoDT = None - else: - if inputNoDataAsValue == 'Yes': - skipReplaceNoDT = 1 - else: - skipReplaceNoDT = None - if nodataMask is None: - if cfg.ui.nodata_mask_checkBox.isChecked() is True: - nodataMask = 'Yes' - else: - nodataMask = 'No' - if useScale is None: - if cfg.ui.set_scale_checkBox.isChecked() is True: - useScale = cfg.ui.scale_doubleSpinBox.value() - else: - useScale = None - if useOffset is None: - if cfg.ui.set_offset_checkBox.isChecked() is True: - useOffset = cfg.ui.offset_doubleSpinBox.value() - else: - useOffset = None - if useNoDataValue is None: - if cfg.ui.nodata_checkBox_3.isChecked() is True: - useNoDataValue = cfg.ui.nodata_spinBox_13.value() - else: - useNoDataValue = None - elif useNoDataValue == 'No': - useNoDataValue = None - if outputNoData is None: - outputNoData = cfg.ui.nodata_spinBox_4.value() - if rasterDataType is None: - rasterDataType = cfg.rasterBandCalcType - # calc data type - if calcDataType is None: - calcDataType = cfg.ui.calc_type_combo.currentText() - if calcDataType == 'Float64': - calcDataType = cfg.np.float64 - elif calcDataType == 'Float32': - calcDataType = cfg.np.float32 - elif calcDataType == 'Int32': - calcDataType = cfg.np.int32 - elif calcDataType == 'UInt32': - calcDataType = cfg.np.uint32 - elif calcDataType == 'Int16': - calcDataType = cfg.np.int16 - elif calcDataType == 'UInt16': - calcDataType = cfg.np.uint16 - elif calcDataType == 'Byte': - calcDataType = cfg.np.byte - else: - calcDataType = cfg.np.float32 - if extentList is None: - if (extentIntersection is None and cfg.ui.intersection_checkBox.isChecked() is True) or extentIntersection == 'Yes': - tPMD = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes') - elif (extentSameAs is None and cfg.ui.extent_checkBox.isChecked() is True) or extentSameAs == 'Yes': - # raster resolution - xyRes = None - if extentRaster is None: - extRaster = cfg.ui.raster_extent_combo.currentText() - else: - extRaster = extentRaster - if extRaster == cfg.mapExtent: - rectangle = cfg.cnvs.extent() - tLX, tLY, lRX, lRY = rectangle.xMinimum(), rectangle.yMaximum(), rectangle.xMaximum(), rectangle.yMinimum() - pCrs = cfg.utls.getQGISCrs() - # check projection - try: - bN0 =cfg.utls.addRasterLayer(bList[0]) - iCrs = cfg.utls.getCrs(bN0) - cfg.utls.removeLayerByLayer(bN0) - except: - pass - # image CRS - if iCrs is None: - iCrs = pCrs - # projection of input point from project's crs to raster's crs - if pCrs != iCrs: - tLPoint = cfg.qgisCoreSCP.QgsPointXY(tLX, tLY) - lRPoint = cfg.qgisCoreSCP.QgsPointXY(lRX, lRY) - try: - tLPoint = cfg.utls.projectPointCoordinates(tLPoint, pCrs, iCrs) - lRPoint = cfg.utls.projectPointCoordinates(lRPoint, pCrs, iCrs) - if tLPoint is False or lRPoint is False: - cfg.utls.setQGISCrs(iCrs) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - else: - tLX = tLPoint.x() - tLY = tLPoint.y() - lRX = lRPoint.x() - lRY = lRPoint.y() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - #elif extRaster == cfg.pixelExtent: - # tLX, tLY, lRX, lRY = extentList[0], extentList[1], extentList[2], extentList[3] - else: - tLX, tLY, lRX, lRY, pSX, pSY = cfg.utls.imageInformationSize(extRaster) - if align is None: - if cfg.ui.align_radioButton.isChecked(): - xyRes = [pSX, pSY, tLX, tLY, lRX, lRY] - # add extent raster to virtual raster list - i = cfg.utls.selectLayerbyName(extRaster, 'Yes') - try: - rPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - elif align == 'Yes': - xyRes = [pSX, pSY, tLX, tLY, lRX, lRY] - # add extent raster to virtual raster list - i = cfg.utls.selectLayerbyName(extRaster, 'Yes') - try: - rPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - self.rasterBandName(bandSetNumber) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - bPath, refCRS = cfg.bCalc.checkProjectionRaster(rPath, referenceCRS = refCRS, extentRaster = extentRaster, extentIntersection = extentIntersection, extentSameAs = extentSameAs) - bandNumberList.append(1) - bList.append(bPath) - if tLX is None: - if outFile is None: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - tPMD = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No', [float(tLX), float(tLY), float(lRX), float(lRY), 'Yes'], xyRes) - else: - tPMD = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - else: - tLX, tLY, lRX, lRY = extentList[0], extentList[1], extentList[2], extentList[3] - tPMD = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No', [float(tLX), float(tLY), float(lRX), float(lRY), 'Yes']) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(out)) - # process calculation - o = cfg.utls.multiProcessRaster(rasterPath = tPMD, functionBand = 'No', functionRaster = cfg.utls.bandCalculation, outputRasterList = [out], nodataValue = useNoDataValue, functionBandArgument = e, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculation ') + str(e), skipReplaceNoData = skipReplaceNoDT, virtualRaster = vrtR, compress = cfg.rasterCompression, compressFormat = 'LZW', outputNoDataValue = outputNoData, dataType = rasterDataType, scale = useScale, offset = useOffset, calcDataType = calcDataType, nodataMask = nodataMask) - if o != 'No': - if quiet == 'No': - r =cfg.utls.addRasterLayer(out) - try: - #cfg.utls.rasterSymbolSingleBandGray(r) - pass - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if eNBS is not None: - try: - if eNBS == '#': - eNBS = None - else: - eNBS = int(eNBS) - 1 - cfg.bst.addBandToBandSet(eN, eNBS) - except: - pass - it = it + 1 - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - else: - self.rasterBandName(bandSetNumber) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band calculation ended') - - # check projection and reproject - def checkProjectionRaster(self, inputRaster, referenceCRS = None, extentRaster = None, extentIntersection = None, extentSameAs = None): - bPath = None - if (extentIntersection is None and cfg.ui.intersection_checkBox.isChecked() is True) or extentIntersection == 'Yes': - pass - elif (extentSameAs is None and cfg.ui.extent_checkBox.isChecked() is True) or extentSameAs == 'Yes': - if extentRaster is None: - extRaster = cfg.ui.raster_extent_combo.currentText() - else: - extRaster = extentRaster - if extRaster == cfg.mapExtent: - pCrs = cfg.utls.getQGISCrs() - referenceCRS = pCrs.toWkt().replace(' ', '') - else: - i = cfg.utls.selectLayerbyName(extRaster, 'Yes') - bPath = cfg.utls.layerSource(i) - referenceCRS = cfg.utls.getCrsGDAL(bPath) - eCrs = cfg.utls.getCrsGDAL(inputRaster) - if referenceCRS is None: - return [inputRaster, eCrs] - else: - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(referenceCRS) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - tVRT = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(rasterPath = inputRaster, outputPath = tVRT, outputWkt = referenceCRS, alignRasterPath = bPath, sameExtent = 'No') - return [tVRT, referenceCRS] - else: - return [inputRaster, referenceCRS] - - # text changed - def textChanged(self): - if cfg.bandCalcIndex == 0: - expression = ' ' + cfg.ui.plainTextEdit_calc.toPlainText() + ' ' - self.checkExpression(expression) - if cfg.forbandsets in expression or cfg.forbsdates in expression or cfg.forbandsinbandset in expression or cfg.calcFunctionNm in expression: - self.expressionButton = True - cfg.ui.toolButton_calculate.setEnabled(True) - cfg.ui.plainTextEdit_calc.setStyleSheet('color : green') - elif cfg.bandCalcIndex == 1: - expression = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(expression) - tW = cfg.ui.decision_rules_tableWidget - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # check the expression and return it - def checkExpression(self, expression): - tW = cfg.ui.tableWidget_band_calc - v = tW.rowCount() - checkO = 'Yes' - cfg.ui.plainTextEdit_calc.setStyleSheet('color : red') - name = [] - nameList = [] - # list of raster names - for x in range(0, v): - name.append('"' + tW.item(x, 0).text() + '"') - name.append('"' + tW.item(x, 1).text() + '"') - nameList.append(['"' + tW.item(x, 0).text() + '"', '"' + tW.item(x, 1).text() + '"']) - ex = [] - outNameList = [] - if expression is None: - checkO = 'No' - else: - bsetList = [cfg.bndSetNumber + 1] - e = expression.rstrip().split('\n') - try: - # band set iteration - if cfg.forbandsets in e[0]: - fE0 = e[0] - bsetList = [] - filterBS = None - try: - fEf = e[0].split(']') - filterBSA = fEf[1].strip() - if len(filterBSA) == 0: - filterBS = None - else: - fE0 = fEf[0] - filterBS = filterBSA.split(',') - except: - filterBS = None - foB = fE0.replace(cfg.forbandsets, '') - try: - # range of band sets - rg = foB.split(':') - bsetListA = list(range(int(rg[0].replace('[', '')), int(rg[1].replace(']', '')) + 1)) - except: - # list of band sets - try: - bsetListA = eval(foB) - except: - checkO = 'No' - if filterBS is None: - bsetList = bsetListA - else: - for j in bsetListA: - try: - if cfg.bandSetsList[j-1][0] == 'Yes': - rB0 = cfg.bandSetsList[j-1][3][0] - else: - rB0 = cfg.bandSetsList[j-1][8] - for filterBSX in filterBS: - if filterBSX.lower() in rB0.lower(): - bsetList.append(j) - break - except: - pass - e.pop(0) - # bands in band set iteration - if cfg.forbandsinbandset in e[0]: - foB = e[0].replace(cfg.forbandsinbandset, '') - try: - # range of band sets - rg = foB.split(':') - bsetList = list(range(int(rg[0].replace('[', '')), int(rg[1].replace(']', '')) + 1)) - except: - # list of band sets - try: - bsetList = eval(foB) - except: - checkO = 'No' - e.pop(0) - # ban set date iteration - elif cfg.forbsdates in e[0]: - fE0 = e[0] - bsetList = [] - filterBS = None - try: - fEf = e[0].split(']') - filterBSA = fEf[1].strip() - if len(filterBSA) == 0: - filterBS = None - else: - fE0 = fEf[0] - filterBS = filterBSA.split(',') - except: - filterBS = None - foB = fE0.replace(cfg.forbsdates, '').replace('[', '').replace(']', '') - dtList = [] - dtRList = [] - if ':' in foB and ',' in foB: - # list of ranges of dates - try: - lrg = foB.split(',') - for lrgL in lrg: - try: - # range of dates - rg = lrgL.split(':') - dtRList.append([cfg.datetimeSCP.datetime.strptime(rg[0].strip(), '%Y-%m-%d'), cfg.datetimeSCP.datetime.strptime(rg[1].strip(), '%Y-%m-%d')]) - except: - pass - except: - checkO = 'No' - else: - try: - # range of dates - rg = foB.split(':') - dtRList.append([cfg.datetimeSCP.datetime.strptime(rg[0].strip(), '%Y-%m-%d'), cfg.datetimeSCP.datetime.strptime(rg[1].strip(), '%Y-%m-%d')]) - except: - # list of dates - try: - rg = foB.split(',') - for rgL in rg: - dtList.append(rgL.strip()) - except: - checkO = 'No' - # list of band set number - if checkO == 'Yes': - # list of dates - if len(dtList) > 0: - for j in range(0, len(cfg.bandSetsList)): - try: - if cfg.bandSetsList[j][9] in dtList: - if filterBS is None: - bsetList.append(j+1) - else: - if cfg.bandSetsList[j][0] == 'Yes': - rB0 = cfg.bandSetsList[j][3][0] - else: - rB0 = cfg.bandSetsList[j][8] - for filterBSX in filterBS: - if filterBSX.lower() in rB0.lower(): - bsetList.append(j+1) - break - except: - pass - else: - # range of dates - for j in range(0, len(cfg.bandSetsList)): - try: - bD = cfg.datetimeSCP.datetime.strptime(cfg.bandSetsList[j][9], '%Y-%m-%d') - # date range - for dStr in dtRList: - if (bD >= dStr[0]) & (bD <= dStr[1]) is True: - if filterBS is None: - bsetList.append(j+1) - break - else: - if cfg.bandSetsList[j][0] == 'Yes': - rB0 = cfg.bandSetsList[j][3][0] - else: - rB0 = cfg.bandSetsList[j][8] - for filterBSX in filterBS: - if filterBSX.lower() in rB0.lower(): - bsetList.append(j+1) - break - except: - pass - e.pop(0) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - checkO = 'No' - if checkO == 'Yes': - h = [] - # replace band set number for iteration - for b in bsetList: - #nmList = [] - for bs in range(0, len(e)): - bsN = None - f = str(e[bs].split('@')[0]) - dT = cfg.utls.getTime() - if len(f)>0: - # split output name - try: - nm = e[bs].split('@')[2].strip() - nPath = e[bs].split('@')[1] - # variable path band set - if cfg.variableOutputNameBandset in nPath: - if cfg.bandSetsList[b-1][0] == 'Yes': - r = cfg.utls.selectLayerbyName(cfg.bandSetsList[b-1][3][0], 'Yes') - else: - r = cfg.utls.selectLayerbyName(cfg.bandSetsList[b-1][8], 'Yes') - rS = cfg.utls.layerSource(r) - nPath = cfg.osSCP.path.dirname(rS) - # temporary directory - elif 'temp' == nPath.lower(): - nPath = cfg.tmpDir - except: - try: - nm = e[bs].split('@')[1].strip() - nPath = None - except: - nm = None - nPath = None - # variable name band set - try: - nm = nm.replace(cfg.variableOutputNameBandset, cfg.bandSetsList[b-1][3][0][:-2]) - except: - pass - try: - nm = nm.replace(cfg.variableOutputNameDate, dT) - except: - pass - try: - nm, bsN = nm.split('%') - nm = nm.strip() - except: - pass - # replace variables - findB = cfg.utls.findBandNumber(b-1) - try: - f = f.replace(cfg.variableOutputNameBandset, cfg.bandSetsList[b-1][3][0][:-2]) - except: - pass - if findB == 'Yes': - if cfg.bandSetsList[b-1][0] == 'Yes': - try: - f = f.replace(cfg.variableRedName, cfg.bandSetsList[b-1][3][int(cfg.REDBand) - 1]) - except: - pass - try: - f = f.replace(cfg.variableNIRName, cfg.bandSetsList[b-1][3][int(cfg.NIRBand) - 1]) - except: - pass - try: - f = f.replace(cfg.variableBlueName, cfg.bandSetsList[b-1][3][int(cfg.BLUEBand) - 1]) - except: - pass - try: - f = f.replace(cfg.variableGreenName, cfg.bandSetsList[b-1][3][int(cfg.GREENBand) - 1]) - except: - pass - try: - f = f.replace(cfg.variableSWIR1Name, cfg.bandSetsList[b-1][3][int(cfg.SWIR1Band) - 1]) - except: - pass - try: - f = f.replace(cfg.variableSWIR2Name, cfg.bandSetsList[b-1][3][int(cfg.SWIR2Band) - 1]) - except: - pass - else: - try: - f = f.replace(cfg.variableRedName, cfg.variableBandsetName + '#b' + str(cfg.REDBand)) - except: - pass - try: - f = f.replace(cfg.variableNIRName, cfg.variableBandsetName + '#b' + str(cfg.NIRBand)) - except: - pass - try: - f = f.replace(cfg.variableBlueName, cfg.variableBandsetName + '#b' + str(cfg.BLUEBand)) - except: - pass - try: - f = f.replace(cfg.variableGreenName, cfg.variableBandsetName + '#b' + str(cfg.GREENBand)) - except: - pass - try: - f = f.replace(cfg.variableSWIR1Name, cfg.variableBandsetName + '#b' + str(cfg.SWIR1Band)) - except: - pass - try: - f = f.replace(cfg.variableSWIR2Name, cfg.variableBandsetName + '#b' + str(cfg.SWIR2Band)) - except: - pass - # replace previous output names - #for r in nmList: - # f = f.replace(r[0], r[1]) - # replace original name - #try: - # if nm is not None: - # nmO = str(e[bs].split('@')[0]).strip() - # nmList.append([nmO, nm]) - #except: - # pass - if cfg.variableBandsetName + '#b' in f: - f = f.replace(cfg.variableBandsetName + '#', cfg.variableBandsetName + str(b)) - try: - # bands in band set iteration - if cfg.variableBand in f: - for bndX in range(0, len(cfg.bandSetsList[b-1][3])): - try: - fRev = f + ' @' + nPath + '@' + nm + '%' + bsN.replace('#', str(b)) - h.append(fRev.replace(cfg.variableBand, cfg.bandSetsList[b-1][3][bndX])) - except: - try: - fRev = f + ' @' + nPath + '@' + nm - h.append(fRev.replace(cfg.variableBand, cfg.bandSetsList[b-1][3][bndX])) - except: - try: - fRev = f + ' @' + nm + '%' + bsN.replace('#', str(b)) - h.append(fRev.replace(cfg.variableBand, cfg.bandSetsList[b-1][3][bndX])) - except: - try: - fRev = f + ' @' + nm - h.append(fRev.replace(cfg.variableBand, cfg.bandSetsList[b-1][3][bndX])) - except: - h.append(f.replace(cfg.variableBand, cfg.bandSetsList[b-1][3][bndX])) - else: - try: - h.append(f + ' @' + nPath + '@' + nm + '%' + bsN.replace('#', str(b))) - except: - try: - h.append(f + ' @' + nPath + '@' + nm) - except: - try: - h.append(f + ' @' + nm + '%' + bsN.replace('#', str(b))) - except: - try: - h.append(f + ' @' + nm) - except: - h.append(f) - except: - pass - e = h - for nf in e: - nm = None - nPath = None - bsN = None - nameList.extend(outNameList) - f = nf.split('@')[0] - try: - nm = nf.split('@')[2].strip() - nPath = nf.split('@')[1].strip() - except: - try: - nm = nf.split('@')[1].strip() - except: - pass - try: - nm = nm.replace(cfg.variableOutputNameBandset, cfg.utls.fileName(cfg.bndSetLst[0]).rpartition('.')[0][:-2]) - except: - pass - try: - dT = cfg.utls.getTime() - nm = nm.replace(cfg.variableOutputNameDate, dT) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), str(nameList)) - # replace NoData values - f = cfg.utls.replaceOperatorNames(f, nameList) - vrt = 'No' - if nm is not None: - try: - nm, bsN = nm.split('%') - nm = nm.strip() - except: - pass - if nm.lower().endswith('.vrt'): - vrt = 'Yes' - if nm.lower().endswith('.tif') or nm.lower().endswith('.vrt'): - nm = nm[:-4] - outNameList.append(['"' + str(nm) + '"', '"' + str(nm) + '"']) - oldF = f - check = 'Yes' - # create function - for i in name: - f = f.replace(i, ' rasterSCPArrayfunctionBand ') - for i in outNameList: - f = f.replace(i[0], ' rasterSCPArrayfunctionBand ') - if cfg.calcFunctionNm in f: - #ex.append([f, nm]) - pass - elif f == oldF: - check = 'No' - checkO = 'No' - else: - # replace numpy operators - f = cfg.utls.replaceNumpyOperators(f) - rasterSCPArrayfunctionBand = cfg.np.arange(9).reshape(3, 3) - try: - o = eval(f) - cfg.ui.plainTextEdit_calc.setStyleSheet('color : green') - if cfg.bandCalcIndex == 0: - self.expressionButton = True - elif cfg.bandCalcIndex == 1: - self.decisionRulesButton = True - cfg.ui.toolButton_calculate.setEnabled(True) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err) + " " + str(f)) - check = 'No' - checkO = 'No' - if check == 'Yes': - if bsN is not None: - n2 = nm + '%' + bsN - else: - n2 = nm - ex.append([oldF, n2, nPath, vrt]) - if checkO == 'No': - cfg.ui.plainTextEdit_calc.setStyleSheet('color : red') - if cfg.bandCalcIndex == 0: - self.expressionButton = False - elif cfg.bandCalcIndex == 1: - self.decisionRulesButton = False - cfg.ui.toolButton_calculate.setEnabled(False) - self.outputNameTable(outNameList) - return ex - - # extent checkbox - def extentCheckbox(self): - if cfg.ui.extent_checkBox.isChecked() is True: - if cfg.ui.intersection_checkBox.isChecked() is True: - cfg.ui.intersection_checkBox.blockSignals(True) - cfg.ui.intersection_checkBox.setCheckState(0) - cfg.ui.intersection_checkBox.blockSignals(False) - - # intersection checkbox - def intersectionCheckbox(self): - if cfg.ui.intersection_checkBox.isChecked() is True: - if cfg.ui.extent_checkBox.isChecked() is True: - cfg.ui.extent_checkBox.blockSignals(True) - cfg.ui.extent_checkBox.setCheckState(0) - cfg.ui.extent_checkBox.blockSignals(False) - - # double click - def doubleClick(self, index): - l = cfg.ui.tableWidget_band_calc - k = l.item(index.row(), index.column()).text() - if cfg.bandCalcIndex == 0: - cursor = cfg.ui.plainTextEdit_calc.textCursor() - cursor.insertText('"' + k + '"') - cfg.ui.plainTextEdit_calc.setFocus() - elif cfg.bandCalcIndex == 1: - tW = cfg.ui.decision_rules_tableWidget - # list of items - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) > 0: - tW.blockSignals(True) - for i in v: - try: - tr = tW.item(i, 1).text() - cfg.utls.setTableItem(tW, i, 1, str(tr + ' "' + k + '" ')) - except: - tW.blockSignals(False) - return 'No' - tW.blockSignals(False) - e = cfg.bCalc.decisionRulesExpression() - check = self.checkExpression(e) - if len(check) > 0: - tW.setStyleSheet('color : green') - else: - tW.setStyleSheet('color : red') - - # move up selected rules - def moveUpRule(self): - tW = cfg.ui.decision_rules_tableWidget - c = tW.rowCount() - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() - 1) - try: - for b in range(0, c): - if tW.item(b, 0).isSelected() or tW.item(b, 1).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b - 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b - 1, 0).setText(str(bNU)) - brNU = tW.item(b, 1).text() - brND = tW.item(b - 1, 1).text() - tW.item(b, 1).setText(str(brND)) - tW.item(b - 1, 1).setText(str(brNU)) - tW.clearSelection() - v = list(set(ns)) - cfg.utls.selectRowsInTable(tW, v) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - - # move down selected rules - def moveDownRule(self): - tW = cfg.ui.decision_rules_tableWidget - c = tW.rowCount() - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() + 1) - try: - for b in reversed(list(range(0, c))): - if tW.item(b, 0).isSelected() or tW.item(b, 1).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b + 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b + 1, 0).setText(str(bNU)) - brNU = tW.item(b, 1).text() - brND = tW.item(b + 1, 1).text() - tW.item(b, 1).setText(str(brND)) - tW.item(b + 1, 1).setText(str(brNU)) - tW.clearSelection() - v = list(set(ns)) - cfg.utls.selectRowsInTable(tW, v) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - - # perform bands filter - def filterTable(self): - l = cfg.ui.tableWidget_band_calc - text = cfg.ui.bandcalc_filter_lineEdit.text() - items = l.findItems(text, cfg.QtSCP.MatchContains) - c = l.rowCount() - list = [] - for item in items: - if item.column() == 1: - list.append(item.row()) - l.blockSignals(True) - for i in range (0, c): - l.setRowHidden(i, False) - if i not in list: - l.setRowHidden(i, True) - l.blockSignals(False) - - # buttons - def insertButton(self, text): - cursor = cfg.ui.plainTextEdit_calc.textCursor() - cursor.insertText(text) - - def buttonPlus(self): - cfg.bCalc.insertButton(' + ') - - def buttonMinus(self): - cfg.bCalc.insertButton(' - ') - - def buttonProduct(self): - cfg.bCalc.insertButton(' * ') - - def buttonRatio(self): - cfg.bCalc.insertButton(' / ') - - def buttonPower(self): - cfg.bCalc.insertButton('^') - - def buttonSQRT(self): - cfg.bCalc.insertButton('sqrt(') - - def buttonLbracket(self): - cfg.bCalc.insertButton('(') - - def buttonRbracket(self): - cfg.bCalc.insertButton(')') - - def buttonGreater(self): - cfg.bCalc.insertButton(' > ') - - def buttonLower(self): - cfg.bCalc.insertButton(' < ') - - def buttonUnequal(self): - cfg.bCalc.insertButton(' != ') - - def buttonEqual(self): - cfg.bCalc.insertButton(' == ') - \ No newline at end of file diff --git a/maininterface/bandcombination.py b/maininterface/bandcombination.py deleted file mode 100644 index 8cec43e..0000000 --- a/maininterface/bandcombination.py +++ /dev/null @@ -1,370 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class BandCombination: - - def __init__(self): - self.clssfctnNm = None - - # calculate band set combination if click on button - def calculateBandSetCombination(self): - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' calculate band combination ') - self.bandSetCombination() - - # cross classification calculation - def bandSetCombination(self, batch = 'No', bandSetNumber = None, rasterOutput = None): - if batch == 'No': - combRstPath = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save band combination raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - combRstPath = rasterOutput - # virtual raster - vrtR = 'No' - if combRstPath is not False: - if combRstPath.lower().endswith('.vrt'): - vrtR = 'Yes' - elif combRstPath.lower().endswith('.tif'): - pass - else: - combRstPath = combRstPath + '.tif' - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox.value() - bandSetNumber = bandSet - 1 - if batch == 'No': - cfg.uiUtls.addProgressBar() - # create list of rasters - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar29() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if ckB != 'Yes': - pass - if len(cfg.bndSetLst) <= 1: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - # name of combination field in output table - combName = '' - for rbName in cfg.bandSetsList[bandSetNumber][3]: - combName = combName + rbName[0:16] + ',' - combName = combName.rstrip(',') - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(combRstPath)) - NoDataVal = cfg.NoDataVal - rCrs = cfg.utls.getCrsGDAL(cfg.bndSetLst[0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(20) - bListNum = [] - nData = [] - for b in range(0, len(cfg.bndSetLst)): - nD = cfg.utls.imageNoDataValue(cfg.bndSetLst[b]) - nData.append(nD) - bListNum.append(1) - eCrs = cfg.utls.getCrsGDAL(cfg.bndSetLst[b]) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(cfg.bndSetLst[b], tPMD, str(rCrs)) - cfg.mx.msg9() - if cfg.osSCP.path.isfile(tPMD): - cfg.bndSetLst[b] = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(40) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' nData: ' + str(nData)) - # No data value - nD = NoDataVal - vrtCheck = cfg.utls.createTempVirtualRaster(cfg.bndSetLst, bListNum, 'Yes', 'Yes', 0, 'No', 'Yes') - calcDataType = cfg.np.int32 - calcNodata = cfg.NoDataValInt32 - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValues, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values '), calcDataType = calcDataType) - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - values = cfg.np.vstack((values, ar[0])) - except: - values = ar[0] - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - # adapted from Jaime answer at https://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array - try: - bVV = values.view(cfg.np.dtype((cfg.np.void, values.dtype.itemsize * values.shape[1]))) - ff, indexA = cfg.np.unique(bVV, return_index=True, return_counts=False) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - return 'No' - cmb = [] - for cmV in values[indexA].tolist(): - ''' - useV = 'Yes' - for rnData in range(0, len(cmV)): - if cfg.np.array(nData[rnData]) == cfg.np.array(cmV[rnData]): - useV = 'No' - break - if useV == 'Yes': - cmb.append(cmV) - ''' - cmb.append(cmV) - cmbArr = cfg.np.array(cmb) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' len(cmb): ' + str(len(cmb))) - maxV = cfg.np.nanmax(cmbArr, axis=0) - if cfg.np.sum(cmbArr<=0) < 1: - calcDataType = cfg.np.uint32 - calcNodata = cfg.NoDataValUInt32 - addC = 1 - else: - addC = 0 - cfg.np.nanmin(cmbArr) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' addC: ' + str(addC)) - # expression builder - check = 'No' - maxDig = 10-len(str(cfg.np.sum(maxV))) - if maxDig < 0: - maxDig = 2 - t = 0 - while t < 5000: - t = t + 1 - rndVarList = [] - sumA = cfg.np.zeros(cmbArr.shape, dtype=calcDataType) - for cmbI in range(0, len(cmb[0])): - if t < 1000: - expR = int(cfg.np.random.random()*10)+1 - if expR > maxDig: - expR = maxDig - constV = int(10**(expR)) - elif t < 2000: - constV = int(10**(maxDig-cmbI)) - elif t < 3000: - constV = int(10**(maxDig-(len(cmb[0])-cmbI))) - elif t < 4000: - constV = int(10**(maxDig)) - else: - expR = int(cfg.np.random.random()*10)+1 - if expR > 8: - expR = 8 - constV = int(10**(expR)) - if constV < 1: - constV = 3 - rndVar = int(constV * cfg.np.random.random()) - if rndVar == 0: - rndVar = 1 - # avoid too large numbers - while cfg.np.sum(rndVar * (cfg.np.array(maxV, dtype=cfg.np.float32) + addC)) > calcNodata: - rndVar = int(rndVar/2) - rndVarList.append(rndVar) - sumA[:, cmbI] = (cmbArr[:, cmbI] + addC) * rndVar - sumT = cfg.np.sum(sumA, axis=1) - uniqueS = cfg.np.unique(sumT, return_index=False, return_counts=False) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rndVarList: ' + str(rndVarList) + ' uniqueS.shape[0] ' + str(uniqueS.shape[0])) - if uniqueS.shape[0] == len(cmb) and cfg.np.sum(uniqueS<0) < 1: - check = 'Yes' - break - if check == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr63() - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR combinations') - return 'No' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rndVarList: ' + str(rndVarList)) - reclassDict = {} - for i in cmb: - newVl = 0 - for rE in range(0, len(rndVarList)): - for rnData in range(0, len(i)): - if cfg.np.array(nData[rnData]) == cfg.np.array(i[rnData]): - newVl = 0 - break - else: - newVl = newVl + (i[rE] + addC) * (rndVarList[rE]) - if newVl > 0: - reclassDict[newVl] = i - n = 1 - reclassList = [] - cmbntns = {} - for newVl in sorted(reclassDict.keys()): - reclassList.append(newVl) - cmbntns[n] = reclassDict[newVl] - n = n + 1 - e = '' - for rE in range(0, len(rndVarList)): - e = e + '(rasterSCPArrayfunctionBand[::, ::, ' + str(rE) + '] + ' + str(addC) + ') * ' + str(rndVarList[rE]) + ' + ' - e = e.rstrip(' + ') - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' e: ' + str(e)) - # check projections - left, right, top, bottom, cRPX, cRPY, rP, un = cfg.utls.imageGeoTransform(vrtCheck) - # calculation - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.crossRasters, outputRasterList = [combRstPath], functionBandArgument = reclassList, functionVariable = e, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band combination '), nodataValue = cfg.NoDataValInt32, outputNoDataValue = cfg.NoDataValInt32, virtualRaster = vrtR, compress = cfg.rasterCompression, dataType = 'UInt32', calcDataType = calcDataType) - # calculate unique values - values = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[1][0, ::]) - sumVal = cfg.np.append(sumVal, ar[1][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - values = values.astype(int) - rasterBandUniqueVal = {} - for v in range(0, len(values)): - try: - cmbX = cmbntns[values[v]] - try: - rasterBandUniqueVal[tuple(cmbX)] = rasterBandUniqueVal[tuple(cmbX)] + sumVal[v] - except: - rasterBandUniqueVal[tuple(cmbX)] = sumVal[v] - except: - pass - refRasterBandUniqueVal = list(set(values)) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cross raster output: ' + str(combRstPath)) - cfg.uiUtls.updateBar(80) - # table output - tblOut = cfg.osSCP.path.dirname(combRstPath) + '/' + cfg.utls.fileNameNoExt(combRstPath) + '.csv' - try: - l = open(tblOut, 'w') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'RasterValue') + '\t' + combName + '\t' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + '\t' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area [' + un + '^2]') + str('\n') - l.write(t) - for c in refRasterBandUniqueVal: - try: - v = tuple(cmbntns[c]) - if rasterBandUniqueVal[v] > 0: - area = str(round(rasterBandUniqueVal[v] * cRPX * cRPY, 5)) - cList = str(c) + '\t' + ','.join([str(l) for l in cmbntns[c]]) + '\t' + cfg.reSCP.sub(r'\.0$', '', str(rasterBandUniqueVal[v])) + '\t' + area + str('\n') - l.write(cList) - except Exception as err: - pass - l.close() - # add raster to layers - rastUniqueVal = cfg.np.unique(values).tolist() - rstr =cfg.utls.addRasterLayer(combRstPath) - cfg.utls.rasterSymbolGeneric(rstr, 'NoData', rasterUniqueValueList = rastUniqueVal) - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.band_set_comb_textBrowser.setText(eM) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' cross matrix calculated') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(100) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.ui.toolBox_band_set_combination.setCurrentIndex(1) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'finished') - \ No newline at end of file diff --git a/maininterface/bandsetTab.py b/maininterface/bandsetTab.py deleted file mode 100644 index be2a061..0000000 --- a/maininterface/bandsetTab.py +++ /dev/null @@ -1,1438 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class BandsetTab: - - def __init__(self): - pass - - # add satellite list to combo - def addSatelliteToCombo(self, satelliteList): - for i in satelliteList: - cfg.ui.wavelength_sat_combo.addItem(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " satellites added") - - # add unit list to combo - def addUnitToCombo(self, unitList): - for i in unitList: - cfg.ui.unit_combo.addItem(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " units added") - - # set Band unit - def setBandUnit(self): - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - for i in range(0, c): - cfg.utls.setTableItem(tW, i, 4, cfg.ui.unit_combo.currentText()) - tW.blockSignals(False) - cfg.BandTabEdited = 'Yes' - self.readBandSet('Yes') - - # set date - def setBandsetDate(self): - if cfg.BandTabEdited != 'No': - Qdate = cfg.ui.bandset_dateEdit.date() - date = Qdate.toPyDate().strftime('%Y-%m-%d') - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - for i in range(0, c): - cfg.utls.setTableItem(tW, i, 6, date) - tW.blockSignals(False) - cfg.BandTabEdited = 'Yes' - self.readBandSet('Yes') - - def satelliteWavelength(self): - self.setSatelliteWavelength() - - # set satellite wavelengths - def setSatelliteWavelength(self, satelliteName = None, bandList = None, bandSetNumber = None): - if satelliteName is None: - satelliteName = cfg.ui.wavelength_sat_combo.currentText() - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - wl = [] - tW.blockSignals(True) - id = cfg.ui.unit_combo.findText(cfg.noUnit) - if satelliteName == cfg.NoSatellite: - for x in range(0, c): - wl.append(x + 1) - id = cfg.ui.unit_combo.findText(cfg.noUnit) - # ASTER center wavelength calculated from USGS, 2015. Advanced Spaceborne Thermal Emission and Reflection Radiometer (ASTER) Level 1 Precision Terrain Corrected Registered At-Sensor Radiance Product (AST_L1T) - elif satelliteName == cfg.satASTER: - wl = [0.560, 0.660, 0.810, 1.650, 2.165, 2.205, 2.260, 2.330, 2.395, 8.300, 8.650, 9.100, 10.600, 11.300] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '3N', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14'] - # Landsat center wavelength calculated from http://landsat.usgs.gov/band_designations_landsat_satellites.php - elif satelliteName == cfg.satLandsat8: - wl = [0.44, 0.48, 0.56, 0.655, 0.865, 1.61, 2.2] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04', '05', '06', '07'] - elif satelliteName == cfg.satLandsat7: - wl = [0.485, 0.56, 0.66, 0.835, 1.65, 2.22] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04', '05', '07'] - elif satelliteName == cfg.satLandsat45: - wl = [0.485, 0.56, 0.66, 0.83, 1.65, 2.215] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04', '05', '07'] - elif satelliteName == cfg.satLandsat13: - wl = [0.55, 0.65, 0.75, 0.95] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['04', '05', '06', '07'] - # MODIS center wavelength calculated from https://lpdaac.usgs.gov/dataset_discovery/modis - elif satelliteName == cfg.satMODIS: - wl = [0.469, 0.555, 0.645, 0.858, 1.24, 1.64, 2.13] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['03', '04', '01', '02', '05', '06', '07'] - elif satelliteName == cfg.satMODIS2: - wl = [0.645, 0.858] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02'] - # RapidEye center wavelength calculated from http://www.blackbridge.com/rapideye/products/ortho.htm - elif satelliteName == cfg.satRapidEye: - wl = [0.475, 0.555, 0.6575, 0.71, 0.805] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04', '05'] - # SPOT center wavelength calculated from http://www.astrium-geo.com/en/194-resolution-and-spectral-bands - elif satelliteName == cfg.satSPOT4 or satelliteName == cfg.satSPOT5: - wl = [0.545, 0.645, 0.835, 1.665] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04'] - elif satelliteName == cfg.satSPOT6: - wl = [0.485, 0.56, 0.66, 0.825] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04'] - # Pléiades center wavelength calculated from http://www.astrium-geo.com/en/3027-pleiades-50-cm-resolution-products - elif satelliteName == cfg.satPleiades: - wl = [0.49, 0.56, 0.65, 0.84] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04'] - # QuickBird center wavelength calculated from http://www.digitalglobe.com/resources/satellite-information - elif satelliteName == cfg.satQuickBird: - wl = [0.4875, 0.543, 0.65, 0.8165] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04'] - # WorldView-2 center wavelength calculated from http://www.digitalglobe.com/resources/satellite-information - elif satelliteName == cfg.satWorldView23: - wl = [0.425, 0.48, 0.545, 0.605, 0.66, 0.725, 0.8325, 0.95] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04', '05', '06', '07', '08'] - # GeoEye-1 center wavelength calculated from http://www.digitalglobe.com/resources/satellite-information - elif satelliteName == cfg.satGeoEye1: - wl = [0.48, 0.545, 0.6725, 0.85] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - bl = ['01', '02', '03', '04'] - # Sentinel-1 - elif satelliteName == cfg.satSentinel1: - wl = [1, 2] - bl = ['1','2'] - id = cfg.ui.unit_combo.findText(cfg.noUnit) - # Sentinel-2 center wavelength from https://sentinel.esa.int/documents/247904/685211/Sentinel-2A+MSI+Spectral+Responses - elif satelliteName == cfg.satSentinel2: - wl = [0.443, 0.490, 0.560, 0.665, 0.705, 0.740, 0.783, 0.842, 0.865, 0.945, 1.375, 1.610, 2.190] - bl = ['01','02','03','04','05','06','07','08','8a','09','10','11','12'] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - # Sentinel-3 center wavelength from Sentinel-3 xfdumanifest.xml - elif satelliteName == cfg.satSentinel3: - wl = [0.400, 0.4125, 0.4425, 0.490, 0.510, 0.560, 0.620, 0.665, 0.67375, 0.68125, 0.70875, 0.75375, 0.76125, 0.764375, 0.7675, 0.77875, 0.865, 0.885, 0.900, 0.940, 1.020] - bl = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21'] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - # GOES center wavelength from GOES-R, 2017. PRODUCT DEFINITION AND USER’S GUIDE (PUG) VOLUME 3: LEVEL 1B PRODUCTS - elif satelliteName == cfg.satGOES: - wl = [0.47, 0.64, 0.87, 1.38, 1.61, 2.25] - bl = ['01', '02', '03', '04', '05', '06'] - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - cfg.BandTabEdited = 'No' - if bandList is None: - vals = [] - q = 1 - for i in range(0, c): - try: - b = bl.index(tW.item(i, 0).text().lower().split(".")[0][-2:]) - val = float(wl[b]) - if val not in vals: - tW.item(i, 1).setText(str(val)) - vals.append(val) - else: - tW.item(i, 1).setText(str(q)) - except: - try: - b = bl.index(tW.item(i, 0).text().lower().split(".")[0][-2:].lstrip('0')) - val = float(wl[b]) - if val not in vals: - tW.item(i, 1).setText(str(val)) - vals.append(val) - else: - tW.item(i, 1).setText(str(q)) - except: - try: - val = float(wl[i]) - if val not in vals: - tW.item(i, 1).setText(str(val)) - vals.append(val) - else: - tW.item(i, 1).setText(str(q)) - except: - pass - q = q + 1 - else: - try: - b = 0 - for n in bandList: - i = wl[int(n) - 1] - tW.item(b, 1).setText(str(float(i))) - b = b + 1 - except: - pass - tW.blockSignals(False) - cfg.BandTabEdited = 'Yes' - cfg.bst.orderByWavelength(bandSetNumber) - noUnitId = cfg.ui.unit_combo.findText(cfg.noUnit) - cfg.ui.unit_combo.setCurrentIndex(noUnitId) - cfg.ui.unit_combo.setCurrentIndex(id) - self.readBandSet('Yes') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " satellite" + str(satelliteName)) - - # add file to band set action - def addFileToBandSetAction(self): - self.addFileToBandSet() - - # add file to band set - def addFileToBandSet(self, batch = 'No', fileListString = None, wavelengthString = None, multiplicativeFactorString = None, additiveFactorString = None, date = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - satellite = None - if batch == 'No': - files = cfg.utls.getOpenFileNames(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a raster'), '', 'Raster (*.*)') - else: - cfg.utls.clearTable(tW) - fileList = fileListString.split(',') - files = [] - # directory - if len(fileList) <= 2 and cfg.QDirSCP(fileList[0].strip("'")).exists(): - dirF = fileList[0].strip("'").rstrip('/') - try: - filter = fileList[1].strip("'").strip() - except: - filter = '' - for r, d, f in cfg.osSCP.walk(dirF): - for x in f: - if filter in x: - files.append(cfg.osSCP.path.join(r, x)) - files = sorted(files) - if date is not None: - if date.lower() == 'auto': - # date from directory name - try: - dStr = cfg.datetimeSCP.datetime.strptime(dirF[-10:], '%Y-%m-%d') - date = dirF[-10:] - except: - try: - dirPart = dirF.split('_') - for dP in dirPart: - dPP = dP.lower().split('t')[0] - try: - dStr = cfg.datetimeSCP.datetime.strptime(dPP, '%Y%m%d') - dPPS = dStr.strftime('%Y-%m-%d') - date = dPPS - break - except: - pass - except: - pass - else: - for f in fileList: - files.append(f.strip()) - try: - wavelength = wavelengthString.split(',') - if len(wavelength) == 1: - for sat in cfg.satWlList: - if wavelength[0].strip("'").lower() in sat.lower(): - satellite = sat - wavelength = None - break - except: - wavelength = None - try: - multiplicativeFactor = multiplicativeFactorString.split(',') - except: - multiplicativeFactor = None - try: - additiveFactor = additiveFactorString.split(',') - except: - additiveFactor = None - if date is None: - date = '' - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - # count table rows - c = tW.rowCount() - if len(files) == 1: - try: - iBC = cfg.utls.getNumberBandRaster(files[0]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr25() - return 'No' - if iBC > 1: - r =cfg.utls.addRasterLayer(files[0]) - cfg.utls.clearTable(tW) - self.rasterToBandName(r.name(), date = date, bandSetNumber = bandSetNumber) - return 'Yes' - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - cfg.utls.clearTable(tW) - for i in files: - check = 'Yes' - try: - iBC = cfg.utls.getNumberBandRaster(i) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err) + 'file' + str(i)) - cfg.mx.msgErr25() - iBC = None - check = 'No' - if iBC == 1 and check == 'Yes': - r =cfg.utls.addRasterLayer(i) - itN = r.name() - # count table rows - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0) - if wavelengthString is not None: - try: - v = float(wavelength[c]) - except: - v = c + 1 - else: - v = c + 1 - cfg.utls.addTableItem(tW, str(float(v)), c, 1) - if multiplicativeFactorString is not None: - try: - v = float(multiplicativeFactor[c]) - except: - v = '1' - else: - v = '1' - cfg.utls.addTableItem(tW, v, c, 2) - if additiveFactorString is not None: - try: - v = float(additiveFactor[c]) - except: - v = '0' - else: - v = '0' - cfg.utls.addTableItem(tW, v, c, 3) - cfg.utls.addTableItem(tW, cfg.ui.unit_combo.currentText(), c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, date, c, 6) - tW.blockSignals(False) - cfg.bst.rasterBandName() - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - if satellite is not None: - cfg.bst.setSatelliteWavelength(satellite) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band set changed n. of bands' + str(c+1)) - - # add band to band set - def addBandToSet(self): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - pass - else: - l = cfg.ui.bands_tableWidget - c = l.rowCount() - s = l.selectedItems() - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row()) - lc = list(set(ns)) - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - if len(list(cfg.bandSetsList[bandSetNumber][4])) > 0: - v = max(cfg.bandSetsList[bandSetNumber][4]) - else: - v = 0 - for b in lc: - # count table rows - c = tW.rowCount() - v = v + 1 - # name of item of list - itN = l.item(b, 0).text() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0) - cfg.utls.addTableItem(tW, str(float(v)), c, 1) - cfg.utls.addTableItem(tW, '1', c, 2) - cfg.utls.addTableItem(tW, '0', c, 3) - cfg.utls.addTableItem(tW, cfg.ui.unit_combo.currentText(), c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, '', c, 6) - tW.blockSignals(False) - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band set changed n. of bands" + str(lc)) - - # add band to band set - def addBandToBandSet(self, bandName, bandSetNumber = None, wavelength = None): - if len(cfg.bndSetLst) > 0: - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - # count table rows - c = tW.rowCount() - # name of item of list - itN = bandName - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0) - if wavelength is None: - cfg.utls.addTableItem(tW, str(c+1), c, 1) - else: - cfg.utls.addTableItem(tW, str(wavelength), c, 1) - cfg.utls.addTableItem(tW, '1', c, 2) - cfg.utls.addTableItem(tW, '0', c, 3) - unit = str(cfg.bst.unitNameConversion(cfg.bandSetsList[bandSetNumber][5], 'Yes')) - cfg.utls.addTableItem(tW, unit, c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, '', c, 6) - tW.blockSignals(False) - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band added to band set " + str(bandName)) - - # set all bands to state 0 or 2 - def allBandSetState(self, value): - tW = cfg.ui.bands_tableWidget - c = tW.rowCount() - if value == 0: - tW.clearSelection() - else: - v = list(range(0, c)) - cfg.utls.selectRowsInTable(tW, v) - - # set raster name as band set - def rasterLayerName(self): - if cfg.rasterComboEdited == 'Yes': - imgNm = cfg.ui.image_raster_name_combo.currentText() - # set input - rLay = cfg.utls.selectLayerbyName(imgNm) - if rLay is not None: - cfg.bst.clearBandSet('No', 'No') - cfg.bst.rasterToBandName(imgNm) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "input raster: " + str(imgNm)) - - # clear the band set - def clearBandSetAction(self): - self.clearBandSet() - - # clear the band set - def clearBandSet(self, question = 'Yes', refresh = 'Yes', bandSetNumber = None): - if question == 'Yes': - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Clear band set'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to clear the band set?')) - else: - a = 'Yes' - if a == 'Yes': - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - cfg.BandTabEdited = 'No' - cfg.utls.clearTable(tW) - cfg.BandTabEdited = 'Yes' - # band set list - try: - cfg.bandSetsList[bandSetNumber] = [] - except: - pass - if refresh == 'Yes': - # read band set - self.readBandSet('Yes', refresh) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band set cleared") - - # order by wavelength - def orderByWavelength(self, bandSetNumber): - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - nm = [] - wvl = [] - add = [] - mul = [] - c = tW.rowCount() - for b in range(0, c): - nm.append(tW.item(b, 0).text()) - wvl.append(float(tW.item(b, 1).text())) - mul.append(tW.item(b, 2).text()) - add.append(tW.item(b, 3).text()) - if wvl is not None: - # sort items - b = 0 - for i in sorted(wvl): - x = wvl.index(i) - cfg.utls.addTableItem(tW, nm[x], b, 0, 'No') - cfg.utls.addTableItem(tW, str(float(i)), b, 1) - cfg.utls.addTableItem(tW, str(mul[x]), b, 2) - cfg.utls.addTableItem(tW, str(add[x]), b, 3) - b = b + 1 - tW.show() - self.readBandSet('Yes') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ordered bands") - tW.blockSignals(False) - cfg.BandTabEdited = 'Yes' - - # band set edited - def editedBandSet(self, row, column): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - if cfg.BandTabEdited == 'Yes' and column == 1: - # check if bandset is empty - c = tW.rowCount() - cfg.BandTabEdited = 'No' - try: - w = str(float(tW.item(row, column).text())) - except: - w = str(float(cfg.bandSetsList[bandSetNumber][4][row])) - cfg.utls.setTableItem(tW, row, column, w) - tW.show() - if c == 0: - self.readBandSet('Yes') - elif float(tW.item(row, column).text()) in cfg.bandSetsList[bandSetNumber][4]: - cfg.mx.msgWar7() - w = str(float(cfg.bandSetsList[bandSetNumber][4][row])) - cfg.utls.setTableItem(tW, row, column, w) - tW.show() - else: - cfg.bst.orderByWavelength(bandSetNumber) - cfg.BandTabEdited = 'Yes' - elif cfg.BandTabEdited == 'Yes' and column == 2: - # check if bandset is empty - c = tW.rowCount() - if c == 0: - self.readBandSet('No') - else: - cfg.BandTabEdited = 'No' - try: - test = float(tW.item(row, column).text()) - cfg.utls.addTableItem(tW, str(tW.item(row, column).text()), row, column) - except: - cfg.utls.addTableItem(tW, str(cfg.bandSetsList[bandSetNumber][6][0][row]), row, column) - tW.show() - self.readBandSet('No') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band edited; bands n. " + str(c)) - elif cfg.BandTabEdited == 'Yes' and column == 3: - # check if bandset is empty - c = tW.rowCount() - if c == 0: - self.readBandSet('No') - else: - cfg.BandTabEdited = 'No' - try: - test = float(tW.item(row, column).text()) - cfg.utls.addTableItem(tW, str(tW.item(row, column).text()), row, column) - except: - cfg.utls.addTableItem(tW, str(cfg.bandSetsList[bandSetNumber][6][1][row]), row, column) - tW.show() - self.readBandSet('No') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band edited; bands n. " + str(c)) - elif cfg.BandTabEdited == 'Yes' and column == 4: - cfg.BandTabEdited = 'No' - cfg.utls.addTableItem(tW, str(cfg.bst.unitNameConversion(cfg.bandSetsList[bandSetNumber][5], 'Yes')), row, column) - cfg.BandTabEdited = 'Yes' - elif cfg.BandTabEdited == 'Yes' and column == 5: - cfg.BandTabEdited = 'No' - cfg.utls.addTableItem(tW, str(cfg.bandSetsList[bandSetNumber][8]), row, column) - cfg.BandTabEdited = 'Yes' - elif cfg.BandTabEdited == 'Yes' and column == 0: - cfg.BandTabEdited = 'No' - cfg.utls.addTableItem(tW, str(cfg.bandSetsList[bandSetNumber][3][row]), row, column) - cfg.BandTabEdited = 'Yes' - - # tab band set changed - def tabBandSetChanged(self, index): - if cfg.BandTabEdited == 'Yes': - cfg.bndSetNumber = index - self.tabChanged() - - # tab changed - def tabChanged(self): - t = cfg.ui.Band_set_tabWidget.count() - cfg.bndSetTabList = [] - for i in range(0, t): - cfg.bndSetTabList.append(str(cfg.ui.Band_set_tabWidget.widget(i).objectName()).split("__")[1]) - cfg.ui.Band_set_tabWidget.setTabText(i, cfg.bandSetName + str(i + 1)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " changed tab band set") - cfg.bst.readBandSet('Yes') - - # select band set tab - def selectBandSetTab(self, index): - t = len(cfg.bndSetTabList) - if index >= t: - cfg.mx.msgErr62(str(index + 1)) - else: - cfg.ui.Band_set_tabWidget.setCurrentIndex(index) - - # select band set tab - def removeBandSetTab(self, index, unloadBands = None): - t = len(cfg.bndSetTabList) - if t > 1: - if unloadBands == 'Yes': - if cfg.bandSetsList[index][0] == 'Yes': - for fN in cfg.bandSetsList[index][3]: - try: - cfg.utls.removeLayer(fN) - except: - pass - else: - try: - cfg.utls.removeLayer(cfg.bandSetsList[index][8]) - except: - pass - cfg.bst.deleteBandSetTab(index) - else: - cfg.mx.msg24() - if unloadBands == 'Yes': - if cfg.bandSetsList[index][0] == 'Yes': - for fN in cfg.bandSetsList[index][3]: - try: - cfg.utls.removeLayer(fN) - except: - pass - else: - try: - cfg.utls.removeLayer(cfg.bandSetsList[index][8]) - except: - pass - cfg.bst.clearBandSet(question = 'No', refresh = 'Yes', bandSetNumber = index) - cfg.bst.readBandSet('Yes') - - # add band set tab - def addBandSetTabAction(self): - b = cfg.bst.addBandSetTab() - return b - - # add band set tab - def addBandSetTab(self, refresh = 'Yes', position = None): - cfg.algWT.addBandSetWeigthTab() - dT = cfg.utls.getTime() - w = 'cfg.ui.tableWidget__' + str(dT) - cfg.bndSetTabList.append(dT) - band_set_tab = cfg.QtWidgetsSCP.QWidget() - band_set_tab.setObjectName(w) - gridLayout = cfg.QtWidgetsSCP.QGridLayout(band_set_tab) - gridLayout.setObjectName('gridLayout' + str(dT)) - exec(w + ' = cfg.QtWidgetsSCP.QTableWidget(band_set_tab)') - tW = eval(w) - tW.setFrameShape(cfg.QtWidgetsSCP.QFrame.WinPanel) - tW.setFrameShadow(cfg.QtWidgetsSCP.QFrame.Sunken) - tW.setAlternatingRowColors(True) - tW.setSelectionMode(cfg.QtWidgetsSCP.QAbstractItemView.MultiSelection) - tW.setSelectionBehavior(cfg.QtWidgetsSCP.QAbstractItemView.SelectRows) - tW.setColumnCount(7) - tW.setObjectName(w) - tW.setRowCount(0) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(0, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(1, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(2, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(3, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(4, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(5, item) - item = cfg.QtWidgetsSCP.QTableWidgetItem() - tW.setHorizontalHeaderItem(6, item) - item = tW.horizontalHeaderItem(0) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band name')) - item = tW.horizontalHeaderItem(1) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Center wavelength')) - item = tW.horizontalHeaderItem(2) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Multiplicative Factor')) - item = tW.horizontalHeaderItem(3) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Additive Factor')) - item = tW.horizontalHeaderItem(4) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Wavelength unit')) - item = tW.horizontalHeaderItem(5) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Image name')) - item = tW.horizontalHeaderItem(6) - item.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Date')) - tW.verticalHeader().setDefaultSectionSize(24) - tW.horizontalHeader().setStretchLastSection(True) - gridLayout.addWidget(tW, 0, 0, 1, 1) - # connect to edited cell - try: - tW.cellChanged.disconnect() - except: - pass - tW.cellChanged.connect(cfg.bst.editedBandSet) - if position is None: - cfg.ui.Band_set_tabWidget.addTab(band_set_tab, cfg.bandSetName + str(len(cfg.bndSetTabList))) - position = len(cfg.bndSetTabList) - else: - if int(position) > (len(cfg.bndSetTabList)): - position = len(cfg.bndSetTabList) - cfg.ui.Band_set_tabWidget.insertTab(int(position) - 1, band_set_tab, cfg.bandSetName + str(len(cfg.bndSetTabList))) - cfg.utls.setColumnWidthList(tW, [[0, 350], [1, 150], [2, 150], [3, 150], [4, 150], [5, 150]]) - if refresh == 'Yes': - cfg.bst.readBandSet('Yes') - cfg.ui.Band_set_tabWidget.setCurrentIndex(int(position) - 1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' added band set') - a = len(cfg.bndSetTabList) - 1 - if a < 0: - a = 0 - return a - - # close Band set tab - def closeBandSetTab(self, index): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Remove band set'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to remove band set ' + str(index + 1) + '?')) - if a == 'Yes': - t = len(cfg.bndSetTabList) - if t > 1: - cfg.bst.deleteBandSetTab(index) - for i in range(0, t-1): - cfg.ui.Band_set_tabWidget.setTabText(i, cfg.bandSetName + str(i + 1)) - cfg.bst.readBandSet('Yes') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' closed band set ' + str(index + 1)) - else: - cfg.mx.msg24() - - # delete Band set tab - def deleteBandSetTab(self, index): - try: - cfg.bndSetTabList.pop(index) - cfg.ui.Band_set_tabWidget.removeTab(index) - cfg.algWT.deleteBandSetWeigthTab(index) - except Exception as err: - cfg.mx.msgErr62(str(index + 1)) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - - # read band set - def readBandSet(self, bandsetPresent = 'Yes', refresh = 'No'): - cfg.bandSetsList = [] - imgName = '' - for i in range(0, len(cfg.bndSetTabList)): - try: - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[i]) - except Exception as err: - self.tabBandSetChanged(0) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return - # check if bandset is empty - c = tW.rowCount() - bandSetList = [bandsetPresent, i, c, None, None, None, None, None, None, None] - # band set name list - bndSet = [] - # band set wavelength - bndSetWvLn = [] - # band set multiplicative and additive factors - bndSetMultiFactorsList = [] - bndSetAddFactorsList = [] - unit = cfg.noUnit - if c == 0: - bandSetList[0] = 'No' - date = '' - if refresh == 'Yes': - cfg.ipt.refreshRasterLayer() - else: - for b in range(0, c): - imgName = tW.item(0, 5).text() - bndSet.append(tW.item(b, 0).text()) - bndSetWvLn.append(float(tW.item(b, 1).text())) - try: - bndSetMultiFactorsList.append(float(tW.item(b, 2).text())) - except: - bndSetMultiFactorsList.append(1) - try: - bndSetAddFactorsList.append(float(tW.item(b, 3).text())) - except: - bndSetAddFactorsList.append(0) - try: - unit = tW.item(0, 4).text() - except: - unit = cfg.noUnit - try: - date = tW.item(0, 6).text() - except: - date = '' - bandSetList[7] = cfg.bandSetName + str(i) - if imgName == '': - bandSetList[0] = 'Yes' - bandSetList[8] = '' - else: - bandSetList[0] = 'No' - bandSetList[8] = imgName - bandSetList[3] = bndSet - bandSetList[4] = bndSetWvLn - bandSetList[5] = self.unitNameConversion(unit) - bandSetList[6] = [bndSetMultiFactorsList, bndSetAddFactorsList] - bandSetList[9] = date - cfg.bandSetsList.append(bandSetList) - cfg.bCalc.rasterBandName() - cfg.bstLT.BandSetListTable() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " read band set") - cfg.bst.configureBandSet(bandsetPresent) - - # configure band set - def configureBandSet(self, reset = 'Yes', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - # write project variables - cfg.utls.writeProjectVariable('bandSetsList', str(cfg.bandSetsList)) - cfg.utls.writeProjectVariable('bndSetNumber', str(cfg.bndSetNumber)) - cfg.tmpVrtDict[bandSetNumber] = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' configure band set') - try: - cfg.bandSetsList[bandSetNumber][3] - except: - return 'No' - # find band number - cfg.utls.findBandNumber() - cfg.utls.checkBandSet(bandSetNumber) - # reset rapid ROI spinbox - cfg.uidc.rapidROI_band_spinBox.setValue(1) - # read algorithm weight table - if reset == 'Yes': - cfg.algWT.resetAlgorithmTable() - else: - cfg.algWT.readAlgorithmTable() - - # convert unit name string in combo - def unitNameConversion(self, unitName, reverse = 'No'): - if reverse == 'No': - if unitName == cfg.wlNano: - u = cfg.unitNano - elif unitName == cfg.wlMicro: - u = cfg.unitMicro - elif unitName == cfg.noUnit: - u= cfg.noUnit - elif reverse == 'Yes': - if unitName == cfg.unitNano: - u = cfg.wlNano - elif unitName == cfg.unitMicro: - u = cfg.wlMicro - elif unitName == cfg.noUnit: - u= cfg.noUnit - return u - - # export band set to file - def exportBandSet(self): - bndSetFile = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save the band set to file'), '', '*.xml', 'xml') - if bndSetFile is not False: - if bndSetFile.lower().endswith('.xml'): - pass - else: - bndSetFile = bndSetFile + '.xml' - self.exportBandSetFile(bndSetFile) - - # export band set - def exportBandSetFile(self, bandSetFile, bandSetNumber = None): - try: - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - # check if bandset is empty - c = tW.rowCount() - if c != 0: - root = cfg.ETSCP.Element('bandset') - root.set('unit',str(cfg.bandSetsList[bandSetNumber][5])) - root.set('date',str(cfg.bandSetsList[bandSetNumber][9])) - root.set('bandsetpresent',str(cfg.bandSetsList[bandSetNumber][0])) - for b in range(0, c): - bandItem = cfg.ETSCP.SubElement(root, 'band') - bandItem.set('number', str(b + 1)) - nameField = cfg.ETSCP.SubElement(bandItem, 'name') - nameField.text = tW.item(b, 0).text() - rangeField = cfg.ETSCP.SubElement(bandItem, 'wavelength') - rangeField.text = tW.item(b, 1).text() - mutliplicativeField = cfg.ETSCP.SubElement(bandItem, 'multiplicative_factor') - mutliplicativeField.text = tW.item(b, 2).text() - additiveField = cfg.ETSCP.SubElement(bandItem, 'additive_factor') - additiveField.text = tW.item(b, 3).text() - unitField = cfg.ETSCP.SubElement(bandItem, 'wavelength_unit') - unitField.text = tW.item(b, 4).text() - imageNameField = cfg.ETSCP.SubElement(bandItem, 'image_name') - imageNameField.text = tW.item(b, 5).text() - o = open(bandSetFile, 'w') - f = cfg.minidomSCP.parseString(cfg.ETSCP.tostring(root)).toprettyxml() - o.write(f) - o.close() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band set exported') - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # import band set from file - def importBandSet(self): - bndSetFile = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a band set file'), '', 'XML (*.xml)') - if len(bndSetFile) > 0: - self.importBandSetFile(bndSetFile) - self.readBandSet('Yes') - - # import band set - def importBandSetFile(self, bandSetFile, bandSetNumber = None): - try: - tree = cfg.ETSCP.parse(bandSetFile) - root = tree.getroot() - # band set - bs = {} - # wavelength - wl = {} - # multiplicative and additive factors - multF = {} - addF = {} - wlU = {} - imNm = {} - # band number - bN = [] - unit = root.get('unit') - bandset = root.get('bandsetpresent') - if unit == cfg.unitMicro: - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - cfg.ui.unit_combo.setCurrentIndex(id) - elif unit == cfg.unitNano: - id = cfg.ui.unit_combo.findText(cfg.wlNano) - cfg.ui.unit_combo.setCurrentIndex(id) - try: - date = root.get('date') - Qdate = cfg.QtCoreSCP.QDateTime.fromString(date, '%Y-%m-%d') - except: - date = '' - for child in root: - n = int(child.get('number')) - bN.append(n) - bs[n] = str(child.find('name').text).strip() - wl[n] = float(child.find('wavelength').text.strip()) - multF[n] = float(child.find('multiplicative_factor').text.strip()) - addF[n] = float(child.find('additive_factor').text.strip()) - wlU[n] = str(child.find('wavelength_unit').text.strip()) - try: - imNm[n] = str(child.find('image_name').text.strip()) - except: - imNm[n] = '' - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - cfg.BandTabEdited = 'No' - try: - cfg.ui.bandset_dateEdit.setDate(Qdate) - except: - pass - while tW.rowCount() > 0: - tW.removeRow(0) - for x in sorted(bN): - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, bs[x], c, 0, 'No') - cfg.utls.addTableItem(tW, str(wl[x]), c, 1) - cfg.utls.addTableItem(tW, str(multF[x]), c, 2) - cfg.utls.addTableItem(tW, str(addF[x]), c, 3) - cfg.utls.addTableItem(tW, str(wlU[x]), c, 4) - cfg.utls.addTableItem(tW, str(imNm[x]), c, 5) - cfg.utls.addTableItem(tW, date, c, 6) - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " band set imported") - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msgErr5() - - # set band set - def setBandSet(self, bandNameList, bandSetNumber = None, date = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - if date is None: - date = '' - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - cfg.BandTabEdited = 'No' - try: - while tW.rowCount() > 0: - tW.removeRow(0) - for x in bandNameList: - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, x, c, 0, 'No') - cfg.utls.addTableItem(tW, c+1, c, 1) - cfg.utls.addTableItem(tW, '1', c, 2) - cfg.utls.addTableItem(tW, '0', c, 3) - cfg.utls.addTableItem(tW, cfg.noUnit, c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, date, c, 6) - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band set set') - except Exception as err: - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr5() - - # move down selected band - def moveDownBand(self): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - pass - else: - s = tW.selectedItems() - cfg.BandTabEdited = 'No' - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() + 1) - try: - for b in reversed(list(range(0, c))): - if tW.item(b, 0).isSelected() or tW.item(b, 1).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b + 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b + 1, 0).setText(str(bNU)) - tW.clearSelection() - v = list(set(ns)) - for i in range (0, len(v)): - tW.selectRow(v[i]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - # update band set - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band moved") - - # sort band name - def sortBandName(self): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - pass - else: - cfg.BandTabEdited = 'No' - try: - bN = [] - bNL = [] - for b in range(0, c): - bN.append(tW.item(b, 0).text()) - split = cfg.reSCP.split('([0-9]+)', tW.item(b, 0).text()) - try: - bNL.append(int(split[-1])) - except: - try: - bNL.append(int(split[-2])) - except: - try: - bNL.append(int(split[-3])) - except: - bNL.append(tW.item(b, 0).text()) - if len(list(set(bNL))) == len(bN): - sortBands = sorted(bNL) - bNsort = [] - for k in sortBands: - q = bNL.index(k) - bNsort.append(bN[q]) - else: - bNsort = sorted(bN) - for b in range(0, c): - tW.item(b, 0).setText(str(bNsort[b])) - tW.clearSelection() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - # update band set - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band moved") - - # move up selected band - def moveUpBand(self): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval("cfg.ui.tableWidget__" + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - pass - else: - s = tW.selectedItems() - cfg.BandTabEdited = 'No' - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() - 1) - try: - for b in range(0, c): - if tW.item(b, 0).isSelected() or tW.item(b, 1).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b - 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b - 1, 0).setText(str(bNU)) - tW.clearSelection() - v = list(set(ns)) - for i in range (0, len(v)): - tW.selectRow(v[i]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - # update band set - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " band moved") - - # Set raster band checklist - def rasterBandName(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - tW = cfg.ui.bands_tableWidget - cfg.utls.clearTable(tW) - for x in sorted(ls, key=lambda c: c.name()): - if x.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer and x.bandCount() == 1 and cfg.bndSetVrtNm not in x.name(): - tW.blockSignals(True) - # count table rows - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, x.name(), c, 0) - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " raster band name checklist created") - - # Set raster to single band names for wavelength definition - def rasterToBandName(self, rasterName, date = '', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - r = cfg.utls.selectLayerbyName(rasterName, 'Yes') - b = r.bandCount() - cfg.BandTabEdited = 'No' - tW.blockSignals(True) - for i in range(0, b): - # count table rows - c = tW.rowCount() - # name of item of list - itN = rasterName + '#b' + str(i) - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0, 'No') - v = i + 1 - wl = str(float(v)) - cfg.utls.addTableItem(tW, wl, c, 1) - cfg.utls.addTableItem(tW, '1', c, 2) - cfg.utls.addTableItem(tW, '0', c, 3) - cfg.utls.addTableItem(tW, '0', c, 4) - cfg.utls.addTableItem(tW, cfg.ui.unit_combo.currentText(), c, 4) - cfg.utls.addTableItem(tW, rasterName, c, 5) - cfg.utls.addTableItem(tW, date, c, 6) - self.readBandSet('Yes') - tW.blockSignals(False) - cfg.BandTabEdited = 'Yes' - - # remove selected band - def removeBand(self): - bandSetNumber = None - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - c = tW.rowCount() - # check if single raster - if c > 0 and cfg.bandSetsList[bandSetNumber][0] == 'No': - cfg.mx.msg25() - else: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Remove band'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to remove the selected bands from band set?')) - if a == 'Yes': - r = [] - for i in tW.selectedItems(): - r.append(i.row()+1) - self.removeBandsFromBandSet(bandSetNumber, r) - - # select all bands for set - def removeBandsFromBandSet(self, bandSetNumber, bandList, unloadBands = None): - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - v = sorted(list(set(eval(str(bandList))))) - cfg.BandTabEdited = 'No' - for x in reversed(v): - if unloadBands == 'Yes': - fN = cfg.bandSetsList[bandSetNumber][3][x-1] - try: - cfg.utls.removeLayer(fN) - except: - pass - # remove items - tW.removeRow(int(x)-1) - self.readBandSet('Yes') - cfg.BandTabEdited = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' band removed') - - # select all bands for set - def selectAllBands(self): - try: - # select all - if self.allBandsCheck == 'Yes': - self.allBandSetState(2) - # set check all bands - self.allBandsCheck = 'No' - # unselect all if previously selected all - elif self.allBandsCheck == 'No': - self.allBandSetState(0) - # set check all bands - self.allBandsCheck = 'Yes' - except: - # first time except - try: - self.allBandSetState(2) - # set check all bands - self.allBandsCheck = 'No' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " all bands clicked") - - # sort band sets by date - def sortByDate(self): - bandSetDateDict = {} - for i in range(0, len(cfg.bandSetsList)): - try: - date = cfg.datetimeSCP.datetime.strptime(str(cfg.bandSetsList[i][9]), '%Y-%m-%d') - bandSetDateDict[i] = date - except: - bandSetDateDict[i] = cfg.datetimeSCP.datetime.strptime('2050-01-01', '%Y-%m-%d') - n = 0 - for i in sorted(bandSetDateDict, key = bandSetDateDict.get): - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[n]) - cfg.BandTabEdited = 'No' - cfg.utls.clearTable(tW) - bndSet = cfg.bandSetsList[i][3] - bndSetWvLn = cfg.bandSetsList[i][4] - unit = str(cfg.bst.unitNameConversion(cfg.bandSetsList[i][5], 'Yes')) - bndSetMultiFactorsList, bndSetAddFactorsList = cfg.bandSetsList[i][6] - imgName = cfg.bandSetsList[i][8] - date = cfg.bandSetsList[i][9] - for x in range(0, len(bndSet)): - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, bndSet[x], c, 0, 'No') - cfg.utls.addTableItem(tW, str(bndSetWvLn[x]), c, 1) - cfg.utls.addTableItem(tW, str(bndSetMultiFactorsList[x]), c, 2) - cfg.utls.addTableItem(tW, str(bndSetAddFactorsList[x]), c, 3) - cfg.utls.addTableItem(tW, str(unit), c, 4) - cfg.utls.addTableItem(tW, str(imgName), c, 5) - cfg.utls.addTableItem(tW, date, c, 6) - n = n + 1 - cfg.BandTabEdited = 'Yes' - self.readBandSet('Yes') - - # create virtual raster - def virtualRasterBandSet(self, outFile = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ck = cfg.utls.checkBandSet(bandSetNumber) - if outFile is None: - rstrOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Save virtual raster"), "", "*.vrt", "vrt") - else: - rstrOut = outFile - if rstrOut is not False and ck == 'Yes': - if rstrOut.lower().endswith(".vrt"): - pass - else: - rstrOut = rstrOut + ".vrt" - st = cfg.utls.createVirtualRaster(cfg.bndSetLst, rstrOut, 'No', 'Yes', 'Yes', 0) - # add virtual raster to layers - cfg.utls.addRasterLayer(rstrOut) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " virtual raster: " + str(st)) - elif ck == 'No': - cfg.mx.msgErr33() - - def stackBandSet(self, outFile = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ck = cfg.utls.checkBandSet(bandSetNumber) - if outFile is None: - rstrOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster'), '', '*.tif', 'tif') - else: - rstrOut = outFile - if rstrOut is not False and ck == 'Yes': - if rstrOut.lower().endswith('.tif'): - pass - else: - rstrOut = rstrOut + '.tif' - if outFile is None: - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - st = cfg.utls.mergeRasterBands(cfg.bndSetLst, rstrOut, compress = 'Yes') - if cfg.osSCP.path.isfile(rstrOut): - cfg.cnvs.setRenderFlag(False) - cfg.utls.addRasterLayer(rstrOut) - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " raster: " + str(st)) - cfg.uiUtls.updateBar(100) - if outFile is None: - cfg.utls.finishSound() - cfg.uiUtls.removeProgressBar() - elif ck == 'No': - cfg.mx.msgErr33() - - # button perform Band set tools - def performBandSetTools(self): - if cfg.ui.overview_raster_bandset_checkBox.isChecked() is False and cfg.ui.band_calc_checkBox.isChecked() is False and cfg.ui.stack_raster_bandset_checkBox.isChecked() is False and cfg.ui.virtual_raster_bandset_checkBox.isChecked() is False: - cfg.mx.msg26() - elif cfg.ui.overview_raster_bandset_checkBox.isChecked() is True and cfg.ui.band_calc_checkBox.isChecked() is False and cfg.ui.stack_raster_bandset_checkBox.isChecked() is False and cfg.ui.virtual_raster_bandset_checkBox.isChecked() is False: - cfg.utls.buildOverviewsBandSet() - else: - i = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Select a directory")) - if len(i) > 0: - cfg.uiUtls.addProgressBar() - cfg.bst.bandSetTools(i, batch = 'No') - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.cnvs.setRenderFlag(True) - - # perform band set tools - def bandSetTools(self, outputDirectory, batch = 'Yes'): - if batch == 'No': - cfg.uiUtls.addProgressBar() - if cfg.actionCheck == 'Yes': - if cfg.ui.band_calc_checkBox.isChecked() is True: - cfg.bCalc.rasterBandName() - cfg.bCalc.calculate(outputDirectory + '/' + cfg.calcRasterNm + '.tif', batch = 'Yes') - if cfg.actionCheck == 'Yes': - if cfg.ui.virtual_raster_bandset_checkBox.isChecked() is True: - try: - cfg.bst.virtualRasterBandSet(outputDirectory + '/' + cfg.utls.fileNameNoExt(cfg.bndSetLst[0])[:-1] + cfg.virtualRasterNm + '.vrt') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if cfg.actionCheck == 'Yes': - if cfg.ui.stack_raster_bandset_checkBox.isChecked() is True: - try: - cfg.bst.stackBandSet(outputDirectory + '/' + cfg.utls.fileNameNoExt(cfg.bndSetLst[0])[:-1] + cfg.stackRasterNm + '.tif') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if cfg.actionCheck == 'Yes': - if cfg.ui.overview_raster_bandset_checkBox.isChecked() is True: - cfg.utls.buildOverviewsBandSet(quiet = 'Yes') - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # perform bands filter - def filterTable(self): - l = cfg.ui.bands_tableWidget - text = cfg.ui.bands_filter_lineEdit.text() - items = l.findItems(text, cfg.QtSCP.MatchContains) - c = l.rowCount() - list = [] - for item in items: - list.append( item.row()) - l.blockSignals(True) - for i in range (0, c): - l.setRowHidden(i, False) - if i not in list: - l.setRowHidden(i, True) - l.blockSignals(False) \ No newline at end of file diff --git a/maininterface/bandsetlistTab.py b/maininterface/bandsetlistTab.py deleted file mode 100644 index a3017dc..0000000 --- a/maininterface/bandsetlistTab.py +++ /dev/null @@ -1,268 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class BandSetListTab: - - def __init__(self): - self.tableEdited = 'Yes' - - # Create list table - def BandSetListTable(self): - tW = cfg.ui.band_set_list_tableWidget - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.clearTable(tW) - for i in range(0, len(cfg.bandSetsList)): - cfg.utls.insertTableRow(tW, i) - if i == cfg.bndSetNumber: - co = cfg.QtGuiSCP.QColor(0, 128, 0) - bo = 'Yes' - else: - co = None - bo = None - cfg.utls.addTableItem(tW, i + 1, i, 0, foreground = co, bold = bo) - bands = str(cfg.bandSetsList[i][3]).replace("[", "").replace("]", "").replace("'", "") - cfg.utls.addTableItem(tW, bands, i, 1, foreground = co, tooltip = bands, bold = bo) - date = str(cfg.bandSetsList[i][9]) - cfg.utls.addTableItem(tW, date, i, 2, foreground = co, tooltip = bands, bold = bo) - tW.blockSignals(False) - self.tableEdited = 'Yes' - - # add band set - def addBandSetToTable(self): - b = cfg.bst.addBandSetTab() - - # display RGB band set - def displayRGB(self): - cfg.uiUtls.addProgressBar() - cfg.QtWidgetsSCP.qApp.processEvents() - rgb = cfg.rgb_combo.currentText() - tW = cfg.ui.band_set_list_tableWidget - # list of items - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - tmpVrt = cfg.tmpVrtDict[cfg.bndSetNumber] - # remove items - c = 0 - for i in v: - cfg.uiUtls.updateBar(int(c * 100 / (len(v))), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", " RGB band set " + str(i+1))) - c= c + 1 - try: - b = cfg.utls.createRGBColorComposite(rgb, i) - except: - try: - b = cfg.utls.createRGBColorComposite("3,2,1", i) - except: - pass - cfg.tmpVrtDict[cfg.bndSetNumber] = tmpVrt - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " row removed") - - # remove band set - def removeBandSetFromTable(self): - # ask for confirm - a = cfg.utls.questionBox("Remove rows", "Are you sure you want to remove highlighted rows from the table?") - if a == 'Yes': - cfg.uiUtls.addProgressBar() - tW = cfg.ui.band_set_list_tableWidget - cfg.ui.Band_set_tabWidget.blockSignals(True) - c = tW.rowCount() - # list of item to remove - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(sorted(set(iR))) - a = 0 - # if remove all band sets - if c == len(v): - a = 1 - cfg.bst.clearBandSet('No', 'No', 0) - # remove items - for i in reversed(list(range(a, len(v)))): - cfg.bst.removeBandSetTab(v[i]) - cfg.uiUtls.updateBar( 100 - (i) * 100 / (len(v)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' removing')) - cfg.bndSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - cfg.ui.Band_set_tabWidget.blockSignals(False) - cfg.bst.tabChanged() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " row removed") - - # move up selected - def moveUpBandset(self): - tW = cfg.ui.band_set_list_tableWidget - t = cfg.ui.Band_set_tabWidget - self.tableEdited = 'No' - tW.blockSignals(True) - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for x in range(0, len(s)): - ns.append(s[x].row()) - v = list(set(ns)) - if 0 not in v: - for i in range(0, len(v)): - t.tabBar().moveTab(v[i], v[i] - 1) - cfg.bst.tabChanged() - try: - for i in range(0, len(v)): - tW.selectRow(v[i] - 1) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - self.tableEdited = 'Yes' - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Bands moved") - - # move down selected - def moveDownBandset(self): - tW = cfg.ui.band_set_list_tableWidget - t = cfg.ui.Band_set_tabWidget - self.tableEdited = 'No' - tW.blockSignals(True) - c = tW.rowCount() - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for x in range(0, len(s)): - ns.append(s[x].row()) - v = list(set(ns)) - if c - 1 not in v: - for i in reversed(list(range(0, len(v)))): - t.tabBar().moveTab(v[i], v[i] + 1) - cfg.bst.tabChanged() - try: - for i in range(0, len(v)): - tW.selectRow(v[i] + 1) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - self.tableEdited = 'Yes' - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Bands moved") - - # double click define active band set - def doubleClick(self, index): - cfg.ui.Band_set_tabWidget.setCurrentIndex(index.row()) - -# export list to file - def exportList(self): - sL = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Save the Band set list to file"), "", "*.scpb", "scpb") - if sL is not False: - cfg.uiUtls.addProgressBar() - try: - dT = cfg.utls.getTime() - unzipDir = cfg.tmpDir + "/" + dT - oDir = cfg.utls.makeDirectory(unzipDir) - # export band sets - for i in range(0, len(cfg.bandSetsList)): - dT = cfg.utls.getTime() - outFile = unzipDir + "/" + cfg.bandSetName + dT + ".xml" - cfg.bst.exportBandSetFile(outFile, i) - cfg.uiUtls.updateBar((i) * 100 / (len(cfg.bandSetsList)), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", " exporting")) - # create zip file - cfg.utls.zipDirectoryInFile(sL, unzipDir) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list exported") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msg14() - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - - # import list from file - def importList(self): - file = cfg.utls.getOpenFileName(None , "Select a Band set list file", "", "SCPB (*.scpb)") - if len(file) > 0: - dT = cfg.utls.getTime() - unzipDir = cfg.tmpDir + "/" + dT - oDir = cfg.utls.makeDirectory(unzipDir) - # unzip to temp dir - try: - cfg.uiUtls.addProgressBar() - with cfg.zipfileSCP.ZipFile(file) as zOpen: - c = len(zOpen.namelist()) - i = 0 - for flName in sorted(zOpen.namelist()): - if cfg.actionCheck == 'Yes': - i = i + 1 - cfg.uiUtls.updateBar(i * 100 / c, cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", " importing")) - zipF = zOpen.open(flName) - fileName = cfg.utls.fileName(flName) - if fileName.endswith(".xml"): - try: - zipO = open(unzipDir + "/" + fileName, "wb") - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - b = cfg.bst.addBandSetTab('No') - cfg.bst.importBandSetFile(unzipDir + "/" + fileName, b) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - except Exception as err: - cfg.mx.msgErr19() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.bst.readBandSet('Yes') - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - - # perform bands filter - def filterTable(self): - l = cfg.ui.band_set_list_tableWidget - text = cfg.ui.band_set_filter_lineEdit.text() - items = l.findItems(text, cfg.QtSCP.MatchContains) - c = l.rowCount() - list = [] - for item in items: - list.append( item.row()) - l.blockSignals(True) - for i in range (0, c): - l.setRowHidden(i, False) - if i not in list: - l.setRowHidden(i, True) - l.blockSignals(False) \ No newline at end of file diff --git a/maininterface/batchTab.py b/maininterface/batchTab.py deleted file mode 100644 index 11279dd..0000000 --- a/maininterface/batchTab.py +++ /dev/null @@ -1,3791 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ -f -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class BatchTab: - - def __init__(self): - pass - - # run - def runButton(self): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Batch'), message = '') - cfg.cnvs.setRenderFlag(False) - expression = ' ' + cfg.ui.plainTextEdit_batch.toPlainText() + ' ' - e = self.checkExpression(expression) - cfg.workingDir = None - n = len(e) - i = 0 - for nf in e: - if len(nf.strip()) > 0: - if nf.strip()[0] != '#': - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Batch') + ' [' + str(i) + '/' + str(n) + '] ' + nf, message = '') - if cfg.actionCheck == 'Yes': - check, runFunction = self.checkExpressionLine(nf) - if check == 'Yes': - if runFunction == '(' + cfg.workingDirNm + ')': - pass - else: - if cfg.workingDir is not None: - runFunction = runFunction.replace(cfg.workingDirNm, cfg.workingDir) - try: - eval(runFunction) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error'), str(err)) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # text changed - def textChanged(self): - expression = ' ' + cfg.ui.plainTextEdit_batch.toPlainText() + ' ' - self.checkExpression(expression) - #cfg.ui.plainTextEdit_batch.setFocus() - - # check the expression and return it - def checkExpression(self, expression): - cfg.ui.plainTextEdit_batch.setStyleSheet('color : red') - #cfg.ui.toolButton_run_batch.setEnabled(False) - cfg.ui.batch_label.setText('') - vexpression = expression - # check working dir - try: - cfg.workingDir = None - fTrail = 0 - for traiL in expression.split('\n'): - fTrail = fTrail + 1 - if len(traiL.strip()) > 0: - if traiL.strip()[0] != '#': - firstLine = traiL - break - if cfg.workingDirNm in firstLine: - check, function = self.checkExpressionLine(firstLine) - try: - nextLines = '\n'.join(expression.split('\n')[fTrail:]) - vexpression = firstLine + '\n' + nextLines.replace(cfg.workingDirNm, cfg.workingDir) - except: - pass - except: - pass - # variables between ! ! - variables = {} - rexpression = '' - varList = [cfg.workingDirNm,cfg.tempDirNm, cfg.startForDirNm, cfg.DirNm, cfg.directoryName, cfg.endForDirNm, cfg.startForFileNm, cfg.FileNm, cfg.FileDirNm, cfg.endForFileNm, cfg.startForBandSetNm, cfg.bandSetNm, cfg.endForBandSetNm] - cfg.ui.batch_label.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Checking ...')) - cfg.QtWidgetsSCP.qApp.processEvents() - for traiL in vexpression.split('\n'): - if len(traiL.strip()) > 0 and traiL.strip()[0] == '!' and traiL.replace(' ', '').split('=')[0].replace('!', '') not in varList: - try: - variables[traiL.replace(' ', '').split('=')[0].strip()] = traiL.split('=')[1].strip() - except: - rexpression = rexpression + traiL + '\n' - for variableVal in variables: - rexpression = rexpression.replace(variableVal, variables[variableVal]) - else: - # replace variables in variables - variablesCopy = variables.copy() - for variableValC in variables: - for variableVal in variables: - if variableVal != variableValC: - variablesCopy[variableValC] = str(variablesCopy[variableValC]).replace(str(variableVal), str(variables[variableVal])) - variables = variablesCopy.copy() - rexpression = rexpression + traiL + '\n' - for variableVal in variables: - rexpression = rexpression.replace(variableVal, variables[variableVal]) - # temporary rasters - if cfg.tempRasterNm in rexpression: - rasterNumber = cfg.reSCP.findall(cfg.tempRasterNm + '(.*?)!', rexpression) - self.tempRasters = [] - for rN in rasterNumber: - if cfg.outTempRastFormat == 'VRT': - rP = cfg.utls.createTempRasterPathBatch(cfg.tempRasterNm.replace('!', '') + str(rN), 'vrt') - else: - rP = cfg.utls.createTempRasterPathBatch(cfg.tempRasterNm.replace('!', '') + str(rN), 'tif') - self.tempRasters.append(rP) - rexpression = rexpression.replace(cfg.tempRasterNm + str(rN) + '!', rP) - # temporary directory - if cfg.tempDirNm in rexpression: - try: - rexpression = rexpression.replace(cfg.tempDirNm, cfg.tmpDir) - except: - pass - fexpression = rexpression - # for directory - if cfg.startForDirNm in fexpression: - rexpressionX = fexpression.split(cfg.startForDirNm) - fReplaceX = '' - for fs in rexpressionX: - if len(fs.strip()) > 0: - fsSplit = fs.lstrip().split('\n') - firstL = fsSplit[0] - forDirX = None - if firstL[0] == ';': - forDir = firstL.split(';') - forDirX = forDir[1].replace('\'', '').strip().rstrip('/') - if len(forDirX) > 0 and cfg.QDirSCP(forDirX).exists(): - try: - forDirFilter = forDir[3].split('|') - except: - forDirFilter = None - try: - forDirLevel = int(forDir[2]) - except: - forDirLevel = 10000 - try: - forDirFilter = forDir[2].split('|') - except: - pass - else: - forDirX = None - fsSplit.pop(0) - fs = '\n'.join(fsSplit) - if forDirX is not None: - fstart = fs.split(cfg.endForDirNm) - for root, dirs, files in cfg.osSCP.walk(forDirX): - if root[len(forDirX):].count(cfg.osSCP.sep) + 1 <= forDirLevel: - for d in dirs: - if forDirFilter is None: - dirPath = cfg.osSCP.path.join(root, d) - fReplaceX1 = fstart[0].replace(cfg.DirNm, dirPath).replace(cfg.directoryName, d) - fLineX = fReplaceX1.rstrip().split('\n') - for line in fLineX: - if len(line) > 0: - if cfg.startForFileNm in line or cfg.FileNm in line or cfg.endForFileNm in line: - fReplaceX = fReplaceX + line + '\n' - else: - check, function = self.checkExpressionLine(line) - if check == 'Yes': - fReplaceX = fReplaceX + line + '\n' - else: - for fFil in forDirFilter: - trueList = [] - for fFilAndX in fFil.strip().replace('\'', '').split('&'): - # check date - try: - dateS = fFilAndX.split(':') - dStr0 = cfg.datetimeSCP.datetime.strptime(dateS[0].strip(), '%Y-%m-%d') - dStr1 = cfg.datetimeSCP.datetime.strptime(dateS[1].strip(), '%Y-%m-%d') - # date from directory name - try: - dStr = cfg.datetimeSCP.datetime.strptime(d[-10:], '%Y-%m-%d') - except: - dStr = cfg.datetimeSCP.datetime.strptime(d.split('_')[-2][-10:], '%Y-%m-%d') - trueList.append((dStr >= dStr0) & (dStr <= dStr1)) - except: - trueList.append(fFilAndX in d) - # add lines - if all(trueList): - dirPath = cfg.osSCP.path.join(root, d) - fReplaceX1 = fstart[0].replace(cfg.DirNm, dirPath).replace(cfg.directoryName, d) - fLineX = fReplaceX1.rstrip().split('\n') - for line in fLineX: - if len(line) > 0: - if cfg.startForFileNm in line or cfg.FileNm in line or cfg.endForFileNm in line: - fReplaceX = fReplaceX + line + '\n' - else: - check, function = self.checkExpressionLine(line) - if check == 'Yes': - fReplaceX = fReplaceX + line + '\n' - break - fstart.pop(0) - fss = '\n'.join(fstart) - try: - fReplaceX = fReplaceX + fss + '\n' - except: - pass - else: - fReplaceX = fReplaceX + fs + '\n' - fexpression = fReplaceX.rstrip('\\n').rstrip('\n') - # for file in directory - if cfg.startForFileNm in fexpression: - fexpressionD = fexpression.split(cfg.startForFileNm) - fReplace2 = '' - for fs in fexpressionD: - if len(fs.strip()) > 0: - fsSplit = fs.lstrip().split('\n') - firstL = fsSplit[0] - forDirX = None - if firstL[0] == ';': - forDir = firstL.split(';') - forDirX = forDir[1].replace('\'', '').strip() - if len(forDirX) > 0 and cfg.QDirSCP(forDirX).exists(): - try: - forDirFileFilter = forDir[3].split('|') - except: - forDirFileFilter = None - try: - forDirLevel = int(forDir[2]) - except: - forDirLevel = 10000 - try: - forDirFileFilter = forDir[2].split('|') - except: - pass - else: - forDirX = None - fsSplit.pop(0) - fs = '\n'.join(fsSplit) - if forDirX is not None: - fstart = fs.split(cfg.endForFileNm) - for root, dirs, files in cfg.osSCP.walk(forDirX): - if root[len(forDirX):].count(cfg.osSCP.sep) + 1 <= forDirLevel: - for x in files: - if forDirFileFilter is None: - filePath = cfg.osSCP.path.join(root, x) - fReplace = fstart[0].replace(cfg.FileNm, filePath).replace(cfg.FileDirNm, root) - fReplace2 = fReplace2 + fReplace + '\n' - else: - for fFil in forDirFileFilter: - trueList = [] - for fFilAndX in fFil.replace('\'', '').split('&'): - # check date - try: - dateS = fFilAndX.split(':') - dStr0 = cfg.datetimeSCP.datetime.strptime(dateS[0], '%Y-%m-%d') - dStr1 = cfg.datetimeSCP.datetime.strptime(dateS[1], '%Y-%m-%d') - try: - ffNm = cfg.utls.fileNameNoExt(x) - dStr = cfg.datetimeSCP.datetime.strptime(ffNm[-10:], '%Y-%m-%d') - except: - dStr = cfg.datetimeSCP.datetime.strptime(ffNm.split('_')[-2][-10:], '%Y-%m-%d') - trueList.append((dStr >= dStr0) & (dStr <= dStr1)) - except: - trueList.append(fFilAndX in x) - if all(trueList): - filePath = cfg.osSCP.path.join(root, x) - fReplace = fstart[0].replace(cfg.FileNm, filePath).replace(cfg.FileDirNm, root) - fReplace2 = fReplace2 + fReplace + '\n' - break - try: - fReplace2 = fReplace2 + fstart[1] + '\n' - except: - pass - else: - fReplace2 = fReplace2 + fs + '\n' - fexpression = fReplace2.rstrip('\\n').rstrip('\n') - # for band set - if cfg.startForBandSetNm in fexpression: - ffexpression = fexpression.split(cfg.startForBandSetNm) - fReplace3 = '' - for fs in ffexpression: - if len(fs.strip()) > 0: - fsSplit = fs.lstrip().split('\n') - firstL = fsSplit[0] - forBS = None - if firstL[0] == ';': - forBss = firstL.split(';') - forBS = forBss[1].replace('\'', '').strip() - fsSplit.pop(0) - fs = '\n'.join(fsSplit) - if forBS is not None: - bsetList = [] - if forBS == '*': - bsetList = list(range(1, len(cfg.bandSetsList)+1)) - else: - try: - # range of band sets - rgX = forBS.split(',') - for rgB in rgX: - try: - # range of band sets - rg = rgB.split(':') - bsetList1 = list(range(int(rg[0]), int(rg[1]) + 1)) - bsetList.extend(bsetList1) - except: - try: - bsetList.extend([int(rgB)]) - except: - pass - except: - pass - fstart = fs.split(cfg.endForBandSetNm) - fReplaceB = '' - for bsset in bsetList: - fReplaceB = fReplaceB + fstart[0].replace(cfg.bandSetNm, str(bsset)) + '\n' - try: - fReplaceB = fReplaceB + fstart[1] - except: - pass - fReplace3 = fReplace3 + fReplaceB + '\n' - else: - fReplace3 = fReplace3 + fs + '\n' - fexpression = fReplace3.rstrip('\\n').rstrip('\n') - fLine = fexpression.rstrip().split('\n') - ef = [] - for line in fLine: - if len(line) > 0 and line[0] != '#': - ef.append(line) - lnmb = 0 - for nf in ef: - if len(nf.strip()) > 0: - if nf.strip()[0] != '#': - lnmb = lnmb + 1 - try: - check, function = self.checkExpressionLine(nf) - except: - check = 'No' - function = [str(nf), str(nf)] - if check == 'Yes': - pass - else: - errNf = function[0] - errPar = function[1] - cfg.ui.batch_label.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error line ') + str(lnmb) + ': ' + str(errNf) + ' --> ' + str(errPar)) - cfg.ui.plainTextEdit_batch.setStyleSheet('color : red') - #cfg.ui.toolButton_run_batch.setEnabled(False) - return ef - cfg.ui.plainTextEdit_batch.setStyleSheet('color : green') - #cfg.ui.toolButton_run_batch.setEnabled(True) - cfg.ui.batch_label.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Check OK')) - return ef - - # check the expression line and return it - def checkExpressionLine(self, expression): - checkO = 'Yes' - errNf = '' - if len(expression.strip()) == 0: - pass - elif expression.strip()[0] == '#': - return checkO, ['', ''] - else: - f = expression.split(';') - nm = f[0].replace(' ', '') - fNm, fRun, fList = cfg.batchT.replaceFunctionNames(nm) - oldF = f - errPar = '' - # create function - if fNm == 'No': - checkO = 'No' - errNf = nm - else: - try: - check, parameters = eval(fNm + '(' + str(f[1:]) + ')') - if check == 'No': - checkO = 'No' - errNf = nm - if errPar is not None: - errPar = parameters - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - checkO = 'No' - errNf = nm - if checkO == 'Yes': - function = fRun + '(' - for p in parameters: - function = function + str(p) + ',' - function = function[:-1] + ')' - return checkO, function - else: - return checkO, [errNf, errPar] - - # replace function names - def replaceFunctionNames(self, name): - for i in cfg.functionNames: - if name.lower().strip() == i[0][0].strip(): - return i[0][1], i[0][2], i[0][3] - return 'No', 'No', 'No' - - # clear batch - def clearBatch(self): - cfg.ui.plainTextEdit_batch.setPlainText('') - - # import batch from text file - def importBatch(self): - file = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a batch file'), '', 'txt (*.txt)') - if len(file) > 0: - text = open(file, 'r').read() - cfg.ui.plainTextEdit_batch.setPlainText(text) - - # export batch to text file - def exportBatch(self): - file = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save the batch to file'), '', '*.txt', 'txt') - if file is not False: - if file.lower().endswith('.txt'): - pass - else: - file = file + '.txt' - f = cfg.ui.plainTextEdit_batch.toPlainText() - o = open(file, 'w') - o.write(f) - o.close() - - # add function list to table - def addFunctionsToTable(self, functionList): - tW = cfg.ui.batch_tableWidget - for i in functionList: - tW.blockSignals(True) - # count table rows - c = tW.rowCount() - try: - itF = i[0][1] - # name of item of list - itN = i[0][0] - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, itN, c, 0) - except: - itN = i[0][0] - # add list items to table - tW.setRowCount(c + 1) - co = cfg.QtGuiSCP.QColor(200, 200, 200) - cfg.utls.addTableItem(tW, itN, c, 0, 'No', co, bold = 'Yes') - tW.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # set function - def setFunction(self, index): - pT = cfg.ui.plainTextEdit_batch - tW = cfg.ui.batch_tableWidget - text = pT.toPlainText() - if len(text) > 0: - space = '\n' - else: - space = '' - nm = tW.item(index.row(), 0).text() - fNm, fRun, fList = cfg.batchT.replaceFunctionNames(nm) - if fNm != 'No': - text = text + space + nm.strip() + ';' - for f in fList: - text = text + f + ';' - pT.setPlainText(text[:-1]) - pT.setFocus() - - # set function button - def setFunctionButton(self): - pT = cfg.ui.plainTextEdit_batch - text = pT.toPlainText() - if len(text) > 0: - space = '\n' - else: - space = '' - nm = cfg.dlg.sender().objectName() - fNm, fRun, fList = cfg.batchT.replaceFunctionNames(nm) - if fNm != 'No': - text = text + space + nm.strip() + ';' - for f in fList: - text = text + f + ';' - pT.setPlainText(text[:-1]) - pT.setFocus() - cfg.utls.batchTab() - - # batch working directory - def workingDirectory(self, paramList): - parameters = [] - for p in paramList: - # working directory inside ' ' - g = cfg.reSCP.findall('[\'](.*?)[\']',p) - workingDir = g[0].replace('\\', '/') - if len(workingDir) > 0 and cfg.QDirSCP(workingDir).exists(): - cfg.workingDir = workingDir - else: - return 'No', 'workingDirectory' - # append parameters - try: - parameters.append(cfg.workingDirNm) - except: - return 'No', 'workingDirectory' - return 'Yes', parameters - - # batch process settings - def processSettings(self, paramList): - threads = 'None' - ram = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'threads': - try: - threads = str(int(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - elif pName == 'ram': - try: - ram = str(int(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(threads) - parameters.append(ram) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch add raster - def performAddRaster(self, paramList): - file = 'None' - name = 'None' - bandset = 'None' - wavelength = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - file = '\'' + g[0] + '\'' - else: - return 'No', pName - elif pName == 'input_raster_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0].strip()) > 0: - name = '\'' + g[0].strip() + '\'' - else: - return 'No', pName - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - elif pName == 'center_wavelength': - try: - wavelength = str(float(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(file) - parameters.append(name) - parameters.append(bandset) - parameters.append(wavelength) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch Landsat conversion - def performLandsatConversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input directory inside ' ' - if pName == 'input_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.label_26.setText(g[0]) - inputDir = '\'' + g[0] + '\'' - if len(g[0]) > 0 and cfg.QDirSCP(str(g[0])).exists(): - pass - else: - l = cfg.ui.landsat_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # MTL file path inside ' ' - elif pName == 'mtl_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.label_27.setText(g[0]) - # temperature in Celsius checkbox (1 checked or 0 unchecked) - elif pName == 'celsius_temperature': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.celsius_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.celsius_checkBox.setCheckState(0) - else: - return 'No', pName - # DOS1 checkbox (1 checked or 0 unchecked) - elif pName == 'apply_dos1': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.DOS1_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.DOS1_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_2.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_3.setValue(val) - except: - return 'No', pName - # pansharpening checkbox (1 checked or 0 unchecked) - elif pName == 'pansharpening': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.pansharpening_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.pansharpening_checkBox.setCheckState(0) - else: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.create_bandset_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.create_bandset_checkBox.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputDir) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.landsatT.populateTable(cfg.ui.label_26.text(), 'Yes') - return 'Yes', parameters - - # batch ASTER conversion - def performASTERConversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.label_143.setText(g[0]) - inputFile = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - l = cfg.ui.ASTER_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # temperature in Celsius checkbox (1 checked or 0 unchecked) - elif pName == 'celsius_temperature': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.celsius_checkBox_2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.celsius_checkBox_2.setCheckState(0) - else: - return 'No', pName - # DOS1 checkbox (1 checked or 0 unchecked) - elif pName == 'apply_dos1': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.DOS1_checkBox_2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.DOS1_checkBox_2.setCheckState(0) - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_5.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_5.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_6.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.create_bandset_checkBox_2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.create_bandset_checkBox_2.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputFile) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.ASTERT.populateTable(cfg.ui.label_143.text(), 'Yes') - return 'Yes', parameters - - # batch MODIS conversion - def performMODISConversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.label_217.setText(g[0]) - inputFile = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - l = cfg.ui.MODIS_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # reproject to WGS 84 checkbox (1 checked or 0 unchecked) - elif pName == 'reproject_wgs84': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.reproject_modis_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.reproject_modis_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_7.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_7.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_8.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.create_bandset_checkBox_3.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.create_bandset_checkBox_3.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputFile) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.MODIST.populateTable(cfg.ui.label_217.text(), 'Yes') - return 'Yes', parameters - - # batch Sentinel-1 conversion - def performSentinel1Conversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input directory inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputFile = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # xml graph file path inside ' ' - elif pName == 'xml_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.S2_label_94.setText(g[0]) - # VH polarization checkbox (1 checked or 0 unchecked) - elif pName == 'vh': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.VH_checkBox_S1.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.VH_checkBox_S1.setCheckState(0) - else: - return 'No', pName - # VV polarization checkbox (1 checked or 0 unchecked) - elif pName == 'vv': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.VV_checkBox_S1.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.VV_checkBox_S1.setCheckState(0) - else: - return 'No', pName - # raster conversion to dB - elif pName == 'convert_to_db': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.convert_to_db_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.convert_to_db_checkBox.setCheckState(0) - else: - return 'No', pName - # raster projection as band set - elif pName == 'raster_project': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.projection_checkBox_S1.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.projection_checkBox_S1.setCheckState(0) - else: - return 'No', pName - # band set number - elif pName == 'raster_projections_band_set': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.band_set_comb_spinBox_11.setValue(val) - except: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S1_nodata_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S1_nodata_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.S1_nodata_spinBox.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S1_create_bandset_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S1_create_bandset_checkBox.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputFile) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch Sentinel conversion - def performSentinel2Conversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input directory inside ' ' - if pName == 'input_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.S2_label_86.setText(g[0]) - inputDir = '\'' + g[0] + '\'' - if len(g[0]) > 0 and cfg.QDirSCP(str(g[0])).exists(): - pass - else: - l = cfg.ui.sentinel_2_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', '')) - 1)) - except: - return 'No', pName - # MTD_SAFL1C file path inside ' ' - elif pName == 'mtd_safl1c_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.S2_label_94.setText(g[0]) - # DOS1 checkbox (1 checked or 0 unchecked) - elif pName == 'apply_dos1': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.DOS1_checkBox_S2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.DOS1_checkBox_S2.setCheckState(0) - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S2_nodata_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S2_nodata_checkBox.setCheckState(0) - else: - return 'No', pName - # preprocess bands 1 9 10 - elif pName == 'preprocess_bands_1_9_10': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.preprocess_b_1_9_10_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.preprocess_b_1_9_10_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.S2_nodata_spinBox.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S2_create_bandset_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S2_create_bandset_checkBox.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputDir) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.sentinel2T.populateTable(cfg.ui.S2_label_86.text(), 'Yes') - return 'Yes', parameters - - # batch Sentinel 3 conversion - def performSentinel3Conversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input directory inside ' ' - if pName == 'input_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.S3_label_87.setText(g[0]) - inputDir = '\'' + g[0] + '\'' - if len(g[0]) > 0 and cfg.QDirSCP(str(g[0])).exists(): - pass - else: - l = cfg.ui.sentinel_3_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # DOS1 checkbox (1 checked or 0 unchecked) - elif pName == 'apply_dos1': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.DOS1_checkBox_S3.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.DOS1_checkBox_S3.setCheckState(0) - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S3_nodata_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S3_nodata_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.S2_nodata_spinBox_2.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.S3_create_bandset_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.S3_create_bandset_checkBox.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputDir) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.sentinel3T.populateTable(cfg.ui.S3_label_87.text(), 'Yes') - return 'Yes', parameters - - # batch GOES conversion - def performGOESConversion(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input directory inside ' ' - if pName == 'input_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - cfg.ui.GOES_label.setText(g[0]) - inputDir = '\'' + g[0] + '\'' - if len(g[0]) > 0 and cfg.QDirSCP(str(g[0])).exists(): - pass - else: - l = cfg.ui.GOES_tableWidget - cfg.utls.clearTable(l) - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.GOES_nodata_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.GOES_nodata_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.GOES_nodata_spinBox.setValue(val) - except: - return 'No', pName - # bandset checkbox (1 checked or 0 unchecked) - elif pName == 'create_bandset': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.GOES_create_bandset_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.GOES_create_bandset_checkBox.setCheckState(0) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputDir) - parameters.append(outputDir) - # batch - parameters.append('\'Yes\'') - try: - parameters.append(bandset) - except: - parameters.append('None') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # populate table - cfg.goesT.populateTable(cfg.ui.GOES_label.text(), 'Yes') - return 'Yes', parameters - - # batch classification - def performClassification(self, paramList): - bandset = 'None' - algFiles = '\'No\'' - reportCheckBox = '\'No\'' - vectorOutput = '\'No\'' - useLcs = '\'No\'' - useLcsAlgorithm = '\'No\'' - useLcsOnlyOverlap = '\'No\'' - maskCheckBox = '\'No\'' - mask = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output classification inside ' ' - if pName == 'output_classification_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputClassification = '\'' + g[0] + '\'' - else: - return 'No', pName - # use macroclass checkbox (1 checked or 0 unchecked) - elif pName == 'use_macroclass': - if pSplit[1].strip().replace(' ', '') == '1': - useMacroclass = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - useMacroclass = '\'No\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # use LCS checkbox (1 checked or 0 unchecked) - elif pName == 'use_lcs': - if pSplit[1].strip().replace(' ', '') == '1': - useLcs = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - useLcs = '\'No\'' - else: - return 'No', pName - # use LCS with algorithm checkbox (1 checked or 0 unchecked) - elif pName == 'use_lcs_algorithm': - if pSplit[1].strip().replace(' ', '') == '1': - useLcsAlgorithm = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - useLcsAlgorithm = '\'No\'' - else: - return 'No', pName - # use LCS only overlap checkbox (1 checked or 0 unchecked) - elif pName == 'use_lcs_only_overlap': - if pSplit[1].strip().replace(' ', '') == '1': - useLcsOnlyOverlap = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - useLcsOnlyOverlap = '\'No\'' - else: - return 'No', pName - # apply mask checkbox (1 checked or 0 unchecked) - elif pName == 'apply_mask': - if pSplit[1].strip().replace(' ', '') == '1': - maskCheckBox = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - maskCheckBox = '\'No\'' - else: - return 'No', pName - # mask file path inside ' ' - elif pName == 'mask_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - mask = '\'' + g[0] + '\'' - else: - return 'No', pName - # vector output checkbox (1 checked or 0 unchecked) - elif pName == 'vector_output': - if pSplit[1].strip().replace(' ', '') == '1': - vectorOutput = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - vectorOutput = '\'No\'' - else: - return 'No', pName - # classification report checkbox (1 checked or 0 unchecked) - elif pName == 'classification_report': - if pSplit[1].strip().replace(' ', '') == '1': - reportCheckBox = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - reportCheckBox = '\'No\'' - else: - return 'No', pName - # save algorithm files checkbox (1 checked or 0 unchecked) - elif pName == 'save_algorithm_files': - if pSplit[1].strip().replace(' ', '') == '1': - algFiles = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - algFiles = '\'No\'' - else: - return 'No', pName - # algorithm name 'Minimum Distance' 'Maximum Likelihood' 'Spectral Angle Mapping' - elif pName == 'algorithm_name': - aL = [cfg.algMinDist, cfg.algML, cfg.algSAM] - a = pSplit[1].strip().strip().replace('\'', '') - if a in aL: - algorithm = '\'' + a + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputClassification) - parameters.append(bandset) - parameters.append(algFiles) - parameters.append(reportCheckBox) - parameters.append(vectorOutput) - parameters.append(algorithm) - parameters.append(useMacroclass) - parameters.append(useLcs) - parameters.append(useLcsAlgorithm) - parameters.append(useLcsOnlyOverlap) - parameters.append(maskCheckBox) - parameters.append(mask) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification - def performRandomForest(self, paramList): - evalClassifier = '\'false\'' - evalFeaturePowerSet = '\'false\'' - minPowerSize = '2' - maxPowerSize = '7' - saveClassifier = '\'No\'' - classPath = '\'\'' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output classification inside ' ' - if pName == 'output_classification_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputClassification = '\'' + g[0] + '\'' - else: - return 'No', pName - # use macroclass checkbox (1 checked or 0 unchecked) - elif pName == 'use_macroclass': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.macroclass_checkBox_rf.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.macroclass_checkBox_rf.setCheckState(0) - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # number of training samples - elif pName == 'number_training_samples': - try: - numberTrainingSamples = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # number of training samples - elif pName == 'number_trees': - try: - treeCount = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # evaluate classifier (1 checked or 0 unchecked) - elif pName == 'evaluate_classifier': - if pSplit[1].strip().replace(' ', '') == '1': - evalClassifier = '\'true\'' - elif pSplit[1].strip().replace(' ', '') == '0': - evalClassifier = '\'false\'' - else: - return 'No', pName - # evaluate feature power set (1 checked or 0 unchecked) - elif pName == 'evaluate_feature_power_set': - if pSplit[1].strip().replace(' ', '') == '1': - evalFeaturePowerSet = '\'true\'' - elif pSplit[1].strip().replace(' ', '') == '0': - evalFeaturePowerSet = '\'false\'' - else: - return 'No', pName - # min power - elif pName == 'min_power': - try: - minPowerSize = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # max power - elif pName == 'max_power': - try: - maxPowerSize = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - - # classifier file path inside ' ' - elif pName == 'classifier_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - classPath = g[0] - else: - classPath = '\'\'' - return 'No', pName - # save classifier checkbox (1 checked or 0 unchecked) - elif pName == 'save_classifier': - if pSplit[1].strip().replace(' ', '') == '1': - saveClassifier = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - saveClassifier = '\'No\'' - else: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputClassification) - parameters.append(bandset) - parameters.append(numberTrainingSamples) - parameters.append(treeCount) - parameters.append(evalClassifier) - parameters.append(evalFeaturePowerSet) - parameters.append(minPowerSize) - parameters.append(maxPowerSize) - parameters.append(classPath) - parameters.append(saveClassifier) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch create band set - def performBandSetCreation(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' separated by , - if pName == 'raster_path_list': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - files = g[0] - if len(files) > 0: - files = '\'' + files + '\'' - else: - return 'No', pName - # wavelength unit 0=number 1=u'µm (1 E-6m)' 2='nm (1 E-9m)' - elif pName == 'wavelength_unit': - if pSplit[1].strip().replace(' ', '') == '0': - noUnitId = cfg.ui.unit_combo.findText(cfg.wlMicro) - cfg.ui.unit_combo.setCurrentIndex(noUnitId) - id = cfg.ui.unit_combo.findText(cfg.noUnit) - cfg.ui.unit_combo.setCurrentIndex(id) - elif pSplit[1].strip().replace(' ', '') == '1': - noUnitId = cfg.ui.unit_combo.findText(cfg.noUnit) - cfg.ui.unit_combo.setCurrentIndex(noUnitId) - id = cfg.ui.unit_combo.findText(cfg.wlMicro) - cfg.ui.unit_combo.setCurrentIndex(id) - elif pSplit[1].strip().replace(' ', '') == '2': - noUnitId = cfg.ui.unit_combo.findText(cfg.noUnit) - cfg.ui.unit_combo.setCurrentIndex(noUnitId) - id = cfg.ui.unit_combo.findText(cfg.wlNano) - cfg.ui.unit_combo.setCurrentIndex(id) - else: - return 'No', pName - # center wavelength inside ' ' separated by , - elif pName == 'center_wavelength': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - center_wavelength = g[0] - if len(center_wavelength) > 0: - center_wavelength = '\'' + center_wavelength + '\'' - else: - return 'No', pName - # multiplicative factor inside ' ' separated by , - elif pName == 'multiplicative_factor': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - multiplicative_factor = g[0] - if len(multiplicative_factor) > 0: - multiplicative_factor = '\'' + multiplicative_factor + '\'' - else: - return 'No', pName - # additive factor inside ' ' separated by , - elif pName == 'additive_factor': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - additive_factor = g[0] - if len(additive_factor) > 0: - additive_factor = '\'' + additive_factor + '\'' - else: - return 'No', pName - # date in format %Y-%m-%d - elif pName == 'date': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - date = g[0] - if len(date) > 0: - date = '\'' + date + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(files) - try: - parameters.append(center_wavelength) - except: - parameters.append('\'\'') - try: - parameters.append(multiplicative_factor) - except: - parameters.append('\'\'') - try: - parameters.append(additive_factor) - except: - parameters.append('\'\'') - try: - parameters.append(date) - except: - pass - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch select band set - def performBandSetSelection(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(bandset) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch remove band set - def performRemoveBandSet(self, paramList): - unload = '\'No\'' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # unload bands (1 checked or 0 unchecked) - elif pName == 'unload_bands': - if pSplit[1].strip().replace(' ', '') == '1': - unload = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - unload = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(bandset) - parameters.append(unload) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch remove band from band set - def performRemoveBandFromBandSet(self, paramList): - unload = '\'No\'' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # band set list ' ' separated by , - elif pName == 'band_list': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - band_list = g[0] - if len(band_list) > 0: - band_list = '\'[' + band_list + ']\'' - else: - return 'No', pName - # unload bands (1 checked or 0 unchecked) - elif pName == 'unload_bands': - if pSplit[1].strip().replace(' ', '') == '1': - unload = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - unload = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(bandset) - parameters.append(band_list) - parameters.append(unload) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch add new band set - def performAddNewBandSet(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - parameters.append('\'Yes\'') - parameters.append(bandset) - return 'Yes', parameters - - # batch send notification - def performSendNotification(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'subject': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - subject = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - elif pName == 'message': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - message = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - parameters.append(subject) - parameters.append(message) - return 'Yes', parameters - - # batch band combination - def performBandCombination(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - else: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(bandset) - parameters.append(outputRaster) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch split raster - def performSplitRaster(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - file = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output directory inside ' ' - elif pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - cfg.ui.output_name_lineEdit.setText(g) - else: - cfg.ui.output_name_lineEdit.setText('') - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'No\'') - parameters.append('\'Yes\'') - parameters.append(file) - parameters.append(outputDir) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # mosaic band sets - def performMosaicBandSets(self, paramList): - virtual = '\'No\'' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - cfg.ui.mosaic_output_name_lineEdit.setText(g) - else: - cfg.ui.mosaic_output_name_lineEdit.setText('') - return 'No', pName - # band set list ' ' separated by , - elif pName == 'band_set_list': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - band_set_list = g[0] - if len(band_set_list) > 0: - if band_set_list == '*': - band_set_list = '\'*\'' - else: - band_set_list = '\'[' + band_set_list + ']\'' - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_9.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_9.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_10.setValue(val) - except: - return 'No', pName - # virtual output checkbox (1 checked or 0 unchecked) - elif pName == 'virtual_output': - if pSplit[1].strip().replace(' ', '') == '1': - virtual = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - virtual = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputDir) - parameters.append(band_set_list) - parameters.append(virtual) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # neighbor pixels band sets - def performNeighborPixels(self, paramList): - matrixSize = 'None' - file = 'None' - namePrefix = 'None' - statPerc = 'None' - circular = 'None' - virtual = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - namePrefix = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # input file path inside ' ' - elif pName == 'matrix_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - file = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # virtual output checkbox (1 checked or 0 unchecked) - elif pName == 'virtual_output': - if pSplit[1].strip().replace(' ', '') == '1': - virtual = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - virtual = '\'No\'' - else: - return 'No', pName - # matrix size (int value) - elif pName == 'matrix_size': - try: - matrixSize = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # circular checkbox (1 checked or 0 unchecked) - elif pName == 'circular': - if pSplit[1].strip().replace(' ', '') == '1': - circular = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - circular = '\'No\'' - else: - return 'No', pName - # statistic name inside ' ' - elif pName == 'statistic': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - statName = None - for i in cfg.statisticList: - if i[0].lower() == g[0].lower(): - statName = '\'' + g[0] + '\'' - break - if statName is None: - return 'No', pName - else: - return 'No', pName - # stat value (int value) - elif pName == 'stat_value': - try: - statPerc = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(bandset) - parameters.append(outputDir) - parameters.append(matrixSize) - parameters.append(file) - parameters.append(statName) - parameters.append(statPerc) - parameters.append(namePrefix) - parameters.append(circular) - parameters.append(virtual) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch band calc - def performBandCalc(self, paramList): - extentRaster = 'None' - bandset = 'None' - outputRaster = 'None' - useValueNoData = '\'No\'' - inputNodataAsValue = '\'No\'' - extentIntersection = '\'Yes\'' - extentSameAs = '\'No\'' - align = '\'Yes\'' - outputNoData = '\'' + str(cfg.NoDataVal) + '\'' - scaleValue = '\'1\'' - offsetValue = '\'0\'' - dataType = '\'Float32\'' - calcDataType = 'None' - useNodataMask = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # expression inside ' ' - if pName == 'expression': - g = pSplit[1].strip().replace('!!', ';') - if len(g) > 2: - expr = g - else: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(g[0]) > 0: - pass - else: - return 'No', pName - # extent same as raster name inside ' ' - elif pName == 'extent_same_as_raster_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - extentRaster = '\'' + g[0] + '\'' - if len(g[0]) > 0: - extentSameAs = '\'Yes\'' - else: - return 'No', pName - # extent checkbox (1 checked or 0 unchecked) - elif pName == 'extent_intersection': - if pSplit[1].strip().replace(' ', '') == '1': - extentIntersection = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - extentIntersection = '\'No\'' - else: - return 'No', pName - # align checkbox (1 checked or 0 unchecked) - elif pName == 'align': - if pSplit[1].strip().replace(' ', '') == '1': - align = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - align = '\'No\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # nodata as value checkbox (1 checked or 0 unchecked) - elif pName == 'input_nodata_as_value': - if pSplit[1].strip().replace(' ', '') == '1': - inputNodataAsValue = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - inputNodataAsValue = '\'No\'' - else: - return 'No', pName - # nodata value (int value) - elif pName == 'use_value_nodata': - try: - useValueNoData = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # nodata mask value (int value) - elif pName == 'nodata_mask': - try: - useNodataMask = str(int(eval(pSplit[1].strip().replace(' ', '')))) - except: - return 'No', pName - # nodata value (int value) - elif pName == 'output_nodata_value': - try: - outputNoData = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # scale value (float value) - elif pName == 'scale_value': - try: - scaleValue = str(float(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # offset value (float value) - elif pName == 'offset_value': - try: - offsetValue = str(float(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # data type prefix inside ' ' - elif pName == 'data_type': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - dataType = '\'' + g + '\'' - else: - return 'No', pName - # calculation data type prefix inside ' ' - elif pName == 'calculation_data_type': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - calcDataType = '\'' + g + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append(outputRaster) - parameters.append('\'Yes\'') - parameters.append(expr) - parameters.append(extentRaster) - parameters.append('None') - parameters.append(inputNodataAsValue) - parameters.append(useValueNoData) - parameters.append(outputNoData) - parameters.append(dataType) - parameters.append(scaleValue) - parameters.append(offsetValue) - parameters.append(align) - if extentSameAs == '\'Yes\'': - extentIntersection = '\'No\'' - parameters.append(extentIntersection) - parameters.append(extentSameAs) - parameters.append('\'No\'') - parameters.append(bandset) - parameters.append(calcDataType) - parameters.append(useNodataMask) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch clip rasters - def performClipRasters(self, paramList): - shapefilePath = 'None' - vector_field = 'None' - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - cfg.ui.output_clip_name_lineEdit.setText(g) - else: - cfg.ui.output_clip_name_lineEdit.setText('') - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # use vector checkbox (1 checked or 0 unchecked) - elif pName == 'use_vector': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.shapefile_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.shapefile_checkBox.setCheckState(0) - else: - return 'No', pName - # use vector field checkbox (1 checked or 0 unchecked) - elif pName == 'use_vector_field': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.vector_field_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.vector_field_checkBox.setCheckState(0) - else: - return 'No', pName - # vector path inside ' ' - elif pName == 'vector_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - shapefilePath = '\'' + g[0] + '\'' - else: - return 'No', pName - # vector field inside ' ' - elif pName == 'vector_field': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - vector_field = '\'' + g[0] + '\'' - else: - return 'No', pName - # ul_x inside ' ' - elif pName == 'ul_x': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.UX_lineEdit.setText(g[0]) - else: - cfg.ui.UX_lineEdit.setText('') - return 'No', pName - # ul_y inside ' ' - elif pName == 'ul_y': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.UY_lineEdit.setText(g[0]) - else: - cfg.ui.UY_lineEdit.setText('') - return 'No', pName - # lr_x inside ' ' - elif pName == 'lr_x': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.LX_lineEdit.setText(g[0]) - else: - cfg.ui.LX_lineEdit.setText('') - return 'No', pName - # lr_y inside ' ' - elif pName == 'lr_y': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.LY_lineEdit.setText(g[0]) - else: - cfg.ui.LY_lineEdit.setText('') - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox.setValue(val) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputDir) - parameters.append(shapefilePath) - parameters.append(bandset) - parameters.append(vector_field) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch reproject rasters - def performReprojectRasters(self, paramList): - alignRasterPath = 'None' - epsgVal = 'None' - bandset = 'None' - xresolution = 'None' - yresolution = 'None' - resamplePixelSize = 'None' - outName = 'None' - outputNoData = 'None' - dataType = 'None' - sameExtent = '\'No\'' - resampling_methods = ['nearest_neighbour', 'near', 'average', 'average', 'sum', 'sum', 'maximum', 'max', 'minimum', 'min', 'mode', 'mode', 'median', 'med', 'first_quartile', 'q1', 'third_quartile', 'q3'] - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - outName = '\'' + g + '\'' - else: - return 'No', pName - # resampling method inside ' ' - elif pName == 'resampling_method': - g = pSplit[1].strip().replace('\'', '') - if g in resampling_methods: - if g == 'nearest_neighbour': - g = 'near' - elif g == 'average': - g = 'average' - elif g == 'sum': - g = 'sum' - elif g == 'maximum': - g = 'max' - elif g == 'minimum': - g = 'min' - elif g == 'mode': - g = 'mode' - elif g == 'median': - g = 'med' - elif g == 'first_quartile': - g = 'q1' - elif g == 'third_quartile': - g = 'q3' - resamplingMethod = '\'' + g + '\'' - else: - return 'No', pName - # data type prefix inside ' ' - elif pName == 'data_type': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - if g.lower() == 'auto': - dataType = 'None' - else: - dataType = '\'' + g + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # use extent checkbox (1 checked or 0 unchecked) - elif pName == 'same_extent_reference': - if pSplit[1].strip().replace(' ', '') == '1': - sameExtent = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - sameExtent = '\'No\'' - else: - return 'No', pName - # raster path inside ' ' - elif pName == 'align_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - alignRasterPath = '\'' + g[0] + '\'' - else: - return 'No', pName - # epsg inside ' ' - elif pName == 'epsg': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - epsgVal = '\'' + g[0] + '\'' - else: - return 'No', pName - # epsg inside ' ' - elif pName == 'resample_pixel_size': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - resamplePixelSize = '\'' + g[0] + '\'' - else: - return 'No', pName - # x resolution inside ' ' - elif pName == 'x_resolution': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - xresolution = '\'' + g[0] + '\'' - else: - return 'No', pName - # nodata value (int value) - elif pName == 'output_nodata_value': - try: - outputNoData = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # y resolution inside ' ' - elif pName == 'y_resolution': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - yresolution = '\'' + g[0] + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputDir) - parameters.append(alignRasterPath) - parameters.append(sameExtent) - parameters.append(epsgVal) - parameters.append(xresolution) - parameters.append(yresolution) - parameters.append(resamplePixelSize) - parameters.append(resamplingMethod) - parameters.append(dataType) - parameters.append(outputNoData) - parameters.append(outName) - parameters.append(bandset) - if alignRasterPath == 'None' and epsgVal == 'None': - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch cloud masking - def performCloudMasking(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # output name prefix inside ' ' - elif pName == 'output_name_prefix': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - cfg.ui.mask_output_name_lineEdit.setText(g) - else: - cfg.ui.mask_output_name_lineEdit.setText('') - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # use buffer checkbox (1 checked or 0 unchecked) - elif pName == 'use_buffer': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.cloud_buffer_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.cloud_buffer_checkBox.setCheckState(0) - else: - return 'No', pName - # size buffer value (int value) - elif pName == 'size_in_pixels': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.cloud_buffer_spinBox.setValue(val) - except: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_11.setValue(val) - except: - return 'No', pName - # input file path inside ' ' - elif pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # class values inside ' ' - elif pName == 'class_values': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.cloud_mask_classes_lineEdit.setText(g[0]) - else: - cfg.ui.cloud_mask_classes_lineEdit.setText('') - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(bandset) - parameters.append(inputRaster) - parameters.append(outputDir) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch spectral distance band sets - def performSpectralDistance(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output raster inside ' ' - if pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # band set number - elif pName == 'first_band_set': - try: - bandset1 = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # band set number - elif pName == 'second_band_set': - try: - bandset2 = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # method (1 minimum distance, 2 SAM) - elif pName == 'distance_algorithm': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.min_distance_radioButton_2.setChecked(True) - cfg.ui.spectral_angle_map_radioButton_2.setChecked(False) - elif pSplit[1].strip().replace(' ', '') == '2': - cfg.ui.min_distance_radioButton_2.setChecked(False) - cfg.ui.spectral_angle_map_radioButton_2.setChecked(True) - else: - return 'No', pName - # threshold checkbox (1 checked or 0 unchecked) - elif pName == 'use_distance_threshold': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.distance_threshold_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.distance_threshold_checkBox.setCheckState(0) - else: - return 'No', pName - # threshold value (float value) - elif pName == 'threshold_value': - try: - val = float(pSplit[1].strip().replace(' ', '')) - cfg.ui.thresh_doubleSpinBox_2.setValue(val) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(bandset1) - parameters.append(bandset2) - parameters.append(outputRaster) - # batch - parameters.append('\'Yes\'') - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch stack rasters - def performStackRaster(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # band set number - if pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputRaster) - parameters.append(bandset) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch reclassification - def performReclassification(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # reclassification values inside ' ' (list of oldValue_newValue separated by ,) - elif pName == 'value_list': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - values = g[0] - if len(values) > 0: - valuesStr = values.split(',') - valList = [] - for v in valuesStr: - val = v.split('_') - valList.append([float(val[0]), float(val[1])]) - values = '\'' + values + '\'' - else: - return 'No', pName - # use signature list code checkbox (1 checked or 0 unchecked) - elif pName == 'use_signature_list_code': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.apply_symbology_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.apply_symbology_checkBox.setCheckState(0) - else: - return 'No', pName - # code field - elif pName == 'code_field': - id = cfg.ui.class_macroclass_comboBox_2.findText(pSplit[1].strip().strip().replace('\'', '')) - if id >= 0: - cfg.ui.class_macroclass_comboBox_2.setCurrentIndex(id) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(outputRaster) - parameters.append(values) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification sieve - def performClassificationSieve(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # size threshold value (int value) - elif pName == 'size_threshold': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.sieve_threshold_spinBox.setValue(val) - except: - return 'No', pName - # code field - elif pName == 'pixel_connection': - id = cfg.ui.sieve_connection_combo.findText(pSplit[1].strip().strip().replace('\'', '')) - if id >= 0: - cfg.ui.sieve_connection_combo.setCurrentIndex(id) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(outputRaster) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification erosion - def performClassificationErosion(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # class values inside ' ' - elif pName == 'class_values': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.erosion_classes_lineEdit.setText(g[0]) - else: - cfg.ui.erosion_classes_lineEdit.setText('') - return 'No', pName - # size threshold value (int value) - elif pName == 'size_in_pixels': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.erosion_threshold_spinBox.setValue(val) - except: - return 'No', pName - # circular checkbox (1 checked or 0 unchecked) - elif pName == 'circular': - if pSplit[1].strip().replace(' ', '') == '1': - circular = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - circular = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(outputRaster) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification dilation - def performClassificationDilation(self, paramList): - circular = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # output file path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - outputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # class values inside ' ' - elif pName == 'class_values': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - cfg.ui.dilation_classes_lineEdit.setText(g[0]) - else: - cfg.ui.dilation_classes_lineEdit.setText('') - return 'No', pName - # size threshold value (int value) - elif pName == 'size_in_pixels': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.dilation_threshold_spinBox.setValue(val) - except: - return 'No', pName - # circular checkbox (1 checked or 0 unchecked) - elif pName == 'circular': - if pSplit[1].strip().replace(' ', '') == '1': - circular = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - circular = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(outputRaster) - parameters.append(circular) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch edit raster using vector - def performEditRasterUsingVector(self, paramList): - vectorFieldName = 'None' - cfg.ui.edit_val_use_vector_radioButton.setChecked(True) - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputRaster = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # input vector inside ' ' - elif pName == 'input_vector_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - inputVector = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - # vector field name inside ' ' - elif pName == 'vector_field_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - vectorFieldName = '\'' + g[0] + '\'' - cfg.ui.use_field_vector_checkBox.setCheckState(2) - else: - return 'No', pName - # expression inside ' ' - elif pName == 'expression': - g = pSplit[1].strip().replace('\'', '') - if len(g) > 0: - cfg.ui.expression_lineEdit.setText(g) - cfg.ui.use_expression_checkBox.setCheckState(2) - else: - cfg.ui.expression_lineEdit.setText('') - return 'No', pName - # constant value (int value) - elif pName == 'constant_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.value_spinBox.setValue(val) - cfg.ui.use_constant_val_checkBox.setCheckState(2) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(inputVector) - parameters.append(vectorFieldName) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch PCA - def performPCA(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output directory inside ' ' - if pName == 'output_dir': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - outputDir = '\'' + g[0] + '\'' - else: - return 'No', pName - # use number of components checkbox (1 checked or 0 unchecked) - elif pName == 'use_number_of_components': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.num_comp_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.num_comp_checkBox.setCheckState(0) - else: - return 'No', pName - # number of components (int value) - elif pName == 'number_of_components': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.pca_components_spinBox.setValue(val) - except: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_4.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_4.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_5.setValue(val) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputDir) - parameters.append(bandset) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch Clustering - def performClustering(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output path inside ' ' - if pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', ''))) - 1) - except: - return 'No', pName - # number of classes (int value) - elif pName == 'number_of_classes': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.kmeans_classes_spinBox.setValue(val) - except: - return 'No', pName - # max number of iterations (int value) - elif pName == 'max_iterations': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.kmeans_iter_spinBox.setValue(val) - except: - return 'No', pName - # ISODATA maximum standard deviation (float value) - elif pName == 'isodata_max_std_dev': - try: - val = float(pSplit[1].strip().replace(' ', '')) - cfg.ui.std_dev_doubleSpinBox.setValue(val) - except: - return 'No', pName - # ISODATA minimum class size (int value) - elif pName == 'isodata_min_class_size': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.min_size_class_spinBox.setValue(val) - except: - return 'No', pName - # threshold checkbox (1 checked or 0 unchecked) - elif pName == 'use_distance_threshold': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.kmean_threshold_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.kmean_threshold_checkBox.setCheckState(0) - else: - return 'No', pName - # method (1 K-means, 2 ISODATA) - elif pName == 'clustering_method': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.kmeans_radioButton.setChecked(True) - cfg.ui.isodata_radioButton.setChecked(False) - elif pSplit[1].strip().replace(' ', '') == '2': - cfg.ui.kmeans_radioButton.setChecked(False) - cfg.ui.isodata_radioButton.setChecked(True) - else: - return 'No', pName - # seed signatures (1 from band values, 2 from signature list, or 3 random) - elif pName == 'seed_signatures': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.kmean_minmax_radioButton.setChecked(True) - elif pSplit[1].strip().replace(' ', '') == '2': - cfg.ui.kmean_siglist_radioButton.setChecked(True) - elif pSplit[1].strip().replace(' ', '') == '3': - cfg.ui.kmean_randomsiglist_radioButton.setChecked(True) - else: - return 'No', pName - # algorithm (1 Minimum Distance, 2 Spectral Angle Mapping) - elif pName == 'distance_algorithm': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.min_distance_radioButton.setChecked(True) - elif pSplit[1].strip().replace(' ', '') == '2': - cfg.ui.spectral_angle_map_radioButton.setChecked(True) - else: - return 'No', pName - # save signatures checkbox (1 checked or 0 unchecked) - elif pName == 'save_signatures': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.kmean_save_siglist_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.kmean_save_siglist_checkBox.setCheckState(0) - else: - return 'No', pName - # threshold value (float value) - elif pName == 'threshold_value': - try: - val = float(pSplit[1].strip().replace(' ', '')) - cfg.ui.thresh_doubleSpinBox.setValue(val) - except: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_8.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_8.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_9.setValue(val) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputRaster) - parameters.append(bandset) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch accuracy - def performAccuracy(self, paramList): - shapefileField = 'None' - useNoData = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # classification path inside ' ' - if pName == 'classification_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - classification = '\'' + g[0] + '\'' - else: - return 'No', pName - # output path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # shapefile field name inside ' ' - elif pName == 'vector_field_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - shapefileField = '\'' + g[0] + '\'' - else: - return 'No', pName - # reference path inside ' ' - elif pName == 'reference_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - reference = '\'' + g[0] + '\'' - else: - return 'No', pName - # nodata value (int value) - elif pName == 'use_value_nodata': - try: - useNoData = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append(classification) - parameters.append(reference) - parameters.append('\'Yes\'') - parameters.append(shapefileField) - parameters.append(outputRaster) - parameters.append(useNoData) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch cross classification - def performCrossClassification(self, paramList): - shapefileField = 'None' - NoDataValue = 'None' - useNodata = 'No' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # classification path inside ' ' - if pName == 'classification_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - classification = '\'' + g[0] + '\'' - else: - return 'No', pName - # output path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # shapefile field name inside ' ' - elif pName == 'vector_field_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - shapefileField = '\'' + g[0] + '\'' - else: - return 'No', pName - # reference path inside ' ' - elif pName == 'reference_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - reference = '\'' + g[0] + '\'' - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_6.setCheckState(2) - useNodata = 'Yes' - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_6.setCheckState(0) - useNodata = 'No' - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - NoDataValue = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # raster from regression checkbox (1 checked or 0 unchecked) - elif pName == 'regression': - if pSplit[1].strip().replace(' ', '') == '1': - regression = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - regression = '\'No\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - if useNodata == 'No': - NoDataValue = 'None' - # append parameters - try: - # batch - parameters.append(classification) - parameters.append(reference) - parameters.append('\'Yes\'') - parameters.append(shapefileField) - parameters.append(outputRaster) - parameters.append(NoDataValue) - parameters.append(regression) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch zonal stat raster - def performZonalStatRaster(self, paramList): - shapefileField = 'None' - statPerc = 'None' - NoDataValue = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # inputRaster path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # output path inside ' ' - elif pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # shapefile field name inside ' ' - elif pName == 'vector_field_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - shapefileField = '\'' + g[0] + '\'' - else: - return 'No', pName - # statistic name inside ' ' - elif pName == 'statistic': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - statName = None - for i in cfg.statisticList: - if i[0].lower() == g[0].lower(): - statName = '\'' + g[0] + '\'' - break - if statName is None: - return 'No', pName - else: - return 'No', pName - # reference path inside ' ' - elif pName == 'reference_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - reference = '\'' + g[0] + '\'' - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox_10.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox_10.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - NoDataValue = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - # stat value (int value) - elif pName == 'stat_value': - try: - statPerc = int(eval(pSplit[1].strip().replace(' ', ''))) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(reference) - parameters.append(shapefileField) - parameters.append(outputRaster) - parameters.append(statName) - parameters.append(statPerc) - parameters.append(NoDataValue) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch vector to raster - def performVectorToRaster(self, paramList): - vectorFieldName = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output path inside ' ' - if pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # input vector path inside ' ' - elif pName == 'vector_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputVector= '\'' + g[0] + '\'' - else: - return 'No', pName - # input vector field name ' ' - elif pName == 'vector_field_name': - pSplitX = pSplit[1].strip() - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(g[0]) > 0: - vectorFieldName = '\'' + g[0] + '\'' - else: - return 'No', pName - # use value field checkbox (1 checked or 0 unchecked) - elif pName == 'use_value_field': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.field_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.field_checkBox.setCheckState(0) - else: - return 'No', pName - # extent same as reference (1 checked or 0 unchecked) - elif pName == 'extent_same_as_reference': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.extent_checkBox_2.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.extent_checkBox_2.setCheckState(0) - else: - return 'No', pName - # constant value (int value) - elif pName == 'constant_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.constant_value_spinBox.setValue(val) - except: - return 'No', pName - # type of conversion inside ' ' ('Center of pixels' , 'All pixels touched') - elif pName == 'type_of_conversion': - id = cfg.ui.conversion_type_combo.findText(pSplit[1].strip().strip().replace('\'', '')) - if id >= 0: - cfg.ui.conversion_type_combo.setCurrentIndex(id) - else: - return 'No', pName - # input raster path inside ' ' - elif pName == 'reference_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(outputRaster) - parameters.append(inputVector) - parameters.append(vectorFieldName) - parameters.append(inputRaster) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch Land Cover Change - def performLandCoverChange(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output path inside ' ' - if pName == 'output_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # input raster path inside ' ' - elif pName == 'reference_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - refRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # input raster path inside ' ' - elif pName == 'new_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - newRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(refRaster) - parameters.append(newRaster) - parameters.append(outputRaster) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification report - def performClassificationReport(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # output path inside ' ' - if pName == 'output_report_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputReport = '\'' + g[0] + '\'' - else: - return 'No', pName - # input raster path inside ' ' - elif pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # nodata checkbox (1 checked or 0 unchecked) - elif pName == 'use_nodata': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.nodata_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.nodata_checkBox.setCheckState(0) - else: - return 'No', pName - # nodata value (int value) - elif pName == 'nodata_value': - try: - val = int(eval(pSplit[1].strip().replace(' ', ''))) - cfg.ui.nodata_spinBox_2.setValue(val) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(inputRaster) - parameters.append('None') - # batch - parameters.append('\'Yes\'') - parameters.append(outputReport) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch classification to vector - def performClassificationToVector(self, paramList): - parameters = [] - dissolve = '\'No\'' - useCode = '\'No\'' - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input raster path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # output vector path inside ' ' - elif pName == 'output_vector_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputVector = '\'' + g[0] + '\'' - else: - return 'No', pName - # use signature list code checkbox (1 checked or 0 unchecked) - elif pName == 'use_signature_list_code': - if pSplit[1].strip().replace(' ', '') == '1': - useCode = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - useCode = '\'No\'' - else: - return 'No', pName - # use signature list code checkbox (1 checked or 0 unchecked) - elif pName == 'dissolve_output': - if pSplit[1].strip().replace(' ', '') == '1': - dissolve = '\'Yes\'' - elif pSplit[1].strip().replace(' ', '') == '0': - dissolve = '\'No\'' - else: - return 'No', pName - # code field - elif pName == 'code_field': - id = cfg.ui.class_macroclass_comboBox.findText(pSplit[1].strip().strip().replace('\'', '')) - if id >= 0: - cfg.ui.class_macroclass_comboBox.setCurrentIndex(id) - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(outputVector) - parameters.append(dissolve) - parameters.append(useCode) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch class signature - def performClassSignature(self, paramList): - bandset = 'None' - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input raster path inside ' ' - if pName == 'input_raster_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - inputRaster = '\'' + g[0] + '\'' - else: - return 'No', pName - # output vector path inside ' ' - elif pName == 'output_text_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - if len(cfg.utls.fileName(g[0])) > 0: - outputText = '\'' + g[0] + '\'' - else: - return 'No', pName - # use signature list code checkbox (1 checked or 0 unchecked) - elif pName == 'save_signatures': - if pSplit[1].strip().replace(' ', '') == '1': - cfg.ui.class_signature_save_siglist_checkBox.setCheckState(2) - elif pSplit[1].strip().replace(' ', '') == '0': - cfg.ui.class_signature_save_siglist_checkBox.setCheckState(0) - else: - return 'No', pName - # band set number - elif pName == 'band_set': - try: - bandset = str(int(eval(pSplit[1].strip().replace(' ', '')) - 1)) - except: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - # batch - parameters.append('\'Yes\'') - parameters.append(inputRaster) - parameters.append(bandset) - parameters.append(outputText) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - - # batch open training input - def performOpenTrainingInput(self, paramList): - parameters = [] - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - # input file path inside ' ' - if pName == 'training_file_path': - pSplitX = pSplit[1].strip() - if cfg.workingDir is not None: - pSplitX = pSplitX.replace(cfg.workingDirNm, cfg.workingDir) - g = cfg.reSCP.findall('[\'](.*?)[\']',pSplitX.replace('\\', '/')) - file = '\'' + g[0] + '\'' - if len(cfg.utls.fileName(g[0])) > 0: - pass - else: - return 'No', pName - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(file) - except: - return 'No', cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'missing parameter') - return 'Yes', parameters - \ No newline at end of file diff --git a/maininterface/classSignatureTab.py b/maininterface/classSignatureTab.py deleted file mode 100644 index 631a2fd..0000000 --- a/maininterface/classSignatureTab.py +++ /dev/null @@ -1,321 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassSignatureTab: - - def __init__(self): - pass - - # calculate class signature action - def calculateClassSignatureAction(self): - self.calculateClassSignature() - - # calculate class signature - def calculateClassSignature(self, batch = 'No', inputClassification = None, bandSetNumber = None, outputFile = None): - if inputClassification is None: - clssfctnNm = cfg.ui.classification_name_combo_3.currentText() - clss = cfg.utls.selectLayerbyName(clssfctnNm, 'Yes') - if clss is None: - return 'No' - inputClassification = cfg.utls.layerSource(clss) - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_8.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - clssOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Save signature output"), "", "*.txt", "txt") - else: - clssOut = outputFile - if clssOut is not False: - if batch == 'No': - cfg.uiUtls.addProgressBar() - if clssOut.lower().endswith(".txt"): - pass - else: - clssOut = clssOut + ".txt" - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "class signature") - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - bndSetIf = 'Yes' - else: - ckB = cfg.utls.checkImageBandSet(bandSetNumber) - bndSetIf = 'No' - if len(cfg.bndSetLst) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - cfg.uiUtls.updateBar(10) - rCrs = cfg.utls.getCrsGDAL(cfg.bndSetLst[0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - cfg.uiUtls.updateBar(20) - # No data value - NoDataVal = cfg.NoDataVal - eCrs = cfg.utls.getCrsGDAL(inputClassification) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - nD = cfg.utls.imageNoDataValue(inputClassification) - if nD is None: - nD = NoDataVal - #tPMD = cfg.utls.createTempRasterPath('tif') - #cfg.utls.GDALReprojectRaster(inputClassification, tPMD, "GTiff", None, "EPSG:" + str(rEPSG), "-ot Float32 -dstnodata " + str(nD)) - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(inputClassification, tPMD, str(rCrs)) - cfg.mx.msg9() - if cfg.osSCP.path.isfile(tPMD): - inputClassification = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - bList = [] - bandNumberList = [] - bList.append(inputClassification) - bandNumberList.append(1) - for x in range(0, len(cfg.bndSetLst)): - if bndSetIf == 'Yes': - bList.append(cfg.bndSetLst[x]) - bandNumberList.append(1) - else: - bList.append(cfg.bndSetLst[x]) - bandNumberList.append(x + 1) - nD = cfg.utls.imageNoDataValue(cfg.bndSetLst[0]) - if nD is None: - nD = NoDataVal - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = inputClassification, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = nD, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - rasterBandUniqueVal = cfg.np.unique(values).tolist() - classes = [] - for c in sorted(rasterBandUniqueVal): - classes.append(int(c)) - cfg.uiUtls.updateBar(30) - argumentList = [list(range(0, len(bList) - 1)), classes] - # create virtual raster - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes') - cfg.parallelArrayDict = {} - cfg.rasterClassSignature = {} - # process - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.rasterPixelCountClassSignature, nodataValue = nD, functionBandArgument = argumentList, functionVariable = cfg.rasterClassSignature, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Statistics'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW') - # find values - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - for arX in ar[0]: - for i in range(0, len(bList) - 1): - for c in classes: - if 'COUNT_BAND_' + str(i) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] = cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] + ar[0][arX] - except: - cfg.rasterClassSignature['COUNT_BAND_' + str(i) + '_c_' + str(c)] = ar[0][arX] - elif 'SUM_BAND_' + str(i) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] = cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] + ar[0][arX] - except: - cfg.rasterClassSignature['SUM_BAND_' + str(i) + '_c_' + str(c)] = ar[0][arX] - elif 'MINIMUM_BAND_' + str(i) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)] = min(ar[0][arX], cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)]) - except: - cfg.rasterClassSignature['MINIMUM_BAND_' + str(i) + '_c_' + str(c)] = ar[0][arX] - elif 'MAXIMUM_BAND_' + str(i) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)] = max(ar[0][arX], cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)]) - except: - cfg.rasterClassSignature['MAXIMUM_BAND_' + str(i) + '_c_' + str(c)] = ar[0][arX] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - # calculate band mean - for c in classes: - for b in range(0, len(bList) - 1): - cfg.rasterClassSignature['MEAN_BAND_' + str(b) + '_c_' + str(c)] = cfg.rasterClassSignature['SUM_BAND_' + str(b) + '_c_' + str(c)] / cfg.rasterClassSignature['COUNT_BAND_' + str(b) + '_c_' + str(c)] - comb = cfg.itertoolsSCP.combinations(list(range(0, len(bList) - 1)), 2) - varList = [] - for i in comb: - varList.append([i[0], i[1]]) - argumentList = [varList, classes, list(range(0, len(bList) - 1))] - cfg.parallelArrayDict = {} - # process - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.rasterStandardDeviationClassSignature, nodataValue = nD, functionBandArgument = argumentList, functionVariable = cfg.rasterClassSignature, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Statistics'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW') - # find values - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - for arX in ar[0]: - for i in varList: - for c in classes: - if 'COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] + ar[0][arX] - except: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] = ar[0][arX] - for f in range(0, len(bList) - 1): - for c in classes: - if 'VAR_BAND_' + str(f) + '_c_' + str(c) == arX: - try: - cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] = cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] + ar[0][arX] - except: - cfg.rasterClassSignature['VAR_BAND_' + str(f) + '_c_' + str(c)] = ar[0][arX] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - cfg.uiUtls.updateBar(70) - comb = cfg.itertoolsSCP.combinations(list(range(0, len(bList) - 1)), 2) - # calculate signature - signatures = [] - for c in classes: - covMat = cfg.np.zeros((len(bList) - 1, len(bList) - 1), dtype=cfg.np.float32) - cfg.tblOut = {} - s2 = [] - if c != nD: - try: - cfg.tblOut['ROI_SIZE'] = cfg.rasterClassSignature['COUNT_BAND_' + str(0) + '_c_' + str(c)] - for b in range(0, len(bList) - 1): - smin = cfg.rasterClassSignature['MINIMUM_BAND_' + str(b) + '_c_' + str(c)] - smax = cfg.rasterClassSignature['MAXIMUM_BAND_' + str(b) + '_c_' + str(c)] - smean = cfg.rasterClassSignature['MEAN_BAND_' + str(b) + '_c_' + str(c)] - sd = cfg.np.sqrt(cfg.rasterClassSignature['VAR_BAND_' + str(b) + '_c_' + str(c)]) - signature = [smin, smax, smean, sd] - s2.append(smean) - cfg.tblOut['WAVELENGTH_' + str(b + 1)] = cfg.bandSetsList[cfg.bndSetNumber][4][b] - covMat[b, b] = cfg.rasterClassSignature['VAR_BAND_' + str(b) + '_c_' + str(c)] - cfg.tblOut['BAND_' + str(b + 1)] = signature - # covariance - for i in comb: - covMat[i[0], i[1]] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] - covMat[i[1], i[0]] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1]) + '_c_' + str(c)] - signatures.append([c, s2, cfg.rasterClassSignature['COUNT_BAND_' + str(0) + '_c_' + str(c)]]) - if cfg.ui.class_signature_save_siglist_checkBox.isChecked() is True: - val = cfg.utls.ROIStatisticsToSignature(covMat, int(c), cfg.classSignatureNm, int(c), cfg.classSignatureNm, bandSetNumber, cfg.bandSetsList[bandSetNumber][5], 'No', 'No') - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - except Exception as err: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - # display parameters - self.displayParameters(signatures, clssOut) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " class signature calculated") - - # display parameters - def displayParameters(self, signatureList, outputFile = None): - tblOut = outputFile - try: - l = open(tblOut, 'w') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - tB = str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Class')) + "\t" + str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Signature')) + "\t" + str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'PixelSum')) + str("\n") - l.write(str(tB)) - for s in signatureList: - tB = str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'C_ID_')) + str(s[0]) + "\t" - vB = None - for k in s[1]: - if vB is None: - vB = str(k) - else: - vB = vB + "," + str(k) - l.write(str(tB) + str(vB) + "\t" + str(s[2]) + str("\n")) - l.close() - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.report_textBrowser_4.setText(str(eM)) - cfg.ui.toolBox_class_signature.setCurrentIndex(1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "calculated") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - \ No newline at end of file diff --git a/maininterface/classificationTab.py b/maininterface/classificationTab.py deleted file mode 100644 index b90c7a9..0000000 --- a/maininterface/classificationTab.py +++ /dev/null @@ -1,766 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassificationTab: - - def __init__(self): - pass - - - # set algorithm - def algorithmName(self): - algName = cfg.ui.algorithm_combo.currentText() - #idAlg = cfg.ui.algorithm_combo.findText(cfg.algName) - idAlg = cfg.ui.algorithm_combo.currentIndex() - if idAlg == 0: - cfg.algName = cfg.algMinDist - elif idAlg == 1: - cfg.algName = cfg.algML - elif idAlg == 2: - cfg.algName = cfg.algSAM - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'algorithm name: error ') - if str(cfg.algName) == cfg.algML: - if cfg.algThrshld > 100: - cfg.mx.msg10() - cfg.ui.alg_threshold_SpinBox.setValue(100) - elif str(cfg.algName) == cfg.algSAM: - if cfg.algThrshld > 90: - cfg.mx.msg11() - cfg.ui.alg_threshold_SpinBox.setValue(90) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'algorithm name: ' + str(cfg.algName)) - - # set algorithm threshold - def algorithmThreshold(self): - cfg.algThrshld = cfg.ui.alg_threshold_SpinBox.value() - if str(cfg.algName) == cfg.algML: - if cfg.algThrshld > 100: - cfg.ui.alg_threshold_SpinBox.setValue(100) - elif str(cfg.algName) == cfg.algSAM: - if cfg.algThrshld > 90: - cfg.ui.alg_threshold_SpinBox.setValue(90) - cfg.algThrshld = cfg.ui.alg_threshold_SpinBox.value() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'algorithm threshold: ' + str(cfg.algThrshld)) - - # perform classification - def runClassificationAction(self): - if cfg.ui.alg_files_checkBox.isChecked() is True: - algFilesCheck = 'Yes' - else: - algFilesCheck = None - if cfg.ui.report_checkBox.isChecked() is True: - report = 'Yes' - else: - report = None - if cfg.ui.vector_output_checkBox.isChecked() is True: - vector = 'Yes' - else: - vector = None - if cfg.ui.macroclass_checkBox.isChecked() is True: - macroclass = 'Yes' - else: - macroclass = None - if cfg.ui.LC_signature_checkBox.isChecked(): - useLcs = 'Yes' - else: - useLcs = None - if cfg.ui.LCS_class_algorithm_checkBox.isChecked(): - useLcsAlgorithm = 'Yes' - else: - useLcsAlgorithm = None - if cfg.ui.LCS_leave_unclassified_checkBox.isChecked(): - leaveUnclassified = 'Yes' - else: - leaveUnclassified = None - if cfg.ui.mask_checkBox.isChecked() is True: - maskC = 'Yes' - else: - maskC = None - maskPath = cfg.ui.mask_lineEdit.text() - if len(maskPath) == 0: - maskC = None - bndStN = cfg.ui.band_set_comb_spinBox_12.value() - 1 - self.runClassification(bandSetNumber = bndStN, algorithmFilesCheck = algFilesCheck, reportCheck = report, vectorConversion = vector, useMacroclass = macroclass, useLcs = useLcs, useLcsAlgorithm = useLcsAlgorithm, LCSLeaveUnclassified = leaveUnclassified, maskCheckBox = maskC, maskPath = maskPath) - - # perform classification - def runClassification(self, batch = 'No', outputClassification = None, bandSetNumber = None, algorithmFilesCheck = None, reportCheck = None, vectorConversion = None, algorithmName = None, useMacroclass = None, useLcs = None, useLcsAlgorithm = None, LCSLeaveUnclassified = None, maskCheckBox = None, maskPath = None): - sL = cfg.classTab.getSignatureList(bandSetNumber, algorithmName) - # for multiprocess - sLMP = cfg.classTab.getSignatureList(bandSetNumber, algorithmName, color = 'No') - if self.trainSigCheck == 'Yes': - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - clssOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save classification output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - clssOut = outputClassification - if clssOut is not False: - cfg.clssPth = clssOut - cfg.QtWidgetsSCP.qApp.processEvents() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification output: ' + str(cfg.clssPth)) - # check if can run classification - ckC = 'Yes' - if cfg.clssPth is None: - ckC = 'No' - # check if image is None - elif cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') is None and cfg.bandSetsList[bandSetNumber][0] != 'Yes': - cfg.mx.msg4() - cfg.ipt.refreshRasterLayer() - ckC = 'No' - if ckC != 'No': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '>>> CLASSIFICATION STARTED') - # base name - nm = cfg.utls.fileNameNoExt(cfg.clssPth) - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - # check band set - ckB = 'Yes' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - cfg.uiUtls.updateBar(10) - if ckB == 'Yes': - cfg.bndSetMaskList = [] - img = cfg.bandSetsList[bandSetNumber][8] - ### if mask - if maskCheckBox is None: - if cfg.ui.mask_checkBox.isChecked() is True: - maskCheckBox = 'Yes' - if maskCheckBox == 'Yes': - # mask shapefile path - if maskPath is None: - maskPath = cfg.ui.mask_lineEdit.text() - # apply mask - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - for x in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - tCD = cfg.utls.createTempRasterPath('tif') - bCSS = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][x], 'Yes') - bCPath = cfg.utls.layerSource(bCSS) - oc = cfg.utls.clipRasterByShapefile(maskPath, bCPath, str(tCD), cfg.outTempRastFormat) - cfg.bndSetMaskList.append(oc) - else: - # temp masked raster - cfg.maskRstSrc = cfg.utls.createTempRasterPath('tif') - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8]) - ql = cfg.utls.layerSource(b) - cfg.maskRstSrc = cfg.utls.clipRasterByShapefile(maskPath, ql, str(cfg.maskRstSrc), cfg.outTempRastFormat) - img = cfg.maskRasterNm - ### if not mask - cfg.uiUtls.updateBar(20) - if algorithmFilesCheck == 'Yes': - rOBaseNm = cfg.osSCP.path.dirname(cfg.clssPth) - algRasterPath = rOBaseNm + '/' + nm + '_' + cfg.algRasterNm + '.tif' - else: - algRasterPath = None - if algorithmName is None: - algorithmName = cfg.algName - if useMacroclass is None: - useMacroclass = cfg.macroclassCheck - classificationOptions = [useLcs, useLcsAlgorithm, LCSLeaveUnclassified, cfg.algBandWeigths, cfg.algThrshld] - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' classification set: ' + str([algorithmName, img, sL, cfg.clssPth, useMacroclass, algRasterPath, 0, None, cfg.rasterCompression, bandSetNumber, classificationOptions])) - ok, cOut, mOut, opOut = self.runAlgorithm(algorithmName, img, sLMP, cfg.clssPth, useMacroclass, algRasterPath, 0, None, cfg.rasterCompression, bandSetNumber, classificationOptions) - if ok == 'Yes': - c = cfg.utls.addRasterLayer(cfg.clssPth) - cfg.utls.moveLayerTop(c) - cfg.uiUtls.updateBar(80) - # apply symbology - self.applyClassSymbology(c, cfg.macroclassCheck, cfg.qmlFl, sL) - # save qml file - cfg.utls.saveQmlStyle(c, cfg.osSCP.path.dirname(clssOut) + '/' + nm + '.qml') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '<<< CLASSIFICATION PERFORMED: ' + str(cfg.clssPth)) - ### calculate report - if reportCheck == 'Yes': - reportOut = cfg.osSCP.path.dirname(cfg.clssPth) + '/' + nm + cfg.reportNm - cfg.classRep.calculateClassificationReport(cfg.clssPth, 0, 'Yes', reportOut) - ### convert classification to vector - cfg.uiUtls.updateBar(85) - if vectorConversion == 'Yes': - cfg.uiUtls.updateBar(85, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion to vector. Please wait ...')) - vO = cfg.osSCP.path.dirname(cfg.clssPth) + '/' + nm + '.gpkg' - cfg.utls.multiProcessRasterToVector(rasterPath = cfg.clssPth, outputVectorPath = vO, dissolveOutput = 'Yes') - vl = cfg.utls.addVectorLayer(str(vO), cfg.utls.fileName(vO), 'ogr') - # apply symbology - self.applyClassSymbologyVector(vl, cfg.macroclassCheck, cfg.qmlFl, sL) - cfg.utls.addLayerToMap(vl) - cfg.uiUtls.updateBar(95) - ### copy signature raster - if algorithmFilesCheck == 'Yes': - if useLcs is None: - if cfg.ui.LC_signature_checkBox.isChecked() is True: - useLcs = 'Yes' - try: - c = cfg.utls.addRasterLayer(mOut) - if useLcs == 'Yes': - cfg.utls.rasterSymbolLCSAlgorithmRaster(c) - for r in opOut: - c = cfg.utls.addRasterLayer(r) - if useLcs == 'Yes': - cfg.utls.rasterSymbolLCSAlgorithmRaster(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'files copied') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr23() - ### ending - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.clssPth = None - ### band set check failed - else: - cfg.mx.msgErr6() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.clssPth = None - cfg.bst.rasterBandName() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'band set check failed') - else: - cfg.mx.msg18() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification no') - - # apply symbology to classification - def applyClassSymbology(self, classificationRaster, macroclassCheck, qmlFile, signatureList = None): - # qml symbology - if qmlFile == '': - if macroclassCheck == 'Yes': - signatureList = cfg.SCPD.createMCIDList() - if len(signatureList) == 0: - cfg.mx.msgWar19() - cfg.utls.rasterSymbol(classificationRaster, signatureList, macroclassCheck) - else: - try: - self.applyQmlStyle(classificationRaster, qmlFile) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # apply symbology to classification vector - def applyClassSymbologyVector(self, classificationVector, macroclassCheck, qmlFile, signatureList = None): - # qml symbology - if qmlFile == '': - if macroclassCheck == 'Yes': - signatureList = cfg.SCPD.createMCIDList() - if len(signatureList) == 0: - cfg.mx.msgWar19() - cfg.utls.vectorSymbol(classificationVector, signatureList, macroclassCheck) - else: - try: - self.applyQmlStyle(classificationRaster, qmlFile) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Apply qml style to classifications and previews - def applyQmlStyle(self, classLayer, stylePath): - # read path from project istance - p = cfg.qgisCoreSCP.QgsProject.instance() - cfg.qmlFl = p.readEntry('SemiAutomaticClassificationPlugin', 'qmlfile', '')[0] - classLayer.loadNamedStyle(cfg.qmlFl) - # refresh legend - if hasattr(classLayer, 'setCacheImage'): - classLayer.setCacheImage(None) - classLayer.triggerRepaint() - cfg.utls.refreshLayerSymbology(classLayer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification symbology applied with qml: ' + str(stylePath)) - - # calculate signatures for checked ROIs - def getSignatureList(self, bandSetNumber = None, algorithmName = None, color = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - refreshTable = None - for i in list(cfg.ROI_SCP_UID.values()): - if str(i) not in list(cfg.signIDs.values()) and cfg.signList['CHECKBOX_' + str(i)] == 2: - rId = cfg.utls.getIDByAttributes(cfg.shpLay, cfg.fldSCP_UID, str(i)) - cfg.utls.calculateSignature(cfg.shpLay, cfg.bandSetsList[bandSetNumber][8], rId, cfg.ROI_MC_ID[i], cfg.ROI_MC_Info[i], cfg.ROI_C_ID[i], cfg.ROI_C_Info[i], None, None, 'No', 'No', i) - refreshTable = 'Yes' - if refreshTable == 'Yes': - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - id = list(cfg.signIDs.values()) - if algorithmName is None: - algorithmName = cfg.algName - signatureList = [] - for i in id: - if cfg.signList['CHECKBOX_' + str(i)] == 2: - s = [] - s.append(cfg.signList['MACROCLASSID_' + str(i)]) - s.append(cfg.signList['MACROCLASSINFO_' + str(i)]) - s.append(cfg.signList['CLASSID_' + str(i)]) - s.append(cfg.signList['CLASSINFO_' + str(i)]) - s.append(cfg.signList['VALUES_' + str(i)]) - s.append(cfg.signList['WAVELENGTH_' + str(i)]) - if color is None: - s.append(cfg.signList['COLOR_' + str(i)]) - else: - s.append(None) - s.append(cfg.signList['COVMATRIX_' + str(i)]) - s.append(cfg.signList['LCS_MIN_' + str(i)]) - s.append(cfg.signList['LCS_MAX_' + str(i)]) - if len(cfg.signList['WAVELENGTH_' + str(i)]) == len(list(cfg.bandSetsList[bandSetNumber][4])): - if str(sorted(cfg.signList['WAVELENGTH_' + str(i)])) != str(sorted(cfg.bandSetsList[bandSetNumber][4])): - cfg.mx.msgWar9(cfg.signList['MACROCLASSID_' + str(i)], cfg.signList['CLASSID_' + str(i)]) - # check if signature has covariance matrix if maximum likelihood - if algorithmName == cfg.algML: - if cfg.signList['COVMATRIX_' + str(i)] == 'No': - cfg.mx.msgWar10(cfg.signList['MACROCLASSID_' + str(i)], cfg.signList['CLASSID_' + str(i)]) - else: - signatureList.append(s) - else: - signatureList.append(s) - else: - cfg.mx.msgErr24(cfg.signList['MACROCLASSID_' + str(i)], cfg.signList['CLASSID_' + str(i)], 'No') - self.trainSigCheck = 'No' - return None - if algorithmName == cfg.algMinDist: - s.append(cfg.signList['MD_THRESHOLD_' + str(i)]) - elif algorithmName == cfg.algML: - s.append(cfg.signList['ML_THRESHOLD_' + str(i)]) - elif algorithmName == cfg.algSAM: - s.append(cfg.signList['SAM_THRESHOLD_' + str(i)]) - if len(signatureList) > 0: - self.trainSigCheck = 'Yes' - else: - self.trainSigCheck = 'No' - return signatureList - - # create classification preview - def createPreview(self, point, algorithmRaster = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - try: - cfg.bandSetsList[bandSetNumber][8] - except: - cfg.mx.msg4() - cfg.ipt.refreshRasterLayer() - cfg.pntPrvw = None - if cfg.pntPrvw != None: - cfg.uiUtls.addProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '>>> PREVIEW click') - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - lastPrevX = cfg.lastPrev - # temp files - tPMD = cfg.utls.createTempRasterPath('tif') - pP = cfg.utls.createTempRasterPath('tif') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'point (X,Y) = (%s,%s)' % (cfg.pntPrvw.x() , cfg.pntPrvw.y())) - # signature list - sL = cfg.classTab.getSignatureList() - # for multiprocess - sLMP = cfg.classTab.getSignatureList(color = 'No') - # input image - if cfg.actionCheck == 'Yes' and self.trainSigCheck == 'Yes': - # check band set - ckB = 'Yes' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - cfg.uiUtls.updateBar(20) - if cfg.ui.LC_signature_checkBox.isChecked(): - useLcs = 'Yes' - else: - useLcs = None - if cfg.ui.LCS_class_algorithm_checkBox.isChecked(): - useLcsAlgorithm = 'Yes' - else: - useLcsAlgorithm = None - if cfg.ui.LCS_leave_unclassified_checkBox.isChecked(): - leaveUnclassified = 'Yes' - else: - leaveUnclassified = None - classificationOptions = [useLcs, useLcsAlgorithm, leaveUnclassified, cfg.algBandWeigths, cfg.algThrshld] - # compression - if int(cfg.prvwSz) <= 2000: - compress = 'No' - else: - compress = cfg.rasterCompression - if algorithmRaster == 'Yes': - tPMA = cfg.utls.createTempRasterPath('vrt') - else: - tPMA = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' classification set: ' + str([cfg.algName, cfg.bandSetsList[bandSetNumber][8], sL, pP, cfg.macroclassCheck, tPMA, int(cfg.prvwSz), point, compress, bandSetNumber, classificationOptions])) - ok, cOut, mOut, opOut = self.runAlgorithm(cfg.algName, cfg.bandSetsList[bandSetNumber][8], sLMP, pP, cfg.macroclassCheck, tPMA, int(cfg.prvwSz), point, compress, bandSetNumber, classificationOptions) - if ok == 'Yes': - if algorithmRaster == 'No': - r = cfg.utls.addRasterLayer(cOut) - cfg.lastPrev = r.name() - cfg.uiUtls.updateBar(80) - # apply symbology - self.applyClassSymbology(r, cfg.macroclassCheck, cfg.qmlFl, sL) - else: - r = cfg.utls.addRasterLayer(mOut) - cfg.lastPrev = r.name() - cfg.utls.rasterPreviewSymbol(r, cfg.algName) - cfg.uiUtls.updateBar(80) - # move to top - cfg.prevList.append(r) - cfg.utls.moveLayerTop(r) - cfg.iface.setActiveLayer(r) - # move previous preview to group - g = cfg.utls.groupIndex(cfg.grpNm) - if g is None: - g = cfg.utls.createGroup(cfg.grpNm) - preP = cfg.utls.selectLayerbyName(lastPrevX) - if preP is not None: - cfg.utls.moveLayer(preP, cfg.grpNm) - cfg.utls.setGroupVisible(g, False) - cfg.utls.setGroupExpanded(g, False) - cfg.show_preview_radioButton2.setChecked(True) - cfg.uiUtls.updateBar(100) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '<<< PREVIEW created: ' + str(pP)) - # enable Redo button - cfg.redoPreviewButton.setEnabled(True) - else: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'preview no') - else: - cfg.uiUtls.removeProgressBar() - if self.trainSigCheck == 'No': - cfg.mx.msg18() - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'preview no') - - # run classification algorithm - def runAlgorithm(self, algorithmName, imageName, signatureList, outputRasterPath, macroclassCheck = 'No', algRasterPath = None, previewSize = 0, previewPoint = None, compress = 'No', bandSetNumber = None, classificationOptions = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No', None, None, None - # if band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - # if masked bandset - if imageName == cfg.maskRasterNm: - bL = cfg.bndSetMaskList - bandNumberList = [] - for i in range(0, len(bL)): - bandNumberList.append(1) - else: - bS = cfg.bandSetsList[bandSetNumber][3] - bL = [] - bandNumberList = [] - for i in range(0, len(bS)): - bandNumberList.append(1) - bSS = cfg.utls.selectLayerbyName(bS[i], 'Yes') - try: - bPath = cfg.utls.layerSource(bSS) - bL.append(bPath) - except Exception as err: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - # if masked raster - if imageName == cfg.maskRasterNm: - iR = cfg.maskRstSrc - else: - r = cfg.utls.selectLayerbyName(imageName, 'Yes') - iR = cfg.utls.layerSource(r) - bL = [iR] - bandNumberList = [] - iBC = cfg.utls.getNumberBandRaster(iR) - for i in range(1, iBC+1): - bandNumberList.append(i) - # subset raster if preview - if previewSize > 0: - # open input with GDAL - rD = cfg.gdalSCP.Open(bL[0], cfg.gdalSCP.GA_ReadOnly) - if rD is None: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' None raster') - return 'No', None, None, None - # pixel size and origin from reference - rGT = rD.GetGeoTransform() - c = rD.RasterXSize - r = rD.RasterYSize - geoT = rD.GetGeoTransform() - tLX = geoT[0] - tLY = geoT[3] - pSX = geoT[1] - pSY = geoT[5] - # start and end pixels - sX = int((previewPoint.x() - tLX) / pSX) - int(previewSize / 2) - sY = int((tLY - previewPoint.y()) / cfg.np.sqrt(pSY ** 2)) - int(previewSize / 2) - lX = tLX + sX * pSX - tY = tLY + sY * pSY - if tY > tLY: - tY = tLY - if lX < tLX: - lX = tLX - eX = lX + previewSize * pSX - eY = tY + previewSize * pSY - lRX = tLX + c * pSX - lRY = tLY + r * pSY - if eX > lRX: - eX = lRX - if eY < lRY: - eY = lRY - xyRes = [pSX, cfg.np.sqrt(pSY ** 2), lX, tY, eX, eY] - tPMD = cfg.utls.createTempVirtualRaster(bL, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No', [float(lX), float(tY), float(eX), float(eY), 'Yes'], xyRes) - rD = None - else: - tPMD = cfg.utls.createTempVirtualRaster(bL, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' multiprocess set: ' + str([tPMD, signatureList, algorithmName, macroclassCheck, classificationOptions, cfg.bandSetsList[bandSetNumber][6]])) - # process calculation - o = cfg.utls.multiProcessRaster(rasterPath = tPMD, signatureList = signatureList, functionBand = 'Yes', functionRaster = cfg.utls.classificationMultiprocess, algorithmName = algorithmName, outputNoDataValue = -999, macroclassCheck = macroclassCheck,classificationOptions = classificationOptions, functionBandArgument = cfg.multiAddFactorsVar, functionVariable = cfg.bandSetsList[bandSetNumber][6], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification'), virtualRaster = 'Yes', compress = compress, compressFormat = 'LZW') - if o == 'No': - return 'No', None, None, None - # output rasters - outputClasses, outputAlgs, outSigDict = o - # virtual raster - vrtR = 'No' - if outputRasterPath.lower().endswith('.vrt'): - vrtR = 'Yes' - tmpList = [] - dirPath = cfg.osSCP.path.dirname(outputRasterPath) - fCount = 1 - for tR in outputClasses: - oTR = dirPath + '/' + cfg.utls.fileNameNoExt(outputRasterPath) + '_%02d' % (fCount,) + '.tif' - fCount = fCount + 1 - tmpList.append(oTR) - cfg.shutilSCP.move(tR, oTR) - cfg.utls.createVirtualRaster2(inputRasterList = tmpList, output = outputRasterPath, NoDataValue = 'Yes') - cOut = outputRasterPath - else: - tPMDC = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = outputClasses, output = tPMDC, NoDataValue = 'Yes') - # mosaic rasters - if previewSize > 0: - cOut = tPMDC - elif vrtR == 'No': - gcopy = cfg.utls.GDALCopyRaster(tPMDC, outputRasterPath, 'GTiff', compress, 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1', additionalParams = '-ot Int16') - cOut = outputRasterPath - for oC in outputClasses: - try: - cfg.osSCP.remove(oC) - except: - pass - opOut = [] - if algRasterPath is not None: - if vrtR == 'Yes': - tmpList = [] - dirPath = cfg.osSCP.path.dirname(algRasterPath) - fCount = 1 - for tR in outputAlgs: - oTR = dirPath + '/' + cfg.utls.fileNameNoExt(algRasterPath) + '_%02d' % (fCount,) + '.tif' - algRasterPath = dirPath + '/' + cfg.utls.fileNameNoExt(algRasterPath) + '.vrt' - fCount = fCount + 1 - tmpList.append(oTR) - cfg.shutilSCP.move(tR, oTR) - cfg.utls.createVirtualRaster2(inputRasterList = tmpList, output = algRasterPath, NoDataValue = 'Yes') - else: - tPMDA = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = outputAlgs, output = tPMDA, NoDataValue = 'Yes') - gcopy = cfg.utls.GDALCopyRaster(tPMDA, algRasterPath, 'GTiff', compress, 'LZW') - for oA in outputAlgs: - try: - cfg.osSCP.remove(oA) - except: - pass - rOBaseNm = cfg.osSCP.path.dirname(outputRasterPath) - for s in range(0, len(signatureList)): - sLR = str(signatureList[s][0]) + '_' + str(signatureList[s][2]) - if vrtR == 'Yes': - tmpList = [] - # base name - nm = cfg.utls.fileNameNoExt(outputRasterPath) - opO = cfg.osSCP.path.dirname(outputRasterPath) + '/' + nm + '_' + cfg.sigRasterNm + '_' + sLR + '.vrt' - dirPath = cfg.osSCP.path.dirname(opO) - fCount = 1 - for tR in outSigDict[sLR]: - oTR = dirPath + '/' + cfg.utls.fileNameNoExt(opO) + '_%02d' % (fCount,) + '.tif' - fCount = fCount + 1 - tmpList.append(oTR) - cfg.shutilSCP.move(tR, oTR) - cfg.utls.createVirtualRaster2(inputRasterList = tmpList, output = opO, NoDataValue = 'Yes') - opOut.append(opO) - else: - try: - tPMDS = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = outSigDict[sLR], output = tPMDS, NoDataValue = 'Yes') - # base name - nm = cfg.utls.fileNameNoExt(outputRasterPath) - opO = rOBaseNm + '/' + nm + '_' + cfg.sigRasterNm + '_' + sLR + '.tif' - gcopy = cfg.utls.GDALCopyRaster(tPMDS, opO, 'GTiff', compress, 'LZW') - opOut.append(opO) - except: - pass - else: - for oA in outputAlgs: - try: - cfg.osSCP.remove(oA) - except: - pass - for s in range(0, len(signatureList)): - sLR = str(signatureList[s][0]) + '_' + str(signatureList[s][2]) - try: - for oS in outSigDict[sLR] : - cfg.osSCP.remove(oS) - except: - pass - # create raster table (removed because of some issues) - #cfg.utls.createRasterTable(outputRasterPath, 1, signatureList) - return 'Yes', cOut, algRasterPath, opOut - - # set variable for macroclass classification - def macroclassCheckbox(self): - if cfg.ui.macroclass_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.regConsiderMacroclass, 'Yes') - cfg.ui.class_checkBox.blockSignals(True) - cfg.ui.class_checkBox.setCheckState(0) - cfg.ui.class_checkBox.blockSignals(False) - else: - cfg.utls.setQGISRegSetting(cfg.regConsiderMacroclass, 'No') - cfg.ui.class_checkBox.blockSignals(True) - cfg.ui.class_checkBox.setCheckState(2) - cfg.ui.class_checkBox.blockSignals(False) - cfg.macroclassCheck = cfg.sets.getQGISRegSetting(cfg.regConsiderMacroclass, 'No') - # check signature intersection - intersect1 = cfg.LCSignT.checkIntersections() - cfg.LCSignT.higlightRowsByID(intersect1) - intersect2 = cfg.spSigPlot.checkIntersections() - cfg.spSigPlot.higlightRowsByID(intersect2) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " checkbox set: " + str(cfg.macroclassCheck)) - - # set variable for class classification - def classCheckbox(self): - if cfg.ui.class_checkBox.isChecked() is True: - cfg.ui.macroclass_checkBox.setCheckState(0) - else: - cfg.ui.macroclass_checkBox.setCheckState(2) - - # set variable for LC signature - def LCSignature_Checkbox(self): - if cfg.ui.LC_signature_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.regLCSignature, 'Yes') - else: - cfg.utls.setQGISRegSetting(cfg.regLCSignature, 'No') - cfg.LCsignatureCheckBox = cfg.sets.getQGISRegSetting(cfg.regLCSignature, 'No') - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.LCsignatureCheckBox)) - - # set variable for mask - def maskCheckbox(self): - if cfg.ui.mask_checkBox.isChecked() is True: - m = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a mask shapefile'), '', 'Shapefile (*.shp)') - if len(m) > 0: - cfg.mskFlPath = m - cfg.ui.mask_lineEdit.setText(str(cfg.mskFlPath)) - cfg.mskFlState = 2 - else: - cfg.mskFlState = 2 - if len(cfg.ui.mask_lineEdit.text()) == 0: - cfg.ui.mask_checkBox.setCheckState(0) - else: - cfg.mskFlState = 0 - cfg.utls.writeProjectVariable('maskFilePath', str(cfg.mskFlPath)) - cfg.utls.writeProjectVariable('maskFileState', str(cfg.mskFlState)) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.mskFlState)) - - # Reset qml style path - def resetQmlStyle(self): - p = cfg.qgisCoreSCP.QgsProject.instance() - p.writeEntry('SemiAutomaticClassificationPlugin', 'qmlfile', '') - cfg.ui.qml_lineEdit.setText('') - cfg.qmlFl = '' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reset qml') - - # Reset mask path - def resetMask(self): - cfg.mskFlPath = '' - cfg.mskFlState = 0 - cfg.utls.writeProjectVariable('maskFilePath', str(cfg.mskFlPath)) - cfg.utls.writeProjectVariable('maskFileState', str(cfg.mskFlState)) - cfg.ui.mask_lineEdit.setText(str(cfg.mskFlPath)) - self.setMaskCheckbox() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reset mask') - - def setMaskCheckbox(self): - cfg.ui.mask_checkBox.blockSignals(True) - cfg.ui.mask_checkBox.setCheckState(int(cfg.mskFlState)) - cfg.ui.mask_checkBox.blockSignals(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "mask checkbox") - - # Select qml style for classifications and previews - def selectQmlStyle(self): - cfg.qmlFl = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a qml style'), '', 'Style (*.qml)') - # write path to project istance - p = cfg.qgisCoreSCP.QgsProject.instance() - p.writeEntry('SemiAutomaticClassificationPlugin', 'qmlfile', cfg.qmlFl) - cfg.ui.qml_lineEdit.setText(cfg.qmlFl) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'qml file: ' + str(cfg.qmlFl)) diff --git a/maininterface/classreportTab.py b/maininterface/classreportTab.py deleted file mode 100644 index 74dd530..0000000 --- a/maininterface/classreportTab.py +++ /dev/null @@ -1,181 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassReportTab: - - def __init__(self): - pass - - # calculate classification report - def calculateClassificationReport(self, classificationPath, NoDataValue = None, batch = 'No', rasterOutput = None): - if batch == 'No': - r = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save classification report'), '', '*.csv', 'csv') - else: - r = rasterOutput - if r is not False: - if r.lower().endswith('.csv'): - pass - else: - r = r + '.csv' - cfg.reportPth = cfg.utls.createTempRasterPath('csv') - try: - clssRstrSrc = str(classificationPath) - ck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - ck = 'No' - if ck == 'No': - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(r)) - # open input with GDAL - if cfg.osSCP.path.isfile(clssRstrSrc): - rD = cfg.gdalSCP.Open(clssRstrSrc, cfg.gdalSCP.GA_ReadOnly) - else: - return 'No' - # pixel size - cRG = rD.GetGeoTransform() - cRPX = abs(cRG[1]) - cRPY = abs(cRG[5]) - # check projections - cRP = rD.GetProjection() - cRSR = cfg.osrSCP.SpatialReference(wkt=cRP) - un = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unknown') - if cRSR.IsProjected: - un = cRSR.GetAttrValue('unit') - else: - pass - # No data value - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox.isChecked() is True: - nD = cfg.ui.nodata_spinBox_2.value() - else: - nD = None - rD = None - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = clssRstrSrc, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = nD, progressMessage = 'UniqueVal ', deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - sumVal = cfg.np.append(sumVal, ar[0][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - rasterBandUniqueVal = {} - for v in range(0, len(values)): - if values[v] != nD: - try: - rasterBandUniqueVal[values[v]] = rasterBandUniqueVal[values[v]] + sumVal[v] - except: - rasterBandUniqueVal[values[v]] = sumVal[v] - sumTot = sum(rasterBandUniqueVal.values()) - # save combination to table - l = open(cfg.reportPth, 'w') - if 'degree' not in un: - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Class') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Percentage %') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area [' + un + '^2]') + str('\n') - else: - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Class') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Percentage %') + str('\n') - l.write(t) - for i in sorted(rasterBandUniqueVal): - if str(i) == 'nan': - pass - else: - p = (float(rasterBandUniqueVal[i]) /float(sumTot)) * 100 - if 'degree' not in un: - t = cfg.reSCP.sub(r'\.0$', '', str(i)) + ' ' + cfg.reSCP.sub(r'\.0$', '', str(rasterBandUniqueVal[i])) + ' ' + str(p) + ' ' + cfg.reSCP.sub(r'\.0$', '', str(round(rasterBandUniqueVal[i] * cRPX * cRPY, 5))) + str('\n') - else: - t = cfg.reSCP.sub(r'\.0$', '', str(i)) + ' ' + cfg.reSCP.sub(r'\.0$', '', str(rasterBandUniqueVal[i])) + ' ' + str(p) + str('\n') - l.write(t) - l.close() - cfg.uiUtls.updateBar(80) - # open csv - try: - f = open(cfg.reportPth) - if cfg.osSCP.path.isfile(cfg.reportPth): - reportTxt = f.read() - cfg.ui.report_textBrowser.setText(str(reportTxt)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' report calculated') - try: - cfg.shutilSCP.copy(cfg.reportPth, r) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' report saved') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.ui.toolBox_class_report.setCurrentIndex(1) - - # calculate classification report if click on button - def calculateClassReport(self): - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " calculate classification report") - c = str(cfg.ui.classification_report_name_combo.currentText()) - r = cfg.utls.selectLayerbyName(c, 'Yes') - if r is not None: - ql = cfg.utls.layerSource(r) - self.calculateClassificationReport(ql) - else: - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - \ No newline at end of file diff --git a/maininterface/classtovectorTab.py b/maininterface/classtovectorTab.py deleted file mode 100644 index ec245f7..0000000 --- a/maininterface/classtovectorTab.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassToVectorTab: - - def __init__(self): - pass - - # convert classification to vector - def convertClassificationToVectorAction(self): - self.convertClassificationToVector() - - # convert classification to vector - def convertClassificationToVector(self, batch = 'No', inputRaster = None, outputVector = None, dissolve = None, useCode = None): - if batch == 'No': - self.clssfctnNm = str(cfg.ui.classification_vector_name_combo.currentText()) - i = cfg.utls.selectLayerbyName(self.clssfctnNm, 'Yes') - try: - classificationPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - out = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save vector output'), '', '*.gpkg', 'gpkg') - else: - if cfg.osSCP.path.isfile(inputRaster): - classificationPath = inputRaster - else: - return 'No' - out = outputVector - if out is not False: - if out.lower().endswith('.gpkg'): - pass - else: - out = out + '.gpkg' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(out)) - n = cfg.utls.fileName(out) - cfg.uiUtls.updateBar(20) - if str(cfg.ui.class_macroclass_comboBox.currentText()) == cfg.fldMacroID_class_def: - mc = 'Yes' - sL = cfg.SCPD.createMCIDList() - else: - mc = 'No' - sL = cfg.classTab.getSignatureList() - if dissolve is None: - if cfg.ui.dissolve_output_checkBox.isChecked() is True: - dissolve = 'Yes' - else: - dissolve = 'No' - res = cfg.utls.multiProcessRasterToVector(rasterPath = classificationPath, outputVectorPath = out, dissolveOutput = dissolve) - cfg.uiUtls.updateBar(80) - if res != 'No': - vl = cfg.utls.addVectorLayer(out, cfg.utls.fileName(out), 'ogr') - if useCode is None or useCode == 'Yes': - if cfg.ui.use_class_code_checkBox.isChecked() is True or useCode == 'Yes': - cfg.utls.vectorSymbol(vl, sL, mc) - # save qml file - nm = cfg.osSCP.path.splitext(n)[0] - cfg.utls.saveQmlStyle(vl, cfg.osSCP.path.dirname(out) + '/' + nm + '.qml') - cfg.uiUtls.updateBar(100) - cfg.utls.addLayerToMap(vl) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() diff --git a/maininterface/clipmultiplerasters.py b/maininterface/clipmultiplerasters.py deleted file mode 100644 index 5c53cf1..0000000 --- a/maininterface/clipmultiplerasters.py +++ /dev/null @@ -1,464 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClipMultipleRasters: - - def __init__(self): - pass - - # add rubber band - def addRubberBandPolygon(self, pointUL, pointLR): - try: - self.clearCanvasPoly() - except: - pass - self.rbbrBndPol = cfg.qgisGuiSCP.QgsRubberBand(cfg.cnvs, cfg.qgisCoreSCP.QgsWkbTypes.LineGeometry) - pointF = cfg.QtCoreSCP.QPointF() - polF = cfg.QtGuiSCP.QPolygonF() - pointF.setX(pointUL.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - pointF.setX(pointLR.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - pointF.setX(pointLR.x()) - pointF.setY(pointLR.y()) - polF.append(pointF) - pointF.setX(pointUL.x()) - pointF.setY(pointLR.y()) - polF.append(pointF) - pointF.setX(pointUL.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - g = cfg.qgisCoreSCP.QgsGeometry().fromQPolygonF(polF) - self.rbbrBndPol.setToGeometry(g, None) - clr = cfg.QtGuiSCP.QColor("#ff0000") - clr.setAlpha(50) - self.rbbrBndPol.setFillColor(clr) - self.rbbrBndPol.setWidth(3) - - # clear canvas - def clearCanvasPoly(self): - self.rbbrBndPol.reset() - cfg.cnvs.refresh() - - # clip multiple rasters action - def clipRastersAction(self): - self.clipRasters() - - # clip multiple rasters - def clipRasters(self, batch = 'No', outputDirectory = None, shapefilePath = None, bandSetNumber = None, vectorField = None): - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_2.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - UX = '' - UY = '' - LX = '' - LY = '' - # creation of the required table of reclassification - rT = [] - # st variable - st = 'No' - if batch == 'No': - oD = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory where to save clipped rasters')) - else: - oD = outputDirectory - if len(oD) == 0: - return 'No' - if cfg.ui.shapefile_checkBox.isChecked() is True: - # use shape - uS = 1 - sN = cfg.ui.shapefile_comboBox.currentText() - sL = cfg.utls.selectLayerbyName(sN) - try: - s = cfg.utls.layerSource(sL) - if cfg.ui.vector_field_checkBox.isChecked() is True: - uSF = 1 - if vectorField is None: - vectorField = cfg.ui.class_field_comboBox_3.currentText() - else: - uSF = 0 - except Exception as err: - cfg.mx.msgErr11() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - elif cfg.ui.temporary_ROI_checkBox.isChecked() is True: - # use shape - uS = 1 - uSF = 0 - if cfg.lstROI is not None: - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - cfg.utls.createSCPVector(cfg.lstROI.crs(), tSHP, format = 'GPKG') - tSS = cfg.utls.addVectorLayer(tSHP) - cfg.utls.copyFeatureToLayer(cfg.lstROI, 1, tSS) - s = tSHP - else: - cfg.mx.msgErr11() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR: no vector' ) - return 'No' - else: - uS = 0 - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - # No data value - noDt = cfg.ui.nodata_spinBox.value() - if len(oD) > 0: - cfg.uiUtls.updateBar(20) - cfg.utls.makeDirectory(oD) - outputName = cfg.ui.output_clip_name_lineEdit.text() - if len(outputName) > 0: - outputName = str(outputName.encode('ascii','replace'))[2:-1] - else: - outputName = '' - # no shapefile - if uS == 0: - UX = cfg.ui.UX_lineEdit.text() - UY = cfg.ui.UY_lineEdit.text() - LX = cfg.ui.LX_lineEdit.text() - LY = cfg.ui.LY_lineEdit.text() - if batch == 'No': - try: - self.clearCanvasPoly() - UL = cfg.qgisCoreSCP.QgsPointXY(float(UX), float(UY)) - LR = cfg.qgisCoreSCP.QgsPointXY(float(LX), float(LY)) - LRP = UL - ULP = LR - UX = str(ULP.x()) - UY = str(ULP.y()) - LX = str(LRP.x()) - LY = str(LRP.y()) - if float(UX) > float(LX): - UX = str(LRP.x()) - LX = str(ULP.x()) - if float(UY) < float(LY): - UY = str(LRP.y()) - LY = str(ULP.y()) - except: - pass - else: - try: - if float(UX) > float(LX): - tUX = UX - UX = str(LX) - LX = str(tUX) - if float(UY) < float(LY): - tUY = UY - UY = str(LY) - LY = str(tUY) - except: - pass - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - rT = cfg.bndSetLst - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters to be clipped' + str(rT)) - if len(rT) == 0: - cfg.mx.msgWar15() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - else: - cfg.mx.msgWar15() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - else: - bi = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(bi) - except Exception as err: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if uS == 1: - rT = cfg.utls.rasterToBands(bPath, cfg.tmpDir, outputName = cfg.utls.fileName(cfg.bandSetsList[bandSetNumber][8]), virtual = 'No') - else: - rT = cfg.utls.rasterToBands(bPath, cfg.tmpDir, outputName = cfg.utls.fileName(cfg.bandSetsList[bandSetNumber][8]), virtual = 'Yes') - cfg.uiUtls.updateBar(50) - # using coordinates - if uS == 0 and len(UX) > 0 and len(UY) > 0 and len(LX) > 0 and len(LY) > 0: - for l in rT: - f = oD + '/' + outputName + '_' + cfg.utls.fileNameNoExt(l) + '.tif' - bbList = [l] - pCrs = cfg.utls.getQGISCrs() - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(pCrs.toWkt()) - eCrs = cfg.utls.getCrsGDAL(l) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - UX1, UY1 = cfg.utls.projectPointCoordinatesOGR(float(UX), float(UY), rEPSG, EPSG) - LX1, LY1 = cfg.utls.projectPointCoordinatesOGR(float(LX), float(LY), rEPSG, EPSG) - else: - UX1 = UX - UY1 = UY - LX1 = LX - LY1 = LY - bandNumberList = [1] - vrtCheck = cfg.utls.createTempVirtualRaster(bbList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes', [float(UX1), float(UY1), float(LX1), float(LY1)]) - cfg.utls.GDALCopyRaster(vrtCheck, f, 'GTiff', cfg.rasterCompression, 'LZW') - cfg.utls.addRasterLayer(f) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters clipped' ) - # using vector - elif uS == 1: - dT = cfg.utls.getTime() - # vector EPSG - if 'Polygon?crs=' in str(s) or 'memory?geometry=' in str(s) or '(memory)' in str(s): - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - try: - s = cfg.utls.saveMemoryLayerToShapefile(sL, tSHP, format = 'GPKG') - except: - s = cfg.utls.saveMemoryLayerToShapefile(s, tSHP, format = 'GPKG') - s = cfg.utls.layerSource(s) - vCrs = cfg.utls.getCrsGDAL(tSHP) - elif 'QgsVectorLayer' in str(s): - # temporary layer - tLN = cfg.subsTmpROI + dT + '.shp' - tLP = cfg.tmpDir + '/' + dT + tLN - # get layer crs - crs = cfg.utls.getCrsGDAL(s) - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP) - mL = cfg.utls.addVectorLayer(tLP , tLN, 'ogr') - f = cfg.qgisCoreSCP.QgsFeature() - for f in s.getFeatures(): - ID = f.id() - # copy ROI to temp shapefile - cfg.utls.copyFeatureToLayer(s, ID, mL) - s = tLP - vCrs = cfg.utls.getCrsGDAL(s) - else: - vCrs = cfg.utls.getCrsGDAL(s) - # in case of reprojection - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileNameNoExt(s) + '.shp' - # band list - bbList = [] - for l in rT: - bbList.append(l) - tRxs = cfg.utls.createTempRasterPath('tif') - # check projection - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - rP = cfg.utls.getCrsGDAL(l) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rP) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rP: ' + str(rP)) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' vCrs: ' + str(vCrs)) - vect = s - if vEPSG.IsSame(rEPSG) != 1: - if cfg.osSCP.path.isfile(reprjShapefile): - vect = reprjShapefile - else: - try: - cfg.utls.repojectShapefile(s, vEPSG, reprjShapefile, rEPSG) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr43() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - vect = reprjShapefile - # if iterate through field - if uSF == 1: - values = cfg.utls.getVectorFieldfValues(vect, vectorField) - if values == 'No': - cfg.mx.msgErr43() - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - for v in values: - check = cfg.utls.vectorToRaster(cfg.emptyFN, vect, cfg.emptyFN, tRxs, l, None, 'GTiff', 1, vectorField + '=' + str(v)) - if check != 'No': - outList = cfg.utls.clipRasterByRaster(bbList, tRxs, oD, 'GTiff', noDt, outputNameRoot = outputName + vectorField + '_' + str(v) + '_', compress = cfg.rasterCompression) - try: - cfg.osSCP.remove(tRxs) - except: - pass - try: - for oU in outList: - cfg.utls.addRasterLayer(oU) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters clipped' ) - else: - st = 'Yes' - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # without field iteration - else: - check = cfg.utls.vectorToRaster(cfg.emptyFN, vect, cfg.emptyFN, tRxs, l, None, 'GTiff', 1) - if check != 'No': - outList = cfg.utls.clipRasterByRaster(bbList, tRxs, oD, 'GTiff', noDt, outputNameRoot = outputName + '_', compress = cfg.rasterCompression) - try: - cfg.osSCP.remove(tRxs) - except: - pass - try: - for oU in outList: - cfg.utls.addRasterLayer(oU) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters clipped' ) - else: - st = 'Yes' - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return 'No' - if st != 'Yes': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - - # Activate pointer - def pointerActive(self): - # connect to click - t = cfg.clipMultiP - cfg.cnvs.setMapTool(t) - px = cfg.QtGuiSCP.QPixmap(":/pointer/icons/pointer/ROI_pointer.svg") - c = cfg.QtGuiSCP.QCursor(px) - cfg.cnvs.setCursor(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "pointer active") - - # left click pointer - def pointerLeftClick(self, point): - self.pointerClickUL(point) - - # right click pointer - def pointerRightClick(self, point): - self.pointerClickLR(point) - - # set coordinates - def pointerClickLR(self, point): - cfg.ui.LX_lineEdit.setText(str(point.x())) - cfg.ui.LY_lineEdit.setText(str(point.y())) - self.showArea() - - # set coordinates - def pointerClickUL(self, point): - cfg.ui.UX_lineEdit.setText(str(point.x())) - cfg.ui.UY_lineEdit.setText(str(point.y())) - self.showArea() - - # show area - def showArea(self): - try: - self.addRubberBandPolygon(cfg.qgisCoreSCP.QgsPointXY(float(cfg.ui.UX_lineEdit.text()), float(cfg.ui.UY_lineEdit.text())), cfg.qgisCoreSCP.QgsPointXY(float(cfg.ui.LX_lineEdit.text()), float(cfg.ui.LY_lineEdit.text()))) - except: - pass - - # refresh shape and training list - def refreshShapeClip(self): - cfg.utls.refreshVectorLayer() - - # show hide area radio button - def showHideArea(self): - try: - if cfg.ui.show_area_radioButton_3.isChecked(): - self.showArea() - else: - self.clearCanvasPoly() - except: - pass - - # checkbox changed - def checkboxShapeChanged(self): - cfg.ui.shapefile_checkBox.blockSignals(True) - cfg.ui.temporary_ROI_checkBox.blockSignals(True) - if cfg.ui.shapefile_checkBox.isChecked(): - if cfg.ui.temporary_ROI_checkBox.isChecked(): - cfg.ui.temporary_ROI_checkBox.setCheckState(0) - cfg.ui.shapefile_checkBox.blockSignals(False) - cfg.ui.temporary_ROI_checkBox.blockSignals(False) - - # checkbox changed - def checkboxTempROIChanged(self): - cfg.ui.shapefile_checkBox.blockSignals(True) - cfg.ui.temporary_ROI_checkBox.blockSignals(True) - if cfg.ui.temporary_ROI_checkBox.isChecked(): - if cfg.ui.shapefile_checkBox.isChecked(): - cfg.ui.shapefile_checkBox.setCheckState(0) - cfg.ui.shapefile_checkBox.blockSignals(False) - cfg.ui.temporary_ROI_checkBox.blockSignals(False) - - # reference layer name - def referenceLayerName(self): - referenceLayer3 = cfg.ui.shapefile_comboBox.currentText() - cfg.ui.class_field_comboBox_3.clear() - l = cfg.utls.selectLayerbyName(referenceLayer3) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != "string": - cfg.dlg.class_field_combo_3(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "reference layer name: " + str(referenceLayer3)) - \ No newline at end of file diff --git a/maininterface/clipmultiplerasterspointer.py b/maininterface/clipmultiplerasterspointer.py deleted file mode 100644 index cc93251..0000000 --- a/maininterface/clipmultiplerasterspointer.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClipMultiplerastersPointer(QgsMapTool): - - rightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - leftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.rightClicked.emit(pnt) - else: - self.leftClicked.emit(pnt) diff --git a/maininterface/cloudmasking.py b/maininterface/cloudmasking.py deleted file mode 100644 index ebe8b20..0000000 --- a/maininterface/cloudmasking.py +++ /dev/null @@ -1,237 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class CloudMasking: - - def __init__(self): - pass - - - # value text changed - def textChanged(self): - self.checkValueList() - - # check value list - def checkValueList(self): - try: - # class value list - valueList = cfg.utls.textToValueList(cfg.ui.cloud_mask_classes_lineEdit.text()) - cfg.ui.cloud_mask_classes_lineEdit.setStyleSheet('color : green') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - except Exception as err: - cfg.ui.cloud_mask_classes_lineEdit.setStyleSheet('color : red') - valueList = [] - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return valueList - - - # mask band sets - def maskAction(self): - self.cloudMaskingBandSet() - - # cloud masking - def cloudMaskingBandSet(self, batch = 'No', bandSetNumber = None, inputClassification = None, outputDirectory = None): - # class value list - valueList = self.checkValueList() - if len(valueList) > 0: - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_9.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if inputClassification is None: - clssfctnNm = cfg.ui.classification_name_combo_4.currentText() - clss = cfg.utls.selectLayerbyName(clssfctnNm, 'Yes') - inputClassification = cfg.utls.layerSource(clss) - if batch == 'No': - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - else: - o = outputDirectory - if len(o) > 0: - if batch == 'No': - cfg.uiUtls.addProgressBar() - bndSetSources = [] - # create list of rasters - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar29() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - bndSetIf = 'Yes' - else: - ckB = cfg.utls.checkImageBandSet(bandSetNumber) - bndSetIf = 'No' - if ckB == 'Yes': - bndSetSources.append(cfg.bndSetLst) - if len(cfg.bndSetLst) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(10) - rCrs = cfg.utls.getCrsGDAL(cfg.bndSetLst[0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(20) - cfg.utls.makeDirectory(o) - eCrs = cfg.utls.getCrsGDAL(inputClassification) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - nD = cfg.utls.imageNoDataValue(inputClassification) - if nD is None: - nD = cfg.NoDataVal - #tPMD = cfg.utls.createTempRasterPath('tif') - #cfg.utls.GDALReprojectRaster(inputClassification, tPMD, 'GTiff', None, 'EPSG:' + str(rEPSG), '-ot Float32 -dstnodata ' + str(nD)) - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(inputClassification, tPMD, str(rCrs)) - cfg.mx.msg9() - if cfg.osSCP.path.isfile(tPMD): - inputClassification = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - if cfg.ui.cloud_buffer_checkBox.isChecked() is True: - size = cfg.ui.cloud_buffer_spinBox.value() - struct = cfg.utls.create3x3Window() - input = inputClassification - ndM = cfg.utls.imageNoDataValue(input) - dType = cfg.utls.getRasterDataTypeName(input) - for s in range(0, size): - tPMD = cfg.utls.createTempRasterPath('vrt') - # process calculation - oP = cfg.utls.multiProcessRaster(rasterPath = input, functionBand = 'No', functionRaster = cfg.utls.rasterDilation, outputRasterList = [tPMD], functionBandArgument = struct, functionVariable = valueList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Dilation '), virtualRaster = 'Yes', compress = 'No', outputNoDataValue = ndM, dataType = dType, boundarySize = 3) - input = tPMD - if cfg.osSCP.path.isfile(tPMD): - inputClassification = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error") - return 'No' - # No data value - NoDataVal = cfg.ui.nodata_spinBox_11.value() - nD = NoDataVal - outputName = cfg.ui.mask_output_name_lineEdit.text() - if len(outputName) > 0: - outputName = str(outputName.encode('ascii','replace'))[2:-1] + "_" - cfg.uiUtls.updateBar(40) - # create functions - bList = [] - bandNumberList = [] - bList.append(inputClassification) - bandNumberList.append(1) - outputList = [] - argumentList = [] - variableList = [] - varList = [] - varList.append('"im0"') - for x in range(1, len(cfg.bndSetLst) + 1): - varList.append('"im' + str(x)+ '"') - for x in range(1, len(cfg.bndSetLst) + 1): - if bndSetIf == 'Yes': - bList.append(cfg.bndSetLst[x-1]) - bandNumberList.append(1) - else: - bList.append(cfg.bndSetLst[x]) - bandNumberList.append(x) - rstrOut = o + '/' + outputName + cfg.utls.fileNameNoExt(cfg.bndSetLst[x-1]) + '.tif' - outputList.append(rstrOut) - # function - e = '' - end = '' - for c in valueList: - e = e + 'cfg.np.where("im0" == ' + str(c) + ', cfg.np.nan, ' - end = end + ')' - e = e + '"im' + str(x) + '"' + end - argumentList.append(e) - variableList.append(varList) - # create virtual raster - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes') - # open input with GDAL - rD = cfg.gdalSCP.Open(vrtCheck, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, outputList, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = 'Yes', compressFormat = 'LZW') - rD = None - # process - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = outputList, nodataValue = nD, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Mask'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW', parallel = cfg.parallelRaster, skipSingleBand = 'Yes') - cfg.cnvs.setRenderFlag(False) - for rOut in outputList: - if cfg.osSCP.path.isfile(rOut): - # add raster to layers - cfg.utls.addRasterLayer(rOut) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - \ No newline at end of file diff --git a/maininterface/clusteringTab.py b/maininterface/clusteringTab.py deleted file mode 100644 index bb85e5f..0000000 --- a/maininterface/clusteringTab.py +++ /dev/null @@ -1,1308 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClusteringTab: - - def __init__(self): - pass - - # kmeans radioButton button changed - def radioKmeansChanged(self): - cfg.ui.kmeans_radioButton.blockSignals(True) - cfg.ui.isodata_radioButton.blockSignals(True) - cfg.ui.kmeans_radioButton.setChecked(True) - cfg.ui.isodata_radioButton.setChecked(False) - cfg.ui.kmeans_radioButton.blockSignals(False) - cfg.ui.isodata_radioButton.blockSignals(False) - - # ISODATA radioButton button changed - def radioIsodataChanged(self): - cfg.ui.kmeans_radioButton.blockSignals(True) - cfg.ui.isodata_radioButton.blockSignals(True) - cfg.ui.isodata_radioButton.setChecked(True) - cfg.ui.kmeans_radioButton.setChecked(False) - cfg.ui.kmeans_radioButton.blockSignals(False) - cfg.ui.isodata_radioButton.blockSignals(False) - - # miniumum distance radioButton button changed - def radioMinDistChanged(self): - cfg.ui.min_distance_radioButton.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton.blockSignals(True) - cfg.ui.min_distance_radioButton.setChecked(True) - cfg.ui.spectral_angle_map_radioButton.setChecked(False) - cfg.ui.min_distance_radioButton.blockSignals(False) - cfg.ui.spectral_angle_map_radioButton.blockSignals(False) - - # SAM radioButton button changed - def radioSAMChanged(self): - cfg.ui.min_distance_radioButton.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton.setChecked(True) - cfg.ui.min_distance_radioButton.setChecked(False) - cfg.ui.min_distance_radioButton.blockSignals(False) - cfg.ui.spectral_angle_map_radioButton.blockSignals(False) - thresh = cfg.ui.thresh_doubleSpinBox.value() - if thresh > 90: - cfg.mx.msg11() - cfg.ui.thresh_doubleSpinBox.setValue(90) - - # kmean_minmax_radioButton button changed - def radiokmean_minmaxChanged(self): - cfg.ui.kmean_minmax_radioButton.blockSignals(True) - cfg.ui.kmean_siglist_radioButton.blockSignals(True) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(True) - cfg.ui.kmean_minmax_radioButton.setChecked(True) - cfg.ui.kmean_siglist_radioButton.setChecked(False) - cfg.ui.kmean_randomsiglist_radioButton.setChecked(False) - cfg.ui.kmean_minmax_radioButton.blockSignals(False) - cfg.ui.kmean_siglist_radioButton.blockSignals(False) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(False) - - # kmean_siglist_radioButton button changed - def radiokmean_siglistChanged(self): - cfg.ui.kmean_minmax_radioButton.blockSignals(True) - cfg.ui.kmean_siglist_radioButton.blockSignals(True) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(True) - cfg.ui.kmean_minmax_radioButton.setChecked(False) - cfg.ui.kmean_siglist_radioButton.setChecked(True) - cfg.ui.kmean_randomsiglist_radioButton.setChecked(False) - cfg.ui.kmean_minmax_radioButton.blockSignals(False) - cfg.ui.kmean_siglist_radioButton.blockSignals(False) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(False) - - # kmean_randomsiglist_radioButton button changed - def radiokmean_randomsiglistChanged(self): - cfg.ui.kmean_minmax_radioButton.blockSignals(True) - cfg.ui.kmean_siglist_radioButton.blockSignals(True) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(True) - cfg.ui.kmean_minmax_radioButton.setChecked(False) - cfg.ui.kmean_siglist_radioButton.setChecked(False) - cfg.ui.kmean_randomsiglist_radioButton.setChecked(True) - cfg.ui.kmean_minmax_radioButton.blockSignals(False) - cfg.ui.kmean_siglist_radioButton.blockSignals(False) - cfg.ui.kmean_randomsiglist_radioButton.blockSignals(False) - - # calculate clustering action - def calculateClusteringAction(self): - self.calculateClustering() - - # calculate clustering - def calculateClustering(self, batch = 'No', outputFile = None, bandSetNumber = None): - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_5.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - clssOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save clustering output'), '', 'TIF file (*.tif)') - else: - clssOut = outputFile - if clssOut is not False: - if clssOut.lower().endswith('.tif'): - pass - else: - clssOut = clssOut + '.tif' - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'clustering') - imageName = cfg.bandSetsList[bandSetNumber][8] - # if band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - bS = cfg.bndSetLst - # open input with GDAL - bL = [] - bandNumberList = [] - for i in bS: - if cfg.osSCP.path.isfile(i): - bandNumberList.append(1) - bL.append(i) - try: - tPMD = cfg.utls.createTempVirtualRaster(bL, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - except: - cfg.mx.msgErr6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error no band set") - return None - else: - cfg.mx.msgErr6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error no band set") - return None - else: - r = cfg.utls.selectLayerbyName(imageName, 'Yes') - iR = cfg.utls.layerSource(r) - # create virtual raster of bands - bndNumberList = [] - bL = [] - iBC = cfg.utls.getNumberBandRaster(iR) - for i in range(1, iBC+1): - bndNumberList.append(i) - tVRT = cfg.utls.createTempRasterPath('vrt') - bL.append(tVRT) - cfg.utls.createVirtualRaster(inputRasterList = [iR], output = tVRT, bandNumberList = [i], quiet = 'Yes') - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster(inputRasterList = bL, output = tPMD, quiet = 'Yes') - if len(bL) > 0: - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(clssOut)) - k_or_sigs = cfg.ui.kmeans_classes_spinBox.value() - if cfg.ui.kmean_siglist_radioButton.isChecked() is True: - sL = cfg.classTab.getSignatureList() - if len(sL) > 0: - k_or_sigs = [] - for s in sL: - vL = [] - for k in range(0, len(cfg.bandSetsList[bandSetNumber][4])): - vL.append(s[4][k*2]) - k_or_sigs.append([vL, s[2], s[6]]) - iterations = cfg.ui.kmeans_iter_spinBox.value() - maxStandardDeviation = cfg.ui.std_dev_doubleSpinBox.value() - if cfg.ui.kmean_threshold_checkBox.isChecked() is True: - thresh = cfg.ui.thresh_doubleSpinBox.value() - else: - thresh = 0.000001 - minSize = cfg.ui.min_size_class_spinBox.value() - NoDataValue = None - if cfg.ui.kmeans_radioButton.isChecked(): - self.kmeansCalculation(tPMD, bL, clssOut, k_or_sigs, iterations, thresh, NoDataValue, batch, bandSetNumber) - elif cfg.ui.isodata_radioButton.isChecked(): - self.isodataCalculation(tPMD, bL, clssOut, k_or_sigs, iterations, thresh, minSize, maxStandardDeviation, NoDataValue, batch, bandSetNumber) - for b in range(0, len(bL)): - bL[b] = None - - # ISODATA calculation (adapted from Ball & Hall, 1965. ISODATA. A novel method of data analysis and pattern classification) - def isodataCalculation(self, inputGDALRaster, bandList, outputFile, k_or_sigs, iterations = 10, thresh = 0.000001, minSize = 10, maxStandardDeviation = 0.000001, NoDataValue = None, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - outputDirectory = cfg.osSCP.path.dirname(outputFile) - # input raster - rD = inputGDALRaster - # band list - bL = bandList - cfg.uiUtls.updateBar(20, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating. Please wait ...')) - try: - classNumber = int(k_or_sigs) - except: - classNumber = len(k_or_sigs) - progressStep = int(60 / iterations) - for iteration in range(0, iterations): - if cfg.actionCheck == 'Yes': - # remove previous raster - try: - cfg.osSCP.remove(r) - except: - pass - r, sigs, sL = self.isodataIteration(rD, bL, iteration, k_or_sigs, classNumber, iterations, thresh, minSize, maxStandardDeviation, NoDataValue, batch, bandSetNumber) - cfg.uiUtls.updateBar(20 + progressStep, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating iteration: ' + str(iteration + 1).replace('-1', '*').replace('0', '*') + '. Please wait ...')) - k_or_sigs = sigs - if r is None: - break - else: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - r, sigs, sL = self.isodataIteration(rD, bL, -2, k_or_sigs, classNumber, iterations, thresh, minSize, maxStandardDeviation, NoDataValue, batch, bandSetNumber) - k_or_sigs = sigs - cfg.uiUtls.updateBar(80, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating classification. Please wait ...')) - r, sigs0, sL0 = self.isodataIteration(rD, bL, -1, k_or_sigs, classNumber, iterations, thresh, minSize, maxStandardDeviation, NoDataValue, batch, bandSetNumber) - cfg.uiUtls.updateBar(90) - if r == 'No': - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error") - cfg.mx.msgErr45() - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - else: - # copy raster - if cfg.rasterCompression != 'No': - try: - cfg.utls.GDALCopyRaster(r, outputFile, 'GTiff', cfg.rasterCompression, 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1') - except Exception as err: - cfg.shutilSCP.copy(r, outputFile) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - cfg.osSCP.remove(r) - except: - pass - else: - cfg.shutilSCP.copy(r, outputFile) - try: - cfg.osSCP.remove(r) - except: - pass - # add raster to layers - l =cfg.utls.addRasterLayer(outputFile) - cfg.utls.rasterSymbol(l, sL, 'No') - cfg.uiUtls.updateBar(90) - # display parameters - self.displayParameters(sL, None, outputDirectory, cfg.utls.fileName(outputFile)) - if cfg.ui.kmean_save_siglist_checkBox.isChecked() is True: - for x in sL: - id = cfg.utls.signatureID() - cfg.signIDs['ID_' + str(id)] = id - vl = [] - wvl = cfg.bandSetsList[bandSetNumber][4] - sd = [] - for k in range(0, int(len(x[4])/2)): - vl.append(x[4][k*2]) - sd.append(0) - cfg.signList['MACROCLASSID_' + str(id)] = x[0] - cfg.signList['MACROCLASSINFO_' + str(id)] = cfg.kmeansNm + str(x[1]) - cfg.signList['CLASSID_' + str(id)] = x[2] - cfg.signList['CLASSINFO_' + str(id)] = cfg.kmeansNm + str(x[3]) - cfg.signList['VALUES_' + str(id)] = x[4] - cfg.signList['LCS_MIN_' + str(id)] = vl - cfg.signList['LCS_MAX_' + str(id)] = vl - cfg.signList['MIN_VALUE_' + str(id)] = vl - cfg.signList['MAX_VALUE_' + str(id)] = vl - cfg.signList['WAVELENGTH_' + str(id)] = wvl - cfg.signList['MEAN_VALUE_' + str(id)] = vl - cfg.signList['SD_' + str(id)] = sd - cfg.signList['COLOR_' + str(id)] = x[6] - cfg.signList['CHECKBOX_' + str(id)] = 2 - cfg.signList['UNIT_' + str(id)] = cfg.bandSetsList[bandSetNumber][5] - cfg.signList['COVMATRIX_' + str(id)] = 'No' - cfg.signList['ROI_SIZE_' + str(id)] = 0 - cfg.signList['MD_THRESHOLD_' + str(id)] = 0 - cfg.signList['ML_THRESHOLD_' + str(id)] = 0 - cfg.signList['SAM_THRESHOLD_' + str(id)] = 0 - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.ui.toolBox_kmeans.setCurrentIndex(1) - cfg.uiUtls.updateBar(100) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ISODATA calculated") - - # isodata iteration - def isodataIteration(self, inputGDALRaster, bandList, iteration, k_or_sigs, classNumber, iterations = 20, thresh = 0.00001, minSize = 10, maxStandardDeviation = 0.000001, NoDataValue = None, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if cfg.actionCheck == 'Yes': - algorithmName = cfg.algMinDist - # calculate band mean - cfg.rasterClustering = {} - # No data value - nD = None - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox_8.isChecked() is True: - nD = cfg.ui.nodata_spinBox_9.value() - # input raster - rD = inputGDALRaster - # band list - bL = bandList - try: - k = int(k_or_sigs) - if cfg.ui.kmean_minmax_radioButton.isChecked() is True: - try: - # values finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = rD, functionBand = 'No', functionRaster = cfg.utls.rasterMinimumMaximum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate raster values iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), nodataValue = nD) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # calculate unique values - cfg.rasterClustering = {} - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - for xK in ar[0]: - for xB in range(0, len(bL)): - if 'MINIMUM_BAND_' + str(xB) == xK: - try: - if cfg.rasterClustering[xK] > ar[0][xK]: - cfg.rasterClustering[xK] = ar[0][xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - if 'MAXIMUM_BAND_' + str(xB) == xK: - try: - if cfg.rasterClustering[xK] < ar[0][xK]: - cfg.rasterClustering[xK] = ar[0][xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - except: - pass - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - signatures1 = [] - signatureList = [] - kN = 1 - classes = [] - classesMP = [] - for p in range(0, k): - sig = [] - signature = [] - for b in range(0, len(bL)): - vMin = cfg.rasterClustering['MINIMUM_BAND_' + str(b)] - vMax = cfg.rasterClustering['MAXIMUM_BAND_' + str(b)] - d = (vMax - vMin) / k - sig.append(vMin - (d/2) + (d * kN)) - signature.append(vMin - (d/2) + (d * kN)) - signature.append(0) - signatures1.append([sig]) - s = [] - s.append(kN) - s.append(str(kN)) - s.append(kN) - s.append(str(kN)) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - c, cc = cfg.utls.randomColor() - s.append(c) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([kN, c]) - classesMP.append([kN, None]) - kN = kN + 1 - else: - # random seeds - points = self.createRandomSeeds(k, nD, bandSetNumber) - signatures1 = [] - signatureList = [] - kN = 1 - classes = [] - classesMP = [] - for p in range(0, len(points)): - sig = cfg.utls.calculatePixelSignature(cfg.qgisCoreSCP.QgsPointXY(points[p][0], points[p][1]), cfg.bandSetsList[bandSetNumber][8], bandSetNumber, 'Pixel', 'No') - signatures1.append(sig) - signature = [] - for v in range(0, len(sig)): - signature.append(sig[v]) - signature.append(0) - s = [] - s.append(kN) - s.append(str(kN)) - s.append(kN) - s.append(str(kN)) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - c, cc = cfg.utls.randomColor() - s.append(c) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([kN, c]) - classesMP.append([kN, None]) - kN = kN + 1 - except: - # seed signatures - try: - k = len(k_or_sigs) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - signatures1 = k_or_sigs - signatureList = [] - classes = [] - classesMP = [] - for p in range(0, k): - sig = signatures1[p][0] - signature = [] - for v in range(0, len(sig)): - signature.append(sig[v]) - signature.append(0) - s = [] - s.append(signatures1[p][1]) - s.append(str(signatures1[p][1])) - s.append(signatures1[p][1]) - s.append(str(signatures1[p][1])) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - s.append(signatures1[p][2]) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([signatures1[p][1], signatures1[p][2]]) - classesMP.append([signatures1[p][1], None]) - # process calculation - classificationOptions = ['No', 'No', 'No', cfg.algBandWeigths, cfg.algThrshld] - # for multiprocess - signatureListMP = signatureList.copy() - for smp in signatureListMP: - smp[6] = None - o = cfg.utls.multiProcessRaster(rasterPath = rD, signatureList = signatureListMP, functionBand = 'Yes', functionRaster = cfg.utls.classificationMultiprocess, algorithmName = algorithmName, outputNoDataValue = -999, macroclassCheck = 'No',classificationOptions = classificationOptions, functionBandArgument = cfg.multiAddFactorsVar, functionVariable = cfg.bandSetsList[bandSetNumber][6], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), virtualRaster = 'Yes', compress = 'No') - if o == 'No': - return 'No', None, None - # output rasters - outputClasses, outputAlgs, outSigDict = o - try: - tPMDC = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = outputClasses, output = tPMDC, NoDataValue = 'Yes') - tPMDA = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = outputAlgs, output = tPMDA, NoDataValue = 'Yes') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - # last classification - if iteration == -1: - # remove temp rasters - try: - for oT in outputAlgs: - try: - cfg.osSCP.remove(oT) - except: - pass - for oTS in outSigDict: - for oT in outSigDict[oTS]: - try: - cfg.osSCP.remove(oT) - except: - pass - except: - pass - return tPMDC, None, None - bLC = bL.copy() - bLC.append(tPMDC) - bLC.append(tPMDA) - tPMDV = cfg.utls.createTempVirtualRaster(bLC, 'No', 'Yes', 'Yes', 0, 'No', 'No') - try: - # values finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = tPMDV, functionBand = 'No', functionRaster = cfg.utls.rasterPixelCountISODATA, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate raster values iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), nodataValue = nD, functionVariable = classesMP) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No', None, None - # calculate unique values - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - for xK in ar[0]: - for c in classes: - for xB in range(0, len(bL)): - if 'SUM_BAND_' + str(xB) + '_c_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - if 'COUNT_BAND_' + str(xB) + '_c_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - if 'SUM_DIST_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - except: - pass - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No', None, None - # calculate band mean - for c in classes: - for b in range(0, len(bL)): - try: - cfg.rasterClustering['MEAN_BAND_' + str(b) + '_c_' + str(c[0])] = cfg.rasterClustering['SUM_BAND_' + str(b) + '_c_' + str(c[0])] / cfg.rasterClustering['COUNT_BAND_' + str(b) + '_c_' + str(c[0])] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - try: - # values finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = tPMDV, functionBand = 'No', functionRaster = cfg.utls.rasterStandardDeviationISODATA, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate raster values iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), nodataValue = nD, functionVariable = [classesMP, cfg.rasterClustering]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No', None, None - # calculate unique values - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - for xK in ar[0]: - for c in classes: - for xB in range(0, len(bL)): - if 'VAR_BAND_' + str(xB) + '_c_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - except: - pass - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No', None, None - classes2 = [] - avDistance = 0 - sumNi = 0 - maxClasses = [] - # calculate standard deviation - for c in classes: - try: - signature = [] - s2 = [] - stdDev = [] - avDist = cfg.rasterClustering['SUM_DIST_' + str(c[0])] - avDistance = avDistance + avDist - Ni = cfg.rasterClustering['COUNT_BAND_' + str(0) + '_c_' + str(c[0])] - if Ni >= minSize: - maxClasses.append(c[0]) - sumNi = sumNi + Ni - for b in range(0, len(bL)): - stdDev.append(cfg.np.sqrt(cfg.rasterClustering['VAR_BAND_' + str(b) + '_c_' + str(c[0])])) - v = cfg.rasterClustering['MEAN_BAND_' + str(b) + '_c_' + str(c[0])] - s2.append(v) - maxStdDev = max(stdDev) - try: - maxStdDevK = stdDev.index(maxStdDev) - except: - maxStdDevK = 0 - classes2.append([c[0], c[1], s2, Ni, avDist, maxStdDev, maxStdDevK]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - # penultimate iteration - if iteration == -2: - signatures2 = [] - signaturesTemp = [] - signatureList2 = [] - count = 1 - for c in classes2: - signature = [] - s2 = [] - for v in c[2]: - signature.append(v) - s2.append(v) - signature.append(0) - if s2 not in signaturesTemp: - signaturesTemp.append(s2) - signatures2.append([s2, count, c[1]]) - s = [] - s.append(count) - s.append(str(count)) - s.append(count) - s.append(str(count)) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - s.append(c[1]) - s.append('No') - s.append('') - s.append('') - s.append(0) - signatureList2.append(s) - count = count + 1 - else: - # average distance - AD = avDistance / sumNi - try: - maxClass = max(maxClasses) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None - classes3 = [] - # check split - if len(classes2) <= classNumber: - for c in classes2: - s2 = [] - s3 = [] - if c[5] > maxStandardDeviation: - if ((c[4] > AD) and (c[3] > (2 * minSize + 2))) or (2 * len(classes2) < classNumber): - s2 = c[2].copy() - s3 = c[2].copy() - if s2[c[6]] - c[5] < 0: - s2[c[6]] = 0 - else: - s2[c[6]] = s2[c[6]] - c[5] - s3[c[6]] = s3[c[6]] + c[5] - classes3.append([c[0], c[1], s2]) - co, cco = cfg.utls.randomColor() - classes3.append([maxClass + 1, co, s3]) - maxClass = maxClass + 1 - else: - classes3.append(c) - # check merge - else: - # calculate distance - distances = [] - merge = [] - for c in classes2: - for cc in classes2: - # calculate pairwise distances - if c[0] < cc[0]: - dist = cfg.utls.euclideanDistance(c[2], cc[2]) - distances.append(dist) - merge.append([c[0], cc[0], c[1], cc[1], c[2], cc[2], c[3], cc[3]]) - diff = len(classes2) - classNumber - cMerge = [] - for n in range(0, diff): - maxDist = max(distances) - minDist = min(distances) - if minDist > thresh: - cl = distances.index(minDist) - mergeClass = merge[cl] - p1 = cfg.np.array(mergeClass[4]) * mergeClass[6] - p2 = cfg.np.array(mergeClass[5]) * mergeClass[7] - s2 = (p1 + p2)/(mergeClass[6] + mergeClass[7]) - classes3.append([mergeClass[0], mergeClass[2], s2.tolist()]) - cMerge.append(mergeClass[0]) - cMerge.append(mergeClass[1]) - distances[cl] = maxDist + 1 - for c in classes2: - if c[0] not in cMerge: - classes3.append(c) - signatures2 = [] - signatureList2 = [] - for c in classes3: - signature = [] - s2 = [] - for v in c[2]: - signature.append(v) - s2.append(v) - signature.append(0) - signatures2.append([s2, c[0], c[1]]) - s = [] - s.append( c[0]) - s.append(str( c[0])) - s.append( c[0]) - s.append(str( c[0])) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - s.append(c[1]) - s.append('No') - s.append('') - s.append('') - s.append(0) - signatureList2.append(s) - # remove temp rasters - try: - for oT in outputAlgs: - try: - cfg.osSCP.remove(oT) - except: - pass - for oTS in outSigDict: - for oT in outSigDict[oTS]: - try: - cfg.osSCP.remove(oT) - except: - pass - except: - pass - return tPMDC, signatures2, signatureList2 - else: - return 'No', None, None - - # K-means calculation - def kmeansCalculation(self, inputGDALRaster, bandList, outputFile, k_or_sigs, iterations = 10, thresh = 0.000001, NoDataValue = None, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - outputDirectory = cfg.osSCP.path.dirname(outputFile) - # input raster - rD = inputGDALRaster - # band list - bL = bandList - cfg.uiUtls.updateBar(20, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating. Please wait ...')) - progressStep = int(60 / iterations) - for iteration in range(0, iterations): - if cfg.actionCheck == 'Yes': - # remove previous raster - try: - cfg.osSCP.remove(r) - except: - pass - r, sigs, sL, distances = self.kmeansIteration(rD, bL, iteration, k_or_sigs, iterations, thresh, NoDataValue, batch, bandSetNumber) - cfg.uiUtls.updateBar(20 + progressStep, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating iteration: ' + str(iteration + 1).replace('-1', '*').replace('0', '*') + '. Please wait ...')) - k_or_sigs = sigs - if r is None: - break - else: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - r, sigs0, sL0, distances0 = self.kmeansIteration(rD, bL, -1, k_or_sigs, iterations, thresh, NoDataValue, batch, bandSetNumber) - cfg.uiUtls.updateBar(80, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', ' Calculating classification. Please wait ...')) - #for x in range(0, len(bL)): - # bL[x] = None - cfg.uiUtls.updateBar(90) - if r == 'No': - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error') - cfg.mx.msgErr45() - else: - # copy raster - if cfg.rasterCompression != 'No': - try: - cfg.utls.GDALCopyRaster(r, outputFile, 'GTiff', cfg.rasterCompression, 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1') - except Exception as err: - cfg.shutilSCP.copy(r, outputFile) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - cfg.osSCP.remove(r) - except: - pass - else: - cfg.shutilSCP.copy(r, outputFile) - try: - cfg.osSCP.remove(r) - except: - pass - # add raster to layers - l =cfg.utls.addRasterLayer(outputFile) - cfg.utls.rasterSymbol(l, sL, 'No') - cfg.uiUtls.updateBar(90) - # display parameters - self.displayParameters(sL, distances, outputDirectory, cfg.utls.fileName(outputFile)) - if cfg.ui.kmean_save_siglist_checkBox.isChecked() is True: - for x in sL: - id = cfg.utls.signatureID() - cfg.signIDs['ID_' + str(id)] = id - vl = [] - wvl = cfg.bandSetsList[bandSetNumber][4] - sd = [] - for k in range(0, int(len(x[4])/2)): - vl.append(x[4][k*2]) - sd.append(0) - cfg.signList['MACROCLASSID_' + str(id)] = x[0] - cfg.signList['MACROCLASSINFO_' + str(id)] = cfg.kmeansNm + str(x[1]) - cfg.signList['CLASSID_' + str(id)] = x[2] - cfg.signList['CLASSINFO_' + str(id)] = cfg.kmeansNm + str(x[3]) - cfg.signList['VALUES_' + str(id)] = x[4] - cfg.signList['LCS_MIN_' + str(id)] = vl - cfg.signList['LCS_MAX_' + str(id)] = vl - cfg.signList['MIN_VALUE_' + str(id)] = vl - cfg.signList['MAX_VALUE_' + str(id)] = vl - cfg.signList['WAVELENGTH_' + str(id)] = wvl - cfg.signList['MEAN_VALUE_' + str(id)] = vl - cfg.signList['SD_' + str(id)] = sd - cfg.signList['COLOR_' + str(id)] = x[6] - cfg.signList['CHECKBOX_' + str(id)] = 2 - cfg.signList['UNIT_' + str(id)] = cfg.bandSetsList[bandSetNumber][5] - cfg.signList['COVMATRIX_' + str(id)] = 'No' - cfg.signList['ROI_SIZE_' + str(id)] = 0 - cfg.signList['MD_THRESHOLD_' + str(id)] = 0 - cfg.signList['ML_THRESHOLD_' + str(id)] = 0 - cfg.signList['SAM_THRESHOLD_' + str(id)] = 0 - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - cfg.ui.toolBox_kmeans.setCurrentIndex(1) - cfg.uiUtls.updateBar(100) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " K-means calculated") - - # K-means iteration - def kmeansIteration(self, inputGDALRaster, bandList, iteration, k_or_sigs, iterations = 20, thresh = 0.00001, NoDataValue = None, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if cfg.actionCheck == 'Yes': - if cfg.ui.min_distance_radioButton.isChecked() is True: - algorithmName = cfg.algMinDist - else: - algorithmName = cfg.algSAM - # calculate band mean - cfg.rasterClustering = {} - # No data value - nD = None - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox_8.isChecked() is True: - nD = cfg.ui.nodata_spinBox_9.value() - # input raster - rD = inputGDALRaster - # band list - bL = bandList - try: - k = int(k_or_sigs) - if cfg.ui.kmean_minmax_radioButton.isChecked() is True: - try: - # values finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = rD, functionBand = 'No', functionRaster = cfg.utls.rasterMinimumMaximum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate raster values iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), nodataValue = nD) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No', None, None, None - # calculate unique values - cfg.rasterClustering = {} - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - for xK in ar[0]: - for xB in range(0, len(bL)): - if 'MINIMUM_BAND_' + str(xB) == xK: - try: - if cfg.rasterClustering[xK] > ar[0][xK]: - cfg.rasterClustering[xK] = ar[0][xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - if 'MAXIMUM_BAND_' + str(xB) == xK: - try: - if cfg.rasterClustering[xK] < ar[0][xK]: - cfg.rasterClustering[xK] = ar[0][xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - except: - pass - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No', None, None, None - signatures1 = [] - signatureList = [] - kN = 1 - classes = [] - classesMP = [] - for p in range(0, k): - sig = [] - signature = [] - for b in range(0, len(bL)): - try: - vMin = cfg.rasterClustering["MINIMUM_BAND_" + str(b)] - vMax = cfg.rasterClustering["MAXIMUM_BAND_" + str(b)] - except: - return 'No', None, None, None - d = (vMax - vMin) / k - sig.append(vMin - (d/2) + (d * kN)) - signature.append(vMin - (d/2) + (d * kN)) - signature.append(0) - signatures1.append([sig]) - s = [] - s.append(kN) - s.append(str(kN)) - s.append(kN) - s.append(str(kN)) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - c, cc = cfg.utls.randomColor() - s.append(c) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([kN, c]) - classesMP.append([kN, None]) - kN = kN + 1 - else: - # random seeds - points = self.createRandomSeeds(k, nD, bandSetNumber) - signatures1 = [] - signatureList = [] - kN = 1 - classes = [] - classesMP = [] - for p in range(0, len(points)): - sig = cfg.utls.calculatePixelSignature(cfg.qgisCoreSCP.QgsPointXY(points[p][0], points[p][1]), cfg.bandSetsList[bandSetNumber][8], bandSetNumber, "Pixel", 'No') - signatures1.append(sig) - signature = [] - for v in range(0, len(sig)): - signature.append(sig[v]) - signature.append(0) - s = [] - s.append(kN) - s.append(str(kN)) - s.append(kN) - s.append(str(kN)) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - c, cc = cfg.utls.randomColor() - s.append(c) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([kN, c]) - classesMP.append([kN, None]) - kN = kN + 1 - except: - # seed signatures - k = len(k_or_sigs) - signatures1 = k_or_sigs - signatureList = [] - classes = [] - classesMP = [] - for p in range(0, k): - sig = signatures1[p][0] - signature = [] - for v in range(0, len(sig)): - signature.append(sig[v]) - signature.append(0) - s = [] - s.append(signatures1[p][1]) - s.append(str(signatures1[p][1])) - s.append(signatures1[p][1]) - s.append(str(signatures1[p][1])) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - s.append(signatures1[p][2]) - s.append('No') - s.append(signature) - s.append(signature) - s.append(0) - signatureList.append(s) - classes.append([signatures1[p][1], signatures1[p][2]]) - classesMP.append([signatures1[p][1], None]) - # process calculation - classificationOptions = ['No', 'No', 'No', cfg.algBandWeigths, cfg.algThrshld] - # for multiprocess - signatureListMP = signatureList.copy() - for smp in signatureListMP: - smp[6] = None - o = cfg.utls.multiProcessRaster(rasterPath = rD, signatureList = signatureListMP, functionBand = 'Yes', functionRaster = cfg.utls.classificationMultiprocess, algorithmName = algorithmName, outputNoDataValue = -999, macroclassCheck = 'No',classificationOptions = classificationOptions, functionBandArgument = cfg.multiAddFactorsVar, functionVariable = cfg.bandSetsList[bandSetNumber][6], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification iteration') + str(iteration + 1).replace('-1', '*').replace('0', '*'), virtualRaster = 'Yes', compress = 'No') - if o == 'No': - return 'No', None, None, None - # output rasters - outputClasses, outputAlgs, outSigDict = o - tPMDC = cfg.utls.createTempRasterPath('vrt') - try: - cfg.utls.createVirtualRaster2(inputRasterList = outputClasses, output = tPMDC, NoDataValue = 'Yes') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None, None - # last classification - if iteration == -1: - # remove temp rasters - try: - for oT in outputAlgs: - try: - cfg.osSCP.remove(oT) - except: - pass - for oTS in outSigDict: - for oT in outSigDict[oTS]: - try: - cfg.osSCP.remove(oT) - except: - pass - except: - pass - return tPMDC, None, None, None - bLC = bL.copy() - bLC.append(tPMDC) - tPMDV = cfg.utls.createTempVirtualRaster(bLC, 'No', 'Yes', 'Yes', 0, 'No', 'No') - try: - # values finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = tPMDV, functionBand = 'No', functionRaster = cfg.utls.rasterPixelCountKmeans, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Calculate raster values iteration ') + str(iteration + 1).replace('-1', '*').replace('0', '*'), nodataValue = nD, functionVariable = classesMP) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No', None, None, None - # calculate unique values - cfg.rasterClustering = {} - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - try: - for xK in ar[0]: - for c in classes: - for xB in range(0, len(bL)): - if 'SUM_BAND_' + str(xB) + '_c_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - if 'COUNT_BAND_' + str(xB) + '_c_' + str(c[0]) == xK: - try: - cfg.rasterClustering[xK] = ar[0][xK] + cfg.rasterClustering[xK] - except: - cfg.rasterClustering[xK] = ar[0][xK] - except: - pass - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No', None, None, None - signatureList2 = [] - signatures2 = [] - for c in classes: - signature = [] - s2 = [] - for b in range(0, len(bL)): - try: - v = cfg.rasterClustering['SUM_BAND_' + str(b) + '_c_' + str(c[0])] / cfg.rasterClustering['COUNT_BAND_' + str(b) + '_c_' + str(c[0])] - if cfg.np.isnan(v): - signature.append(0) - s2.append(0) - else: - signature.append(v) - s2.append(v) - signature.append(0) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', None, None, None - signatures2.append([s2, c[0], c[1]]) - s = [] - s.append( c[0]) - s.append(str( c[0])) - s.append( c[0]) - s.append(str( c[0])) - s.append(signature) - s.append(cfg.bandSetsList[bandSetNumber][4]) - s.append(c[1]) - s.append('No') - s.append('') - s.append('') - s.append(0) - signatureList2.append(s) - # check distance - distances = [] - for i in range(0, k): - if algorithmName == cfg.algMinDist: - dist = cfg.utls.euclideanDistance(signatures1[i][0], signatures2[i][0]) - elif algorithmName == cfg.algSAM: - dist = cfg.utls.spectralAngle(signatures1[i][0], signatures2[i][0]) - distances.append(dist) - # remove temp rasters - try: - for oT in outputAlgs: - try: - cfg.osSCP.remove(oT) - except: - pass - for oTS in outSigDict: - for oT in outSigDict[oTS]: - try: - cfg.osSCP.remove(oT) - except: - pass - except: - pass - if max(distances) <= thresh: - return None, signatures2, signatureList2, distances - else: - return tPMDC, signatures2, signatureList2, distances - else: - return 'No', None, None, None - - # create random point - def createRandomSeeds(self, pointNumber, NoDataValue = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - try: - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[bandSetNumber][3][0] - else: - if cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') is None: - cfg.mx.msg4() - return 'No' - else: - imageName = cfg.bandSetsList[bandSetNumber][8] - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "No image selected") - img = cfg.utls.selectLayerbyName(imageName, 'Yes') - crs = cfg.utls.getCrs(img) - geographicFlag = crs.isGeographic() - if geographicFlag is False: - tLX, tLY, lRX, lRY, pSX, pSY = cfg.utls.imageInformationSize(imageName) - Xmin = int(round(min(tLX, lRX))) - Xmax = int(round(max(tLX, lRX))) - Ymin = int(round(min(tLY, lRY))) - Ymax = int(round(max(tLY, lRY))) - points = cfg.utls.randomPoints(pointNumber, Xmin, Xmax, Ymin, Ymax, None, cfg.bandSetsList[bandSetNumber][8], NoDataValue, None, None, bandSetNumber) - return points - else: - cfg.mx.msgWar14() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # display parameters - def displayParameters(self, signatureList, distances = None, outputDirectory = None, outputFileName = None): - tblOut = outputDirectory + "/" + str(outputFileName) + cfg.kmeansReportNm - try: - l = open(tblOut, 'w') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - try: - t = str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Clustering')) + " " + str("\n") + str("\n") - l.write(t) - tB = str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Class')) + " " + str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Signature')) + " " + str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'Distance')) + str("\n") - l.write(str(tB)) - c = 0 - for s in signatureList: - if distances is None: - d = " " - else: - d = str(distances[c]) - tB = str(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", 'C_ID_')) + str(s[2]) + " " - vB = None - for k in range(0, int(len(s[4])/2)): - vl = s[4][k*2] - if vB is None: - vB = str(vl) - else: - vB = vB + "," + str(vl) - l.write(str(tB) + str(vB) + " " + d + str("\n")) - c = c + 1 - l.close() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.report_textBrowser_3.setText(str(eM)) - cfg.ui.toolBox_kmeans.setCurrentIndex(1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "calculated") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) \ No newline at end of file diff --git a/maininterface/crossclassificationTab.py b/maininterface/crossclassificationTab.py deleted file mode 100644 index 894ab7c..0000000 --- a/maininterface/crossclassificationTab.py +++ /dev/null @@ -1,595 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class CrossClassification: - - def __init__(self): - self.clssfctnNm = None - - # calculate cross classification if click on button - def calculateCrossClassification(self): - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' calculate Cross Classification ') - self.crossClassification(self.clssfctnNm, cfg.referenceLayer2) - - # classification name - def classificationLayerName(self): - self.clssfctnNm = cfg.ui.classification_name_combo_2.currentText() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classification name: ' + str(self.clssfctnNm)) - - # cross classification calculation - def crossClassification(self, classification, reference, batch = 'No', shapefileField = None, rasterOutput = None, NoDataValue = None, regressionRaster = 'No'): - # check if numpy is updated - try: - cfg.np.count_nonzero([1,1,0]) - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - rstrCheck = 'No' - cfg.mx.msgErr26() - if batch == 'No': - crossRstPath = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save cross classification raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - crossRstPath = rasterOutput - # virtual raster - vrtR = 'No' - if crossRstPath is not False: - if crossRstPath.lower().endswith('.vrt'): - vrtR = 'Yes' - elif crossRstPath.lower().endswith('.tif'): - pass - else: - crossRstPath = crossRstPath + '.tif' - if batch == 'No': - iClass = cfg.utls.selectLayerbyName(classification, 'Yes') - l = cfg.utls.selectLayerbyName(reference) - else: - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(reference, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - l = cfg.utls.addVectorLayer(reference, cfg.utls.fileName(reference), 'ogr') - else: - l = cfg.utls.addRasterLayer(reference) - reml = l - rD = None - if cfg.osSCP.path.isfile(classification): - iClass = cfg.utls.addRasterLayer(classification) - remiClass = iClass - else: - return 'No' - except: - return 'No' - # regression - if batch == 'No': - if cfg.ui.regression_raster_checkBox.isChecked() is True: - regressionRaster = 'Yes' - # date time for temp name - dT = cfg.utls.getTime() - if iClass is not None and l is not None: - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(crossRstPath)) - # if not reference shapefile - if l.type() != 0: - # check projections - rCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(l)) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - eCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(iClass)) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(cfg.utls.layerSource(iClass), tPMD, str(rCrs)) - cfg.mx.msg9() - remiClass2 = cfg.utls.addRasterLayer(tPMD) - iClass = remiClass2 - else: - # vector EPSG - if 'Polygon?crs=' in str(cfg.utls.layerSource(l)) or 'memory?geometry=' in str(cfg.utls.layerSource(l)): - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - l = cfg.utls.saveMemoryLayerToShapefile(l, tSHP, format = 'GPKG') - vCrs = cfg.utls.getCrsGDAL(tSHP) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - else: - ql = cfg.utls.layerSource(l) - vCrs = cfg.utls.getCrsGDAL(ql) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - # in case of reprojection - qll = cfg.utls.layerSource(l) - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileName(qll) - qlll = cfg.utls.layerSource(iClass) - rCrs = cfg.utls.getCrsGDAL(qlll) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if vEPSG.IsSame(rEPSG) != 1: - if cfg.osSCP.path.isfile(reprjShapefile): - pass - else: - try: - qllll = cfg.utls.layerSource(l) - cfg.utls.repojectShapefile(qllll, vEPSG, reprjShapefile, rEPSG) - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - l = cfg.utls.addVectorLayer(reprjShapefile, cfg.utls.fileName(reprjShapefile) , 'ogr') - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.QtWidgetsSCP.qApp.processEvents() - # temp raster layer - tRC = cfg.utls.createTempRasterPath('tif') - # cross classification - eMN = dT + cfg.crossClassNm - cfg.reportPth = str(cfg.tmpDir + '/' + eMN) - tblOut = cfg.osSCP.path.dirname(crossRstPath) + '/' + cfg.utls.fileNameNoExt(crossRstPath) + '.csv' - cfg.uiUtls.updateBar(10) - # if reference shapefile - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - if batch == 'No': - fd = cfg.ui.class_field_comboBox_2.currentText() - else: - fd = shapefileField - if batch == 'No': - # convert reference layer to raster - qlllll = cfg.utls.layerSource(l) - qllllll = cfg.utls.layerSource(iClass) - vect = cfg.utls.vectorToRaster(fd, str(qlllll), classification, str(tRC), str(qllllll), extent = 'Yes') - else: - qlllllll = cfg.utls.layerSource(l) - vect = cfg.utls.vectorToRaster(fd, str(qlllllll), classification, str(tRC), classification, extent = 'Yes') - if vect == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - referenceRaster = tRC - # if reference raster - elif l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer: - if batch == 'No': - referenceRaster = cfg.utls.layerSource(l) - else: - referenceRaster = reference - # No data value - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox_6.isChecked() is True: - nD = cfg.ui.nodata_spinBox_7.value() - else: - nD = None - # create virtual raster - qlllllllI = cfg.utls.layerSource(iClass) - bList = [referenceRaster, qlllllllI] - bListNum = [1, 1] - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bListNum, 'Yes', 'Yes', 0, 'No', 'Yes') - bandsUniqueVal = [] - k = [] - for b in bList: - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = b, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = nD, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values')) - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - rasterBandUniqueVal = cfg.np.unique(values).tolist() - refRasterBandUniqueVal = sorted(rasterBandUniqueVal) - try: - refRasterBandUniqueVal.remove(nD) - except: - pass - bandsUniqueVal.append(refRasterBandUniqueVal) - if 0 in refRasterBandUniqueVal: - k.append(1) - else: - k.append(0) - try: - cmb = list(cfg.itertoolsSCP.product(*bandsUniqueVal)) - testCmb = cmb[0] - except Exception as err: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr63() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # expression builder - check = 'No' - t = 0 - while t < 100: - t = t + 1 - rndVarList = [] - calcDataType = cfg.np.uint32 - # first try fixed list - if t == 1: - coT = 333 - for cmbI in range(0, len(cmb[0])): - rndVarList.append(coT) - coT = coT + 1 - # random list - else: - for cmbI in range(0, len(cmb[0])): - rndVarList.append(int(999 * cfg.np.random.random())) - newValueList = [] - reclassDict = {} - for i in cmb: - newVl = (i[0] + k[0]) * (rndVarList[0]) + (i[1] + k[1]) * (rndVarList[1]) - reclassDict[newVl] = i - newValueList.append(newVl) - if i[0] < 0 or i[1] < 0 : - calcDataType = cfg.np.int32 - uniqueValList = cfg.np.unique(newValueList) - if int(uniqueValList.shape[0]) == len(newValueList): - n = 1 - col = [] - row = [] - reclassList = [] - cmbntns = {} - for newVl in sorted(reclassDict.keys()): - i = reclassDict[newVl] - reclassList.append(newVl) - cmbntns[n] = [i[1], i[0]] - col.append(i[1]) - row.append(i[0]) - n = n + 1 - check = 'Yes' - break - if check == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - e = '(rasterSCPArrayfunctionBand[::, ::, 0] + ' + str(k[0]) +' ) * ' + str(rndVarList[0]) + ' + (rasterSCPArrayfunctionBand[::, ::, 1] + ' + str(k[1]) +' ) * ' + str(rndVarList[1]) - # check projections - left, right, top, bottom, cRPX, cRPY, rP, un = cfg.utls.imageGeoTransform(vrtCheck) - # calculation - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.crossRasters, outputRasterList = [crossRstPath], nodataValue = nD, functionBandArgument = reclassList, functionVariable = e, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cross classification'), outputNoDataValue = cfg.NoDataValUInt32, virtualRaster = vrtR, compress = cfg.rasterCompression, dataType = 'UInt32', calcDataType = calcDataType) - cfg.uiUtls.updateBar(60) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'cross raster output: ' + str(crossRstPath)) - # calculate unique values - values = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[1][0, ::]) - sumVal = cfg.np.append(sumVal, ar[1][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - reclRasterBandUniqueVal = {} - values = values.astype(int) - for v in range(0, len(values)): - try: - reclRasterBandUniqueVal[values[v]] = reclRasterBandUniqueVal[values[v]] + sumVal[v] - except: - reclRasterBandUniqueVal[values[v]] = sumVal[v] - rasterBandUniqueVal = {} - for v in range(0, len(values)): - try: - cmbX = cmbntns[values[v]] - rasterBandUniqueVal[(cmbX[0], cmbX[1])] = [reclRasterBandUniqueVal[values[v]], values[v]] - except: - pass - cfg.uiUtls.updateBar(80) - col2 = list(set(col)) - row2 = list(set(row)) - cols = sorted(cfg.np.unique(col2).tolist()) - rows = sorted(cfg.np.unique(row2).tolist()) - crossClass = cfg.np.zeros((len(rows), len(cols))) - cList = 'V_' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reference') + '\t' - try: - l = open(tblOut, 'w') - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'CrossClassCode') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reference') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area [' + un + '^2]') + str('\n') - l.write(t) - rSumX = 0 - rSumY = 0 - rSumTot = 0 - for c in cols: - cList = cList + str(int(c)) + '\t' - for r in rows: - try: - v = (c, r) - area = str(round(rasterBandUniqueVal[v][0] * cRPX * cRPY, 5)) - t = str(rasterBandUniqueVal[v][1]) + '\t' + str(int(c)) + '\t' + str(int(r)) + '\t' + str(int(rasterBandUniqueVal[v][0])) + '\t' + area + str('\n') - l.write(t) - crossClass[rows.index(r), cols.index(c)] = rasterBandUniqueVal[v][0] * cRPX * cRPY - rSumX = rSumX + c * rasterBandUniqueVal[v][0] - rSumY = rSumY + r * rasterBandUniqueVal[v][0] - rSumTot = rSumTot + rasterBandUniqueVal[v][0] - except: - crossClass[rows.index(r), cols.index(c)] = 0 - # calculate regression - if regressionRaster == 'Yes': - rXMean = rSumX / rSumTot - rYMean = rSumY / rSumTot - # linear regression y = b0 + b1 x + E - Sxy = 0 - Sxx = 0 - Syy = 0 - for c in cols: - for r in rows: - try: - v = (c, r) - Sxx = Sxx + rasterBandUniqueVal[v][0] * (c - rXMean)**2 - Syy = Syy + rasterBandUniqueVal[v][0] * (r - rYMean)**2 - Sxy = Sxy + (c - rXMean) * (r - rYMean) * rasterBandUniqueVal[v][0] - except: - pass - try: - rCoeff = Sxy / (Sxx * Syy)**0.5 - rCoeff2 = rCoeff**2 - slope = Sxy / Sxx - intercept = rYMean - slope * rXMean - VAR_Y = (Syy - slope * Sxy) / (rSumTot-2) - VAR_slope = VAR_Y / Sxx - VAR_intercept = VAR_Y * ( 1/rSumTot + rXMean**2 / Sxx) - conf_slope = 2 * (VAR_slope)**0.5 - conf_intercept = 2 * (VAR_intercept)**0.5 - except: - rCoeff = '' - rCoeff2 = '' - slope = '' - intercept = '' - VAR_Y = '' - VAR_slope = '' - conf_slope = '' - VAR_intercept = '' - conf_intercept = '' - # save combination to table - l.write(str('\n')) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'CROSS MATRIX [') + str(un) + '^2]' + '\n' - l.write(tStr) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Classification') + '\n' - l.write(tStr) - tStr = cList + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') + '\n' - l.write(tStr) - # temp matrix - tmpMtrx= cfg.tmpDir + '/' + cfg.tempMtrxNm + dT + '.txt' - cfg.np.savetxt(tmpMtrx, crossClass, delimiter='\t', fmt='%i') - tM = open(tmpMtrx, 'r') - # write matrix - ix = 0 - for j in tM: - tMR = str(int(rows[ix])) + '\t' + j.rstrip('\n') + '\t' + str(int(crossClass[ix, :].sum())) + str('\n') - l.write(tMR) - ix = ix + 1 - # last line - lL = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') - for c in range(0, len(cols)): - lL = lL + '\t' + str(int(crossClass[:, c].sum())) - totMat = int(crossClass.sum()) - lL = lL + '\t' + str(totMat) + str('\n') - l.write(lL) - # write linear regression - if regressionRaster == 'Yes': - l.write(str('\n')) - l.write('Linear regression Y = B0 + B1*X' + '\n') - l.write('Coeff. det. R^2' + '\t' + str(rCoeff2) + '\n') - l.write('Coeff. correlation r' + '\t' + str(rCoeff) + '\n') - l.write('B1' + '\t' + str(slope) + ' ± ' + str(conf_slope) + ' \n') - l.write('B0' + '\t' + str(intercept) + ' ± ' + str(conf_intercept) + '\n') - l.write('Variance Y' + '\t' + str(VAR_Y) + '\n') - l.write('Variance B1' + '\t' + str(VAR_slope) + '\n') - l.write('Variance B0' + '\t' + str(VAR_intercept) + '\n') - l.close() - # add raster to layers - rastUniqueVal = cfg.np.unique(values).tolist() - rstr = cfg.utls.addRasterLayer(crossRstPath) - cfg.utls.rasterSymbolGeneric(rstr, 'NoData', rasterUniqueValueList = rastUniqueVal) - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.cross_matrix_textBrowser.setText(eM) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' cross matrix calculated') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if regressionRaster == 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' regression raster') - # output rasters - outRasterB0 = cfg.osSCP.path.dirname(crossRstPath) + '/' + cfg.utls.fileNameNoExt(crossRstPath) + '_b0.tif' - oM = [] - oM.append(outRasterB0) - try: - rDD = cfg.gdalSCP.Open(vrtCheck, cfg.gdalSCP.GA_ReadOnly) - oMR = cfg.utls.createRasterFromReference(rDD, 1, oM, cfg.NoDataVal, 'GTiff', 'Float32', 0, None, cfg.rasterCompression, 'LZW', constantValue = intercept) - # close GDAL rasters - for b in range(0, len(oMR)): - oMR[b] = None - # add raster to layers - rstr = cfg.utls.addRasterLayer(outRasterB0) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - outRasterB1 = cfg.osSCP.path.dirname(crossRstPath) + '/' + cfg.utls.fileNameNoExt(crossRstPath) + '_b1.tif' - oM = [] - oM.append(outRasterB1) - try: - oMR = cfg.utls.createRasterFromReference(rDD, 1, oM, cfg.NoDataVal, 'GTiff', 'Float32', 0, None, cfg.rasterCompression, 'LZW', constantValue = slope) - # close GDAL rasters - for b in range(0, len(oMR)): - oMR[b] = None - # add raster to layers - rstr = cfg.utls.addRasterLayer(outRasterB1) - rDD = None - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(100) - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.ui.toolBox_cross_classification.setCurrentIndex(1) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'finished') - else: - self.refreshReferenceLayer() - cfg.utls.refreshClassificationLayer() - - # reference layer name - def referenceLayerName(self): - cfg.referenceLayer2 = cfg.ui.reference_name_combo_2.currentText() - cfg.ui.class_field_comboBox_2.clear() - l = cfg.utls.selectLayerbyName(cfg.referenceLayer2) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != 'string': - cfg.dlg.class_field_combo_2(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reference layer name: ' + str(cfg.referenceLayer2)) - - # refresh reference layer name - def refreshReferenceLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.reference_name_combo_2.clear() - # reference layer name - cfg.referenceLayer2 = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer): - if (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.Polygon) or (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon): - cfg.dlg.reference_layer_combo_2(l.name()) - elif (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.reference_layer_combo_2(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reference layers refreshed') diff --git a/maininterface/dilationTab.py b/maininterface/dilationTab.py deleted file mode 100644 index 8468e03..0000000 --- a/maininterface/dilationTab.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class DilationRaster: - - def __init__(self): - pass - - # value text changed - def textChanged(self): - self.checkValueList() - - # check value list - def checkValueList(self): - try: - # class value list - valueList = cfg.utls.textToValueList(cfg.ui.dilation_classes_lineEdit.text()) - cfg.ui.dilation_classes_lineEdit.setStyleSheet("color : green") - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - except Exception as err: - cfg.ui.dilation_classes_lineEdit.setStyleSheet("color : red") - valueList = [] - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return valueList - - # dilation classification - def dilationClassificationAction(self): - self.dilationClassification() - - # dilation classification - def dilationClassification(self, batch = 'No', rasterInput = None, rasterOutput = None, circularStructure = None): - # class value list - valueList = self.checkValueList() - if len(valueList) > 0: - if batch == 'No': - outputRaster = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - outputRaster = rasterOutput - # virtual raster - vrtR = 'No' - if outputRaster is not False: - if outputRaster.lower().endswith('.vrt'): - vrtR = 'Yes' - elif outputRaster.lower().endswith('.tif'): - pass - else: - outputRaster = outputRaster + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - cfg.cnvs.setRenderFlag(False) - raster = cfg.ui.dilation_raster_name_combo.currentText() - r = cfg.utls.selectLayerbyName(raster, 'Yes') - else: - r = 'No' - if r is not None: - if batch == 'No': - rSource = cfg.utls.layerSource(r) - else: - if cfg.osSCP.path.isfile(rasterInput): - rSource = rasterInput - else: - return 'No' - if rSource is None: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' None raster') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(outputRaster)) - input = rSource - nd = cfg.utls.imageNoDataValue(input) - dType = cfg.utls.getRasterDataTypeName(input) - size = cfg.ui.dilation_threshold_spinBox.value() - if circularStructure is None: - if cfg.ui.circular_structure_checkBox_2.isChecked(): - circularStructure = 'Yes' - else: - circularStructure = 'No' - if circularStructure == 'No': - structure = cfg.np.ones((size*2+1,size*2+1)) - else: - structure = cfg.utls.createCircularStructure(size) - additionalLayer = 3 - if vrtR == 'Yes': - tPMD = outputRaster - else: - tPMD = cfg.utls.createTempRasterPath('vrt') - # process calculation - o = cfg.utls.multiProcessRaster(rasterPath = input, functionBand = 'No', functionRaster = cfg.utls.rasterDilation, outputRasterList = [tPMD], functionBandArgument = structure, functionVariable = valueList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Dilation '), virtualRaster = 'Yes', compress = cfg.rasterCompression, outputNoDataValue = nd, dataType = dType, boundarySize = structure.shape[0]+1, additionalLayer = additionalLayer) - input = tPMD - if vrtR != 'Yes': - # copy raster - try: - cfg.utls.GDALCopyRaster(tPMD, outputRaster, 'GTiff', cfg.rasterCompression, 'LZW') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if cfg.osSCP.path.isfile(outputRaster): - oR = cfg.utls.addRasterLayer(outputRaster) - if r != 'No': - try: - cfg.utls.copyRenderer(r, oR) - except: - pass - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.utls.refreshClassificationLayer() - cfg.mx.msgErr9() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error raster not found") - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - \ No newline at end of file diff --git a/maininterface/downloadproductpointer.py b/maininterface/downloadproductpointer.py deleted file mode 100644 index 7120e1f..0000000 --- a/maininterface/downloadproductpointer.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -from qgis.gui import * -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class DownloadProductPointer(QgsMapTool): - - rightClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - leftClicked = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - moved = cfg.pyqtSignalSCP( ['QgsPointXY'] ) - - def __init__(self, canvas): - QgsMapTool.__init__(self, canvas) - self.cnvs = canvas - - def canvasMoveEvent(self, event): - point = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - self.moved.emit(point) - - def canvasReleaseEvent(self, event): - pnt = self.cnvs.getCoordinateTransform().toMapCoordinates(event.pos()) - # click - if(event.button() == cfg.QtSCP.RightButton): - self.rightClicked.emit(pnt) - else: - self.leftClicked.emit(pnt) diff --git a/maininterface/downloadproducts.py b/maininterface/downloadproducts.py deleted file mode 100644 index e21e7fe..0000000 --- a/maininterface/downloadproducts.py +++ /dev/null @@ -1,3159 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class DownloadProducts: - - def __init__(self): - # check all bands - self.checkAll = 'No' - self.rbbrBndPol = cfg.qgisGuiSCP.QgsRubberBand(cfg.cnvs, cfg.qgisCoreSCP.QgsWkbTypes.LineGeometry) - cfg.ui.dateEdit_to.setDate(cfg.QDateSCP.currentDate()) - cfg.ui.dateEdit_from.setDate(cfg.QDateSCP.currentDate().addDays(-365)) - - # add satellite list to combo - def addSatelliteToCombo(self, satelliteList): - for i in satelliteList: - cfg.ui.landsat_satellite_combo.addItem(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " satellites added") - - # user - def rememberUser(self): - if cfg.ui.remember_user_checkBox_2.isChecked(): - user = cfg.ui.user_usgs_lineEdit.text() - pswd = cfg.utls.encryptPassword(cfg.ui.password_usgs_lineEdit.text()) - cfg.utls.setQGISRegSetting(cfg.regUSGSUser, user) - cfg.utls.setQGISRegSetting(cfg.regUSGSPass, pswd) - - def rememberUserCheckbox(self): - if cfg.ui.remember_user_checkBox_2.isChecked(): - self.rememberUser() - else: - cfg.utls.setQGISRegSetting(cfg.regUSGSUser, "") - cfg.utls.setQGISRegSetting(cfg.regUSGSPass, "") - - # add rubber band - def addRubberBandPolygon(self, pointUL, pointLR): - try: - self.clearCanvasPoly() - except: - pass - pointF = cfg.QtCoreSCP.QPointF() - polF = cfg.QtGuiSCP.QPolygonF() - pointF.setX(pointUL.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - pointF.setX(pointLR.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - pointF.setX(pointLR.x()) - pointF.setY(pointLR.y()) - polF.append(pointF) - pointF.setX(pointUL.x()) - pointF.setY(pointLR.y()) - polF.append(pointF) - pointF.setX(pointUL.x()) - pointF.setY(pointUL.y()) - polF.append(pointF) - g = cfg.qgisCoreSCP.QgsGeometry().fromQPolygonF(polF) - self.rbbrBndPol.setToGeometry(g, None) - clr = cfg.QtGuiSCP.QColor('#ff0000') - clr.setAlpha(50) - self.rbbrBndPol.setFillColor(clr) - self.rbbrBndPol.setWidth(3) - - # clear canvas - def clearCanvasPoly(self): - self.rbbrBndPol.reset() - cfg.cnvs.refresh() - - # Activate pointer - def pointerActive(self): - # connect to click - t = cfg.dwnlPrdPnt - cfg.cnvs.setMapTool(t) - px = cfg.QtGuiSCP.QPixmap(':/pointer/icons/pointer/ROI_pointer.svg') - c = cfg.QtGuiSCP.QCursor(px) - cfg.cnvs.setCursor(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'pointer active: Landsat') - - # left click pointer - def pointerLeftClick(self, point): - self.pointerClickUL(point) - - # right click pointer - def pointerRightClick(self, point): - self.pointerClickLR(point) - - # show area - def showArea(self): - pCrs = cfg.utls.getQGISCrs() - # WGS84 EPSG 4326 - iCrs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem() - iCrs.createFromProj4('+proj=longlat +datum=WGS84 +no_defs') - try: - UL = cfg.qgisCoreSCP.QgsPointXY(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text())) - UL1 = cfg.utls.projectPointCoordinates(UL, iCrs, pCrs) - LR = cfg.qgisCoreSCP.QgsPointXY(float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - LR1 = cfg.utls.projectPointCoordinates(LR, iCrs, pCrs) - self.addRubberBandPolygon(UL1, LR1) - except: - pass - - # set coordinates - def pointerClickLR(self, point): - pCrs = cfg.utls.getQGISCrs() - # WGS84 EPSG 4326 - iCrs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem('EPSG:4326') - point1 = cfg.utls.projectPointCoordinates(point, pCrs, iCrs) - if point1 is not False: - try: - if float(cfg.ui.UX_lineEdit_3.text()) < point1.x(): - cfg.ui.LX_lineEdit_3.setText(str(point1.x())) - else: - cfg.ui.LX_lineEdit_3.setText(str(cfg.ui.UX_lineEdit_3.text())) - cfg.ui.UX_lineEdit_3.setText(str(point1.x())) - if float(cfg.ui.UY_lineEdit_3.text()) > point1.y(): - cfg.ui.LY_lineEdit_3.setText(str(point1.y())) - else: - cfg.ui.LY_lineEdit_3.setText(str(cfg.ui.UY_lineEdit_3.text())) - cfg.ui.UY_lineEdit_3.setText(str(point1.y())) - except: - cfg.ui.LX_lineEdit_3.setText(str(point1.x())) - cfg.ui.LY_lineEdit_3.setText(str(point1.y())) - self.showArea() - - # set coordinates - def pointerClickUL(self, point): - pCrs = cfg.utls.getQGISCrs() - # WGS84 EPSG 4326 - iCrs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem('EPSG:4326') - point1 = cfg.utls.projectPointCoordinates(point, pCrs, iCrs) - if point1 is not False: - try: - if float(cfg.ui.LX_lineEdit_3.text()) > point1.x(): - cfg.ui.UX_lineEdit_3.setText(str(point1.x())) - else: - cfg.ui.UX_lineEdit_3.setText(str(cfg.ui.LX_lineEdit_3.text())) - cfg.ui.LX_lineEdit_3.setText(str(point1.x())) - if float(cfg.ui.LY_lineEdit_3.text()) < point1.y(): - cfg.ui.UY_lineEdit_3.setText(str(point1.y())) - else: - cfg.ui.UY_lineEdit_3.setText(str(cfg.ui.LY_lineEdit_3.text())) - cfg.ui.LY_lineEdit_3.setText(str(point1.y())) - except: - cfg.ui.UX_lineEdit_3.setText(str(point1.x())) - cfg.ui.UY_lineEdit_3.setText(str(point1.y())) - self.showArea() - - # save download table - def saveDownloadTable(self, file = None): - downloadTable = cfg.utls.tableToText(cfg.ui.download_images_tableWidget) - if file is None: - cfg.utls.writeProjectVariable('SCP_DownloadTable', str(downloadTable)) - else: - try: - l = open(file, 'w') - except: - pass - try: - l.write(downloadTable) - l.close() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # open download table - def openDownloadTable(self, file = None): - if file is None: - text = cfg.utls.readProjectVariable('SCP_DownloadTable', '') - else: - f = open(file, 'r') - text = f.read() - if len(text) > 0: - downloadTable = cfg.utls.textToTable(cfg.ui.download_images_tableWidget, text) - if downloadTable == 'No': - cfg.utls.clearTable(cfg.ui.download_images_tableWidget) - cfg.mx.msgErr19() - - # import table file - def importTableText(self): - file = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a text file of product table'), '', 'txt (*.txt)') - if len(file) > 0: - self.openDownloadTable(file) - - # find images - def exportTableText(self): - tW = cfg.ui.download_images_tableWidget - c = tW.rowCount() - if c > 0: - d = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export table to file'), '', '*.txt', 'txt') - if d is not False: - if d.lower().endswith('.txt'): - pass - else: - d = d + '.txt' - self.saveDownloadTable(d) - - # find images - def findImages(self): - self.downloadMetadata() - - # download image metadata - def downloadMetadata(self): - sat = cfg.ui.landsat_satellite_combo.currentText() - if sat in cfg.satSentinelList: - self.queryDatabaseSentinel2() - elif sat in cfg.satSentinel3List: - self.queryDatabaseSentinel3() - elif sat in cfg.satSentinel1List: - self.queryDatabaseSentinel1() - elif sat in cfg.satLandsatList: - self.downloadMetadataLandsat() - elif sat in cfg.satASTERtList: - self.downloadMetadataASTER() - elif sat in cfg.satMODIStList: - self.downloadMetadataMODIS() - elif sat in cfg.satGOEStList: - self.downloadMetadataGOES() - - # download image metadata from NASA CMR Search https://cmr.earthdata.nasa.gov/search/site/search_api_docs.html - def downloadMetadataLandsat(self): - listImgID = [] - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - if sat == cfg.usgsLandsat8: - NASAcollection = cfg.NASALandsat8Collection - USGScollection = cfg.usgsLandsat8Collection - elif sat == cfg.usgsLandsat7: - NASAcollection = cfg.NASALandsat7Collection - USGScollection = cfg.usgsLandsat7Collection - elif sat == cfg.usgsLandsat45: - NASAcollection = cfg.NASALandsat45Collection - USGScollection = cfg.usgsLandsat45Collection - elif sat == cfg.usgsLandsat15: - NASAcollection = cfg.NASALandsat15Collection - USGScollection = cfg.usgsLandsat15Collection - imageFindList = [] - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - try: - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - try: - cfg.uiUtls.addProgressBar() - cfg.QtWidgetsSCP.qApp.processEvents() - tW = cfg.ui.download_images_tableWidget - tW.setSortingEnabled(False) - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - # cloud cover returns 0 results - # without cloud cover - searchUrl = 'https://cmr.earthdata.nasa.gov/search/granules.echo10?bounding_box=' + cfg.ui.UX_lineEdit_3.text() + '%2C' + cfg.ui.LY_lineEdit_3.text() + '%2C' + cfg.ui.LX_lineEdit_3.text() + '%2C' + cfg.ui.UY_lineEdit_3.text() + '&echo_collection_id=' + NASAcollection + '&temporal=' + dateFrom + '%2C' + dateTo + 'T23%3A59%3A59.000Z&sort_key%5B%5D=-start_date&page_size=' + str(resultNum) + '&pretty=true' - # connect and search - searchResult = cfg.utls.NASASearch(searchUrl) - xmlFile = searchResult.read() - imgIDList = [] - doc = cfg.minidomSCP.parseString(xmlFile) - entries = doc.getElementsByTagName('Granule') - pages = len(entries) - page = 0 - cloudCover = 0 - for entry in entries: - page = page + 1 - cfg.uiUtls.updateBar(30 + int(page * 70 / pages), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - gId = entry.getElementsByTagName('GranuleUR')[0] - imgID = gId.firstChild.data - lId = entry.getElementsByTagName('LocalVersionId')[0] - lImgId = lId.firstChild.data - if imgID not in imgIDList: - imgIDList.append(imgID) - imgDispID = imgID - on = entry.getElementsByTagName('ProviderBrowseUrl') - url = on[0].getElementsByTagName('URL')[0] - imgPreview = url.firstChild.data - if 'https://ims.cr.usgs.gov/browse/' not in imgPreview and 'https://earthexplorer.usgs.gov' not in imgPreview: - imgPreview = 'https://ims.cr.usgs.gov/browse/' + imgPreview - StartCoordinate1 = entry.getElementsByTagName('StartCoordinate1')[0] - path = StartCoordinate1.firstChild.data - StartCoordinate2 = entry.getElementsByTagName('StartCoordinate2')[0] - row = StartCoordinate2.firstChild.data - dt = entry.getElementsByTagName('BeginningDateTime')[0] - imgDate = dt.firstChild.data - imgDate = cfg.datetimeSCP.datetime.strptime(imgDate[0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M:%S') - try: - cc = entry.getElementsByTagName('QAPercentCloudCover')[0] - cloudCover = cc.firstChild.data - except: - addAttrs = entry.getElementsByTagName('AdditionalAttribute') - for addAttr in addAttrs: - addAttrNames = addAttr.getElementsByTagName('Name') - for addAttrName in addAttrNames: - addAttrNameC = addAttrName.firstChild.data - if addAttrNameC == 'LandCloudCover': - addAttrValues = addAttr.getElementsByTagName('Values')[0] - addAttrVal = addAttrValues.getElementsByTagName('Value')[0] - cloudCover = addAttrVal.firstChild.data - PointLatitude = entry.getElementsByTagName('PointLatitude') - PointLongitude = entry.getElementsByTagName('PointLongitude') - lat = [] - for latit in PointLatitude: - lat.append(float(latit.firstChild.data)) - lon = [] - for longi in PointLongitude: - lon.append(float(longi.firstChild.data)) - listImgID.append([imgID, imgDate, cloudCover, path, row, lon, lat, imgPreview, lImgId]) - c = tW.rowCount() - for imID in listImgID: - if len(imageFindList) > 0: - for iF in imageFindList: - if iF in imID[0].lower(): - imgCheck = 'Yes' - break - else: - imgCheck = 'No' - # workaround for cloud cover filter - elif maxCloudCover < float(imID[2]): - imgCheck = 'No' - else: - imgCheck = 'Yes' - if imgCheck == 'Yes': - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imID[0], c, 1) - cfg.utls.addTableItem(tW, str(imID[1]), c, 2) - cfg.utls.addTableItem(tW, int(round(float(imID[2]))), c, 3) - cfg.utls.addTableItem(tW, imID[3], c, 4) - cfg.utls.addTableItem(tW, imID[4], c, 5) - min_lon = min(imID[5]) - max_lon = max(imID[5]) - min_lat = min(imID[6]) - max_lat = max(imID[6]) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW,float(max_lon), c, 9) - cfg.utls.addTableItem(tW, USGScollection, c, 10) - cfg.utls.addTableItem(tW, imID[7], c, 11) - cfg.utls.addTableItem(tW, NASAcollection, c, 12) - cfg.utls.addTableItem(tW, imID[8], c, 13) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Landsat images') - c = tW.rowCount() - if c == 0: - cfg.mx.msg21() - except Exception as err: - cfg.mx.msgErr39() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # Add OpenStreetMap to the map as described in https://wiki.openstreetmap.org/wiki/QGIS (© OpenStreetMap contributors. The cartography is licensed as CC BY-SA) - def displayOSM(self): - cfg.utls.addRasterLayer(cfg.plgnDir + '/docs/openstreetmap_wms.xml', 'OpenStreetMap') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' OSM added') - - # display images - def displayImages(self): - tW = cfg.ui.download_images_tableWidget - ids = [] - for i in tW.selectedIndexes(): - ids.append(i.row()) - id = set(ids) - if len(id) > 0: - progressStep = 100 / len(id) - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - progress = 0 - for i in id: - sat = str(tW.item(i, 0).text()) - if sat in cfg.satSentinelList: - self.displayGranulesSentinel2(i, progress) - elif sat in cfg.satSentinel3List: - self.displayGranulesSentinel3(i, progress) - elif sat in cfg.satSentinel1List: - self.displayGranulesSentinel1(i, progress) - elif sat in cfg.satLandsatList or sat in cfg.satASTERtList or sat in cfg.satMODIStList: - self.displayImagesNASA(i, progress) - progress = progress + progressStep - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading ...')) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.cnvs.refresh() - - # display images - def displayImagesNASA(self, row, progress, preview = 'No'): - i = row - tW = cfg.ui.download_images_tableWidget - sat = str(tW.item(i, 0).text()) - imgID = str(tW.item(i, 1).text()) - path = str(tW.item(i, 4).text()) - row = str(tW.item(i, 5).text()) - min_lat = str(tW.item(i, 6).text()) - min_lon = str(tW.item(i, 7).text()) - max_lat = str(tW.item(i, 8).text()) - max_lon = str(tW.item(i, 9).text()) - jpg = str(tW.item(i, 11).text()) - # image preview - imOut = cfg.tmpDir + '//' + imgID + '_thumb.jpg' - if preview == 'Yes' and cfg.osSCP.path.isfile(imOut): - self.previewInLabel(imOut) - return imOut - if cfg.osSCP.path.isfile(cfg.tmpDir + '//' + imgID + '.vrt'): - l = cfg.utls.selectLayerbyName(imgID) - if l is not None: - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - else: - r =cfg.utls.addRasterLayer(cfg.tmpDir + '//' + imgID + '.vrt') - cfg.utls.setRasterColorComposite(r, 1, 2, 3) - else: - self.downloadThumbnail(imgID, path, row, min_lat, min_lon, max_lat, max_lon, jpg, sat, progress, preview) - if cfg.osSCP.path.isfile(cfg.tmpDir + '//' + imgID + '.vrt'): - r =cfg.utls.addRasterLayer(cfg.tmpDir + '//' + imgID + '.vrt') - cfg.utls.setRasterColorComposite(r, 1, 2, 3) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' thumbnails displayed') - - # display image in label - def previewInLabel(self, imagePath): - tmpImage = cfg.reSCP.sub(r'\.jp2$', '.png', str(imagePath)) - if imagePath.endswith('.jp2') and not cfg.osSCP.path.isfile(tmpImage): - cfg.utls.getGDALForMac() - # georeference thumbnail - a = cfg.gdalPath + 'gdal_translate ' + imagePath + ' ' + tmpImage + ' -of PNG' - if cfg.sysSCPNm != 'Windows': - a = cfg.shlexSCP.split(a) - try: - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - sP = cfg.subprocessSCP.Popen(a, shell=False, startupinfo = startupinfo, stdin = cfg.subprocessSCP.DEVNULL) - else: - sP = cfg.subprocessSCP.Popen(a, shell=False) - sP.wait() - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - imagePath = tmpImage - label = cfg.ui.image_preview_label - pixmap = cfg.QtGuiSCP.QPixmap(imagePath).scaled(300, 300) - label.setPixmap(pixmap) - return imagePath - - # table click - def tableClick(self): - tW = cfg.ui.download_images_tableWidget - i = tW.currentRow() - ids = [] - for tI in tW.selectedIndexes(): - ids.append(tI.row()) - idT = set(ids) - if i >= 0 and not len(idT) > 1: - cfg.uiUtls.addProgressBar() - progress = 10 - sat = str(tW.item(i, 0).text()) - if sat in cfg.satSentinelList: - self.displayGranulesSentinel2(i, progress, 'Yes') - elif sat in cfg.satSentinel3List: - self.displayGranulesSentinel3(i, progress, 'Yes') - elif sat in cfg.satSentinel1List: - self.displayGranulesSentinel1(i, progress, 'Yes') - elif sat in cfg.satLandsatList or sat in cfg.satASTERtList or sat in cfg.satMODIStList: - self.displayImagesNASA(i, progress, 'Yes') - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading ...')) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image index: ' + str(i)) - - # download thumbnail - def downloadThumbnail(self, imgID, path, row, min_lat, min_lon, max_lat, max_lon, imageJPG, sat, progress = None, preview = 'No'): - imOut = cfg.tmpDir + '//' + imgID + '_thumb.jpg' - if sat in cfg.satLandsatList: - check = cfg.utls.downloadFile(imageJPG, imOut, imgID + '_thumb.jpg', progress) - elif sat == cfg.usgsASTER: - user = cfg.ui.user_usgs_lineEdit_2.text() - password = cfg.ui.password_usgs_lineEdit_2.text() - check = cfg.utls.passwordConnectPython(user, password, imageJPG, 'urs.earthdata.nasa.gov', imOut, progress, 'No') - elif sat in cfg.satMODIStList: - user = cfg.ui.user_usgs_lineEdit_2.text() - password =cfg.ui.password_usgs_lineEdit_2.text() - check = cfg.utls.passwordConnectPython(user, password, imageJPG, 'urs.earthdata.nasa.gov', imOut, progress, 'No') - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID + '_thumb.jpg ', cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - cfg.mx.msgErr40() - - # remove highlighted images from table - def removeImageFromTable(self): - tW = cfg.ui.download_images_tableWidget - cfg.utls.removeRowsFromTable(tW) - - # download images in table - def downloadImages(self): - tW = cfg.ui.download_images_tableWidget - c = tW.rowCount() - if c > 0: - d = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Download the images in the table (requires internet connection)')) - if len(d) > 0: - self.downloadSentinelImages(d) - self.downloadSentinel3Images(d) - self.downloadSentinel1Images(d) - self.downloadLandsatImages(d) - self.downloadASTERImages(d) - self.downloadMODISImages(d) - self.downloadGOESImages(d) - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.utls.finishSound() - - # download Landsat data - def downloadLandsatImages(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - if cfg.ui.virtual_download_checkBox.isChecked(): - virtualDownload = 'vrt' - else: - virtualDownload = None - try: - iLeft = float(cfg.ui.UX_lineEdit_3.text()) - iTop = float(cfg.ui.UY_lineEdit_3.text()) - iRight = float(cfg.ui.LX_lineEdit_3.text()) - iBottom = float(cfg.ui.LY_lineEdit_3.text()) - extentList = [iLeft, iRight, iTop, iBottom] - except: - extentList = None - c = tW.rowCount() - progressStep = 100 / c - progressStep2 = progressStep/12 - progress = 0 - outDirList = [] - imgList = [] - links = [] - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat in cfg.satLandsatList: - imgID = str(tW.item(i, 1).text()) - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgID, 'Yes') is None: - pass - else: - acquisitionDate = str(tW.item(i, 2).text()) - path = str(tW.item(i, 4).text()) - row = str(tW.item(i, 5).text()) - USGScollection = str(tW.item(i, 10).text()) - NASAcollection = str(tW.item(i, 12).text()) - lImgID = str(tW.item(i, 13).text()) - outDir = outputDirectory + '/' + imgID + '_' + acquisitionDate[0:10] - oDir = cfg.utls.makeDirectory(outDir) - if oDir is None: - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr58() - return 'No' - outDirList.append(outDir) - # download Landsat data using the service https://storage.googleapis.com/gcp-public-data-landsat - sat = imgID[0:4] - collID = '01' - urlL = 'https://storage.googleapis.com/gcp-public-data-landsat/'+ sat + '/' + collID +'/' + path.zfill(3) + '/' + row.zfill(3) +'/' + imgID + '/' + imgID + '_' - check = cfg.utls.downloadFile( urlL + 'MTL.txt', outDir + '//' + imgID + '_MTL.txt', imgID + '_MTL.txt', progress) - if check == 'Yes': - meta = open(outDir + '//' + imgID + '_MTL.txt', 'r').read() - if 'NoSuchKey' in meta: - check = 'No' - if check == 'Yes': - links.append(urlL + 'MTL.txt') - if NASAcollection == cfg.NASALandsat8Collection: - bRange = [1,2,3,4,5,6,7,8,9,10,11,12] - elif NASAcollection == cfg.NASALandsat7Collection: - bRange = [1,2,3,4,5,6,7,8,12] - elif NASAcollection == cfg.NASALandsat45Collection: - bRange = [1,2,3,4,5,6,7,12] - elif NASAcollection == cfg.NASALandsat15Collection: - if sat[-1] == '4' or sat[-1]== '5': - bRange = [1,2,3,4] - else: - bRange = [4,5,6,7] - for i in bRange: - progress = progress + progressStep2 - if cfg.actionCheck == 'Yes': - if exporter == 'Yes': - links.append(urlL + 'B' + str(i) + '.TIF') - else: - t = 'cfg.ui.checkBox_band_' + str(i) + '.isChecked()' - checkBand = eval(t) - if checkBand is True: - # Landsat 7 bands 6 - if NASAcollection == cfg.NASALandsat7Collection and i == 6: - self.downloadDispatcher( urlL + 'B6_VCID_1.TIF', outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_1.TIF', imgID + '_B6_VCID_1.TIF', progress, extentList, virtualDownload) - if cfg.osSCP.path.isfile(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_1.TIF'): - imgList.append(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_1.TIF') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image downloaded ' + imgID + '_B6_VCID_1.TIF') - self.downloadDispatcher( urlL + 'B6_VCID_2.TIF', outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_1.TIF', imgID + '_B6_VCID_2.TIF', progress, extentList, virtualDownload) - if cfg.osSCP.path.isfile(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_2.TIF'): - imgList.append(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B6_VCID_2.TIF') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image downloaded ' + imgID + '_B6_VCID_2.TIF') - else: - self.downloadDispatcher(urlL + 'B' + str(i) + '.TIF', outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B' + str(i) + '.TIF', imgID + '_B' + str(i) + '.TIF', progress, extentList, virtualDownload) - if cfg.osSCP.path.isfile(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B' + str(i) + '.TIF'): - imgList.append(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_B' + str(i) + '.TIF') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image downloaded ' + imgID + '_B' + str(i)) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - if cfg.actionCheck == 'Yes': - progress = progress + progressStep2 - if cfg.ui.checkBox_band_12.isChecked(): - if exporter == 'Yes': - links.append(urlL + 'BQA.TIF') - else: - self.downloadDispatcher( urlL + 'BQA.TIF', outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_BQA.TIF', imgID + '_BQA.TIF', progress, extentList, virtualDownload) - if cfg.osSCP.path.isfile(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_BQA.TIF'): - imgList.append(outDir + '//' + imgID + '_' + acquisitionDate[0:10] + '_BQA.TIF') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image downloaded ' + imgID + '_BQA.TIF') - else: - outUrl = self.downloadLandsatImagesFromUSGS(lImgID, USGScollection, row, outDir, progress, exporter) - links.append(outUrl) - progress = progress + progressStep - else: - cfg.uiUtls.removeProgressBar() - return 'No' - if exporter == 'Yes': - return links - else: - cfg.cnvs.setRenderFlag(False) - if cfg.ui.preprocess_checkBox.isChecked(): - n = len(outDirList) - i = 0 - for d in outDirList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.landsatT.populateTable(d, 'Yes') - o = d + '_converted' - cfg.utls.makeDirectory(o) - cfg.landsatT.landsat(d, o, 'Yes') - elif cfg.ui.load_in_QGIS_checkBox.isChecked(): - for d in outDirList: - try: - for f in cfg.osSCP.listdir(d): - if f.lower().endswith('.tif'): - r =cfg.utls.addRasterLayer(d + '/' + f) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - - # download image preview - def downloadLandsatImagesFromUSGS(self, imageID, collection, row, outputDirectory, progress, exporter = 'No'): - url = 'http://earthexplorer.usgs.gov/download/' + collection + '/' + imageID + '/STANDARD/EE' - if exporter == 'Yes': - return url - else: - user = cfg.ui.user_usgs_lineEdit.text() - password =cfg.ui.password_usgs_lineEdit.text() - try: - imgID = imageID + '.tar.gz' - check = cfg.utls.downloadFileUSGS(user, password, 'https://ers.cr.usgs.gov', url, cfg.tmpDir + '//' + imgID, imgID, progress, 'Yes') - if str(check) == 'Cancel action': - return check - if cfg.osSCP.path.getsize(cfg.tmpDir + '//' + imgID) > 10000: - tarFiles = cfg.tarfileSCP.open(cfg.tmpDir + '//' + imgID, 'r:gz') - tarFiles.extractall(outputDirectory) - tarFiles.close() - cfg.osSCP.remove(cfg.tmpDir + '//' + imgID) - return url - else: - cfg.mx.msgErr55(imgID) - return 'No' - except Exception as err: - cfg.mx.msgErr50(str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # select the download type - def downloadDispatcher(self, url, outputPath, fileName = None, progress = None, extentList = None, downloadType = None): - if downloadType is None: - cfg.utls.downloadFile(url, outputPath, fileName, progress) - elif downloadType == 'vrt': - cfg.utls.downloadVirtualImages(url, outputPath, fileName, progress, extentList) - - # export links - def exportLinks(self): - tW = cfg.ui.download_images_tableWidget - c = tW.rowCount() - if c > 0: - d = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Export download links'), '', '*.txt', 'txt') - if d is not False: - if d.lower().endswith('.txt'): - pass - else: - d = d + '.txt' - linksS = self.downloadSentinelImages(cfg.tmpDir, 'Yes') - linksS3 = self.downloadSentinel3Images(cfg.tmpDir, 'Yes') - linksS1 = self.downloadSentinel1Images(cfg.tmpDir, 'Yes') - linksL = self.downloadLandsatImages(cfg.tmpDir, 'Yes') - linksA = self.downloadASTERImages(cfg.tmpDir, 'Yes') - linksM = self.downloadMODISImages(cfg.tmpDir, 'Yes') - linksG = self.downloadGOESImages(cfg.tmpDir, 'Yes') - links = linksS + linksS3 + linksS1 + linksL + linksA + linksM + linksG - if links == 'No': - pass - else: - l = open(d, 'w') - for t in links: - l.write(t + '\n') - l.close() - cfg.utls.finishSound() - cfg.uiUtls.removeProgressBar() - - # check all bands - def checkAllBands(self): - if self.checkAll == 'Yes': - for i in range(1, 13): - t = 'cfg.ui.checkBox_band_' + str(i) + '.setCheckState(2)' - eval(t) - self.checkAll = 'No' - else: - for i in range(1, 13): - t = 'cfg.ui.checkBox_band_' + str(i) + '.setCheckState(0)' - eval(t) - self.checkAll = 'Yes' - - # clear table - def clearTable(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset signature list'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to clear the table?')) - if a == 'Yes': - tW = cfg.ui.download_images_tableWidget - cfg.utls.clearTable(tW) - - # show hide area radio button - def showHideArea(self): - try: - if cfg.ui.show_area_radioButton_2.isChecked(): - self.showArea() - else: - self.clearCanvasPoly() - except: - pass - -### Sentinel-3 - - # read database - def queryDatabaseSentinel3(self): - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - imageFindList = [] - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - imgQuery = 'OL_1_EFR*' - else: - imageFindList.append('s3') - imgQuery = 'OL_1_EFR*' - try: - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - if abs(float(cfg.ui.UX_lineEdit_3.text()) - float(cfg.ui.LX_lineEdit_3.text())) > 10 or abs(float(cfg.ui.UY_lineEdit_3.text()) - float(cfg.ui.LY_lineEdit_3.text())) > 10: - cfg.mx.msgWar18() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - cfg.uiUtls.addProgressBar() - tW = cfg.ui.download_images_tableWidget - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - cfg.QtWidgetsSCP.qApp.processEvents() - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - imageTableList = [] - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # loop for results - maxResultNum = resultNum - if maxResultNum > 100: - maxResultNum = 100 - for startR in range(0, resultNum, maxResultNum): - url = topUrl + '/search?q=' + imgQuery + '%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]%20AND%20footprint:%22Intersects(POLYGON((' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ')))%22' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - #url = topUrl + '/search?q=' + imgQuery + '%20AND%20cloudcoverpercentage:[0%20TO%20' + str(maxCloudCover) + ']%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]%20AND%20footprint:%22Intersects(POLYGON((' + cfg.ui.UX_lineEdit_3.text() + "%20" + cfg.ui.UY_lineEdit_3.text() + "," + cfg.ui.UX_lineEdit_3.text() + "%20" + cfg.ui.LY_lineEdit_3.text() + "," + cfg.ui.LX_lineEdit_3.text() + "%20" + cfg.ui.LY_lineEdit_3.text() + "," + cfg.ui.LX_lineEdit_3.text() + "%20" + cfg.ui.UY_lineEdit_3.text() + "," + cfg.ui.UX_lineEdit_3.text() + "%20" + cfg.ui.UY_lineEdit_3.text() + ')))%22' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - cloudcoverpercentage = 0 - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, quiet = 'Yes') - if response == 'No': - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - topUrl =topLevelUrl - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl) - if response == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - #info = response.info() - xml = response.read() - tW.setSortingEnabled(False) - try: - doc = cfg.minidomSCP.parseString(xml) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if 'HTTP Status 500' in xml: - cfg.mx.msgWar24() - else: - cfg.mx.msgErr40() - cfg.uiUtls.removeProgressBar() - return 'No' - entries = doc.getElementsByTagName('entry') - e = 0 - for entry in entries: - if cfg.actionCheck == 'Yes': - productType = 'OL_1_EFR___' - e = e + 1 - cfg.uiUtls.updateBar(30 + e * int(70/len(entries)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - imgNameTag = entry.getElementsByTagName('title')[0] - imgName = imgNameTag.firstChild.data - imgIDTag = entry.getElementsByTagName('id')[0] - imgID = imgIDTag.firstChild.data - summary = entry.getElementsByTagName('summary')[0] - infos = summary.firstChild.data.split(',') - for info in infos: - infoIt = info.strip().split(' ') - if infoIt[0] == 'Date:': - acqDateI = infoIt[1] - if infoIt[0] == 'Size:': - size = infoIt[1] + ' ' + infoIt[2] - strings = entry.getElementsByTagName('str') - for x in strings: - attr = x.getAttribute('name') - if attr == 'producttype': - productType = x.firstChild.data - if attr == 'footprint': - footprintCoord = x.firstChild.data.replace('MULTIPOLYGON (((', '').replace('POLYGON ((', '').replace(')))', '').replace('))', '').split(',') - xList = [] - yList = [] - for coords in footprintCoord: - cc = coords.lstrip() - xList.append(float(cc.split(' ')[0])) - yList.append(float(cc.split(' ')[1])) - min_lon = min(xList) - max_lon = max(xList) - min_lat = min(yList) - max_lat = max(yList) - doubles = entry.getElementsByTagName('double') - for xd in doubles: - attr = xd.getAttribute('name') - if attr == 'cloudcoverpercentage': - cloudcoverpercentage = xd.firstChild.data - try: - if cfg.actionCheck == 'Yes': - for filter in imageFindList: - if filter in imgName.lower(): - acZoneI = imgName[64:81] - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - imgPreview = topUrl + "/odata/v1/Products('" + imgID + "')/Products('Quicklook')/$value" - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgName, c, 1) - cfg.utls.addTableItem(tW, acqDateI, c, 2) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3) - cfg.utls.addTableItem(tW, acZoneI, c, 4) - cfg.utls.addTableItem(tW, "", c, 5) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW, float(max_lon), c, 9) - cfg.utls.addTableItem(tW, size, c, 10) - cfg.utls.addTableItem(tW, imgPreview, c, 11) - cfg.utls.addTableItem(tW, imgID, c, 12) - cfg.utls.addTableItem(tW, imgName, c, 13) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Sentinel images") - - # display granule preview - def displayGranulesSentinel3(self, row, progress, preview = 'No'): - i = row - tW = cfg.ui.download_images_tableWidget - imgNm = str(tW.item(i, 1).text()) - acquisitionDate = str(tW.item(i, 2).text()) - imgID = imgNm + '.vrt' - url = str(tW.item(i, 11).text()) - # image preview - imOut = cfg.tmpDir + '//' + imgID - if preview == 'Yes' and cfg.osSCP.path.isfile(imOut): - self.previewInLabel(imOut) - return imOut - if cfg.osSCP.path.isfile(imOut + '.vrt'): - l = cfg.utls.selectLayerbyName(imgID) - if l is not None: - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - else: - r =cfg.utls.addRasterLayer(imOut, imgID) - else: - min_lat = str(tW.item(i, 6).text()) - min_lon = str(tW.item(i, 7).text()) - max_lat = str(tW.item(i, 8).text()) - max_lon = str(tW.item(i, 9).text()) - self.downloadThumbnailSentinel3(imgID, min_lat, min_lon, max_lat, max_lon, url, progress, preview) - if cfg.osSCP.path.isfile(imOut + '.vrt'): - r =cfg.utls.addRasterLayer(imOut + '.vrt', imgID) - cfg.utls.setRasterColorComposite(r, 1, 2, 3) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " granules displayed") - - # download image preview - def downloadThumbnailSentinel3(self, imgID, min_lat, min_lon, max_lat, max_lon, imageJPG, progress = None, preview = 'No'): - imOut = cfg.tmpDir + '//' + imgID - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress, quiet = 'Yes') - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - imageJPG = imageJPG.replace(topUrl, topLevelUrl) - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress) - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - cfg.mx.msgErr40bis() - - # download images - def downloadSentinel3Images(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - outDirList = [] - imgList = [] - links = [] - c = tW.rowCount() - progressStep = 100 / c - progress = 0 - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat == cfg.esaSentinel3: - imgName = str(tW.item(i, 13).text()) - acquisitionDate = str(tW.item(i, 2).text()) - imgID = str(tW.item(i, 12).text()) - imgName2 = str(tW.item(i, 1).text()) - imgJp2 = imgName2 + '.vrt' - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgJp2, 'Yes') is None: - pass - else: - outFiles = [] - outDirList.append(outputDirectory + '//' + imgName2) - progress = progress + progressStep - if exporter == 'No': - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgName2) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # download bands - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_1, '01', imgID, imgName, imgName2, acquisitionDate,outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_2, '02', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_3, '03', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_4, '04', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_5, '05', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_6, '06', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_7, '07', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_8, '08', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_9, '09', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_10, '10', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_11, '11', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_12, '12', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_13, '13', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_14, '14', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_15, '15', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_16, '16', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_17, '17', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_18, '18', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_19, '19', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_20, '20', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.checkBoxs3_band_21, '21', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.s3_ancillary_data_checkBox, 'ancillary1', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.s3_ancillary_data_checkBox, 'ancillary2', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.s3_ancillary_data_checkBox, 'ancillary3', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - self.checkSentinel3ImageBands(cfg.ui.s3_ancillary_data_checkBox, 'ancillary4', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links) - for oFile in outFiles: - cfg.shutilSCP.copy(oFile[0], oFile[1]) - cfg.osSCP.remove(oFile[0]) - else: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.ui.preprocess_checkBox.isChecked() and exporter == 'No': - n = len(outDirList) - i = 0 - for d in outDirList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.sentinel3T.populateTable(d, 'Yes') - o = d + '_con' - oDir = cfg.utls.makeDirectory(o) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.sentinel3T.sentinel3(d, o, 'Yes') - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return links - - # check band download - def checkSentinel3ImageBands(self, checkbox, bandNumber, imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFilesList, linksList): - if cfg.actionCheck == 'Yes': - if checkbox.isChecked(): - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl + '/odata/v1/Products' - topUrl2 =topLevelUrl - if bandNumber == 'ancillary1': - urlL = topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SEN3')/Nodes('tie_geometries.nc')/$value" - outFile = cfg.tmpDir + "//" + imgName[0:15] + "_" + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName2 + '//tie_geometries.nc' - elif bandNumber == 'ancillary2': - urlL = topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SEN3')/Nodes('qualityFlags.nc')/$value" - outFile = cfg.tmpDir + "//" + imgName[0:15] + "_" + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName2 + '//qualityFlags.nc' - elif bandNumber == 'ancillary3': - urlL = topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SEN3')/Nodes('geo_coordinates.nc')/$value" - outFile = cfg.tmpDir + '//' + imgName[0:15] + '_' + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName2 + '//geo_coordinates.nc' - elif bandNumber == 'ancillary4': - urlL = topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SEN3')/Nodes('instrument_data.nc')/$value" - outFile = cfg.tmpDir + '//' + imgName[0:15] + '_' + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName2 + '//instrument_data.nc' - else: - urlL = topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SEN3')/Nodes('Oa" + bandNumber + "_radiance.nc')/$value" - outFile = cfg.tmpDir + '//' + imgName[0:15] + '_' + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName2 + '//' + imgName[0:15] + '_' + acquisitionDate[0:10] + '_B' + bandNumber + '.nc' - if exporter == 'No': - self.downloadFileSentinel3(urlL, outFile, progress) - try: - if cfg.osSCP.path.getsize(outFile) < 100000: - self.downloadFileSentinel3(urlL, outFile, progress) - if cfg.osSCP.path.getsize(outFile) < 100000: - cfg.mx.msgWar23(imgName2 + '_B' + bandNumber) - outFilesList.append([outFile, outCopyFile]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - else: - linksList.append(urlL) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - - # download file - def downloadFileSentinel3(self, url, output, progress = None): - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress, quiet = 'Yes') - if check == 'Yes': - return output - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress) - if check == 'Yes': - return output - else: - cfg.mx.msgErr40() - return 'No' - -### Sentinel-2 - - # user - def rememberUserSentinel2(self): - if cfg.ui.remember_user_checkBox.isChecked(): - user = cfg.ui.user_scihub_lineEdit.text() - pswd = cfg.utls.encryptPassword(cfg.ui.password_scihub_lineEdit.text()) - cfg.utls.setQGISRegSetting(cfg.regSciHubUser, user) - cfg.utls.setQGISRegSetting(cfg.regSciHubPass, pswd) - - def rememberUserCheckboxSentinel2(self): - if cfg.ui.remember_user_checkBox.isChecked(): - self.rememberUserSentinel2() - else: - cfg.utls.setQGISRegSetting(cfg.regSciHubUser, '') - cfg.utls.setQGISRegSetting(cfg.regSciHubPass, '') - - def alternativeCheckboxSentinel2(self): - if cfg.ui.sentinel2_alternative_search_checkBox.isChecked(): - cfg.utls.setQGISRegSetting(cfg.regSentinelAlternativeSearch, '2') - else: - cfg.utls.setQGISRegSetting(cfg.regSentinelAlternativeSearch, '0') - - # reset service - def resetService(self): - cfg.ui.sentinel_service_lineEdit.setText(cfg.SciHubServiceNm) - cfg.utls.setQGISRegSetting(cfg.regSciHubService, cfg.SciHubServiceNm) - - # service - def rememberService(self): - service = cfg.ui.sentinel_service_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regSciHubService, service) - - # download file - def downloadFileSentinel2(self, url, output, progress = None): - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress, quiet = 'Yes') - if check == 'Yes': - return 'Yes' - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ' + url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress) - if check == 'Yes': - return output - else: - cfg.mx.msgErr40bis() - return 'No' - - # display granule preview - def displayGranulesSentinel2(self, row, progress, preview = 'No'): - i = row - tW = cfg.ui.download_images_tableWidget - imgNm = str(tW.item(i, 1).text()) - acquisitionDate = str(tW.item(i, 2).text()) - if imgNm[0:4] == 'L1C_': - imgID = imgNm + '_p.jp2' - elif imgNm[0:4] == 'L2A_': - imgID = imgNm + '_p.jp2' - else: - imgID = imgNm[0:-7] + '_p.jp2' - url = str(tW.item(i, 11).text()) - # image preview - imOut = cfg.tmpDir + '//' + imgID - if preview == 'Yes' and cfg.osSCP.path.isfile(imOut): - self.previewInLabel(imOut) - return imOut - if cfg.osSCP.path.isfile(imOut + '.vrt') or cfg.osSCP.path.isfile(cfg.reSCP.sub(r'\.jp2$', '.png', str(imOut)) + '.vrt' ): - l = cfg.utls.selectLayerbyName(imgID) - if l is not None: - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - else: - r =cfg.utls.addRasterLayer(imOut + '.vrt', imgID) - else: - if 'storage.googleapis.com' in url: - check = cfg.utls.downloadFile(url, imOut, None, progress) - else: - check = self.downloadFileSentinel2(url, imOut, progress) - if check != 'No': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - min_lat = str(tW.item(i, 6).text()) - min_lon = str(tW.item(i, 7).text()) - max_lat = str(tW.item(i, 8).text()) - max_lon = str(tW.item(i, 9).text()) - self.onflyGeorefImage(imOut, imOut + '.vrt', min_lon, max_lon, min_lat, max_lat) - if cfg.osSCP.path.isfile(imOut + '.vrt'): - r =cfg.utls.addRasterLayer(imOut + '.vrt', cfg.reSCP.sub(r'\.vrt$', '', str(imgID))) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' granules displayed') - - # use CREODIAS Finder API https://creodias.eu/ (from https://creodias.eu/eo-data-finder-api-manual the database is accessible free and anonymously, and open for anonymous access to everyone, no authorization is used). For other DIAS platforms see https://www.copernicus.eu/en/access-data/dias - def queryDatabaseSentinel2Alternative(self): - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - imageFindList = [] - m = 'S2*' - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower().replace('*', '')) - imgQuery = '' - if len(imageFindList) == 1: - imgQuery = m + '%20AND%20' - else: - imageFindList.append('s2') - imgQuery = '' - try: - NoRect = 'No' - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - if abs(float(cfg.ui.UX_lineEdit_3.text()) - float(cfg.ui.LX_lineEdit_3.text())) > 10 or abs(float(cfg.ui.UY_lineEdit_3.text()) - float(cfg.ui.LY_lineEdit_3.text())) > 10: - cfg.mx.msgWar18() - except Exception as err: - if len(imageFindList) == 1: - imgQuery = m + '*' + '%20AND%20' - NoRect = 'Yes' - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - cfg.uiUtls.addProgressBar() - imgQuery = cfg.ui.imageID_lineEdit.text() - if len(imgQuery) == 0: - imgQuery = 'S2' - tW = cfg.ui.download_images_tableWidget - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - cfg.QtWidgetsSCP.qApp.processEvents() - imageTableList = [] - # loop for results - maxResultNum = resultNum - if maxResultNum > 100: - maxResultNum = 100 - page = 0 - for startR in range(0, resultNum, maxResultNum): - page = page + 1 - if NoRect == 'Yes': - url = 'https://finder.creodias.eu/resto/api/collections/Sentinel2/search.json?cloudCover=[0%2C' + str(maxCloudCover) + ']&maxRecords=' + str(maxResultNum) + '&page=' + str(page) + '&sortParam=startDate&sortOrder=descending&status=all&dataset=ESA-DATASET' + '&productIdentifier=%25' + imgQuery + '%25&startDate=' + str(dateFrom) + 'T00%3A00%3A00Z&completionDate=' + str(dateTo) + 'T23%3A59%3A59Z' - else: - url = 'https://finder.creodias.eu/resto/api/collections/Sentinel2/search.json?cloudCover=[0%2C' + str(maxCloudCover) + ']&maxRecords=' + str(maxResultNum) + '&page=' + str(page) + '&sortParam=startDate&sortOrder=descending&status=all&dataset=ESA-DATASET' + '&productIdentifier=%25' + imgQuery + '%25&startDate=' + str(dateFrom) + 'T00%3A00%3A00Z&completionDate=' + str(dateTo) + 'T23%3A59%3A59Z&geometry=POLYGON((' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + '))' - jsonT = cfg.utls.createTempRasterPath('json') - check = cfg.utls.downloadFile(url, jsonT) - if check != 'Yes': - cfg.uiUtls.removeProgressBar() - return 'No' - try: - with open(jsonT) as jsonTF: - doc = cfg.jsonSCP.load(jsonTF) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr40() - cfg.uiUtls.removeProgressBar() - return 'No' - tW.setSortingEnabled(False) - entries = doc['features'] - e = 0 - for entry in entries: - if cfg.actionCheck == 'Yes': - productType = 'S2MSI1C' - e = e + 1 - cfg.uiUtls.updateBar(30 + e * int(70/len(entries)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - imgName = entry['properties']['title'].replace('.SAFE', '') - acqDateI = entry['properties']['startDate'] - productType = entry['properties']['productType'] - cloudcoverpercentage = entry['properties']['cloudCover'] - footprintCoord = entry['geometry']['coordinates'][0] - xList = [] - yList = [] - for coords in footprintCoord: - xList.append(float(coords[0])) - yList.append(float(coords[1])) - min_lon = min(xList) - max_lon = max(xList) - min_lat = min(yList) - max_lat = max(yList) - if cfg.actionCheck == 'Yes': - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - if productType == 'L1C': - url2 = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL1C.xml' - else: - url2 = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL2A.xml' - xml2T = cfg.utls.createTempRasterPath('xml') - check = cfg.utls.downloadFile(url2, xml2T) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' xml downloaded' ) - try: - newV = None - if xml2T is not None: - doc2 = cfg.minidomSCP.parse(xml2T) - else: - doc2 = cfg.minidomSCP.parseString(xml2) - try: - imgName2Tag = doc2.getElementsByTagName('IMAGE_FILE')[0] - except: - imgName2Tag = doc2.getElementsByTagName('IMAGE_FILE_2A')[0] - imgName2 = imgName2Tag.firstChild.data.split('/')[1] - if cfg.actionCheck == 'Yes': - for filter in imageFindList: - if filter in imgName.lower() or filter in imgName2.lower(): - acZoneI = imgName2.split("_")[1][1:] - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - if productType == 'L1C': - imgName3 = imgName2Tag.firstChild.data.split('/')[3] - imgName3 = imgName3.split('_') - pviName = imgName3[0] + '_' + imgName3[1] + '_PVI.jp2' - imgPreview = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/QI_DATA/' + pviName - else: - imgName3 = imgName2Tag.firstChild.data.split('/')[4] - imgName3 = imgName3.split('_') - pviName = imgName3[0] + '_' + imgName3[1] + '_PVI.jp2' - imgPreview = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/QI_DATA/' + pviName - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgName2, c, 1) - cfg.utls.addTableItem(tW, acqDateI, c, 2) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3) - cfg.utls.addTableItem(tW, acZoneI, c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW, float(max_lon), c, 9) - cfg.utls.addTableItem(tW, '', c, 10) - cfg.utls.addTableItem(tW, imgPreview, c, 11) - cfg.utls.addTableItem(tW, imgName, c, 12) - cfg.utls.addTableItem(tW, imgName, c, 13) - newV = 'Yes' - break - except Exception as err: - if cfg.actionCheck == 'Yes': - for filter in imageFindList: - if filter in imgName.lower(): - # add item to table - c = tW.rowCount() - co = cfg.QtGuiSCP.QColor(160, 160, 160) - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 1, 'Yes', co) - cfg.utls.addTableItem(tW, acqDateI, c, 2, 'Yes', co) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 4, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 5, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lat), c, 6, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lon), c, 7, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lat), c, 8, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lon), c, 9, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 10, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 11, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 12, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 13, 'Yes', co) - newV = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - break - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Sentinel images') - - # read database - def queryDatabaseSentinel2(self): - if len(cfg.ui.user_scihub_lineEdit.text()) == 0 or cfg.ui.sentinel2_alternative_search_checkBox.isChecked(): - cfg.downProd.queryDatabaseSentinel2Alternative() - else: - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - imageFindList = [] - m = 'S2*' - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower().replace('*', '')) - imgQuery = '' - if len(imageFindList) == 1: - imgQuery = m + '%20AND%20' - else: - imageFindList.append('s2') - imgQuery = '' - try: - NoRect = 'No' - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - if abs(float(cfg.ui.UX_lineEdit_3.text()) - float(cfg.ui.LX_lineEdit_3.text())) > 10 or abs(float(cfg.ui.UY_lineEdit_3.text()) - float(cfg.ui.LY_lineEdit_3.text())) > 10: - cfg.mx.msgWar18() - except Exception as err: - if len(imageFindList) == 1: - imgQuery = m + '*' + '%20AND%20' - NoRect = 'Yes' - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - cfg.uiUtls.addProgressBar() - tW = cfg.ui.download_images_tableWidget - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - cfg.QtWidgetsSCP.qApp.processEvents() - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - imageTableList = [] - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # loop for results - maxResultNum = resultNum - if maxResultNum > 100: - maxResultNum = 100 - for startR in range(0, resultNum, maxResultNum): - if NoRect == 'Yes': - url = topUrl + '/search?q=(' + imgQuery + 'platformname:Sentinel-2)%20AND%20cloudcoverpercentage:[0%20TO%20' + str(maxCloudCover) + ']%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - else: - url = topUrl + '/search?q=(' + imgQuery + 'platformname:Sentinel-2)%20AND%20cloudcoverpercentage:[0%20TO%20' + str(maxCloudCover) + ']%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]%20AND%20footprint:%22Intersects(POLYGON((' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ')))%22' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, quiet = 'Yes') - if response == 'No': - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - topUrl =topLevelUrl - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl) - if response == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - #info = response.info() - try: - xml = response.read() - doc = cfg.minidomSCP.parseString(xml) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - if 'HTTP Status 500' in xml: - cfg.mx.msgWar24() - else: - cfg.mx.msgErr40() - except: - cfg.mx.msgErr40() - cfg.uiUtls.removeProgressBar() - return 'No' - tW.setSortingEnabled(False) - entries = doc.getElementsByTagName('entry') - e = 0 - for entry in entries: - if cfg.actionCheck == 'Yes': - productType = 'S2MSI1C' - e = e + 1 - cfg.uiUtls.updateBar(30 + e * int(70/len(entries)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - imgNameTag = entry.getElementsByTagName('title')[0] - imgName = imgNameTag.firstChild.data - imgIDTag = entry.getElementsByTagName('id')[0] - imgID = imgIDTag.firstChild.data - summary = entry.getElementsByTagName('summary')[0] - infos = summary.firstChild.data.split(',') - for info in infos: - infoIt = info.strip().split(' ') - if infoIt[0] == 'Date:': - acqDateI = infoIt[1] - # if infoIt[0] == 'Satellite:': - # print "Satellite " + infoIt[1] - if infoIt[0] == 'Size:': - size = infoIt[1] + ' ' + infoIt[2] - strings = entry.getElementsByTagName('str') - for x in strings: - attr = x.getAttribute('name') - if attr == 'producttype': - productType = x.firstChild.data - if attr == 'footprint': - footprintCoord = x.firstChild.data.replace('MULTIPOLYGON (((', '').replace('POLYGON ((', '').replace(')))', '').replace('))', '').split(',') - xList = [] - yList = [] - for coords in footprintCoord: - cc = coords.lstrip() - xList.append(float(cc.split(' ')[0])) - yList.append(float(cc.split(' ')[1])) - min_lon = min(xList) - max_lon = max(xList) - min_lat = min(yList) - max_lat = max(yList) - doubles = entry.getElementsByTagName('double') - for xd in doubles: - attr = xd.getAttribute('name') - if attr == 'cloudcoverpercentage': - cloudcoverpercentage = xd.firstChild.data - if cfg.actionCheck == 'Yes': - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - if productType == 'S2MSI2Ap' or productType == 'S2MSI2A': - url2 = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL2A.xml' - else: - url2 = 'https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL1C.xml' - xml2T = cfg.utls.createTempRasterPath('xml') - check = cfg.utls.downloadFile(url2, xml2T) - if check == 'Yes': - pass - else: - xml2T = None - if productType == 'S2MSI2Ap' or productType == 'S2MSI2A': - url2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('MTD_MSIL2A.xml')/$value" - else: - url2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('MTD_MSIL1C.xml')/$value" - response2 = cfg.utls.passwordConnectPython(user, password, url2, topLevelUrl, None, None, quiet = 'No') - try: - xml2 = response2.read() - except: - xml2 = response2 - if len(xml2) == 0 or 'Navigation failed' in str(xml2) or 'Internal Server Error' in str(xml2): - # old xml version - #url2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('" + imgName.replace('_PRD_MSIL1C_', '_MTD_SAFL1C_') + ".xml')/$value" - #response2 = cfg.utls.passwordConnectPython(user, password, url2, topLevelUrl) - pass - if response2 == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' xml downloaded' ) - try: - newV = None - if xml2T is not None: - doc2 = cfg.minidomSCP.parse(xml2T) - else: - doc2 = cfg.minidomSCP.parseString(xml2) - try: - imgName2Tag = doc2.getElementsByTagName('IMAGE_FILE')[0] - except: - imgName2Tag = doc2.getElementsByTagName('IMAGE_FILE_2A')[0] - imgName2 = imgName2Tag.firstChild.data.split('/')[1] - if cfg.actionCheck == 'Yes': - for filter in imageFindList: - if filter in imgName.lower() or filter in imgName2.lower(): - acZoneI = imgName2.split("_")[1][1:] - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - if xml2T is None: - imgPreview = topUrl + "/odata/v1/Products('" + imgID + "')/Products('Quicklook')/$value" - imgPreview2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('" + imgName2[0:-7] + "_B01.jp2')/$value" - else: - imgPreview = topUrl + "/odata/v1/Products('" + imgID + "')/Products('Quicklook')/$value" - imgPreview2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('" + imgName2[0:-7] + "_B01.jp2')/$value" - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgName2, c, 1) - cfg.utls.addTableItem(tW, acqDateI, c, 2) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3) - cfg.utls.addTableItem(tW, acZoneI, c, 4) - cfg.utls.addTableItem(tW, "", c, 5) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW, float(max_lon), c, 9) - cfg.utls.addTableItem(tW, size, c, 10) - cfg.utls.addTableItem(tW, imgPreview, c, 11) - cfg.utls.addTableItem(tW, imgID, c, 12) - cfg.utls.addTableItem(tW, imgName, c, 13) - newV = 'Yes' - break - except Exception as err: - if cfg.actionCheck == 'Yes': - for filter in imageFindList: - if filter in imgName.lower(): - # add item to table - c = tW.rowCount() - co = cfg.QtGuiSCP.QColor(160, 160, 160) - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 1, 'Yes', co) - cfg.utls.addTableItem(tW, acqDateI, c, 2, 'Yes', co) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3, 'Yes', co) - cfg.utls.addTableItem(tW, "", c, 4, 'Yes', co) - cfg.utls.addTableItem(tW, "", c, 5, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lat), c, 6, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lon), c, 7, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lat), c, 8, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lon), c, 9, 'Yes', co) - cfg.utls.addTableItem(tW, size, c, 10, 'Yes', co) - cfg.utls.addTableItem(tW, "", c, 11, 'Yes', co) - cfg.utls.addTableItem(tW, imgID, c, 12, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 13, 'Yes', co) - newV = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - break - if newV is None: - # old xml version - try: - doc2 = cfg.minidomSCP.parseString(xml2) - entries2 = doc2.getElementsByTagName("Granules") - if len(entries2) == 0: - entries2 = doc2.getElementsByTagName("Granule") - for entry2 in entries2: - if cfg.actionCheck == 'Yes': - imgName2 = entry2.attributes["granuleIdentifier"].value - for filter in imageFindList: - if filter in imgName.lower() or filter in imgName2.lower(): - acZoneI = imgName2[-12:-7] - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - imgPreview = topUrl + "/odata/v1/Products('" + imgID + "')/Products('Quicklook')/$value" - imgPreview2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('" + imgName2[0:-7] + "_B01.jp2')/$value" - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgName2, c, 1) - cfg.utls.addTableItem(tW, acqDateI, c, 2) - cfg.utls.addTableItem(tW, float(cloudcoverpercentage), c, 3) - cfg.utls.addTableItem(tW, acZoneI, c, 4) - cfg.utls.addTableItem(tW, "", c, 5) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW, float(max_lon), c, 9) - cfg.utls.addTableItem(tW, size, c, 10) - cfg.utls.addTableItem(tW, imgPreview2, c, 11) - cfg.utls.addTableItem(tW, imgID, c, 12) - cfg.utls.addTableItem(tW, imgName, c, 13) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Sentinel images') - - # download images - def downloadSentinelImages(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - outDirList = [] - imgList = [] - links = [] - check = 'Yes' - c = tW.rowCount() - progressStep = 100 / c - progress = 0 - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl + '/odata/v1/Products' - topUrl2 =topLevelUrl - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat == cfg.esaSentinel2: - imgName = str(tW.item(i, 13).text()) - acquisitionDate = str(tW.item(i, 2).text()) - imgID = str(tW.item(i, 12).text()) - imgName2 = str(tW.item(i, 1).text()) - if imgName2[0:4] == 'L1C_': - imgJp2 = imgName2 + '_p.jp2' - elif imgName2[0:4] == 'L2A_': - imgJp2 = imgName2 + '_p.jp2' - else: - imgJp2 = imgName2[0:-7] + '_p.jp2' - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgJp2, 'Yes') is None: - pass - else: - outFiles = [] - if imgName2[0:4] == 'L1C_': - outDirList.append(outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10]) - elif imgName2[0:4] == 'L2A_': - outDirList.append(outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10]) - else: - outDirList.append(outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10]) - progress = progress + progressStep - if exporter == 'No': - if imgName2[0:4] == 'L1C_': - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10]) - elif imgName2[0:4] == 'L2A_': - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10]) - else: - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10]) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # download ancillary data - urlL1 = [] - urlL2 = [] - urlL3 = [] - #download metadata - if imgName2[0:4] == 'L1C_': - # new version - urlL1.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('MTD_MSIL1C.xml')/$value") - outFile1 = outputDirectory + "//" + imgName2 + "_" + acquisitionDate[0:10] + "//" + 'MTD_MSIL1C.xml' - urlL2.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('MTD_TL.xml')/$value") - outFile2 = outputDirectory + "//" + imgName2 + "_" + acquisitionDate[0:10] + "//" + 'MTD_TL.xml' - # download QI - urlL3.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('QI_DATA')/Nodes('MSK_CLOUDS_B00.gml')/$value") - outFile3 = outputDirectory + "//" + imgName2 + "_" + acquisitionDate[0:10] + "//" + 'MSK_CLOUDS_B00.gml' - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - urlL1.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL1C.xml') - urlL2.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/MTD_TL.xml') - urlL3.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/QI_DATA/MSK_CLOUDS_B00.gml') - elif imgName2[0:4] == 'L2A_': - # new version - urlL1.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('MTD_MSIL2A.xml')/$value") - outFile1 = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + 'MTD_MSIL2A.xml' - urlL2.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('MTD_TL.xml')/$value") - outFile2 = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + 'MTD_TL.xml' - # download QI - urlL3.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('QI_DATA')/Nodes('MSK_CLOUDS_B00.gml')/$value") - outFile3 = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + 'MSK_CLOUDS_B00.gml' - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - urlL1.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/MTD_MSIL2A.xml') - urlL2.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/MTD_TL.xml') - urlL3.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/GRANULE/' + imgName2 + '/QI_DATA/MSK_CLOUDS_B00.gml') - else: - # old version - urlL1.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('" + imgName.replace('_PRD_MSIL1C_', '_MTD_SAFL1C_') + ".xml')/$value") - outFile1 = outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10] + '//' + imgName.replace('_PRD_MSIL1C_', '_MTD_SAFL1C_') + '.xml' - urlL2.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('" + imgName2[0:-7].replace('_MSI_L1C_', '_MTD_L1C_') + ".xml')/$value") - outFile2 = outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10] + '//' + imgName2[0:-7].replace('_MSI_L1C_', '_MTD_L1C_') + '.xml' - # download QI - urlL3.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('QI_DATA')/Nodes('" + imgName2[0:-7].replace('_MSI_L1C_TL_', '_MSK_CLOUDS_') + "_B00_MSIL1C.gml')/$value") - outFile3 = outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10] + '//' + imgName2[0:-7].replace('_MSI_L1C_TL_', '_MSK_CLOUDS_') + '_B00_MSIL1C.gml' - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - urlL1.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/' + imgName.replace('_PRD_MSIL1C_', '_MTD_SAFL1C_') + '.xml') - urlL2.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/' + imgName2 + '/GRANULE/' + imgName2[0:-7].replace('_MSI_L1C_', '_MTD_L1C_') + '.xml') - urlL3.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE/' + imgName2 + '/GRANULE/QI_DATA/' + imgName2[0:-7].replace('_MSI_L1C_TL_', '_MSK_CLOUDS_') + '_B00_MSIL1C.gml') - tempFile1 = cfg.utls.createTempRasterPath('xml') - check = cfg.utls.downloadFile(urlL1[1], tempFile1, None, progress) - if cfg.ui.ancillary_data_checkBox.isChecked(): - if exporter == 'No': - if check == 'Yes': - cfg.utls.downloadFile(urlL1[1], outFile1, None, progress) - cfg.utls.downloadFile(urlL2[1], outFile2, None, progress) - cfg.utls.downloadFile(urlL3[1], outFile3, None, progress) - else: - self.downloadFileSentinel2(urlL1[0], outFile1, progress) - self.downloadFileSentinel2(urlL2[0], outFile2, progress) - self.downloadFileSentinel2(urlL3[0], outFile3, progress) - else: - if check == 'Yes': - links.append(urlL1[1]) - links.append(urlL2[1]) - links.append(urlL3[1]) - else: - links.append(urlL1[0]) - links.append(urlL2[0]) - links.append(urlL3[0]) - # download bands - self.checkImageBands(cfg.ui.checkBoxs_band_1, '01', imgID, imgName, imgName2, acquisitionDate,outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_2, '02', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_3, '03', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_4, '04', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_5, '05', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_6, '06', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_7, '07', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_8, '08', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_9, '8A', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_10, '09', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_11, '10', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_12, '11', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - self.checkImageBands(cfg.ui.checkBoxs_band_13, '12', imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFiles, links, check) - for oFile in outFiles: - cfg.shutilSCP.copy(oFile[0], oFile[1] + '.jp2') - cfg.osSCP.remove(oFile[0]) - if cfg.ui.load_in_QGIS_checkBox.isChecked() and cfg.ui.preprocess_checkBox.isChecked() is False: - c = cfg.utls.addRasterLayer(oFile[1] + '.jp2') - else: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.ui.preprocess_checkBox.isChecked() and exporter == 'No': - n = len(outDirList) - i = 0 - for d in outDirList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.sentinel2T.populateTable(d, 'Yes') - o = d + "_con" - oDir = cfg.utls.makeDirectory(o) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.sentinel2T.sentinel2(d, o, 'Yes') - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return links - - # check all bands - def checkAllBandsSentinel2(self): - if self.checkAll == 'Yes': - for i in range(1, 14): - t = 'cfg.ui.checkBoxs_band_' + str(i) + '.setCheckState(2)' - eval(t) - cfg.ui.ancillary_data_checkBox.setCheckState(2) - self.checkAll = 'No' - else: - for i in range(1, 14): - t = 'cfg.ui.checkBoxs_band_' + str(i) + '.setCheckState(0)' - eval(t) - cfg.ui.ancillary_data_checkBox.setCheckState(0) - self.checkAll = 'Yes' - - # check all bands - def checkAllBandsSentinel3(self): - if self.checkAll == 'Yes': - for i in range(1, 22): - t = 'cfg.ui.checkBoxs3_band_' + str(i) + '.setCheckState(2)' - eval(t) - cfg.ui.s3_ancillary_data_checkBox.setCheckState(2) - self.checkAll = 'No' - else: - for i in range(1, 22): - t = 'cfg.ui.checkBoxs3_band_' + str(i) + '.setCheckState(0)' - eval(t) - cfg.ui.s3_ancillary_data_checkBox.setCheckState(0) - self.checkAll = 'Yes' - - # check all bands - def checkAllBandsGOES(self): - if self.checkAll == 'Yes': - for i in range(1, 7): - t = 'cfg.ui.checkBoxs_goes_band_' + str(i) + '.setCheckState(2)' - eval(t) - self.checkAll = 'No' - else: - for i in range(1, 7): - t = 'cfg.ui.checkBoxs_goes_band_' + str(i) + '.setCheckState(0)' - eval(t) - self.checkAll = 'Yes' - - # check band download - def checkImageBands(self, checkbox, bandNumber, imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFilesList, linksList, checkDownload = None): - if cfg.actionCheck == 'Yes': - check = 'No' - if checkbox.isChecked(): - # download from hub - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl + '/odata/v1/Products' - topUrl2 =topLevelUrl - urlL = [] - if imgName2[0:4] == 'L1C_': - urlL.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('" + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + ".jp2')/$value") - # download Sentinel data using the service https://storage.googleapis.com/gcp-public-data-sentinel-2 - urlL.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE' + '/GRANULE/' + imgName2 + '/IMG_DATA/' + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + '.jp2') - outFile = cfg.tmpDir + '//' + imgName2.split('_')[1] + '_' + imgName.split('_')[2] + '_B' + bandNumber + '.jp2' - outCopyFile = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//L1C_' + imgName2[4:] + '_B' + bandNumber - elif imgName2[0:4] == 'L2A_': - if bandNumber in ['02', '03', '04', '08']: - urlL.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('R10m')/Nodes('" + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + "_10m.jp2')/$value") - urlL.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE' + '/GRANULE/' + imgName2 + '/IMG_DATA/R10m/' + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + '_10m.jp2') - outFile = cfg.tmpDir + '//' + imgName2.split('_')[1] + '_' + imgName.split('_')[2] + '_B' + bandNumber + '.jp2' - outCopyFile = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + imgName2[4:] + '_B' + bandNumber - elif bandNumber in ['05', '06', '07', '11', '12', '8A']: - urlL.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('R20m')/Nodes('" + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + "_20m.jp2')/$value") - urlL.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE' + '/GRANULE/' + imgName2 + '/IMG_DATA/R20m/' + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + '_20m.jp2') - outFile = cfg.tmpDir + '//' + imgName2.split('_')[1] + '_' + imgName.split('_')[2] + '_B' + bandNumber + '.jp2' - outCopyFile = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + imgName2[4:] + '_B' + bandNumber - elif bandNumber in ['01', '09']: - urlL.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('R60m')/Nodes('" + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + "_60m.jp2')/$value") - urlL.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/L2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE' + '/GRANULE/' + imgName2 + '/IMG_DATA/R60m/' + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + '_60m.jp2') - outFile = cfg.tmpDir + '//' + imgName2.split('_')[1] + '_' + imgName.split('_')[2] + '_B' + bandNumber + '.jp2' - outCopyFile = outputDirectory + '//' + imgName2 + '_' + acquisitionDate[0:10] + '//' + imgName2[4:] + '_B' + bandNumber - else: - return - else: - urlL.append(topUrl + "('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('GRANULE')/Nodes('" + imgName2 + "')/Nodes('IMG_DATA')/Nodes('" + imgName2[0:-7] + '_B' + bandNumber + ".jp2')/$value") - urlL.append('https://storage.googleapis.com/gcp-public-data-sentinel-2/tiles/' + imgName[39:41] + '/'+ imgName[41] + '/'+ imgName[42:44] + '/' +imgName + '.SAFE' + '/GRANULE/' + imgName2 + '/IMG_DATA/' + imgName2.split("_")[1] + "_" + imgName.split("_")[2] + '_B' + bandNumber + '.jp2') - outFile = cfg.tmpDir + '//' + imgName2[0:-7] + '_B' + bandNumber + '.jp2' - outCopyFile = outputDirectory + '//' + imgName2[0:-7] + '_' + acquisitionDate[0:10] + '//' + imgName2[0:-7] + '_B' + bandNumber - if exporter == 'No': - if checkDownload == 'Yes': - if cfg.ui.virtual_download_checkBox.isChecked(): - virtualDownload = 'vrt' - else: - virtualDownload = None - try: - iLeft = float(cfg.ui.UX_lineEdit_3.text()) - iTop = float(cfg.ui.UY_lineEdit_3.text()) - iRight = float(cfg.ui.LX_lineEdit_3.text()) - iBottom = float(cfg.ui.LY_lineEdit_3.text()) - extentList = [iLeft, iRight, iTop, iBottom] - except: - extentList = None - self.downloadDispatcher(urlL[1], outFile, None, progress, extentList, virtualDownload) - else: - check = self.downloadFileSentinel2(urlL[0], outFile, progress) - if cfg.osSCP.path.isfile(outFile): - outFilesList.append([outFile, outCopyFile]) - else: - cfg.mx.msgWar23(imgName2[0:-7] + '_B' + bandNumber + '.jp2') - else: - if checkDownload == 'Yes': - linksList.append(urlL[1]) - else: - linksList.append(urlL[0]) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - - # download image preview - def downloadThumbnailSentinel2(self, imgID, min_lat, min_lon, max_lat, max_lon, imageJPG, progress = None, preview = 'No'): - imOut = cfg.tmpDir + '//' + imgID - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl = topLevelUrl - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress, quiet = 'Yes') - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - imageJPG = imageJPG.replace(topUrl, topLevelUrl) - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress) - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - cfg.mx.msgErr40bis() - - # georef image on the fly based on UL and LR - def onflyGeorefImage(self, inputImage, outputVRT, min_lon, max_lon, min_lat, max_lat): - cLon = (float(min_lon) + float(max_lon)) / 2 - cLat = (float(min_lat) + float(max_lat)) / 2 - # calculate UTM zone (adapted from http://stackoverflow.com/questions/9186496/determining-utm-zone-to-convert-from-longitude-latitude) - zone = 1 + int((cLon + 180) / 6) - # exceptions - if cLon >= 3.0 and cLon < 12.0 and cLat >= 56.0 and cLat < 64.0: - zone = 32 - elif cLon >= 0.0 and cLon < 9.0 and cLat >= 72.0 and cLat < 84.0: - zone = 31 - elif cLon >= 9.0 and cLon < 21.0 and cLat >= 72.0 and cLat < 84.0: - zone = 33 - elif cLon >= 21.0 and cLon < 33.0 and cLat >= 72.0 and cLat < 84.0: - zone = 35 - elif cLon >= 33.0 and cLon < 42.0 and cLat >= 72.0 and cLat < 84.0: - zone = 37 - UL = cfg.qgisCoreSCP.QgsPointXY(float(min_lon), float(max_lat)) - LR = cfg.qgisCoreSCP.QgsPointXY(float(max_lon), float(min_lat)) - # WGS84 EPSG 4326 - wgsCrs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem() - wgsCrs.createFromProj4('+proj=longlat +datum=WGS84 +no_defs') - iCrs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem() - iCrs.createFromProj4('+proj=utm +zone=' + str(zone) + ' +datum=WGS84 +units=m +no_defs') - UL1 = cfg.utls.projectPointCoordinates(UL, wgsCrs, iCrs) - LR1 = cfg.utls.projectPointCoordinates(LR, wgsCrs, iCrs) - if UL1 != False and LR1 != False: - cfg.utls.getGDALForMac() - # georeference thumbnail - a = cfg.gdalPath + 'gdal_translate -of VRT -a_ullr ' + str(UL1.x()) + ' ' + str(UL1.y()) + ' ' + str(LR1.x()) + ' ' + str(LR1.y()) + ' -a_srs "+proj=utm +zone=' + str(zone) + ' +datum=WGS84 +units=m +no_defs" ' + inputImage + ' ' + outputVRT - if cfg.sysSCPNm != 'Windows': - a = cfg.shlexSCP.split(a) - try: - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - sP = cfg.subprocessSCP.Popen(a, shell=False, startupinfo = startupinfo, stdin = cfg.subprocessSCP.DEVNULL) - else: - sP = cfg.subprocessSCP.Popen(a, shell=False) - sP.wait() - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' onfly georef' + str(inputImage)) - else: - cfg.mx.msgErr41() - -### Sentinel-1 - - # read database S1 - def queryDatabaseSentinel1(self): - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - imageFindList = [] - m = 'GRD' - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - imgQuery = 'GRD' - if len(imageFindList) == 1: - imgQuery = '*' + m + '*' - else: - imageFindList.append('s1') - imgQuery = 'GRD' - try: - NoRect = 'No' - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - if abs(float(cfg.ui.UX_lineEdit_3.text()) - float(cfg.ui.LX_lineEdit_3.text())) > 10 or abs(float(cfg.ui.UY_lineEdit_3.text()) - float(cfg.ui.LY_lineEdit_3.text())) > 10: - cfg.mx.msgWar18() - except Exception as err: - if len(imageFindList) == 1: - imgQuery = m + '*' - NoRect = 'Yes' - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - cfg.uiUtls.addProgressBar() - tW = cfg.ui.download_images_tableWidget - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - cfg.QtWidgetsSCP.qApp.processEvents() - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - imageTableList = [] - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # loop for results - maxResultNum = resultNum - if maxResultNum > 100: - maxResultNum = 100 - imgQuery = '(%20(platformname:Sentinel-1%20AND%20producttype:GRD))' - for startR in range(0, resultNum, maxResultNum): - if NoRect == 'Yes': - url = topUrl + '/search?q=' + imgQuery + '%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - else: - url = topUrl + '/search?q=' + imgQuery + '%20AND%20beginPosition:[' + str(dateFrom) + 'T00:00:00.000Z%20TO%20' + str(dateTo) + 'T23:59:59.999Z]%20AND%20footprint:%22Intersects(POLYGON((' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.LY_lineEdit_3.text() + ',' + cfg.ui.LX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ',' + cfg.ui.UX_lineEdit_3.text() + '%20' + cfg.ui.UY_lineEdit_3.text() + ')))%22' + '&rows=' + str(maxResultNum) + '&start=' + str(startR) - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, quiet = 'Yes') - if response == 'No': - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - topUrl =topLevelUrl - response = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl) - if response == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - #info = response.info() - xml = response.read() - tW.setSortingEnabled(False) - try: - doc = cfg.minidomSCP.parseString(xml) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if 'HTTP Status 500' in xml: - cfg.mx.msgWar24() - else: - cfg.mx.msgErr40() - cfg.uiUtls.removeProgressBar() - return 'No' - entries = doc.getElementsByTagName('entry') - e = 0 - for entry in entries: - if cfg.actionCheck == 'Yes': - productType = 'S1GRD' - e = e + 1 - cfg.uiUtls.updateBar(30 + e * int(70/len(entries)), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - imgNameTag = entry.getElementsByTagName('title')[0] - imgName = imgNameTag.firstChild.data - imgIDTag = entry.getElementsByTagName('id')[0] - imgID = imgIDTag.firstChild.data - summary = entry.getElementsByTagName('summary')[0] - infos = summary.firstChild.data.split(',') - for info in infos: - infoIt = info.strip().split(' ') - if infoIt[0] == 'Date:': - acqDateI = infoIt[1] - # if infoIt[0] == 'Satellite:': - # print 'Satellite ' + infoIt[1] - if infoIt[0] == 'Size:': - size = infoIt[1] + ' ' + infoIt[2] - strings = entry.getElementsByTagName('str') - for x in strings: - attr = x.getAttribute('name') - if attr == 'producttype': - productType = x.firstChild.data - if attr == 'footprint': - footprintCoord = x.firstChild.data.replace('MULTIPOLYGON (((', '').replace('POLYGON ((', '').replace(')))', '').replace('))', '').split(',') - xList = [] - yList = [] - for coords in footprintCoord: - cc = coords.lstrip() - xList.append(float(cc.split(' ')[0])) - yList.append(float(cc.split(' ')[1])) - min_lon = min(xList) - max_lon = max(xList) - min_lat = min(yList) - max_lat = max(yList) - url2 = topUrl + "/odata/v1/Products('" +imgID + "')/Nodes('" +imgName + ".SAFE')/Nodes('manifest.safe')/$value" - if cfg.actionCheck == 'Yes': - response2 = cfg.utls.passwordConnectPython(user, password, url2, topLevelUrl, None, None, quiet = 'No') - try: - xml2 = response2.read() - except: - xml2 = response2 - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' xml downloaded' ) - if cfg.actionCheck == 'Yes': - try: - for filter in imageFindList: - if filter in imgName.lower(): - doc2 = cfg.minidomSCP.parseString(xml2) - entries2 = doc2.getElementsByTagName('s1:pass') - for entry2 in entries2: - orbit = entry2.firstChild.data - entries2 = doc2.getElementsByTagName('safe:relativeOrbitNumber') - for entry2 in entries2: - relativeOrbit = entry2.firstChild.data - try: - entries3 = doc2.getElementsByTagName('s1sarl1:sliceNumber') - for entry3 in entries3: - sliceNumber = entry3.firstChild.data - except: - sliceNumber = '' - try: - entries4 = doc2.getElementsByTagName('safe:number') - for entry4 in entries4: - satelliteN = entry4.firstChild.data - except: - satelliteN = "" - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - imgPreview = topUrl + "/odata/v1/Products('" + imgID + "')/Products('Quicklook')/$value" - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgName, c, 1) - cfg.utls.addTableItem(tW, acqDateI, c, 2) - cfg.utls.addTableItem(tW, orbit, c, 3) - cfg.utls.addTableItem(tW, satelliteN + 'o' + relativeOrbit, c, 4) - cfg.utls.addTableItem(tW, satelliteN + 's' + sliceNumber, c, 5) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW, float(max_lon), c, 9) - cfg.utls.addTableItem(tW, size, c, 10) - cfg.utls.addTableItem(tW, imgPreview, c, 11) - cfg.utls.addTableItem(tW, imgID, c, 12) - cfg.utls.addTableItem(tW, imgName, c, 13) - break - except Exception as err: - for filter in imageFindList: - if filter in imgName.lower(): - # add item to table - c = tW.rowCount() - co = cfg.QtGuiSCP.QColor(160, 160, 160) - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 1, 'Yes', co) - cfg.utls.addTableItem(tW, acqDateI, c, 2, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 3, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 4, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 5, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lat), c, 6, 'Yes', co) - cfg.utls.addTableItem(tW, float(min_lon), c, 7, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lat), c, 8, 'Yes', co) - cfg.utls.addTableItem(tW, float(max_lon), c, 9, 'Yes', co) - cfg.utls.addTableItem(tW, size, c, 10, 'Yes', co) - cfg.utls.addTableItem(tW, '', c, 11, 'Yes', co) - cfg.utls.addTableItem(tW, imgID, c, 12, 'Yes', co) - cfg.utls.addTableItem(tW, imgName, c, 13, 'Yes', co) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - break - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Sentinel images") - - # display granule preview - def displayGranulesSentinel1(self, row, progress, preview = 'No'): - i = row - tW = cfg.ui.download_images_tableWidget - imgNm = str(tW.item(i, 1).text()) - acquisitionDate = str(tW.item(i, 2).text()) - imgID = imgNm + '_p.jpg' - url = str(tW.item(i, 11).text()) - # image preview - imOut = cfg.tmpDir + '//' + imgID - if preview == 'Yes' and cfg.osSCP.path.isfile(imOut): - self.previewInLabel(imOut) - return imOut - if cfg.osSCP.path.isfile(imOut + '.vrt'): - l = cfg.utls.selectLayerbyName(imgID) - if l is not None: - cfg.utls.setLayerVisible(l, True) - cfg.utls.moveLayerTop(l) - else: - r =cfg.utls.addRasterLayer(imOut, imgID) - else: - min_lat = str(tW.item(i, 6).text()) - min_lon = str(tW.item(i, 7).text()) - max_lat = str(tW.item(i, 8).text()) - max_lon = str(tW.item(i, 9).text()) - self.downloadThumbnailSentinel1(imgID, min_lat, min_lon, max_lat, max_lon, url, progress, preview) - if cfg.osSCP.path.isfile(imOut + '.vrt'): - r =cfg.utls.addRasterLayer(imOut + '.vrt', imgID) - cfg.utls.setRasterColorComposite(r, 1, 2, 3) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' granules displayed') - - # download image preview - def downloadThumbnailSentinel1(self, imgID, min_lat, min_lon, max_lat, max_lon, imageJPG, progress = None, preview = 'No'): - imOut = cfg.tmpDir + '//' + imgID - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress, quiet = 'Yes') - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - imageJPG = imageJPG.replace(topUrl, topLevelUrl) - check = cfg.utls.passwordConnectPython(user, password, imageJPG, topLevelUrl, imOut, progress) - if check == 'Yes': - if preview == 'Yes': - self.previewInLabel(imOut) - return imOut - self.onflyGeorefImage(cfg.tmpDir + '//' + imgID, cfg.tmpDir + '//' + imgID + '.vrt', min_lon, max_lon, min_lat, max_lat) - else: - cfg.mx.msgErr40bis() - - # download images - def downloadSentinel1Images(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - outDirList = [] - imgList = [] - links = [] - c = tW.rowCount() - progressStep = 100 / c - progress = 0 - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - outFiles = [] - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat == cfg.esaSentinel1: - imgName = str(tW.item(i, 13).text()) - acquisitionDate = str(tW.item(i, 2).text()) - orbit = str(tW.item(i, 3).text()) - relativeOrbit = str(tW.item(i, 4).text()) - sliceNumber = str(tW.item(i, 5).text()) - imgID = str(tW.item(i, 12).text()) - imgJp2 = imgName + '_p.jpg' - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgJp2, 'Yes') is None: - pass - else: - # add info to name - try: - imgName = imgName.replace('.zip', '') + '_s' + orbit[0] + '_' + relativeOrbit + '_' + sliceNumber + '_' + acquisitionDate[0:10] - except: - imgName = imgName.replace('.zip', '') - outDirList.append(outputDirectory + '//' + imgName) - progress = progress + progressStep - if exporter == 'No': - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgName) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # download ancillary data - if cfg.ui.ancillary_data_checkBox.isChecked(): - pass - # download bands - self.checkImageS1Bands(None, None, imgID, imgName, None, acquisitionDate,outputDirectory + '//' + imgName, exporter, progress, outFiles, links) - for oFile in outFiles: - cfg.shutilSCP.copy(oFile[0], oFile[1]) - cfg.osSCP.remove(oFile[0]) - else: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.ui.preprocess_checkBox.isChecked() and exporter == 'No': - n = len(outFiles) - i = 0 - for oFile in outFiles: - if cfg.actionCheck == 'Yes': - d = oFile[1] - o = oFile[2] + '_con' - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - oDir = cfg.utls.makeDirectory(o) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.sentinel1T.sentinel1(d, o, 'Yes') - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return links - - # check band download - def checkImageS1Bands(self, checkbox, bandNumber, imgID, imgName, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFilesList, linksList): - if cfg.actionCheck == 'Yes': - # download from hub - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl + '/odata/v1/Products' - topUrl2 =topLevelUrl - urlL = topUrl + "('" +imgID + "')/$value" - outFile = cfg.tmpDir + '//' + imgName + '.zip' - outCopyFile = outputDirectory + '//' + imgName + '.zip' - if exporter == 'No': - self.downloadFileSentinel1(urlL, outFile, progress) - try: - if cfg.osSCP.path.getsize(outFile) < 100000: - self.downloadFileSentinel1(urlL, outFile, progress) - if cfg.osSCP.path.getsize(outFile) < 100000: - cfg.mx.msgWar23(imgName) - outFilesList.append([outFile, outCopyFile, outputDirectory]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - linksList.append(urlL) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - - # download file - def downloadFileSentinel1(self, url, output, progress = None): - user = cfg.ui.user_scihub_lineEdit.text() - password =cfg.ui.password_scihub_lineEdit.text() - # check url - topLevelUrl = cfg.ui.sentinel_service_lineEdit.text() - topUrl =topLevelUrl - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ' + url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress, quiet = 'Yes') - if check == 'Yes': - return output - else: - # second try - topLevelUrl = 'https://scihub.copernicus.eu/dhus' - url = url.replace(topUrl, topLevelUrl) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ' + url) - check = cfg.utls.passwordConnectPython(user, password, url, topLevelUrl, output, progress) - if check == 'Yes': - return output - else: - cfg.mx.msgErr40bis() - return 'No' - -### ASTER - - # download image metadata from NASA CMR Search https://cmr.earthdata.nasa.gov/search/site/search_api_docs.html - def downloadMetadataASTER(self): - listImgID = [] - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime('%Y-%m-%d') - dateTo = QdateTo.toPyDate().strftime('%Y-%m-%d') - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - if sat == cfg.usgsASTER: - NASAcollection = cfg.NASAASTERCollection - imageFindList = [] - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - try: - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msg23() - return 'No' - try: - cfg.uiUtls.addProgressBar() - cfg.QtWidgetsSCP.qApp.processEvents() - tW = cfg.ui.download_images_tableWidget - tW.setSortingEnabled(False) - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Searching ...")) - searchUrl = 'https://cmr.earthdata.nasa.gov/search/granules.echo10?bounding_box=' + cfg.ui.UX_lineEdit_3.text() + '%2C' + cfg.ui.LY_lineEdit_3.text() + '%2C' + cfg.ui.LX_lineEdit_3.text() + '%2C' + cfg.ui.UY_lineEdit_3.text() + '&echo_collection_id=' + NASAcollection + '&temporal=' + dateFrom + '%2C' + dateTo + 'T23%3A59%3A59.000Z&cloud_cover=0,' + str(maxCloudCover) + '&sort_key%5B%5D=-start_date&page_size=' + str(resultNum) + '&pretty=true' - # connect and search - searchResult = cfg.utls.NASASearch(searchUrl) - xmlFile = searchResult.read() - imgIDList = [] - doc = cfg.minidomSCP.parseString(xmlFile) - entries = doc.getElementsByTagName("Granule") - pages = len(entries) - page = 0 - for entry in entries: - page = page + 1 - cfg.uiUtls.updateBar(30 + int(page * 70 / pages), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - gId = entry.getElementsByTagName('ProducerGranuleId')[0] - imgID = gId.firstChild.data - if imgID not in imgIDList: - imgIDList.append(imgID) - imgDispID = imgID - cc = entry.getElementsByTagName('QAPercentCloudCover')[0] - cloudCover = cc.firstChild.data - on = entry.getElementsByTagName('OnlineResources') - urls = on[0].getElementsByTagName('URL') - imgPreview = '' - for ur in urls: - url = ur.firstChild.data - if '.jpg' in url: - imgPreview = url - break - dt = entry.getElementsByTagName('SingleDateTime')[0] - imgDate = dt.firstChild.data - imgDate = cfg.datetimeSCP.datetime.strptime(imgDate[0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M:%S') - PointLatitude = entry.getElementsByTagName('PointLatitude') - lat = [] - for latit in PointLatitude: - lat.append(float(latit.firstChild.data)) - PointLongitude = entry.getElementsByTagName('PointLongitude') - lon = [] - for longi in PointLongitude: - lon.append(float(longi.firstChild.data)) - DayNightFlag = entry.getElementsByTagName('DayNightFlag')[0] - dayNight = DayNightFlag.firstChild.data - listImgID.append([imgID, imgDate, cloudCover, imgDispID, dayNight, lon, lat, imgPreview.replace('http:', 'https:')]) - cfg.uiUtls.updateBar(100, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - c = tW.rowCount() - for imID in listImgID: - if len(imageFindList) > 0: - for iF in imageFindList: - if iF in imID[0].lower(): - imgCheck = 'Yes' - break - else: - imgCheck = 'No' - else: - imgCheck = 'Yes' - if imgCheck == 'Yes': - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imID[3], c, 1) - cfg.utls.addTableItem(tW, str(imID[1]), c, 2) - cfg.utls.addTableItem(tW, int(round(float(imID[2]))), c, 3) - cfg.utls.addTableItem(tW, "", c, 4) - cfg.utls.addTableItem(tW, imID[4], c, 5) - min_lon = min(imID[5]) - max_lon = max(imID[5]) - min_lat = min(imID[6]) - max_lat = max(imID[6]) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW,float(max_lon), c, 9) - cfg.utls.addTableItem(tW,'EOSDIS Earthdata', c, 10) - cfg.utls.addTableItem(tW, imID[7], c, 11) - cfg.utls.addTableItem(tW, NASAcollection, c, 12) - cfg.utls.addTableItem(tW, imID[0], c, 13) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ASTER images') - c = tW.rowCount() - if c == 0: - cfg.mx.msg21() - except Exception as err: - cfg.mx.msgErr39() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # user - def rememberUserEarthdata(self): - if cfg.ui.remember_user_checkBox_3.isChecked(): - user = cfg.ui.user_usgs_lineEdit_2.text() - pswd = cfg.utls.encryptPassword(cfg.ui.password_usgs_lineEdit_2.text()) - cfg.utls.setQGISRegSetting(cfg.regUSGSUserASTER, user) - cfg.utls.setQGISRegSetting(cfg.regUSGSPassASTER, pswd) - - def rememberUserCheckboxEarthdata(self): - if cfg.ui.remember_user_checkBox_3.isChecked(): - self.rememberUserEarthdata() - else: - cfg.utls.setQGISRegSetting(cfg.regUSGSUserASTER, "") - cfg.utls.setQGISRegSetting(cfg.regUSGSPassASTER, "") - - - # download ASTER data - def downloadASTERImages(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - c = tW.rowCount() - progressStep = 100 / c - progressStep2 = progressStep/12 - progress = 0 - outDirList = [] - outFileList = [] - imgList = [] - links = [] - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat in cfg.satASTERtList: - imgID = str(tW.item(i, 13).text()) - imgDispID = str(tW.item(i, 1).text()) - date = str(tW.item(i, 2).text())[0:10] - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgDispID, 'Yes') is None: - pass - else: - NASAcollection = str(tW.item(i, 12).text()) - outDir = outputDirectory + '/' + imgDispID - if exporter == 'No': - oDir = cfg.utls.makeDirectory(outDir) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - return 'No' - outDirList.append(outDir) - outFileList.append(outDir + '//' + imgDispID + '.hdf') - progress = progress + progressStep - outUrl = self.downloadASTERImagesFromNASA(imgID, NASAcollection, imgDispID, outDir, progress, exporter, date) - links.append(outUrl) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - if exporter == 'Yes': - return links - else: - cfg.cnvs.setRenderFlag(False) - if cfg.ui.preprocess_checkBox.isChecked(): - n = len(outFileList) - i = 0 - for d in outFileList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.ASTERT.populateTable(d, 'Yes') - o = d + '_converted' - oDir = cfg.utls.makeDirectory(o) - cfg.ASTERT.ASTER(d, o, 'Yes') - elif cfg.ui.load_in_QGIS_checkBox.isChecked(): - for d in outDirList: - try: - for f in cfg.osSCP.listdir(d): - if f.lower().endswith('.tif'): - r =cfg.utls.addRasterLayer(d + '/' + f) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - - # download image - def downloadASTERImagesFromNASA(self, imageID, collection, imageDisplayID, outputDirectory, progress, exporter = 'No', date = None): - # The ASTER L1T data products are retrieved from the online Data Pool, courtesy of the NASA Land Processes Distributed Active Archive Center (LP DAAC), USGS/Earth Resources Observation and Science (EROS) Center, Sioux Falls, South Dakota, https://lpdaac.usgs.gov/data_access/data_pool' - url = 'https://e4ftl01.cr.usgs.gov/ASTT/AST_L1T.003/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - if exporter == 'Yes': - return url - else: - user = cfg.ui.user_usgs_lineEdit_2.text() - password =cfg.ui.password_usgs_lineEdit_2.text() - try: - imgID = imageDisplayID + '.hdf' - check = cfg.utls.passwordConnectPython(user, password, url, 'urs.earthdata.nasa.gov', cfg.tmpDir + '//' + imgID, progress) - if str(check) == 'Cancel action': - return check - if cfg.osSCP.path.getsize(cfg.tmpDir + '//' + imgID) > 10000: - if collection == cfg.NASAASTERCollection: - cfg.shutilSCP.copy(cfg.tmpDir + '//' + imgID, outputDirectory + '//' + imgID) - cfg.osSCP.remove(cfg.tmpDir + '//' + imgID) - else: - tarFiles = cfg.tarfileSCP.open(cfg.tmpDir + '//' + imgID, 'r:gz') - tarFiles.extractall(outputDirectory) - tarFiles.close() - cfg.osSCP.remove(cfg.tmpDir + '//' + imgID) - return url - else: - cfg.mx.msgErr55(imgID) - return 'No' - except Exception as err: - cfg.mx.msgErr55(imgID) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - -### GOES - - # download image metadata from Amazon Web Services https://registry.opendata.aws/noaa-goes/ - def downloadMetadataGOES(self): - QdateFrom = cfg.ui.dateEdit_from.date() - dStrT = QdateFrom.toPyDate().timetuple() - # calculate julian day - fromDay = dStrT.tm_yday - fromYear = dStrT.tm_year - QdateTo = cfg.ui.dateEdit_to.date() - dStrTo = QdateTo.toPyDate().timetuple() - # calculate julian day - toDay = dStrTo.tm_yday - toYear = dStrTo.tm_year - if fromYear != toYear: - cfg.mx.msgWar34() - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - if sat == cfg.goes16: - goesCol = 'https://noaa-goes16.s3.amazonaws.com' - elif sat == cfg.goes17: - goesCol = 'https://noaa-goes17.s3.amazonaws.com' - imageFindList = [] - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - else: - imageFindList.append('l1b') - cfg.uiUtls.addProgressBar() - cfg.QtWidgetsSCP.qApp.processEvents() - tW = cfg.ui.download_images_tableWidget - tW.setSortingEnabled(False) - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - # iterat days - dCount = 0 - for day in range(fromDay, toDay + 1): - if cfg.actionCheck == 'Yes': - dCount = dCount + 1 - if dCount < resultNum: - # iterate hours - for hour in range(0, 24): - if cfg.actionCheck == 'Yes': - cfg.uiUtls.updateBar(30 + int(hour * 70 / 24), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ... [day ' + str(day) + ']')) - searchUrl = goesCol + '/?list-type=2&delimiter=/&prefix=ABI-L1b-RadF/' + str(fromYear) + '/' + str(day).zfill(3) + '/' + str(hour).zfill(2) + '/' - # connect and search - xml2T = cfg.utls.createTempRasterPath('xml') - searchResult = cfg.utls.downloadFile(searchUrl, xml2T) - xmlFile = open(xml2T, 'r').read() - imgIDList = [] - doc = cfg.minidomSCP.parseString(xmlFile) - entries = doc.getElementsByTagName('Key') - for entry in entries: - if cfg.actionCheck == 'Yes': - imgID = entry.firstChild.data - if 'C01' in imgID: - for imF in imageFindList: - if imF in imgID.lower(): - c = tW.rowCount() - inDate = cfg.datetimeSCP.datetime.strptime(imgID.split('_s')[1][0:13], '%Y%j%H%M%S').strftime('%Y.%m.%dT%H_%M_%S') - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imgID.split('/')[-1], c, 1) - cfg.utls.addTableItem(tW, str(inDate), c, 2) - cfg.utls.addTableItem(tW, '', c, 3) - cfg.utls.addTableItem(tW, '', c, 4) - cfg.utls.addTableItem(tW, '', c, 5) - cfg.utls.addTableItem(tW, '', c, 6) - cfg.utls.addTableItem(tW, '', c, 7) - cfg.utls.addTableItem(tW, '', c, 8) - cfg.utls.addTableItem(tW, '', c, 9) - cfg.utls.addTableItem(tW,'AWS', c, 10) - cfg.utls.addTableItem(tW, '', c, 11) - cfg.utls.addTableItem(tW, imgID.split('_s')[1][0:14], c, 12) - cfg.utls.addTableItem(tW, searchUrl, c, 13) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' GOES images') - c = tW.rowCount() - if c == 0: - cfg.mx.msg21() - - # download images - def downloadGOESImages(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - outDirList = [] - imgList = [] - links = [] - c = tW.rowCount() - progressStep = 100 / c - progress = 0 - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat == cfg.goes16 or sat == cfg.goes17: - imgID = str(tW.item(i, 1).text()) - acquisitionDate = str(tW.item(i, 2).text()) - imgName2 = str(tW.item(i, 12).text()) - searchUrl = str(tW.item(i, 13).text()) - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked(): - pass - else: - outFiles = [] - outDirList.append(outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate) - progress = progress + progressStep - if exporter == 'No': - oDir = cfg.utls.makeDirectory(outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - # download bands - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_1, '01', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_2, '02', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_3, '03', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_4, '04', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_5, '05', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - self.checkGOESImageBands(cfg.ui.checkBoxs_goes_band_6, '06', imgID, searchUrl, imgName2, acquisitionDate, outputDirectory + '//' + imgID[0:25] + '_' + acquisitionDate, exporter, progress, outFiles, links) - for oFile in outFiles: - cfg.shutilSCP.copy(oFile[0], oFile[1]) - cfg.osSCP.remove(oFile[0]) - else: - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - if cfg.ui.preprocess_checkBox.isChecked() and exporter == 'No': - n = len(outDirList) - i = 0 - for d in outDirList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.goesT.populateTable(d, 'Yes') - o = d + "_con" - oDir = cfg.utls.makeDirectory(o) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.goesT.GOES(d, o, 'Yes') - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return links - - # check band download - def checkGOESImageBands(self, checkbox, bandNumber, imgName, searchUrl, imgName2, acquisitionDate, outputDirectory, exporter, progress, outFilesList, linksList): - if cfg.actionCheck == 'Yes': - if checkbox.isChecked(): - # connect and search - xml2T = cfg.utls.createTempRasterPath('xml') - searchResult = cfg.utls.downloadFile(searchUrl, xml2T) - xmlFile = open(xml2T, 'r').read() - imgIDList = [] - doc = cfg.minidomSCP.parseString(xmlFile) - entries = doc.getElementsByTagName('Key') - for entry in entries: - imgID = entry.firstChild.data - if 'C' + str(bandNumber) in imgID and imgName2 in imgID: - outFile = cfg.tmpDir + '//' + imgName[0:25] + '_' + acquisitionDate+ '_B' + bandNumber + '.nc' - outCopyFile = outputDirectory + '//' + imgName[0:25] + '_' + acquisitionDate + '_B' + bandNumber + '.nc' - urlL = searchUrl.split('?')[0] + imgID - if exporter == 'No': - cfg.utls.downloadFile(urlL, outFile) - outFilesList.append([outFile, outCopyFile]) - else: - linksList.append(urlL) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - - -### MODIS - - # download image metadata from NASA CMR Search https://cmr.earthdata.nasa.gov/search/site/search_api_docs.html - def downloadMetadataMODIS(self): - listImgID = [] - QdateFrom = cfg.ui.dateEdit_from.date() - QdateTo = cfg.ui.dateEdit_to.date() - dateFrom = QdateFrom.toPyDate().strftime("%Y-%m-%d") - dateTo = QdateTo.toPyDate().strftime("%Y-%m-%d") - maxCloudCover = int(cfg.ui.cloud_cover_spinBox.value()) - resultNum = int(cfg.ui.result_number_spinBox_2.value()) - sat = cfg.ui.landsat_satellite_combo.currentText() - if sat == cfg.usgsMODIS_MOD09GQ: - NASAcollection = cfg.NASAMOD09GQCollection - elif sat == cfg.usgsMODIS_MYD09GQ: - NASAcollection = cfg.NASAMYD09GQCollection - elif sat == cfg.usgsMODIS_MOD09GA: - NASAcollection = cfg.NASAMOD09GACollection - elif sat == cfg.usgsMODIS_MYD09GA: - NASAcollection = cfg.NASAMYD09GACollection - elif sat == cfg.usgsMODIS_MOD09Q1: - NASAcollection = cfg.NASAMOD09Q1Collection - elif sat == cfg.usgsMODIS_MYD09Q1: - NASAcollection = cfg.NASAMYD09Q1Collection - elif sat == cfg.usgsMODIS_MOD09A1: - NASAcollection = cfg.NASAMOD09A1Collection - elif sat == cfg.usgsMODIS_MYD09A1: - NASAcollection = cfg.NASAMYD09A1Collection - imageFindList = [] - if len(cfg.ui.imageID_lineEdit.text()) > 0: - imgIDLine = cfg.ui.imageID_lineEdit.text() - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(';') - if len(imgIDLineSplit) == 1: - imgIDLineSplit = str(imgIDLine).replace(' ', '').split(',') - for m in imgIDLineSplit: - imageFindList.append(m.lower()) - try: - rubbRect = cfg.qgisCoreSCP.QgsRectangle(float(cfg.ui.UX_lineEdit_3.text()), float(cfg.ui.UY_lineEdit_3.text()), float(cfg.ui.LX_lineEdit_3.text()), float(cfg.ui.LY_lineEdit_3.text())) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg23() - return 'No' - try: - cfg.uiUtls.addProgressBar() - cfg.QtWidgetsSCP.qApp.processEvents() - tW = cfg.ui.download_images_tableWidget - tW.setSortingEnabled(False) - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - # issue with cloud cover search - #searchUrl = 'https://cmr.earthdata.nasa.gov/search/granules.echo10?bounding_box=' + cfg.ui.UX_lineEdit_3.text() + '%2C' + cfg.ui.LY_lineEdit_3.text() + '%2C' + cfg.ui.LX_lineEdit_3.text() + '%2C' + cfg.ui.UY_lineEdit_3.text() + '&echo_collection_id=' + NASAcollection + '&temporal=' + dateFrom + '%2C' + dateTo + 'T23%3A59%3A59.000Z&cloud_cover=0,' + str(maxCloudCover) + '&sort_key%5B%5D=-start_date&page_size=' + str(resultNum) + '&pretty=true' - searchUrl = 'https://cmr.earthdata.nasa.gov/search/granules.echo10?bounding_box=' + cfg.ui.UX_lineEdit_3.text() + '%2C' + cfg.ui.LY_lineEdit_3.text() + '%2C' + cfg.ui.LX_lineEdit_3.text() + '%2C' + cfg.ui.UY_lineEdit_3.text() + '&echo_collection_id=' + NASAcollection + '&temporal=' + dateFrom + '%2C' + dateTo + 'T23%3A59%3A59.000Z&sort_key%5B%5D=-start_date&page_size=' + str(resultNum) + '&pretty=true' - # connect and search - searchResult = cfg.utls.NASASearch(searchUrl) - xmlFile = searchResult.read() - imgIDList = [] - doc = cfg.minidomSCP.parseString(xmlFile) - entries = doc.getElementsByTagName('Granule') - pages = len(entries) - page = 0 - for entry in entries: - page = page + 1 - cfg.uiUtls.updateBar(30 + int(page * 70 / pages), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - gId = entry.getElementsByTagName('ProducerGranuleId')[0] - imgID = gId.firstChild.data - if imgID not in imgIDList: - imgIDList.append(imgID) - imgDispID = imgID.replace('.hdf', '') - #cc = entry.getElementsByTagName("QAPercentCloudCover")[0] - #cloudCover = cc.firstChild.data - cloudCover = 0 - on = entry.getElementsByTagName('OnlineResources') - url = on[0].getElementsByTagName('URL')[1] - imgPreview = url.firstChild.data - # in case of missing preview - if not imgPreview.lower().endswith('.jpg'): - inTime = entry.getElementsByTagName('InsertTime')[0] - inDate = inTime.firstChild.data - inDate = cfg.datetimeSCP.datetime.strptime(inDate[0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y.%m.%d') - imgPreview = 'https://e4ftl01.cr.usgs.gov/WORKING/BRWS/Browse.001/' + inDate + '/BROWSE.' + imgDispID.replace('GQ', 'GA') + '.1.jpg' - dt = entry.getElementsByTagName('BeginningDateTime')[0] - imgDate = dt.firstChild.data - imgDate = cfg.datetimeSCP.datetime.strptime(imgDate[0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M:%S') - PointLatitude = entry.getElementsByTagName('PointLatitude') - lat = [] - for latit in PointLatitude: - lat.append(float(latit.firstChild.data)) - PointLongitude = entry.getElementsByTagName('PointLongitude') - lon = [] - for longi in PointLongitude: - pppLon = float(longi.firstChild.data) - if pppLon < -170: - pppLon = 180 + (180 + pppLon) - lon.append(pppLon) - DayNightFlag = entry.getElementsByTagName('DayNightFlag')[0] - dayNight = DayNightFlag.firstChild.data - listImgID.append([imgID, imgDate, cloudCover, imgDispID, dayNight, lon, lat, imgPreview.replace('http:', 'https:')]) - cfg.uiUtls.updateBar(100, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Searching ...')) - c = tW.rowCount() - for imID in listImgID: - if len(imageFindList) > 0: - for iF in imageFindList: - if iF in imID[0].lower(): - imgCheck = 'Yes' - break - else: - imgCheck = 'No' - else: - imgCheck = 'Yes' - if imgCheck == 'Yes': - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, sat, c, 0) - cfg.utls.addTableItem(tW, imID[3], c, 1) - cfg.utls.addTableItem(tW, str(imID[1]), c, 2) - cfg.utls.addTableItem(tW, int(round(float(imID[2]))), c, 3) - cfg.utls.addTableItem(tW, '', c, 4) - cfg.utls.addTableItem(tW, imID[4], c, 5) - min_lon = min(imID[5]) - max_lon = max(imID[5]) - min_lat = min(imID[6]) - max_lat = max(imID[6]) - cfg.utls.addTableItem(tW, float(min_lat), c, 6) - cfg.utls.addTableItem(tW, float(min_lon), c, 7) - cfg.utls.addTableItem(tW, float(max_lat), c, 8) - cfg.utls.addTableItem(tW,float(max_lon), c, 9) - cfg.utls.addTableItem(tW,'EOSDIS Earthdata', c, 10) - cfg.utls.addTableItem(tW, imID[7], c, 11) - cfg.utls.addTableItem(tW, NASAcollection, c, 12) - cfg.utls.addTableItem(tW, imID[0], c, 13) - tW.setSortingEnabled(True) - cfg.uiUtls.removeProgressBar() - self.clearCanvasPoly() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' MODIS images') - c = tW.rowCount() - if c == 0: - cfg.mx.msg21() - except Exception as err: - cfg.mx.msgErr39() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - - # download MODIS data - def downloadMODISImages(self, outputDirectory, exporter = 'No'): - cfg.uiUtls.addProgressBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Downloading'), message = '') - tW = cfg.ui.download_images_tableWidget - c = tW.rowCount() - progressStep = 100 / c - progressStep2 = progressStep/12 - progress = 0 - outDirList = [] - outFileList = [] - imgList = [] - links = [] - for i in range(0, c): - sat = str(tW.item(i, 0).text()) - if cfg.actionCheck == 'Yes': - if sat in cfg.satMODIStList: - imgID = str(tW.item(i, 13).text()) - imgDispID = str(tW.item(i, 1).text()) - date = str(tW.item(i, 2).text())[0:10] - if cfg.ui.download_if_preview_in_legend_checkBox.isChecked() and cfg.utls.selectLayerbyName(imgDispID, 'Yes') is None: - pass - else: - NASAcollection = str(tW.item(i, 12).text()) - outDir = outputDirectory + "/" + imgDispID - if exporter == 'No': - oDir = cfg.utls.makeDirectory(outDir) - if oDir is None: - cfg.mx.msgErr58() - cfg.uiUtls.removeProgressBar() - return 'No' - outDirList.append(outDir) - outFileList.append(outDir + "//" + imgDispID + ".hdf") - progress = progress + progressStep - outUrl = self.downloadMODISImagesFromNASA(imgID, NASAcollection, imgDispID, outDir, progress, exporter, date) - links.append(outUrl) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - if exporter == 'Yes': - return links - else: - cfg.cnvs.setRenderFlag(False) - if cfg.ui.preprocess_checkBox.isChecked(): - n = len(outFileList) - i = 0 - for d in outFileList: - i = i + 1 - cfg.uiUtls.updateBar(mainMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Processing') + ' [' + str(i) + '/' + str(n) + '] ' + cfg.osSCP.path.basename(d), message = '') - if cfg.actionCheck == 'Yes': - cfg.MODIST.populateTable(d, 'Yes') - o = d + '_converted' - oDir = cfg.utls.makeDirectory(o) - cfg.MODIST.MODIS(d, o, 'Yes') - elif cfg.ui.load_in_QGIS_checkBox.isChecked(): - for d in outDirList: - try: - for f in cfg.osSCP.listdir(d): - if f.lower().endswith('.tif'): - r =cfg.utls.addRasterLayer(d + '/' + f) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - - # download image - def downloadMODISImagesFromNASA(self, imageID, collection, imageDisplayID, outputDirectory, progress, exporter = 'No', date = None): - # The MODIS data products are retrieved from the online Data Pool, courtesy of the NASA Land Processes Distributed Active Archive Center (LP DAAC), USGS/Earth Resources Observation and Science (EROS) Center, Sioux Falls, South Dakota, https://lpdaac.usgs.gov/data_access/data_pool' - if collection == cfg.NASAMOD09GQCollection: - url = 'https://e4ftl01.cr.usgs.gov/MOLT/MOD09GQ.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMYD09GQCollection: - url = 'https://e4ftl01.cr.usgs.gov/MOLA/MYD09GQ.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMOD09GACollection: - url = 'https://e4ftl01.cr.usgs.gov/MOLT/MOD09GA.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMYD09GACollection: - url = 'https://e4ftl01.cr.usgs.gov/MOLA/MYD09GA.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMOD09Q1Collection: - url = 'https://e4ftl01.cr.usgs.gov/MOLT/MOD09Q1.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMYD09Q1Collection: - url = 'https://e4ftl01.cr.usgs.gov/MOLA/MYD09Q1.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMOD09A1Collection: - url = 'https://e4ftl01.cr.usgs.gov/MOLT/MOD09A1.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - elif collection == cfg.NASAMYD09A1Collection: - url = 'https://e4ftl01.cr.usgs.gov/MOLA/MYD09A1.006/' + date.replace('-', '.')+ '/' + imageDisplayID + '.hdf' - if exporter == 'Yes': - return url - else: - user = cfg.ui.user_usgs_lineEdit_2.text() - password =cfg.ui.password_usgs_lineEdit_2.text() - try: - imgID = imageDisplayID + '.hdf' - check = cfg.utls.passwordConnectPython(user, password, url, 'urs.earthdata.nasa.gov', cfg.tmpDir + '//' + imgID, progress) - if str(check) == 'Cancel action': - return check - if cfg.osSCP.path.getsize(cfg.tmpDir + '//' + imgID) > 10000: - cfg.shutilSCP.copy(cfg.tmpDir + '//' + imgID, outputDirectory + '//' + imgID) - cfg.osSCP.remove(cfg.tmpDir + '//' + imgID) - else: - cfg.mx.msgErr55(imgID) - return 'No' - except Exception as err: - cfg.mx.msgErr55(imgID) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - - # perform bands filter - def filterTable(self): - l = cfg.ui.download_images_tableWidget - text = cfg.ui.products_filter_lineEdit.text() - items = l.findItems(text, cfg.QtSCP.MatchContains) - c = l.rowCount() - list = [] - for item in items: - list.append( item.row()) - l.blockSignals(True) - for i in range (0, c): - l.setRowHidden(i, False) - if i not in list: - l.setRowHidden(i, True) - l.blockSignals(False) \ No newline at end of file diff --git a/maininterface/editraster.py b/maininterface/editraster.py deleted file mode 100644 index bcb3139..0000000 --- a/maininterface/editraster.py +++ /dev/null @@ -1,429 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class EditRaster: - - def __init__(self): - pass - - # set raster value - def setRasterValueAction(self): - self.setRasterValue() - - # set raster value - def setRasterValue(self, batch = 'No', rasterInput = None, vectorInput = None, vectorFieldName = None): - if cfg.ui.edit_val_use_ROI_radioButton.isChecked() and cfg.lstROI is None: - cfg.mx.msg22() - return - else: - if batch == 'No': - self.rstrNm = cfg.ui.edit_raster_name_combo.currentText() - b = cfg.utls.selectLayerbyName(self.rstrNm, 'Yes') - else: - b = 'No' - if b is not None: - if batch == 'No': - rSource = cfg.utls.layerSource(b) - else: - rSource = rasterInput - cfg.ui.undo_edit_Button.setEnabled(False) - cfg.undoEditRasterToolbar_toolButton.setEnabled(False) - # create feature list - rId = [] - f = cfg.qgisCoreSCP.QgsFeature() - # using vector - if cfg.ui.edit_val_use_vector_radioButton.isChecked(): - if batch == 'No': - shapeNm = cfg.ui.vector_name_combo_2.currentText() - shape = cfg.utls.selectLayerbyName(shapeNm) - else: - shape = cfg.utls.addVectorLayer(vectorInput , cfg.utls.fileName(vectorInput), "ogr") - if shape is None: - return - for f in shape.getFeatures(): - rId.append(f.id()) - vector = shape - # using ROI polygon - elif cfg.ui.edit_val_use_ROI_radioButton.isChecked(): - for f in cfg.lstROI.getFeatures(): - rId.append(f.id()) - vector = cfg.lstROI - # hide ROI - cfg.show_ROI_radioButton.setChecked(False) - cfg.SCPD.showHideROI() - self.setValueRaster(rSource, vector, rId, batch, vectorFieldName) - if b != 'No': - b.reload() - b.triggerRepaint() - cfg.cnvs.refresh() - if batch == 'No': - pass - else: - cfg.utls.removeLayerByLayer(shape) - else: - cfg.utls.refreshClassificationLayer() - cfg.mx.msgErr9() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error raster not found") - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - - # set value raster - def setValueRaster(self, inputRaster, inputVectorQGIS, qgisVectorFeatureList, batch = 'No', vectorFieldName = None, toolbarValue = None): - crs = cfg.utls.getCrs(inputVectorQGIS) - # using ROI polygon - if cfg.ui.edit_val_use_ROI_radioButton.isChecked() or toolbarValue is not None: - # temporary layer - tLP = cfg.utls.createTempRasterPath('gpkg') - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP, format = 'GPKG') - vector = cfg.utls.addVectorLayer(tLP, cfg.utls.fileName(tLP), "ogr") - for pI in qgisVectorFeatureList: - cfg.utls.copyFeatureToLayer(inputVectorQGIS, pI, vector) - if toolbarValue is None: - toolbarValue = cfg.ui.value_spinBox.value() - self.performEdit(inputRaster, tLP, toolbarValue) - cfg.ui.undo_edit_Button.setEnabled(True) - cfg.undoEditRasterToolbar_toolButton.setEnabled(True) - # using vector - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - progress = 0 - progressStep = 100 / (len(qgisVectorFeatureList) + 1) - n = 0 - for pI in qgisVectorFeatureList: - n = n + 1 - progress = progress + progressStep - cfg.uiUtls.updateBar(progress) - # temporary layer - tLP = cfg.utls.createTempRasterPath('gpkg') - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP, format = 'GPKG') - vector = cfg.utls.addVectorLayer(tLP, cfg.utls.fileName(tLP), 'ogr') - cfg.utls.copyFeatureToLayer(inputVectorQGIS, pI, vector) - if cfg.ui.use_constant_val_checkBox.isChecked() is True: - value = cfg.ui.value_spinBox.value() - else: - if vectorFieldName is None: - fd = cfg.ui.field_comboBox_2.currentText() - else: - fd = vectorFieldName - if len(fd) == 0: - cfg.utls.refreshVectorLayer() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - fId = cfg.utls.fieldID(inputVectorQGIS, fd) - f = cfg.utls.getFeaturebyID(inputVectorQGIS, pI) - value = f.attributes()[fId] - self.performEdit(inputRaster, tLP, value) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - # perform raster edit - def performEdit(self, inputRasterPath, inputVectorPath, editValue = None): - # convert polygon to raster - tRxs = cfg.utls.createTempRasterPath('tif') - check = cfg.utls.vectorToRaster(cfg.emptyFN, str(inputVectorPath), cfg.emptyFN, tRxs, str(inputRasterPath), None, 'GTiff', 1) - # open input with GDAL - rD = cfg.gdalSCP.Open(inputRasterPath, cfg.gdalSCP.GA_Update) - if rD is None: - return 'No' - rD2 = cfg.gdalSCP.Open(tRxs, cfg.gdalSCP.GA_ReadOnly) - if rD2 is None: - return 'No' - # pixel size and origin - rGT = rD.GetGeoTransform() - tLX = rGT[0] - tLY = rGT[3] - pSX = rGT[1] - pSY = rGT[5] - rGT2 = rD2.GetGeoTransform() - tLX2 = rGT2[0] - tLY2 = rGT2[3] - # number of x pixels - rC = rD.RasterXSize - rC2 = rD2.RasterXSize - # number of y pixels - rR = rD.RasterYSize - rR2 = rD2.RasterYSize - if tLX2 < tLX: - startX = tLX - else: - startX = tLX2 - if tLY2 > tLY: - startY = tLY - else: - startY = tLY2 - self.pixelStartColumn = abs(int((tLX - startX) / pSX )) - self.pixelStartRow = abs(int((tLY - startY) / pSY )) - startColumn2 = abs(int((tLX2 - startX) / pSX )) - startRow2 = abs(int((tLY2 - startY) / pSY )) - columnNum = rC2 - startColumn2 - rowNum = rR2 - startRow2 - if columnNum < 1 or rowNum < 1: - return - if self.pixelStartColumn + columnNum > rC: - columnNum1 = rC - self.pixelStartColumn - else: - columnNum1 = columnNum - if columnNum1 < 0: - return - if self.pixelStartRow + rowNum > rR: - rowNum1 = rR - self.pixelStartRow - else: - rowNum1 = rowNum - if rowNum1 < 0: - return - # read raster - iRB = rD.GetRasterBand(1) - try: - o = iRB.GetOffset() - s = iRB.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - a = iRB.ReadAsArray(self.pixelStartColumn, self.pixelStartRow, columnNum1, rowNum1) - off = o - sca = s - self.a1 = a - iRB2 = rD2.GetRasterBand(1) - try: - o = iRB2.GetOffset() - s = iRB2.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - b = iRB2.ReadAsArray(startColumn2, startRow2, columnNum1, rowNum1) - a2 = b*s+o - # expression - if cfg.ui.use_expression_checkBox.isChecked() is True: - expression = ' ' + cfg.ui.expression_lineEdit.text() + ' ' - e = self.checkExpression(expression, editValue) - if e == 'No': - return 'No' - else: - dataArray = eval(e) - else: - value = editValue - dataArray = cfg.np.where(a2 >0 , value, self.a1*sca+off) - iRB = None - iRB2 = None - self.writeArrayBlock(rD, 1, dataArray/sca-off, self.pixelStartColumn, self.pixelStartRow) - rD = None - rD2 = None - - # reload vector list - def reloadVectorList(self): - cfg.utls.refreshVectorLayer() - - # text changed - def textChanged(self): - expression = ' ' + cfg.ui.expression_lineEdit.text() + ' ' - self.checkExpression(expression, 0) - - # check the expression and return it - def checkExpression(self, expression, editValue): - expr = expression - expr = expr.replace(cfg.variableName, 'self.a1') - # replace numpy operators - expr = cfg.utls.replaceNumpyOperators(expr) - # value from vector - expr = expr.replace(cfg.vectorVariableName, str(editValue)) - e = 'cfg.np.where(a2 >0 ,' + expr + ', self.a1)' - # test - ar1 = cfg.np.arange(9).reshape(3, 3) - eCopy = e - eCopy = eCopy.replace('self.a1', 'ar1') - eCopy = eCopy.replace('a2', 'ar1') - try: - o = eval(eCopy) - cfg.ui.expression_lineEdit.setStyleSheet('color : green') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - return e - except Exception as err: - cfg.ui.expression_lineEdit.setStyleSheet('color : red') - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # undo edit - def undoEdit(self): - try: - b = cfg.utls.selectLayerbyName(self.rstrNm, 'Yes') - rSource = cfg.utls.layerSource(b) - # open input with GDAL - rD = cfg.gdalSCP.Open(rSource, cfg.gdalSCP.GA_Update) - if rD is None: - return 'No' - self.writeArrayBlock(rD, 1, self.a1, self.pixelStartColumn, self.pixelStartRow) - rD = None - b.reload() - b.triggerRepaint() - cfg.cnvs.refresh() - cfg.ui.undo_edit_Button.setEnabled(False) - cfg.undoEditRasterToolbar_toolButton.setEnabled(False) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - except: - pass - - # write an array to band - def writeArrayBlock(self, gdalRaster, bandNumber, dataArray, pixelStartColumn, pixelStartRow): - b = gdalRaster.GetRasterBand(bandNumber) - b.WriteArray(dataArray, pixelStartColumn, pixelStartRow) - b.FlushCache() - b = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # checkbox changed - def checkboxVectorFieldChanged(self): - cfg.ui.use_constant_val_checkBox.blockSignals(True) - cfg.ui.use_expression_checkBox.blockSignals(True) - cfg.ui.use_field_vector_checkBox.blockSignals(True) - if cfg.ui.use_field_vector_checkBox.isChecked(): - cfg.ui.use_expression_checkBox.setCheckState(0) - cfg.ui.use_constant_val_checkBox.setCheckState(0) - else: - cfg.ui.use_field_vector_checkBox.setCheckState(2) - cfg.ui.use_expression_checkBox.blockSignals(False) - cfg.ui.use_constant_val_checkBox.blockSignals(False) - cfg.ui.use_field_vector_checkBox.blockSignals(False) - cfg.ui.edit_val_use_vector_radioButton.setChecked(True) - - # checkbox changed - def checkboxConstantValChanged(self): - cfg.ui.use_constant_val_checkBox.blockSignals(True) - cfg.ui.use_expression_checkBox.blockSignals(True) - cfg.ui.use_field_vector_checkBox.blockSignals(True) - if cfg.ui.use_constant_val_checkBox.isChecked(): - cfg.ui.use_expression_checkBox.setCheckState(0) - cfg.ui.use_field_vector_checkBox.setCheckState(0) - else: - cfg.ui.use_constant_val_checkBox.setCheckState(2) - cfg.ui.use_expression_checkBox.blockSignals(False) - cfg.ui.use_constant_val_checkBox.blockSignals(False) - cfg.ui.use_field_vector_checkBox.blockSignals(False) - - # checkbox changed - def checkboxUseExpressionChanged(self): - cfg.ui.use_expression_checkBox.blockSignals(True) - cfg.ui.use_constant_val_checkBox.blockSignals(True) - cfg.ui.use_field_vector_checkBox.blockSignals(True) - if cfg.ui.use_expression_checkBox.isChecked(): - cfg.ui.use_constant_val_checkBox.setCheckState(0) - cfg.ui.use_field_vector_checkBox.setCheckState(0) - else: - cfg.ui.use_expression_checkBox.setCheckState(2) - cfg.ui.use_expression_checkBox.blockSignals(False) - cfg.ui.use_constant_val_checkBox.blockSignals(False) - cfg.ui.use_field_vector_checkBox.blockSignals(False) - - # radio button changed - def radioUseROIPolygonChanged(self): - cfg.ui.edit_val_use_ROI_radioButton.blockSignals(True) - cfg.ui.edit_val_use_vector_radioButton.blockSignals(True) - if cfg.ui.edit_val_use_ROI_radioButton.isChecked(): - cfg.ui.edit_val_use_vector_radioButton.setChecked(False) - else: - cfg.ui.edit_val_use_vector_radioButton.setChecked(True) - cfg.ui.edit_val_use_ROI_radioButton.blockSignals(False) - cfg.ui.edit_val_use_vector_radioButton.blockSignals(False) - if cfg.ui.use_field_vector_checkBox.isChecked(): - cfg.ui.use_constant_val_checkBox.setCheckState(2) - - # radio button changed - def radioUseVectorChanged(self): - cfg.ui.edit_val_use_ROI_radioButton.blockSignals(True) - cfg.ui.edit_val_use_vector_radioButton.blockSignals(True) - if cfg.ui.edit_val_use_vector_radioButton.isChecked(): - cfg.ui.edit_val_use_ROI_radioButton.setChecked(False) - else: - cfg.ui.edit_val_use_ROI_radioButton.setChecked(True) - cfg.ui.edit_val_use_ROI_radioButton.blockSignals(False) - cfg.ui.edit_val_use_vector_radioButton.blockSignals(False) - - # edit using toolbar values - def toolbarEditValue(self, toolbarValue): - if cfg.lstROI is None: - cfg.mx.msg22() - return - self.rstrNm = cfg.ui.edit_raster_name_combo.currentText() - b = cfg.utls.selectLayerbyName(self.rstrNm, 'Yes') - if b is not None: - rSource = cfg.utls.layerSource(b) - cfg.ui.undo_edit_Button.setEnabled(False) - cfg.undoEditRasterToolbar_toolButton.setEnabled(False) - # create feature list - rId = [] - f = cfg.qgisCoreSCP.QgsFeature() - for f in cfg.lstROI.getFeatures(): - rId.append(f.id()) - vector = cfg.lstROI - # hide ROI - cfg.show_ROI_radioButton.setChecked(False) - cfg.SCPD.showHideROI() - self.setValueRaster(rSource, vector, rId, 'No', None, toolbarValue) - if b != 'No': - b.reload() - b.triggerRepaint() - cfg.cnvs.refresh() - - # toolbar value 0 - def toolbarValue0(self): - self.toolbarEditValue(int(cfg.val0_spin.value())) - - # toolbar value 1 - def toolbarValue1(self): - self.toolbarEditValue(int(cfg.val1_spin.value())) - - # toolbar value 2 - def toolbarValue2(self): - self.toolbarEditValue(int(cfg.val2_spin.value())) - \ No newline at end of file diff --git a/maininterface/erosionTab.py b/maininterface/erosionTab.py deleted file mode 100644 index bc23e6f..0000000 --- a/maininterface/erosionTab.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ErosionRaster: - - def __init__(self): - pass - - # value text changed - def textChanged(self): - self.checkValueList() - - # check value list - def checkValueList(self): - try: - # class value list - valueList = cfg.utls.textToValueList(cfg.ui.erosion_classes_lineEdit.text()) - cfg.ui.erosion_classes_lineEdit.setStyleSheet('color : green') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - except Exception as err: - cfg.ui.erosion_classes_lineEdit.setStyleSheet('color : red') - valueList = [] - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return valueList - - # erosion classification - def erosionClassificationAction(self): - self.erosionClassification() - - # erosion classification - def erosionClassification(self, batch = 'No', rasterInput = None, rasterOutput = None,circularStructure = None): - # class value list - valueList = self.checkValueList() - if len(valueList) > 0: - if batch == 'No': - outputRaster = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - outputRaster = rasterOutput - # virtual raster - vrtR = 'No' - if outputRaster is not False: - if outputRaster.lower().endswith('.vrt'): - vrtR = 'Yes' - elif outputRaster.lower().endswith('.tif'): - pass - else: - outputRaster = outputRaster + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - cfg.cnvs.setRenderFlag(False) - raster = cfg.ui.erosion_raster_name_combo.currentText() - r = cfg.utls.selectLayerbyName(raster, 'Yes') - else: - r = 'No' - if r is not None: - if batch == 'No': - rSource = cfg.utls.layerSource(r) - else: - if cfg.osSCP.path.isfile(rasterInput): - rSource = rasterInput - else: - return 'No' - if rSource is None: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' None raster') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - return 'No' - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(outputRaster)) - input = rSource - nd = cfg.utls.imageNoDataValue(input) - dType = cfg.utls.getRasterDataTypeName(input) - size = cfg.ui.erosion_threshold_spinBox.value() - if circularStructure is None: - if cfg.ui.circular_structure_checkBox_3.isChecked(): - circularStructure = 'Yes' - else: - circularStructure = 'No' - if circularStructure == 'No': - structure = cfg.np.ones((3,3)) - else: - structure = cfg.utls.createCircularStructure(1) - # iterate - for s in range(0, size): - # last iteration - if s == size-1: - tPMD = outputRaster - vrtRR = vrtR - else: - vrtRR = 'Yes' - if vrtR == 'No': - tPMD = cfg.utls.createTempRasterPath('tif') - else: - tPMD = cfg.utls.createTempRasterPath('vrt') - # process calculation - o = cfg.utls.multiProcessRaster(rasterPath = input, functionBand = 'No', functionRaster = cfg.utls.rasterErosion, outputRasterList = [tPMD], functionBandArgument = structure, functionVariable = valueList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Erosion step ') + str(s+1) + '/' + str(size), virtualRaster = vrtR, compress = 'No', outputNoDataValue = nd, dataType = dType, boundarySize = 3, additionalLayer = 5) - input = tPMD - if cfg.osSCP.path.isfile(outputRaster): - oR =cfg.utls.addRasterLayer(outputRaster) - if r != 'No': - try: - cfg.utls.copyRenderer(r, oR) - except: - pass - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.utls.refreshClassificationLayer() - cfg.mx.msgErr9() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error raster not found") - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode()) - \ No newline at end of file diff --git a/maininterface/landcoverchange.py b/maininterface/landcoverchange.py deleted file mode 100644 index f977729..0000000 --- a/maininterface/landcoverchange.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class LandCoverChange: - - def __init__(self): - pass - - # reference classification name - def classificationReferenceLayerName(self): - cfg.refClssfctnNm = cfg.ui.classification_reference_name_combo.currentText() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "reference classification name: " + str(cfg.refClssfctnNm)) - - # start land cover change calculation - def landCoverChangeAction(self): - self.landCoverChange() - - # start land cover change calculation - def landCoverChange(self, batch = 'No', referenceRaster = None, newRaster = None, rasterOutput = None): - if batch == 'No': - # input - refRstr = cfg.utls.selectLayerbyName(cfg.refClssfctnNm, 'Yes') - try: - refRstrSrc = cfg.utls.layerSource(refRstr) - rstrCheck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - rstrCheck = 'No' - newRstr = cfg.utls.selectLayerbyName(cfg.newClssfctnNm, 'Yes') - try: - newRstrSrc = cfg.utls.layerSource(newRstr) - rstrCheck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - rstrCheck = 'No' - else: - refRstrSrc = referenceRaster - newRstrSrc = newRaster - if cfg.osSCP.path.isfile(refRstrSrc) and cfg.osSCP.path.isfile(newRstrSrc): - rstrCheck = 'Yes' - else: - rstrCheck = 'No' - # check if numpy is updated - try: - cfg.np.count_nonzero([1,1,0]) - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msgErr26() - return 'No' - if rstrCheck == 'No': - cfg.mx.msg4() - else: - if batch == 'No': - chngRstPath = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save land cover change raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - chngRstPath = rasterOutput - # virtual raster - vrtR = 'No' - if chngRstPath is not False: - # check projections - rCrs = cfg.utls.getCrsGDAL(refRstrSrc) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - eCrs = cfg.utls.getCrsGDAL(newRstrSrc) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(newRstrSrc, tPMD, str(rCrs)) - cfg.mx.msg9() - newRstrSrc = tPMD - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(chngRstPath)) - if chngRstPath.lower().endswith('.vrt'): - vrtR = 'Yes' - elif chngRstPath.lower().endswith('.tif'): - pass - else: - chngRstPath = chngRstPath + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - tblOut = cfg.osSCP.path.dirname(chngRstPath) + '/' + cfg.utls.fileNameNoExt(chngRstPath) + '.csv' - # combination finder - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = refRstrSrc, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values')) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # calculate unique values - valuesA = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - valuesA = cfg.np.append(valuesA, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - try: - cmbA = cfg.np.unique(valuesA, axis = 0).tolist() - refRasterBandUniqueVal = sorted(cmbA) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - # new raster - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = newRstrSrc, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values')) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # calculate unique values - valuesB = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - valuesB = cfg.np.append(valuesB, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - try: - cmbB = cfg.np.unique(valuesB, axis = 0).tolist() - newRasterBandUniqueVal = sorted(cmbB) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - bandsUniqueVal = [refRasterBandUniqueVal, newRasterBandUniqueVal] - if 0 in refRasterBandUniqueVal: - k0 = 1 - else: - k0 = 0 - if 0 in newRasterBandUniqueVal: - k1 = 1 - else: - k1 = 0 - try: - cmb = list(cfg.itertoolsSCP.product(*bandsUniqueVal)) - testCmb = cmb[0] - except Exception as err: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr63() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # expression builder - check = 'No' - t = 0 - while t < 100: - t = t + 1 - rndVarList = [] - calcDataType = cfg.np.uint32 - # first try fixed list - if t == 1: - coT = 333 - for cmbI in range(0, len(cmb[0])): - rndVarList.append(coT) - coT = coT + 1 - # random list - else: - for cmbI in range(0, len(cmb[0])): - rndVarList.append(int(999 * cfg.np.random.random())) - newValueList = [] - reclassDict = {} - for i in cmb: - newVl = (i[0] + k0) * (rndVarList[0]) + (i[1] + k1) * (rndVarList[1]) - reclassDict[newVl] = i - newValueList.append(newVl) - if i[0] < 0 or i[1] < 0 : - calcDataType = cfg.np.int32 - uniqueValList = cfg.np.unique(newValueList) - if int(uniqueValList.shape[0]) == len(newValueList): - n = 1 - col = [] - row = [] - reclassList = [] - cmbntns = {} - for newVl in sorted(reclassDict.keys()): - i = reclassDict[newVl] - reclassList.append(newVl) - cmbntns[n] = [i[1], i[0]] - col.append(i[1]) - row.append(i[0]) - n = n + 1 - check = 'Yes' - break - if check == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - e = '(rasterSCPArrayfunctionBand[::, ::, 0] + ' + str(k0) +' ) * ' + str(rndVarList[0]) + ' + (rasterSCPArrayfunctionBand[::, ::, 1] + ' + str(k1) +' ) * ' + str(rndVarList[1]) - # calculation - bList = [refRstrSrc, newRstrSrc] - bandNumberList = [1, 1] - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.crossRasters, outputRasterList = [chngRstPath], functionBandArgument = reclassList, functionVariable = e, progressMessage =cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Land cover change'), virtualRaster = vrtR, compress = cfg.rasterCompression, outputNoDataValue = cfg.NoDataValUInt32, dataType = 'UInt32', calcDataType = calcDataType) - # check projections - left, right, top, bottom, cRPX, cRPY, rP, un = cfg.utls.imageGeoTransform(chngRstPath) - if o == 'No': - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr45() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error') - return 'No' - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'land cover change raster output: ' + str(chngRstPath)) - # calculate unique values - values = cfg.np.array([]) - sumVal = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[1][0, ::]) - sumVal = cfg.np.append(sumVal, ar[1][1, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - return 'No' - reclRasterBandUniqueVal = {} - values = values.astype(int) - for v in range(0, len(values)): - try: - reclRasterBandUniqueVal[values[v]] = reclRasterBandUniqueVal[values[v]] + sumVal[v] - except: - reclRasterBandUniqueVal[values[v]] = sumVal[v] - rasterBandUniqueVal = {} - for v in range(0, len(values)): - try: - cmbX = cmbntns[values[v]] - rasterBandUniqueVal[(cmbX[0], cmbX[1])] = [reclRasterBandUniqueVal[values[v]], values[v]] - except: - pass - cfg.uiUtls.updateBar(80) - col2 = list(set(col)) - row2 = list(set(row)) - cols = sorted(cfg.np.unique(col2).tolist()) - rows = sorted(cfg.np.unique(row2).tolist()) - crossClass = cfg.np.zeros((len(rows), len(cols))) - cList = 'V_' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ReferenceClass') + '\t' - try: - l = open(tblOut, 'w') - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - cfg.utls.removeLayerByLayer(remiClass) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'CrossClassCode') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'NewClass') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'ReferenceClass') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PixelSum') + ' ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Area [' + un + '^2]') + str('\n') - l.write(t) - for c in cols: - cList = cList + str(c) + '\t' - for r in rows: - try: - v = (c, r) - area = str(rasterBandUniqueVal[v][0] * cRPX * cRPY) - t = str(rasterBandUniqueVal[v][1]) + '\t' + str(c) + '\t' + str(r) + '\t' + str(rasterBandUniqueVal[v][0]) + '\t' + area + str('\n') - l.write(t) - crossClass[rows.index(r), cols.index(c)] = rasterBandUniqueVal[v][0] * cRPX * cRPY - except: - crossClass[rows.index(r), cols.index(c)] = 0 - # save combination to table - l.write(str('\n')) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'LAND COVER CHANGE MATRIX [') + str(un) + '^2]' + '\n' - l.write(tStr) - tStr = '\t' + '> ' + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'NewClass') + '\n' - l.write(tStr) - tStr = cList + cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') + '\n' - l.write(tStr) - # date time for temp name - dT = cfg.utls.getTime() - # temp matrix - tmpMtrx= cfg.tmpDir + '/' + cfg.tempMtrxNm + dT + '.txt' - cfg.np.savetxt(tmpMtrx, crossClass, delimiter='\t', fmt='%i') - tM = open(tmpMtrx, 'r') - # write matrix - ix = 0 - for j in tM: - tMR = str(rows[ix]) + '\t' + j.rstrip('\n') + '\t' + str(int(crossClass[ix, :].sum())) + str('\n') - l.write(tMR) - ix = ix + 1 - # last line - lL = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Total') - for c in range(0, len(cols)): - lL = lL + '\t' + str(int(crossClass[:, c].sum())) - totMat = int(crossClass.sum()) - lL = lL + '\t' + str(totMat) + str('\n') - l.write(lL) - l.close() - # open csv - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - changeTxt = f.read() - cfg.ui.change_textBrowser.setText(str(changeTxt)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # add raster to layers - rstr = cfg.utls.addRasterLayer(chngRstPath) - cfg.utls.rasterSymbolGeneric(rstr, rasterUniqueValueList = sorted(reclRasterBandUniqueVal.keys())) - cfg.uiUtls.updateBar(100) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.ui.toolBox_landCoverChange.setCurrentIndex(1) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'finished') - - # state of checkbox for mask unchanged - def maskUnchangedCheckbox(self): - if cfg.ui.mask_unchanged_checkBox.isChecked() is True: - cfg.unchngMaskCheck = True - else: - cfg.unchngMaskCheck = False - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " checkbox set: " + str(cfg.unchngMaskCheck)) - - # new classification name - def newClassificationLayerName(self): - cfg.newClssfctnNm = cfg.ui.new_classification_name_combo.currentText() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "reference classification name: " + str(cfg.newClssfctnNm)) - - # refresh reference classification name - def refreshClassificationReferenceLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.classification_reference_name_combo.clear() - # reference classification name - cfg.refClssfctnNm = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.classification_reference_layer_combo(l.name()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "reference classification layers refreshed") - - # refresh new classification name - def refreshNewClassificationLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.new_classification_name_combo.clear() - # new classification name - cfg.newClssfctnNm = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.new_classification_layer_combo(l.name()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "new classification layers refreshed") \ No newline at end of file diff --git a/maininterface/landsatTab.py b/maininterface/landsatTab.py deleted file mode 100644 index 0099d67..0000000 --- a/maininterface/landsatTab.py +++ /dev/null @@ -1,976 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class LandsatTab: - - def __init__(self): - self.nodataCalc = cfg.NoDataValFloat32 - - # landsat input - def inputLandsat(self): - i = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - cfg.ui.label_26.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # MTL input - def inputMTL(self): - m = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a MTL file'), '', 'MTL file .txt (*.txt);;MTL file .met (*.met)') - cfg.ui.label_27.setText(str(m)) - if len(cfg.ui.label_26.text()) > 0: - self.populateTable(cfg.ui.label_26.text()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(m)) - - # landsat conversion to reflectance and temperature - def landsat(self, inputDirectory, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - self.sA = '' - self.eSD = '' - sat = cfg.ui.satellite_lineEdit.text() - if str(sat) == '': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No satellite error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - if len(cfg.ui.sun_elev_lineEdit.text()) > 0: - sE = float(cfg.ui.sun_elev_lineEdit.text()) - # sine sun elevation - self.sA = cfg.np.sin(sE * cfg.np.pi / 180) - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No sun elevation error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr37() - return 'No' - # earth sun distance - if len(cfg.ui.earth_sun_dist_lineEdit.text()) > 0: - try: - self.eSD = float(cfg.ui.earth_sun_dist_lineEdit.text()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No earth sun distance error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - dt = cfg.ui.date_lineEdit.text() - if len(str(self.eSD)) == 0: - dFmt = '%Y-%m-%d' - try: - self.eSD = cfg.utls.calculateEarthSunDistance(dt, dFmt) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - cfg.uiUtls.updateBar(5) - l = cfg.ui.landsat_tableWidget - inp = inputDirectory - out = outputDirectory - cfg.utls.makeDirectory(out) - # name prefix - pre = 'RT_' - prePAN = 'PAN_' - # input bands - c = l.rowCount() - # temp raster - tempRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - bandPansharpDict = {} - panRasterList = [] - # conversion list - convInputList = [] - # temperature list - temperatureList = [] - # pan band - panList = [] - for i in range(0, c): - if cfg.actionCheck == 'Yes': - inputRaster = inp + '/' + l.item(i,0).text() - oNme = pre + l.item(i,0).text() - oNm, ext = cfg.osSCP.path.splitext(oNme) - outputRaster = out + '/' + oNme - panRaster = out + '/' + prePAN + l.item(i,0).text() - tempRaster = cfg.utls.createTempRasterPath('tif') - tempRasterList.append(tempRaster) - bandName = l.item(i,0).text() - try: - REFLECTANCE_MULT = float(l.item(i,3).text()) - except: - REFLECTANCE_MULT = '' - try: - REFLECTANCE_ADD = float(l.item(i,4).text()) - except: - REFLECTANCE_ADD = '' - try: - RADIANCE_MAXIMUM = float(l.item(i,5).text()) - except: - RADIANCE_MAXIMUM = '' - try: - REFLECTANCE_MAXIMUM = float(l.item(i,6).text()) - except: - REFLECTANCE_MAXIMUM = '' - try: - K1_CONSTANT = float(l.item(i,7).text()) - except: - K1_CONSTANT = '' - try: - K2_CONSTANT = float(l.item(i,8).text()) - except: - K2_CONSTANT = '' - try: - LMAX = float(l.item(i,9).text()) - except: - LMAX = '' - try: - LMIN = float(l.item(i,10).text()) - except: - LMIN = '' - try: - QCALMAX = float(l.item(i,11).text()) - except: - QCALMAX = '' - try: - QCALMIN = float(l.item(i,12).text()) - except: - QCALMIN = '' - try: - RADIANCE_MULT = float(l.item(i,1).text()) - except: - try: - # for compatibility with glcf images - RADIANCE_MULT = (LMAX - LMIN) / (QCALMAX - QCALMIN) - except: - RADIANCE_MULT = '' - try: - RADIANCE_ADD = float(l.item(i,2).text()) - except: - try: - # for compatibility with glcf images - RADIANCE_ADD = LMIN - QCALMIN * (LMAX - LMIN) / (QCALMAX - QCALMIN) - except: - RADIANCE_ADD = '' - nm = cfg.osSCP.path.splitext(bandName)[0] - # conversion - if str(sat).lower() in ['landsat_1', 'landsat1','landsat_2', 'landsat2','landsat_3', 'landsat3']: - # landsat bands (e.g. b4, b4) - if nm[len(nm) - 1].isdigit(): - e = self.landsat1_7reflectance(sat, str(nm[len(nm) - 1]), RADIANCE_MULT, RADIANCE_ADD) - if e != 'No': - convInputList.append([inputRaster, e, outputRaster]) - # band list - if int(nm[len(nm) - 1]) in [4, 5, 6, 7]: - bandSetList.append(int(nm[len(nm) - 1])) - bandSetNameList.append(oNm) - elif str(sat).lower() in ['landsat_4', 'landsat4', 'landsat_5', 'landsat5', 'landsat_7', 'landsat7']: - # landsat bands (e.g. b10, b20, b61) - if nm[len(nm) - 2].isdigit() and nm[len(nm) - 1].isdigit(): - if str(nm[len(nm) - 1]) == '0': - if str(nm[len(nm) - 2]) == '6': - e = self.landsat457Temperature(sat, RADIANCE_MULT, RADIANCE_ADD) - temperatureList.append([inputRaster, e, outputRaster]) - else: - e = self.landsat1_7reflectance(sat, str(nm[len(nm) - 2]), RADIANCE_MULT, RADIANCE_ADD) - if e != 'No': - # band list - if int(nm[len(nm) - 2]) in [1, 2, 3, 4, 5]: - bandSetList.append(int(nm[len(nm) - 2])) - bandSetNameList.append(oNm) - if int(nm[len(nm) - 2]) < 5 and str(sat).lower() in ['landsat_7', 'landsat7']: - bandPansharpDict[int(nm[len(nm) - 2])] = outputRaster - panRasterList.append(panRaster) - convInputList.append([inputRaster, e, outputRaster]) - elif int(nm[len(nm) - 2]) == 8: - bandPansharpDict[0] = outputRaster - panList = [inputRaster, e, outputRaster] - elif int(nm[len(nm) - 2]) == 7: - bandSetList.append(6) - bandSetNameList.append(cfg.osSCP.path.splitext(oNm)[0]) - convInputList.append([inputRaster, e, outputRaster]) - # landsat thermal bands - elif str(nm[len(nm) - 2]) == '6': - e = self.landsat457Temperature(sat, RADIANCE_MULT, RADIANCE_ADD) - temperatureList.append([inputRaster, e, outputRaster]) - # landsat bands (e.g. b1, b2, b6_VCID_1) - elif str(nm[len(nm) - 8: len(nm) - 1]) != '6_VCID_' and nm[len(nm) - 1].isdigit(): - # landsat thermal bands - if str(nm[len(nm) -1]) == '6': - e = self.landsat457Temperature(sat, RADIANCE_MULT, RADIANCE_ADD) - temperatureList.append([inputRaster, e, outputRaster]) - else: - e = self.landsat1_7reflectance(sat, str(nm[len(nm) - 1]), RADIANCE_MULT, RADIANCE_ADD) - if e != 'No': - # band list - if int(nm[len(nm) - 1]) in [1, 2, 3, 4, 5]: - bandSetList.append(int(nm[len(nm) - 1])) - bandSetNameList.append(oNm) - if int(nm[len(nm) - 1]) < 5 and str(sat).lower() in ['landsat_7', 'landsat7']: - bandPansharpDict[int(nm[len(nm) - 1])] = outputRaster - panRasterList.append(panRaster) - convInputList.append([inputRaster, e, outputRaster]) - elif int(nm[len(nm) - 1]) == 8: - bandPansharpDict[0] = outputRaster - panList = [inputRaster, e, outputRaster] - elif int(nm[len(nm) - 1]) == 7: - bandSetList.append(6) - bandSetNameList.append(cfg.osSCP.path.splitext(oNm)[0]) - convInputList.append([inputRaster, e, outputRaster]) - # landsat thermal bands - elif str(nm[len(nm) - 8: len(nm) - 1]) == '6_VCID_' and nm[len(nm) - 1].isdigit(): - e = self.landsat457Temperature(sat, RADIANCE_MULT, RADIANCE_ADD) - temperatureList.append([inputRaster, e, outputRaster]) - elif str(sat).lower() in ['landsat8', 'landsat_8', 'landsat9', 'landsat_9']: - # landsat thermal bands - if nm[len(nm) - 2: len(nm) - 0] in ['10', '11']: - e = self.landsat8Temperature(RADIANCE_MULT, RADIANCE_ADD, K1_CONSTANT, K2_CONSTANT) - temperatureList.append([inputRaster, e, outputRaster]) - # for bands < 10 - elif str(nm[len(nm) - 8: len(nm) - 1]) != '6_VCID_' and nm[len(nm) - 1].isdigit(): - e = self.landsat8reflectance(sat, str(nm[len(nm) - 1]), REFLECTANCE_MULT, REFLECTANCE_ADD, RADIANCE_MULT, RADIANCE_ADD, RADIANCE_MAXIMUM, REFLECTANCE_MAXIMUM) - # band list - if int(nm[len(nm) - 1]) in [1, 2, 3, 4, 5, 6, 7]: - bandSetList.append(int(nm[len(nm) - 1])) - bandSetNameList.append(oNm) - if int(nm[len(nm) - 1]) < 5 and int(nm[len(nm) - 1]) > 1: - bandPansharpDict[int(nm[len(nm) - 1])] = outputRaster - panRasterList.append(panRaster) - convInputList.append([inputRaster, e, outputRaster]) - elif int(nm[len(nm) - 1]) == 8: - bandPansharpDict[0] = outputRaster - panList = [inputRaster, e, outputRaster] - elif str(sat).lower() in ['landsat_1_sr', 'landsat_2_sr', 'landsat_3_sr', 'landsat_4_sr', 'landsat_5_sr', 'landsat_7_sr', 'landsat_8_sr']: - e = self.landsatSurfaceReflectance(sat, str(nm[len(nm) - 1]), REFLECTANCE_MULT, REFLECTANCE_ADD, RADIANCE_MULT, RADIANCE_ADD, RADIANCE_MAXIMUM, REFLECTANCE_MAXIMUM) - convInputList.append([inputRaster, e, outputRaster]) - # band list - if len(bandSetList) > 0: - bandSetList.append(max(bandSetList) + 1) - else: - bandSetList.append(1) - bandSetNameList.append(oNm) - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - NoData = cfg.ui.nodata_spinBox_3.value() - else: - NoData = cfg.NoDataVal - if len(convInputList) > 0: - # conversion - inputList = [] - functionList = [] - variableList = [] - outputRasterList = [] - for inP in convInputList: - inputList.append(inP[0]) - functionList.append(inP[1]) - outputRasterList.append(inP[2]) - variableList.append(['"raster"']) - try: - tPMDN = cfg.utls.createTempVirtualRaster(inputList, 'No', 'Yes', 'Yes', 0, 'No', 'No') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - # DOS 1 - if cfg.ui.DOS1_checkBox.isChecked() is True: - LDNmList = cfg.utls.findDNmin(tPMDN, NoData) - argumentList = [] - for dnM in range(0, len(LDNmList)): - e = functionList[dnM].replace('LDNm', str(LDNmList[dnM])) - argumentList.append(e) - else: - argumentList = functionList - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataValFloat32, 'GTiff', 'Float32', 0, None, compress = cfg.rasterCompression, compressFormat = 'DEFLATE') - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(oM[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - # temperature - if len(temperatureList) > 0: - inputList = [] - argumentList = [] - variableList = [] - outputRasterList = [] - for inP in temperatureList: - inputList.append(inP[0]) - argumentList.append(inP[1]) - outputRasterList.append(inP[2]) - variableList.append(['"raster"']) - try: - tPMDT = cfg.utls.createTempVirtualRaster(inputList, 'No', 'Yes', 'Yes', 0, 'No', 'No') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDT, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = cfg.rasterCompression, compressFormat = 'LZW') - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDT, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(oM[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - if cfg.actionCheck == 'Yes' and cfg.ui.pansharpening_checkBox.isChecked() is True and len(panList) > 1: - # pan band conversion - if cfg.ui.DOS1_checkBox.isChecked() is True: - LDNmList = cfg.utls.findDNmin(panList[0], NoData) - argumentList = panList[1].replace('LDNm', str(LDNmList[0])) - else: - argumentList = panList[1] - # band conversion - o = cfg.utls.multiProcessRaster(rasterPath = panList[0], functionBand = 'No', functionRaster = cfg.utls.bandCalculation, outputRasterList = [panList[2]], nodataValue = NoData, functionBandArgument = argumentList, functionVariable = [['"raster"', '"raster"']], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), compress = cfg.rasterCompression, compressFormat = 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1') - if cfg.osSCP.path.isfile(panList[2]): - cfg.utls.addRasterLayer(panList[2]) - else: - cfg.mx.msgErr38(panList[2]) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(panList[2])) - # pansharpening type Brovey Transform - argumentList, functionVariableList = self.pansharpeningExpressions(str(sat).lower()) - panSharpList = [] - for bP in sorted(bandPansharpDict): - panSharpList.append(bandPansharpDict[bP]) - try: - tPMDP = cfg.utls.createTempVirtualRaster(panSharpList, 'No', 'Yes', 'Yes', 0, 'No', 'Yes') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - for iA in range(0, len(argumentList)): - o = cfg.utls.multiProcessRaster(rasterPath = tPMDP, functionBand = 'No', functionRaster = cfg.utls.bandCalculation, outputRasterList = [panRasterList[iA]], nodataValue = NoData, functionBandArgument = argumentList[iA], functionVariable = functionVariableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Pansharpening'), compress = cfg.rasterCompression, compressFormat = 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1') - bandSetNameList = [] - # load raster bands - for outR in panRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - bandSetNameList.append(cfg.utls.fileNameNoExt(outR)) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - # create band set - if cfg.ui.create_bandset_checkBox.isChecked() is True: - if str(sat).lower() in ['landsat8', 'landsat_8', 'landsat_8_sr', 'landsat9', 'landsat_9', 'landsat_9_sr']: - satName = cfg.satLandsat8 - elif str(sat).lower() in ['landsat_7','landsat_7_sr', 'landsat7']: - satName = cfg.satLandsat7 - elif str(sat).lower() in ['landsat_4', 'landsat_4_sr', 'landsat4', 'landsat_5', 'landsat_5_sr', 'landsat5']: - satName = cfg.satLandsat45 - elif str(sat).lower() in ['landsat_1', 'landsat_1_sr', 'landsat1','landsat_2','landsat_2_sr', 'landsat2','landsat_3','landsat_3_sr', 'landsat3']: - satName = cfg.satLandsat13 - else: - satName = 'No' - if satName != 'No': - if cfg.ui.add_new_bandset_checkBox_1.isChecked() is True: - if len(cfg.bndSetLst) > 0: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, dt) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - if str(sat).lower() in ['landsat_1', 'landsat1','landsat_2', 'landsat2','landsat_3', 'landsat3']: - cfg.bst.setSatelliteWavelength(satName, None, bandSetNumber) - else: - cfg.bst.setSatelliteWavelength(satName, bandSetList, bandSetNumber) - cfg.bst.bandSetTools(out) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # pansharpening expressions - def pansharpeningExpressions(self, satellite): - e = [] - if satellite in ['landsat8', 'landsat_8', 'landsat9', 'landsat_9']: - # Intensity (SCP weights) - for oR in ['"blue"', '"green"', '"red"']: - o = oR + '* "pan" / ((0.42* "blue" + 0.98 * "green" + 0.6 * "red") / 2)' - f = [['"pan"', '"pan"'], ['"blue"', '"blue"'], ['"green"', '"green"'], ['"red"', '"red"']] - e.append(o) - elif satellite in ['landsat7', 'landsat_7']: - # Intensity (SCP weights) - for oR in ['"blue"', '"green"', '"red"', '"nir"']: - o = oR + '* "pan" / ((0.42* "blue" + 0.98 * "green" + 0.6* "red" + 1* "nir" ) / 3)' - f = [['"pan"', '"pan"'], ['"blue"', '"blue"'], ['"green"', '"green"'], ['"red"', '"red"'], ['"nir"', '"nir"']] - e.append(o) - return e, f - - # landsat 8 conversion to Reflectance - def landsat8reflectance(self, satellite, bandNumber, REFLECTANCE_MULT_BAND, REFLECTANCE_ADD_BAND, RADIANCE_MULT_BAND, RADIANCE_ADD_BAND, RADIANCE_MAXIMUM_BAND, REFLECTANCE_MAXIMUM_BAND): - sat = satellite - x = bandNumber - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - else: - nD = cfg.NoDataVal - # TOA reflectance with correction for sun angle - if cfg.ui.DOS1_checkBox.isChecked() is False or str(sat).lower() in ['surface reflectance', 'surface_reflectance', 'surfacereflectance']: - try: - m = float(REFLECTANCE_MULT_BAND) - a = float(REFLECTANCE_ADD_BAND) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( ( "raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) / (' + str(self.sA) + ') , 0, 1) )' - # DOS atmospheric correction - else: - # Esun calculation (see http://grass.osgeo.org/grass65/manuals/i.landsat.toar.html) - radM = float(RADIANCE_MAXIMUM_BAND) - refM = float(REFLECTANCE_MAXIMUM_BAND) - eS = (cfg.np.pi * self.eSD * self.eSD) * radM / refM - # calculate DOS1 corrected reflectance - # radiance calculation - try: - m = float(RADIANCE_MULT_BAND) - a = float(RADIANCE_ADD_BAND) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # path radiance Lp = ML* DNm + AL – 0.01* ESUNλ * cosθs / (π * d^2) - Lp = str(m) + ' * LDNm + ' + str(a - 0.01 * eS * self.sA / (cfg.np.pi * self.eSD * self.eSD)) - # land surface reflectance ρ = [π * (Lλ - Lp) * d^2]/ (ESUNλ * cosθs) - e = ' cfg.np.where( "raster" == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( ( ("raster" *' + str('%.16f' % m) + ' + (' + str('%.16f' % a) + ') - (' + str(Lp) + ' ) ) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % self.eSD) + ' * ' + str('%.16f' % self.eSD) + ') / ( ' + str('%.16f' % eS)+ ' * ' + str(self.sA) + ' ), 0, 1) )' - return e - - # landsat conversion of surface reflectance products - def landsatSurfaceReflectance(self, satellite, bandNumber, REFLECTANCE_MULT_BAND, REFLECTANCE_ADD_BAND): - sat = satellite - x = bandNumber - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - else: - nD = cfg.NoDataVal - # reflectance - try: - m = float(REFLECTANCE_MULT_BAND) - a = float(REFLECTANCE_ADD_BAND) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( "raster" *' + str('%.16f' % m) + ' + (' + str('%.16f' % a) + '), 0, 1) )' - return e - - # landsat 1 to 7 conversion to Reflectance - def landsat1_7reflectance(self, satellite, bandNumber, RADIANCE_MULT_BAND, RADIANCE_ADD_BAND): - sat = satellite - x = bandNumber - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - else: - nD = cfg.NoDataVal - # Esun - dEsunB = {} - # Esun from Chander, G.; Markham, B. L. & Helder, D. L. Summary of current radiometric calibration coefficients for Landsat MSS, TM, ETM+, and EO-1 ALI sensors Remote Sensing of Environment, 2009, 113, 893 - 903 - # landsat 1 - if str(sat).lower() in ['landsat_1', 'landsat1']: - dEsunB = {'ESUN_BAND4': 1823, 'ESUN_BAND5': 1559, 'ESUN_BAND6': 1276, 'ESUN_BAND7': 880.1} - # landsat 2 - elif str(sat).lower() in ['landsat_2', 'landsat2']: - dEsunB = {'ESUN_BAND4': 1829, 'ESUN_BAND5': 1539, 'ESUN_BAND6': 1268, 'ESUN_BAND7': 886.6} - # landsat 3 - elif str(sat).lower() in ['landsat_3', 'landsat3']: - dEsunB = {'ESUN_BAND4': 1839, 'ESUN_BAND5': 1555, 'ESUN_BAND6': 1291, 'ESUN_BAND7': 887.9} - # landsat 4 - elif str(sat).lower() in ['landsat_4', 'landsat4']: - dEsunB = {'ESUN_BAND1': 1983, 'ESUN_BAND2': 1795, 'ESUN_BAND3': 1539, 'ESUN_BAND4': 1028, 'ESUN_BAND5': 219.8, 'ESUN_BAND7': 83.49} - # landsat 5 - elif str(sat).lower() in ['landsat_5', 'landsat5']: - dEsunB = {'ESUN_BAND1': 1983, 'ESUN_BAND2': 1796, 'ESUN_BAND3': 1536, 'ESUN_BAND4': 1031, 'ESUN_BAND5': 220, 'ESUN_BAND7': 83.44} - # landsat 7 Esun from http://landsathandbook.gsfc.nasa.gov/data_prod/prog_sect11_3.html - elif str(sat).lower() in ['landsat_7', 'landsat7']: - dEsunB = {'ESUN_BAND1': 1970, 'ESUN_BAND2': 1842, 'ESUN_BAND3': 1547, 'ESUN_BAND4': 1044, 'ESUN_BAND5': 225.7, 'ESUN_BAND7': 82.06, 'ESUN_BAND8': 1369} - eS = float(dEsunB['ESUN_BAND' + str(x)]) - multipFactor = 1 - if str(cfg.RADIANCE_UNITS) == '"mW/cm^2/srad"': - multipFactor = 10 - try: - m = float(RADIANCE_MULT_BAND) * multipFactor - a = float(RADIANCE_ADD_BAND) * multipFactor - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - # TOA reflectance - if cfg.ui.DOS1_checkBox.isChecked() is False: - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( (( "raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % self.eSD) + ' * ' + str('%.16f' % self.eSD) + ') / ( ' + str('%.16f' % eS)+ ' * (' + str(self.sA) + ') ) , 0, 1))' - # DOS atmospheric correction - elif cfg.ui.DOS1_checkBox.isChecked() is True: - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - e = '("raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + '))' - # path radiance Lp = ML* DNm + AL – 0.01* ESUNλ * cosθs / (π * d^2) - Lp = str(m) + ' * LDNm + ' + str(a - 0.01 * eS * self.sA / (cfg.np.pi * self.eSD * self.eSD)) - # land surface reflectance ρ = [π * (Lλ - Lp) * d^2]/ (ESUNλ * cosθs) - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( ( (' + e + ' - (' + str(Lp) + ') ) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % self.eSD) + ' * ' + str('%.16f' % self.eSD) + ' ) / ( ' + str('%.16f' % eS)+ ' * (' + str(self.sA) + ') ), 0, 1) )' - return e - - # landsat 4,5, or 7 temperature - def landsat457Temperature(self, satellite, RADIANCE_MULT_BAND, RADIANCE_ADD_BAND): - sat = satellite - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - else: - nD = cfg.NoDataVal - # landsat 4 - if str(sat).lower() in ['landsat_4', 'landsat4']: - # k1 and k2 from Chander, G. & Markham, B. Revised landsat-5 TM radiometric calibration procedures and postcalibration dynamic ranges Geoscience and Remote Sensing, IEEE Transactions on, 2003, 41, 2674 - 2677 - k1 = float(671.62) - k2 = float(1284.30) - # landsat 5 - elif str(sat).lower() in ['landsat_5', 'landsat5']: - # k1 and k2 from Chander, G. & Markham, B. Revised landsat-5 TM radiometric calibration procedures and postcalibration dynamic ranges Geoscience and Remote Sensing, IEEE Transactions on, 2003, 41, 2674 - 2677 - k1 = float(607.76) - k2 = float(1260.56) - # landsat 7 - elif str(sat).lower() in ['landsat_7', 'landsat7']: - # k1 and k2 from NASA (Ed.) landsat 7 Science Data Users Handbook landsat Project Science Office at NASA's Goddard Space Flight Center in Greenbelt, pp.186 - k1 = float(666.09) - k2 = float(1282.71) - # Kelvin or cs - cs = 0 - if cfg.ui.celsius_checkBox.isChecked() is True: - cs = 273.15 - # At-Satellite Brightness Temperature - try: - m = float(RADIANCE_MULT_BAND) - a = float(RADIANCE_ADD_BAND) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ((' + str('%.16f' % k2) + ') / ( ln( (' + str('%.16f' % k1) + ' / ( "raster" * ' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) ) + 1)) - ' + str(cs) + ') )' - return e - - # landsat 8 temperature - def landsat8Temperature(self, RADIANCE_MULT_BAND, RADIANCE_ADD_BAND, K1_CONSTANT_BAND, K2_CONSTANT_BAND): - # No data value - if cfg.ui.nodata_checkBox_2.isChecked() is True: - nD = cfg.ui.nodata_spinBox_3.value() - else: - nD = cfg.NoDataVal - # Kelvin or cs - cs = 0 - if cfg.ui.celsius_checkBox.isChecked() is True: - cs = 273.15 - try: - m = float(RADIANCE_MULT_BAND) - a = float(RADIANCE_ADD_BAND) - k1 = float(K1_CONSTANT_BAND) - k2 = float(K2_CONSTANT_BAND) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ((' + str('%.16f' % k2) + ') / ( ln( (' + str('%.16f' % k1) + ' / ( "raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) ) + 1)) - ' + str(cs) + ') )' - return e - - # landsat correction button - def performLandsatCorrection(self): - if len(cfg.ui.label_26.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.landsat(cfg.ui.label_26.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform landsat correction: ' + str(cfg.ui.label_26.text())) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - sat = '' - dt = '' - sE = '' - esd = '' - surface_reflectance = 'No' - cfg.ui.satellite_lineEdit.setText(sat) - cfg.ui.date_lineEdit.setText(dt) - cfg.ui.sun_elev_lineEdit.setText(sE) - cfg.ui.earth_sun_dist_lineEdit.setText(esd) - l = cfg.ui.landsat_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 250]]) - cfg.utls.clearTable(l) - inp = input - if len(inp) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - if len(cfg.ui.label_27.text()) == 0: - for f in cfg.osSCP.listdir(inp): - #check metadata of surface reflectance level 2 products - if f.lower().endswith('_t1.xml'): - doc = cfg.minidomSCP.parse(inp + '/' + str(f)) - satellite = doc.getElementsByTagName('satellite')[0] - sat = satellite.firstChild.data - acquisition_date = doc.getElementsByTagName('acquisition_date')[0] - dt = acquisition_date.firstChild.data - surface_reflectance = 'Yes' - sat = sat + '_sr' - cfg.ui.satellite_lineEdit.setText(sat) - cfg.ui.date_lineEdit.setText(dt) - cfg.ui.sun_elev_lineEdit.setText('1') - cfg.ui.earth_sun_dist_lineEdit.setText('1') - if f.lower().endswith('.txt') and 'mtl' in f.lower(): - MTLFile = inp + '/' + str(f) - # for compatibility with glcf images - if f.lower().endswith('.met'): - MTLFile = inp + '/' + str(f) - else: - MTLFile = cfg.ui.label_27.text() - #### open MTL file - if surface_reflectance == 'No': - try: - # get information from MTL - cfg.RADIANCE_UNITS = None - with open(MTLFile, 'r') as MTL: - for r in MTL: - # satellite - if 'SPACECRAFT_ID' in r.split(): - sat = str(r.split()[2]).replace("'", '').replace('"', '') - if 'SUN_ELEVATION' in r.split(): - sE = str(r.split()[2]) - if 'EARTH_SUN_DISTANCE' in r.split(): - esd = str(r.split()[2]) - if 'DATE_ACQUIRED' in r.split() or 'ACQUISITION_DATE' in r.split(): - dt = str(r.split()[2]) - if 'RADIANCE_UNITS' in r.split(): - cfg.RADIANCE_UNITS = str(r.split()[2]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr8() - check = 'No' - if esd == '': - # date format - dFmt = '%Y-%m-%d' - try: - esd = str(cfg.utls.calculateEarthSunDistance(dt, dFmt)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.ui.satellite_lineEdit.setText(sat) - cfg.ui.date_lineEdit.setText(dt) - cfg.ui.sun_elev_lineEdit.setText(sE) - cfg.ui.earth_sun_dist_lineEdit.setText(esd) - #### list bands - # bands - dBs = {} - bandNames = [] - # input dictionaries - for f in cfg.osSCP.listdir(inp): - if f.lower().endswith('.tif'): - # name - nm = cfg.osSCP.path.splitext(f)[0] - if str(sat).lower() in ['landsat_4', 'landsat4', 'landsat_5', 'landsat5', 'landsat_7', 'landsat7']: - # landsat bands - if nm[len(nm) - 2].isdigit() and nm[len(nm) - 1].isdigit(): - if str(nm[len(nm) - 1]) == '0': - dBs['BAND_{0}'.format(nm[len(nm) - 2])] = str(f) - bandNames.append(f) - # landsat 7 thermal bands - elif str(nm[len(nm) - 2]) == '6': - dBs['BAND_6_VCID_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - elif str(nm[len(nm) - 8: len(nm) - 1]) != '6_VCID_' and nm[len(nm) - 1].isdigit(): - dBs['BAND_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - # landsat 7 thermal bands - elif str(nm[len(nm) - 8: len(nm) - 1]) == '6_VCID_' and nm[len(nm) - 1].isdigit(): - dBs['BAND_6_VCID_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - elif str(sat).lower() in ['landsat_8', 'landsat8', 'landsat_9', 'landsat9']: - # for bands > 9 - if nm[len(nm) - 2: len(nm) - 0] in ['10', '11']: - dBs['BAND_' + nm[len(nm) - 2: len(nm) - 0]] = str(f) - bandNames.append(f) - # for bands < 10 - elif str(nm[len(nm) - 8: len(nm) - 1]) != '6_VCID_' and nm[len(nm) - 1].isdigit() : - dBs['BAND_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - elif str(sat).lower() in ['landsat_1', 'landsat1','landsat_2', 'landsat2','landsat_3', 'landsat3']: - # landsat bands - if nm[len(nm) - 1].isdigit() : - dBs['BAND_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - elif str(sat).lower() in ['landsat_1_sr', 'landsat_2_sr', 'landsat_3_sr', 'landsat_4_sr', 'landsat_5_sr', 'landsat_7_sr', 'landsat_8_sr']: - # landsat bands - if nm[len(nm) - 1].isdigit() : - dBs['BAND_{0}'.format(nm[len(nm) - 1])] = str(f) - bandNames.append(f) - else: - bandNames.append(f) - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0, 'No') - b = b + 1 - if check != 'No': - # radiance - dRadMB = {} - dRadAB = {} - # reflectance - dRefMB = {} - dRefAB = {} - # constants - dK1B = {} - dK2B = {} - # radiance and reflectance maximum band - dRadMxB = {} - dRefMxB = {} - dRad = {} - if surface_reflectance == 'No': - # get information from MTL - with open(MTLFile, 'r') as MTL: - for r in MTL: - for key, band in dBs.items(): - try: - # for conversion to TOA Radiance from https://landsat.usgs.gov/landsat8_Using_Product.php - if 'RADIANCE_MULT_' + str(key) in r.split(): - dRadMB['RADIANCE_MULT_' + str(key)] = str(r.split()[2]) - if 'RADIANCE_ADD_' + str(key) in r.split(): - dRadAB['RADIANCE_ADD_' + str(key)] = str(r.split()[2]) - # for conversion to TOA Reflectance - if 'REFLECTANCE_MULT_' + str(key) in r.split(): - dRefMB['REFLECTANCE_MULT_' + str(key)] = str(r.split()[2]) - if 'REFLECTANCE_ADD_' + str(key) in r.split(): - dRefAB['REFLECTANCE_ADD_' + str(key)] = str(r.split()[2]) - # for Esun calculation - if 'RADIANCE_MAXIMUM_' + str(key) in r.split(): - dRadMxB['RADIANCE_MAXIMUM_' + str(key)] = str(r.split()[2]) - if 'REFLECTANCE_MAXIMUM_' + str(key) in r.split(): - dRefMxB['REFLECTANCE_MAXIMUM_' + str(key)] = str(r.split()[2]) - # for At-Satellite Brightness Temperature - if 'K1_CONSTANT_' + str(key) in r.split(): - dK1B['K1_CONSTANT_' + str(key)] = str(r.split()[2]) - if 'K2_CONSTANT_' + str(key) in r.split(): - # rV = r.split()[2] - dK2B['K2_CONSTANT_' + str(key)] = str(r.split()[2]) - # for compatibility with glcf images - if 'LMAX_' + str(key.replace('_', '').replace('VCID', '')) in r.split(): - dRad['LMAX_' + str(key)] = str(r.split()[2]) - if 'LMIN_' + str(key.replace('_', '').replace('VCID', '')) in r.split(): - dRad['LMIN_' + str(key)] = str(r.split()[2]) - if 'QCALMAX_' + str(key.replace('_', '').replace('VCID', '')) in r.split(): - dRad['QCALMAX_' + str(key)] = str(r.split()[2]) - if 'QCALMIN_' + str(key.replace('_', '').replace('VCID', '')) in r.split(): - dRad['QCALMIN_' + str(key)] = str(r.split()[2]) - if 'GAIN_' + str(key) in r.split() or 'GAIN_' + str(key).replace('BAND_', 'BAND') in r.split(): - try: - dRadMB['RADIANCE_MULT_' + str(key)] = str(float(r.split()[2])) - except: - pass - if 'BIAS_' + str(key) in r.split() or ('BIAS_' + str(key)).replace('BAND_', 'BAND') in r.split(): - try: - dRadAB['RADIANCE_ADD_' + str(key)] = str(float(r.split()[2])) - except: - pass - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # add items to table - b = 0 - for bandName in sorted(bandNames): - for key, band in dBs.items(): - if bandName == band: - if surface_reflectance == 'Yes': - try: - cfg.utls.addTableItem(l, 0.0001, b, 3) - except: - pass - try: - cfg.utls.addTableItem(l, 0, b, 4) - except: - pass - if dRadMB: - try: - cfg.utls.addTableItem(l, dRadMB['RADIANCE_MULT_' + str(key)], b, 1) - except: - pass - if dRadAB: - try: - cfg.utls.addTableItem(l, dRadAB['RADIANCE_ADD_' + str(key)], b, 2) - except: - pass - if dRefMB: - try: - cfg.utls.addTableItem(l, dRefMB['REFLECTANCE_MULT_' + str(key)], b, 3) - except: - pass - if dRefAB: - try: - cfg.utls.addTableItem(l, dRefAB['REFLECTANCE_ADD_' + str(key)], b, 4) - except: - pass - if dRadMxB: - try: - cfg.utls.addTableItem(l, dRadMxB['RADIANCE_MAXIMUM_' + str(key)], b, 5) - except: - pass - if dRefMxB: - try: - cfg.utls.addTableItem(l, dRefMxB['REFLECTANCE_MAXIMUM_' + str(key)], b, 6) - except: - pass - if dK1B: - try: - cfg.utls.addTableItem(l, dK1B['K1_CONSTANT_' + str(key)], b, 7) - except: - pass - if dK2B: - try: - cfg.utls.addTableItem(l, dK2B['K2_CONSTANT_' + str(key)], b, 8) - except: - pass - if dRad: - try: - cfg.utls.addTableItem(l, dRad['LMAX_' + str(key)], b, 9) - cfg.utls.addTableItem(l, dRad['LMIN_' + str(key)], b, 10) - cfg.utls.addTableItem(l, dRad['QCALMAX_' + str(key)], b, 11) - cfg.utls.addTableItem(l, dRad['QCALMIN_' + str(key)], b, 12) - except: - pass - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.landsat_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText('') - - # earth sun distance - def editedEarthSunDist(self): - try: - float(cfg.ui.earth_sun_dist_lineEdit.text()) - except: - cfg.ui.earth_sun_dist_lineEdit.setText('') - - # sun elevation - def editedSunElevation(self): - try: - float(cfg.ui.sun_elev_lineEdit.text()) - except: - cfg.ui.sun_elev_lineEdit.setText('') - - def editedDate(self): - dFmt = '%Y-%m-%d' - dt = cfg.ui.date_lineEdit.text() - try: - cfg.utls.calculateEarthSunDistance(dt, dFmt) - cfg.ui.date_lineEdit.setStyleSheet('color : black') - except: - cfg.ui.date_lineEdit.setStyleSheet('color : red') - - def removeHighlightedBand(self): - l = cfg.ui.landsat_tableWidget - cfg.utls.removeRowsFromTable(l) - - def editedSatellite(self): - sat = cfg.ui.satellite_lineEdit.text() - if str(sat).lower() in ['landsat_1', 'landsat1','landsat_2', 'landsat2','landsat_3', 'landsat3','landsat_4', 'landsat4', 'landsat_5', 'landsat5', 'landsat_7', 'landsat7', 'landsat_8', 'landsat8', 'landsat_9', 'landsat9', 'landsat_1_sr', 'landsat_2_sr', 'landsat_3_sr', 'landsat_4_sr', 'landsat_5_sr', 'landsat_7_sr', 'landsat_8_sr']: - cfg.ui.satellite_lineEdit.setStyleSheet('color : black') - else: - cfg.ui.satellite_lineEdit.setStyleSheet('color : red') - \ No newline at end of file diff --git a/maininterface/modisTab.py b/maininterface/modisTab.py deleted file mode 100644 index a78e75a..0000000 --- a/maininterface/modisTab.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class MODISTab: - - def __init__(self): - pass - - # MODIS input - def inputMODIS(self): - i = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a HDF file'), '', 'file .hdf (*.hdf)') - cfg.ui.label_217.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # MODIS conversion - def MODIS(self, inputFile, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(5) - l = cfg.ui.MODIS_tableWidget - # input - if inputFile.lower().endswith('.hdf') and cfg.osSCP.path.isfile(inputFile): - fileNm = cfg.utls.fileNameNoExt(inputFile) - # open input with GDAL - rD = cfg.gdalSCP.Open(inputFile, cfg.gdalSCP.GA_ReadOnly) - rDSub = rD.GetSubDatasets() - out = outputDirectory - oDir = cfg.utls.makeDirectory(out) - date = cfg.ui.MODIS_date_lineEdit.text() - # name prefix - pre = 'RT_' - # input bands - c = l.rowCount() - # temp raster - tempRasterList = [] - convInputList = [] - # output raster list - outputRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - bandNumberList = [] - for i in range(0, c): - if cfg.actionCheck == 'Yes': - iBand = l.item(i,0).text() - iBandN = iBand[-2:] - # MODIS bands - for sb in rDSub: - inputRaster = None - nm = sb[0] - bandName = fileNm + '_' + iBandN - inputRaster = nm - try: - bnI = inputRaster.split('b')[1][0:2] - if inputRaster is not None and 'sur_refl' in str(inputRaster) and iBandN == bnI: - oNm = pre + iBand + '.tif' - outputRaster = out + '/' + oNm - outputRasterList.append(outputRaster) - try: - coeff = float(l.item(i,1).text()) - except: - coeff = '' - if cfg.ui.reproject_modis_checkBox.isChecked() is True: - # temp files - tPMD = cfg.utls.createTempRasterPath('tif') - cfg.utls.GDALReprojectRaster(inputRaster, tPMD, 'GTiff', None, 'EPSG:4326', '-ot Float32 -dstnodata -999') - inputRaster = tPMD - tempRasterList.append(tPMD) - # conversion - m = float(coeff) - e = '( "raster" *' + str('%.16f' % m) + ' )' - # band list - bandSetList.append(int(bandName[-2:])) - bandSetNameList.append(pre + bandName) - convInputList.append([inputRaster, e, outputRaster]) - except: - pass - # conversion - inputList = [] - argumentList = [] - variableList = [] - for inP in convInputList: - inputList.append(inP[0]) - argumentList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - tPMDN = cfg.utls.createTempVirtualRaster(inputList, 'No', 'Yes', 'Yes', 0, 'No', 'No') - # No data value - if cfg.ui.nodata_checkBox_7.isChecked() is True: - NoData = cfg.ui.nodata_spinBox_8.value() - else: - NoData = cfg.NoDataVal - oM = cfg.utls.createTempRasterList(len(inputList)) - # open input with GDAL - rD = cfg.gdalSCP.Open(tPMDN, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = cfg.rasterCompression, compressFormat = 'LZW') - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(oM[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - for tmpR in tempRasterList: - try: - cfg.osSCP.remove(tmpR) - except: - pass - # create band set - if cfg.ui.create_bandset_checkBox.isChecked() is True: - if cfg.ui.add_new_bandset_checkBox_5.isChecked() is True: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, date) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - if len(bandSetNameList) > 2: - cfg.bst.setSatelliteWavelength(cfg.satMODIS, None, bandSetNumber) - else: - cfg.bst.setSatelliteWavelength(cfg.satMODIS2, None, bandSetNumber) - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - tW.clearSelection() - tW.selectRow(0) - tW.selectRow(1) - cfg.bst.moveDownBand() - cfg.bst.moveDownBand() - tW.clearSelection() - cfg.bst.bandSetTools(out) - cfg.uiUtls.updateBar(100) - # close GDAL rasters - rDSub = None - rD = None - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # MODIS conversion button - def performMODISConversion(self): - if len(cfg.ui.label_217.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.MODIS(cfg.ui.label_217.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform MODIS conversion: ' + str(cfg.ui.label_217.text())) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - l = cfg.ui.MODIS_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 250]]) - cfg.utls.clearTable(l) - if len(input) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - # bands - bandNames = [] - # input - if input.lower().endswith('.hdf'): - fileNm = cfg.utls.fileNameNoExt(input) - # open input with GDAL - rD = cfg.gdalSCP.Open(input, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - pass - else: - # get metadata - rDMeta = rD.GetMetadata_List() - for metadata in rDMeta: - if 'LOCALGRANULEID' in metadata: - mod_ID = metadata.split('=')[1] - if 'RANGEBEGINNINGDATE' in metadata: - date = metadata.split('=')[1] - cfg.ui.MODIS_ID_lineEdit.setText(mod_ID) - cfg.ui.MODIS_date_lineEdit.setText(date) - rDSub = rD.GetSubDatasets() - # MODIS bands - for sb in rDSub: - nm = sb[0] - if 'sur_refl' in str(nm): - try: - bandNames.append(fileNm + '_' + nm.split('b')[1][0:2]) - except: - pass - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0, 'No') - cfg.utls.addTableItem(l, str(0.0001), b, 1) - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - # edited cell - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.MODIS_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText("") - - def removeHighlightedBand(self): - l = cfg.ui.MODIS_tableWidget - cfg.utls.removeRowsFromTable(l) - \ No newline at end of file diff --git a/maininterface/mosaicbandsets.py b/maininterface/mosaicbandsets.py deleted file mode 100644 index 2ef3ffd..0000000 --- a/maininterface/mosaicbandsets.py +++ /dev/null @@ -1,240 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class MosaicBandSets: - - def __init__(self): - pass - - # list band sets - def textChanged(self): - self.checkValueList() - - # check value list - def checkValueList(self): - try: - # class value list - text = cfg.ui.mosaic_band_sets_lineEdit.text() - if text == '*': - l = list(range(1, len(cfg.bandSetsList)+1)) - else: - l = text.split(',') - valueList = [] - for v in l: - valueList.append(int(v)) - cfg.ui.mosaic_band_sets_lineEdit.setStyleSheet('color : green') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - except Exception as err: - cfg.ui.mosaic_band_sets_lineEdit.setStyleSheet('color : red') - valueList = [] - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return valueList - - # mosaic band sets - def mosaicAction(self): - self.mosaicBandSets() - - # mosaic multiple band sets - def mosaicBandSets(self, batch = 'No', outputDirectory = None, bandSetList = None, virtual = None): - if bandSetList is None: - bandSetList = cfg.mosaicBS.checkValueList() - else: - if bandSetList == '*': - bandSetList = list(range(1, len(cfg.bandSetsList)+1)) - else: - try: - bandSetList = eval(bandSetList) - except: - cfg.mx.msgWar28() - return 'No' - if virtual is None: - if cfg.ui.mosaic_virtual_checkBox.isChecked() is True: - virtual = 'Yes' - if len(bandSetList) > 0: - bSL = [] - for v in bandSetList: - bSL.append(v-1) - if batch == 'No': - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - else: - o = outputDirectory - if len(o) > 0: - cfg.utls.makeDirectory(o) - outputName = cfg.ui.mosaic_output_name_lineEdit.text() - if len(outputName) > 0: - outputName = str(outputName.encode('ascii','replace'))[2:-1] + '_' - bndSetSources = [] - if batch == 'No': - cfg.uiUtls.addProgressBar() - # create list of rasters - for bandSetNumber in bSL: - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - if len(cfg.bndSetLst) > 0: - bndSetSources.append(cfg.bndSetLst) - else: - bi = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - try: - bPath = cfg.utls.layerSource(bi) - except Exception as err: - cfg.mx.msg4() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - rT = cfg.utls.rasterToBands(bPath, cfg.tmpDir, outputName = cfg.utls.fileName(cfg.bandSetsList[bandSetNumber][8]), virtual = 'No') - if len(rT) > 0: - bndSetSources.append(rT) - if len(cfg.bndSetLst) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - if len(bndSetSources) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(10) - rCrs = cfg.utls.getCrsGDAL(bndSetSources[0][0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - # No data value - if cfg.ui.nodata_checkBox_9.isChecked() is True: - NoDataVal = cfg.ui.nodata_spinBox_10.value() - else: - NoDataVal = 'Yes' - for bst in bndSetSources: - if len(bst) != len(bndSetSources[0]): - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - bstIndex = bndSetSources.index(bst) - for b in range(0, len(bst)): - eCrs = cfg.utls.getCrsGDAL(bst[b]) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - if cfg.bandSetsList[bstIndex][0] == 'Yes': - nD = cfg.utls.imageNoDataValue(bst[b]) - if nD is None: - nD = cfg.NoDataVal - if virtual == 'Yes': - tPMD = o + '/' + cfg.utls.fileNameNoExt(bndSetSources[bstIndex][b]) + 'p.vrt' - else: - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(bst[b], tPMD, str(rCrs)) - cfg.mx.msg9() - #tPMD = cfg.utls.createTempRasterPath('tif') - #cfg.utls.GDALReprojectRaster(bst[b], tPMD, 'GTiff', None, 'EPSG:' + str(rEPSG), '-ot Float32 -dstnodata ' + str(nD)) - if cfg.osSCP.path.isfile(tPMD): - bndSetSources[bstIndex][b] = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - else: - nD = cfg.utls.imageNoDataValue(bst[b]) - if nD is None: - nD = cfg.NoDataVal - if virtual == 'Yes': - tPMD = o + '/' + cfg.utls.fileNameNoExt(bndSetSources[bstIndex][b]) + 'p.tif' - else: - tPMD = cfg.utls.createTempRasterPath('tif') - cfg.utls.GDALReprojectRaster(bst[b], tPMD, 'GTiff', None, rCrs, '-ot Float32 -dstnodata ' + str(nD)) - if cfg.osSCP.path.isfile(tPMD): - for bb in range(0, len(bst)): - bndSetSources[bstIndex][bb] = tPMD - break - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(20) - for y in range(0, len(bndSetSources[0])): - bList = [] - for x in range(0, len(bndSetSources)): - bstIndex = bndSetSources.index(bndSetSources[x]) - bList.append(bndSetSources[x][y]) - dType = cfg.utls.getRasterDataTypeName(bndSetSources[0][y]) - if virtual == 'Yes': - tVRT = o + '/' + outputName + cfg.utls.fileNameNoExt(bndSetSources[0][y]) + '.vrt' - rstrOut = tVRT - else: - rstrOut = o + '/' + outputName + cfg.utls.fileNameNoExt(bndSetSources[0][y]) + '.tif' - tVRT = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createVirtualRaster2(inputRasterList = bList, output = tVRT, NoDataValue = NoDataVal, dataType = dType) - if virtual != 'Yes': - cfg.utls.GDALCopyRaster(tVRT, rstrOut, 'GTiff', cfg.rasterCompression) - if cfg.osSCP.path.isfile(rstrOut): - cfg.utls.addRasterLayer(rstrOut) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - \ No newline at end of file diff --git a/maininterface/multipleroiTab.py b/maininterface/multipleroiTab.py deleted file mode 100644 index 313f2d7..0000000 --- a/maininterface/multipleroiTab.py +++ /dev/null @@ -1,429 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class MultipleROITab: - - def __init__(self): - pass - - # add point - def addPointToTable(self): - tW = cfg.ui.point_tableWidget - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "added point " + str(c + 1)) - - # add random point - def addRandomPointToTable(self, point): - tW = cfg.ui.point_tableWidget - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - #tW.setRowCount(c + 1) - if cfg.uidc.rapid_ROI_checkBox.isChecked() is True: - RBand = str(cfg.ROIband) - else: - RBand = "" - cfg.utls.addTableItem(tW, str(point[0]), c, 0) - cfg.utls.addTableItem(tW, str(point[1]), c, 1) - cfg.utls.addTableItem(tW, str(cfg.ROIMacroID), c, 2) - cfg.utls.addTableItem(tW, str(cfg.ROIMacroClassInfo), c, 3) - cfg.utls.addTableItem(tW, str(cfg.ROIID), c, 4) - cfg.utls.addTableItem(tW, str(cfg.ROIInfo), c, 5) - cfg.utls.addTableItem(tW, str(cfg.minROISz), c, 6) - cfg.utls.addTableItem(tW, str(cfg.maxROIWdth), c, 7) - cfg.utls.addTableItem(tW, str(cfg.rngRad), c, 8) - cfg.utls.addTableItem(tW, RBand, c, 9) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "added point " + str(c + 1)) - - # text changed - def textChanged(self): - stratifiedExpression = cfg.ui.stratified_lineEdit.text() - tSplit = stratifiedExpression.split(";") - for b in tSplit: - try: - cfg.ui.stratified_lineEdit.setStyleSheet("color : green") - check = 'Yes' - eval(b.replace(cfg.variableName, "1")) - if b.strip() == cfg.variableName: - cfg.ui.stratified_lineEdit.setStyleSheet("color : red") - check = 'No' - except: - cfg.ui.stratified_lineEdit.setStyleSheet("color : red") - check = 'No' - return check - - # create random point - def createRandomPoint(self): - bandSet = cfg.ui.band_set_comb_spinBox_10.value() - bandSetNumber = bandSet - 1 - try: - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[bandSetNumber][3][0] - else: - imageName = cfg.bandSetsList[bandSetNumber][8] - except: - cfg.mx.msg4() - return 'No' - img = cfg.utls.selectLayerbyName(imageName, 'Yes') - crs = cfg.utls.getCrs(img) - self.pCoordinates = crs - geographicFlag = crs.isGeographic() - if geographicFlag is False: - minDistance = None - points = None - stratified = None - stratifiedExpression = None - if cfg.ui.stratified_point_checkBox.isChecked() is True: - check = cfg.multiROI.textChanged() - if check == 'Yes': - stratified = 'Yes' - stratifiedExpression = cfg.ui.stratified_lineEdit.text() - else: - cfg.mx.msgErr64() - return 'No' - cfg.uiUtls.addProgressBar() - tLX, tLY, lRX, lRY, pSX, pSY = cfg.utls.imageInformationSize(imageName) - Xmin = int(round(min(tLX, lRX))) - Xmax = int(round(max(tLX, lRX))) - Ymin = int(round(min(tLY, lRY))) - Ymax = int(round(max(tLY, lRY))) - pointNumber = int(cfg.ui.point_number_spinBox.value()) - cfg.uiUtls.updateBar(10) - if cfg.ui.point_distance_checkBox.isChecked() is True: - minDistance = int(cfg.ui.point_distance_spinBox.value()) - if cfg.ui.point_grid_checkBox.isChecked() is True: - gridSize = int(cfg.ui.point_grid_spinBox.value()) - XRange = list(range(Xmin, Xmax, gridSize)) - YRange = list(range(Ymin, Ymax, gridSize)) - if len(XRange) == 1: - XRange = [Xmin, Xmax] - if len(YRange) == 1: - YRange = [Ymin, Ymax] - for x in XRange: - if XRange.index(x) < (len(XRange) - 1): - for y in YRange: - if YRange.index(y) < (len(YRange) - 1): - newpoints = cfg.utls.randomPoints(1, x, XRange[XRange.index(x)+1], y, YRange[YRange.index(y)+1], minDistance, imageName, None, None, None, bandSetNumber) - if points is None: - points = newpoints - else: - points.append(newpoints[0]) - elif stratified is not None: - tSplit = stratifiedExpression.split(';') - for b in tSplit: - newpoints = cfg.utls.randomPoints(pointNumber, Xmin, Xmax, Ymin, Ymax, minDistance, imageName, None, stratified, b, bandSetNumber) - if points is None: - points = newpoints - else: - points = points + newpoints - else: - points = cfg.utls.randomPoints(pointNumber, Xmin, Xmax, Ymin, Ymax, minDistance, imageName, None, None, None, bandSetNumber) - cfg.uiUtls.updateBar(50) - # check distance - if minDistance is not None: - npPoints = cfg.np.array(points) - for i in range(0, len(points)): - distance = cfg.cdistSCP(npPoints, npPoints) - if i < distance.shape[0]: - index = cfg.np.where((distance[i,:] <= minDistance) & (distance[i,:] > 0)) - npPoints = cfg.np.delete(npPoints, index, 0) - points = npPoints.tolist() - for i in range(0, len(points)): - self.addRandomPointToTable(points[i]) - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - else: - cfg.mx.msgWar14() - - # create ROI - def createROIfromPoint(self): - bandSet = cfg.ui.band_set_comb_spinBox_10.value() - bandSetNumber = bandSet - 1 - tW = cfg.ui.point_tableWidget - c = tW.rowCount() - if c > 0: - # save previous point for single ROI - try: - pP = cfg.lstPnt - except: - pass - cfg.uiUtls.addProgressBar() - rpdROICheckOrig = cfg.rpdROICheck - for i in range(0, c): - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'No': - cfg.uiUtls.updateBar((i+1) * 100 / (c + 1)) - try: - X = tW.item(i,0).text() - Y = tW.item(i,1).text() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msg6() - try: - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[bandSetNumber][3][0] - else: - imageName = cfg.bandSetsList[bandSetNumber][8] - img = cfg.utls.selectLayerbyName(imageName, 'Yes') - crs = cfg.utls.getCrs(img) - self.pCoordinates = crs - except: - cfg.mx.msg4() - try: - p = cfg.qgisCoreSCP.QgsPointXY(float(X), float(Y)) - cfg.utls.checkPointImage(cfg.bandSetsList[bandSetNumber][8], p, bandSetNumber = bandSetNumber, pointCoordinates = self.pCoordinates) - if cfg.pntCheck == 'Yes': - cfg.pntROI = cfg.lstPnt - # create ROI - if len(tW.item(i,6).text()) > 0: - v = int(tW.item(i,6).text()) - cfg.minROISz = v - if len(tW.item(i,7).text()) > 0: - v = int(tW.item(i,7).text()) - cfg.maxROIWdth = v - if len(tW.item(i,8).text()) > 0: - v = float(tW.item(i,8).text()) - cfg.rngRad = v - if len(tW.item(i,9).text()) > 0: - v = int(tW.item(i,9).text()) - cfg.ROIband = v - cfg.rpdROICheck = '2' - cfg.origPoint = cfg.pntROI - cfg.SCPD.createROI(cfg.pntROI, 'No', bandSetNumber = bandSetNumber) - # save ROI - v = int(tW.item(i, 2).text()) - cfg.ROIMacroID = v - cfg.ROIMacroClassInfo = tW.item(i, 3).text() - v = int(tW.item(i, 4).text()) - cfg.ROIID = v - cfg.ROIInfo = tW.item(i, 5).text() - cfg.SCPD.saveROItoShapefile('No', bandSetNumber = bandSetNumber) - # disable undo save ROI - cfg.uidc.undo_save_Button.setEnabled(False) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msgErr20() - # restore settings for single ROI - cfg.SCPD.setROIMacroID() - cfg.SCPD.roiMacroclassInfo() - cfg.SCPD.setROIID() - cfg.SCPD.roiClassInfo() - cfg.SCPD.minROISize() - cfg.SCPD.maxROIWidth() - cfg.SCPD.rangeRadius() - cfg.SCPD.rapidROIband() - cfg.SCPD.rapidROICheckbox() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.rpdROICheck = rpdROICheckOrig - # restore previous point for single ROI - try: - cfg.lstPnt = pP - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ROI created') - - # export point list to file - def exportPointList(self): - pointListFile = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save the point list to file'), '', '*.csv', 'csv') - try: - if pointListFile.lower().endswith('.csv'): - pass - else: - pointListFile = pointListFile + '.csv' - f = open(pointListFile, 'w') - sep = '\t' - f.write('X\tY\tMC_ID\tMC_Info\tC_ID\tC_Info\tMin\tMax\tDist\tRapid_ROI_band\n') - f.close() - tW = cfg.ui.point_tableWidget - c = tW.rowCount() - for i in range(0, c): - f = open(pointListFile, 'a') - sep = '\t' - X = tW.item(i,0).text() - Y = tW.item(i,1).text() - MID = tW.item(i,2).text() - MInf = tW.item(i,3).text() - CID = tW.item(i,4).text() - CInf = tW.item(i,5).text() - MinSize = '' - MaxWidth = '' - RangRad = '' - RBand = '' - try: - MinSize = tW.item(i,6).text() - MaxWidth = tW.item(i,7).text() - RangRad = tW.item(i,8).text() - RBand = tW.item(i,9).text() - except: - pass - txt = X + sep + Y + sep + MID + sep + MInf + sep + CID + sep + CInf + sep + MinSize + sep + MaxWidth + sep + RangRad + sep + RBand+ '\n' - f.write(txt) - f.close() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' point list exported') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # import points from file - def importPoints(self): - bandSet = cfg.ui.band_set_comb_spinBox_10.value() - bandSetNumber = bandSet - 1 - pointFile = cfg.utls.getOpenFileName(None , 'Select a point list file', '', 'CSV (*.csv);; Point shapefile .shp (*.shp)') - if pointFile.lower().endswith('.csv'): - try: - f = open(pointFile) - if cfg.osSCP.path.isfile(pointFile): - file = f.readlines() - if '\t' in file[0]: - sep = '\t' - else: - sep = ';' - tW = cfg.ui.point_tableWidget - for b in range(1, len(file)): - # point list - p = file[b].strip().split(sep) - MinSize = cfg.minROISz - MaxWidth = cfg.maxROIWdth - RangRad = cfg.rngRad - RBand = '' - try: - MinSize = p[6] - MaxWidth = p[7] - RangRad = p[8] - RBand = p[9] - except: - pass - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, p[0], c, 0) - cfg.utls.addTableItem(tW, p[1], c, 1) - cfg.utls.addTableItem(tW, p[2], c, 2) - cfg.utls.addTableItem(tW, p[3], c, 3) - cfg.utls.addTableItem(tW, p[4], c, 4) - cfg.utls.addTableItem(tW, p[5], c, 5) - cfg.utls.addTableItem(tW, MinSize, c, 6) - cfg.utls.addTableItem(tW, MaxWidth, c, 7) - cfg.utls.addTableItem(tW, RangRad, c, 8) - cfg.utls.addTableItem(tW, RBand, c, 9) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' points imported') - except Exception as err: - cfg.mx.msgErr19() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - elif pointFile.lower().endswith('.shp'): - try: - vCrs = cfg.utls.getCrsGDAL(pointFile) - lPRS = cfg.osrSCP.SpatialReference() - lPRS.ImportFromWkt(vCrs) - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - imageName = cfg.bandSetsList[bandSetNumber][3][0] - except: - cfg.mx.msgWar25(str(bandSetNumber + 1)) - return 'No' - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - iCrs = cfg.utls.getCrs(bN0) - ql = cfg.utls.layerSource(bN0) - else: - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - iCrs = cfg.utls.getCrs(bN0) - ql = cfg.utls.layerSource(bN0) - self.pCoordinates = iCrs - #rPSys = cfg.osrSCP.SpatialReference(wkt=iCrs.toWkt()) - #rPSys.AutoIdentifyEPSG() - #rPRS = rPSys.GetAuthorityCode(None) - rCrs = cfg.utls.getCrsGDAL(ql) - rPRS = cfg.osrSCP.SpatialReference() - rPRS.ImportFromWkt(rCrs) - if lPRS.IsSame(rPRS) != 1: - # date time for temp name - dT = cfg.utls.getTime() - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileName(pointFile) - cfg.utls.repojectShapefile(pointFile, lPRS, reprjShapefile, rPRS, 'wkbPoint') - pointFile = reprjShapefile - d = cfg.ogrSCP.GetDriverByName('ESRI Shapefile') - dr = d.Open(pointFile, 0) - iL = dr.GetLayer() - iF = iL.GetNextFeature() - while iF: - g = iF.GetGeometryRef() - p = [g.GetX(), g.GetY()] - iF.Destroy() - iF = iL.GetNextFeature() - self.addRandomPointToTable(p) - iL = None - dr = None - except Exception as err: - cfg.mx.msgErr19() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - def removePointFromTable(self): - cfg.utls.removeRowsFromTable(cfg.ui.point_tableWidget) - - # Activate signature calculation checkbox2 - def signatureCheckbox2(self): - p = cfg.qgisCoreSCP.QgsProject.instance() - if cfg.ui.signature_checkBox2.isChecked() is True: - p.writeEntry('SemiAutomaticClassificationPlugin', 'calculateSignature', 'Yes') - cfg.sigClcCheck = '2' - cfg.uidc.signature_checkBox.setCheckState(2) - else: - p.writeEntry('SemiAutomaticClassificationPlugin', 'calculateSignature', 'No') - cfg.sigClcCheck = '0' - cfg.uidc.signature_checkBox.setCheckState(0) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.sigClcCheck)) - \ No newline at end of file diff --git a/maininterface/neighborpixelsTab.py b/maininterface/neighborpixelsTab.py deleted file mode 100644 index 6b1412b..0000000 --- a/maininterface/neighborpixelsTab.py +++ /dev/null @@ -1,221 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class NeighborPixels: - - def __init__(self): - pass - - # neighbor - def classNeighborAction(self): - self.classNeighbor() - - # matrix file - def inputMatrixFile(self): - m = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a XML file'), '', 'CSV file (*.csv);;Text file (*.txt)') - cfg.ui.label_287.setText(str(m)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(m)) - - # classification neighbor - def classNeighbor(self, batch = 'No', bandSetNumber = None, outputDirectory = None, size = None, structure = None, statName = None, statPerc = None, outputName = None, circularStructure = None, virtual = None): - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_15.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - else: - o = outputDirectory - if len(o) > 0: - cfg.utls.makeDirectory(o) - if virtual is None: - if cfg.ui.neighbor_virtual_checkBox.isChecked() is True: - virtual = 'Yes' - if outputName is None: - outputName = cfg.ui.neighbor_output_name_lineEdit.text() - if len(outputName) > 0: - outputName = str(outputName.encode('ascii','replace'))[2:-1] + '_' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # create list of rasters - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - bndSetSources = [] - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - bndSetSources = cfg.bndSetLst - else: - try: - r = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8], 'Yes') - iR = cfg.utls.layerSource(r) - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - iBC = cfg.utls.getNumberBandRaster(iR) - for i in range(1, iBC+1): - bndNumberList.append(i) - tVRT = cfg.utls.createTempRasterPath('vrt') - bndSetSources.append(tVRT) - cfg.utls.createVirtualRaster(inputRasterList = [iR], output = tVRT, bandNumberList = [i], quiet = 'Yes') - if len(bndSetSources) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error') - return 'No' - cfg.uiUtls.updateBar(10) - if size is None: - size = cfg.ui.class_neighbor_threshold_spinBox.value() - if statName is None: - statName = cfg.ui.statistic_name_combobox_2.currentText() - if circularStructure is None: - if cfg.ui.circular_structure_checkBox.isChecked(): - circularStructure = 'Yes' - else: - circularStructure = 'No' - for i in cfg.statisticList: - if i[0].lower() == statName.lower(): - statNp = i[1] - if i[0].lower() == 'percentile': - if statPerc is None: - statPerc = cfg.ui.statistic_lineEdit_2.text() - try: - statPerc = int(statPerc) - break - except: - cfg.mx.msgErr66() - return 'No' - else: - break - if cfg.statPerc in statNp: - ee = statNp.replace('array', 'A') - try: - statPerc = int(statPerc) - ee = ee.replace(cfg.statPerc, str(statPerc)) - except: - pass - else: - ee = statNp.replace('array', 'A, axis=2') - functionList = [ee.replace('np.', 'cfg.np.')] - if structure is None: - if len(cfg.ui.label_287.text()) > 0: - try: - structure = self.openStructure(cfg.ui.label_287.text()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - else: - if circularStructure == 'No': - structure = cfg.np.ones((size*2+1,size*2+1)) - else: - structure = cfg.utls.createCircularStructure(size) - else: - try: - structure = self.openStructure(structure) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'structure ' + str(structure)) - for y in range(0, len(bndSetSources)): - if cfg.actionCheck == 'Yes': - input = bndSetSources[y] - additionalLayer = 3 - if virtual == 'Yes': - outputRaster = o + '/' + outputName + cfg.utls.fileNameNoExt(bndSetSources[y]) + '.vrt' - else: - outputRaster = o + '/' + outputName + cfg.utls.fileNameNoExt(bndSetSources[y]) + '.tif' - # process calculation - u = cfg.utls.multiProcessRaster(rasterPath = input, functionBand = 'No', functionRaster = cfg.utls.rasterNeighbor, outputRasterList = [outputRaster], functionBandArgument = structure, functionVariable = functionList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Neighbor pixels'), virtualRaster = virtual, compress = cfg.rasterCompression, outputNoDataValue = cfg.NoDataValFloat32, boundarySize = structure.shape[0]+1, additionalLayer = additionalLayer) - if cfg.osSCP.path.isfile(outputRaster): - oR =cfg.utls.addRasterLayer(outputRaster) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error raster not found') - # logger - cfg.utls.logCondition(str(__name__) + "-" + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - - # open structure file - def openStructure(self, structure): - text = open(structure, 'r') - lines = text.readlines() - for b in lines: - b = b.replace('nan', 'cfg.np.nan').replace('\n', '') - a = eval(b) - i = cfg.np.array(a, dtype=cfg.np.float32) - try: - c = cfg.np.append(c, [i], axis=0) - except: - try: - c = cfg.np.append([c], [i], axis=0) - except: - c = i - return c - - # stat combo - def loadStatisticCombo(self): - cfg.ui.statistic_name_combobox_2.blockSignals(True) - cfg.ui.statistic_name_combobox_2.clear() - for i in cfg.statisticList: - cfg.dlg.statistic_name_combo2(i[0]) - cfg.ui.statistic_name_combobox_2.blockSignals(False) \ No newline at end of file diff --git a/maininterface/pcaTab.py b/maininterface/pcaTab.py deleted file mode 100644 index 4026456..0000000 --- a/maininterface/pcaTab.py +++ /dev/null @@ -1,340 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class PcaTab: - - def __init__(self): - pass - - # calculate PCA action - def calculatePCAAction(self): - self.calculatePCA() - - # calculate PCA - def calculatePCA(self, batch = 'No', outputDirectory = None, bandSetNumber = None): - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_4.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - outF = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Select a directory")) - else: - outF = outputDirectory - if len(outF) > 0: - oDir = cfg.utls.makeDirectory(outF) - imageName = cfg.bandSetsList[bandSetNumber][8] - # if band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - lenBL = len(cfg.bndSetLst) - iR = cfg.utls.createTempVirtualRaster(cfg.bndSetLst, 'No', 'Yes', 'Yes', 0, 'No', 'Yes') - else: - cfg.mx.msgErr6() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Error no band set") - return None - else: - r = cfg.utls.selectLayerbyName(imageName, 'Yes') - try: - iR = cfg.utls.layerSource(r) - # open input with GDAL - rD = cfg.gdalSCP.Open(iR, cfg.gdalSCP.GA_ReadOnly) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - # band list - bL = cfg.utls.readAllBandsFromRaster(rD) - lenBL = len(bL) - rD = None - if cfg.ui.num_comp_checkBox.isChecked() is True: - numbComp = cfg.ui.pca_components_spinBox.value() - if numbComp > lenBL: - numbComp = lenBL - else: - numbComp = lenBL - if cfg.osSCP.path.isfile(iR): - self.PCACalculation(iR, lenBL, outF, numbComp, None, batch) - - # PCA calculation - def PCACalculation(self, inputRaster, numberOfBands, outputDirectory, numberComponents = 1, NoDataValue = None, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - # No data value - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox_4.isChecked() is True: - nD = cfg.ui.nodata_spinBox_5.value() - else: - nD = None - cfg.rasterClassSignature = {} - varList = [] - argumentList = [] - for bN in range(0, numberOfBands): - argumentList.append(bN) - varList.append(bN) - cfg.parallelArrayDict = {} - # calculate pixel sum - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.rasterPixelCount, nodataValue = nD, functionBandArgument = argumentList, functionVariable = varList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Statistics'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW', parallel = cfg.parallelArray) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - for arX in ar[0]: - cfg.rasterClassSignature[arX] = ar[0][arX] - except: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - # calculate band mean - try: - for i in range(0, numberOfBands): - cfg.rasterClassSignature['MEAN_BAND_' + str(i)] = cfg.rasterClassSignature['SUM_BAND_' + str(i)] / cfg.rasterClassSignature['COUNT_BAND_' + str(i)] - except Exception as err: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - comb = cfg.itertoolsSCP.combinations(list(range(0, numberOfBands)), 2) - argumentList = [] - varList = [] - for i in comb: - argumentList.append([i[0], i[1]]) - varList.append(cfg.rasterClassSignature) - cfg.parallelArrayDict = {} - # process - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.rasterCovariance, nodataValue = nD, functionBandArgument = argumentList, functionVariable = cfg.rasterClassSignature, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Statistics'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW') - cfg.uiUtls.updateBar(40) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - for arX in ar[0]: - for i in argumentList: - if 'COV_BAND_' + str(i[0]) + '-' + str(i[1]) == arX: - try: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] + ar[0][arX] - except: - cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] = ar[0][arX] - for i in range(0, numberOfBands): - if 'COV_BAND_' + str(i) + '-' + str(i) == arX: - try: - cfg.rasterClassSignature['COV_BAND_' + str(i) + '-' + str(i)] = cfg.rasterClassSignature['COV_BAND_' + str(i) + '-' + str(i)] + ar[0][arX] - except: - cfg.rasterClassSignature['COV_BAND_' + str(i) + '-' + str(i)] = ar[0][arX] - except: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - return 'No' - covM = self.createCovarianceMatrix(numberOfBands) - corrM = self.createCorrelationMatrix(covM) - comp, totalVariance, totalVarianceCumulative, eigenValues = self.calculateEigenVectors(covM) - comp = comp[:numberComponents] - totalVariance = totalVariance[:numberComponents] - totalVarianceCumulative = totalVarianceCumulative[:numberComponents] - eigenValues =eigenValues[:numberComponents] - # output rasters - oM = cfg.utls.createTempRasterList(numberOfBands) - outputList = [] - for n in range(0, numberComponents): - out = outputDirectory + '/bandset' + str(bandSetNumber + 1) + '_pc' + str(n+1) + '.tif' - outputList.append(out) - # open input with GDAL - rD = cfg.gdalSCP.Open(inputRaster, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, outputList, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = 'Yes', compressFormat = 'LZW') - # temporary bands - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, compress = 'No') - rD = None - # normalize bands - functionList = [] - variableList = [] - for b in range(0, numberOfBands): - e = 'raster - ' + str(cfg.rasterClassSignature['MEAN_BAND_' + str(b)]) - functionList.append(e) - variableList.append(['raster']) - # process - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = nD, functionBandArgument = functionList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - cfg.uiUtls.updateBar(60) - # virtual raster - tPMD = cfg.utls.createTempVirtualRaster(oM, 'No', 'Yes', 'Yes', 0, 'No', 'No') - # calculate PCA bands - o = cfg.utls.multiProcessRaster(rasterPath = tPMD, functionBand = 'No', functionRaster = cfg.utls.calculatePCABands, outputRasterList = ['No'], nodataValue = nD, functionBandArgument = [comp], functionVariable = [outputList], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'PCA'), outputNoDataValue = nD, compress = cfg.rasterCompression, compressFormat = 'LZW', threadNumber = 1, parallel = cfg.parallelRaster, skipSingleBand = 'Yes') - # remove temporary raster - for tR in oM: - try: - cfg.osSCP.remove(tR) - except: - pass - # load raster - if o != 'No': - for r in outputList: - # add raster to layers - cfg.utls.addRasterLayer(r) - # display parameters - self.displayParameters(covM, corrM, comp, totalVariance, totalVarianceCumulative, eigenValues, outputDirectory, 'bandset' + str(bandSetNumber + 1) + '_') - cfg.ui.toolBox_PCA.setCurrentIndex(1) - cfg.uiUtls.updateBar(100) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' PCA calculated') - - # display PCA parameters - def displayParameters(self, covarianceMatrix, correlationMatrix, components, totalVariance, totalVarianceCumulative, eigenValues, outputDirectory, outputFileName = None): - tblOut = outputDirectory + '/' + str(outputFileName) + cfg.PCAReportNm - try: - l = open(tblOut, 'w') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - t = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Principal Components Analysis')) + ' ' + str('\n') + str('\n') - l.write(t) - t = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Covariance matrix')) + ' ' - l.write(str(t) + str('\n')) - tB = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Bands')) + ' ' - for y in range(0, covarianceMatrix.shape[0]): - tB = tB + str(y + 1) + ' ' - l.write(str(tB) + str('\n')) - for y in range(0, covarianceMatrix.shape[0]): - t = str(y + 1) + ' ' - for x in range(0, covarianceMatrix.shape[1]): - t = t + str(covarianceMatrix[y,x]) + ' ' - l.write(str(t) + str('\n')) - l.write(str('\n')) - t = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Correlation matrix')) + ' ' - l.write(str(t) + str('\n')) - l.write(str(tB) + str('\n')) - for y in range(0, correlationMatrix.shape[0]): - t = str(y + 1) + ' ' - for x in range(0, correlationMatrix.shape[1]): - t = t + str(correlationMatrix[y,x]) + ' ' - l.write(str(t) + str('\n')) - l.write(str('\n')) - t = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Eigen vectors')) + ' ' - l.write(str(t) + str('\n')) - tB = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Bands')) + ' ' - for y in range(0, len(components)): - tB = tB + str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Vector_')) + str(y + 1) + ' ' - l.write(str(tB) + str('\n')) - for i in range(0, len(components)): - t = str(i + 1) + ' ' - for v in components: - t = t + str(v[i]) + ' ' - l.write(str(t) + str('\n')) - l.write(str('\n')) - t = str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Eigen values')) + ' ' + str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Accounted variance')) + ' ' + str(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cumulative variance')) + ' ' - l.write(str(t) + str('\n')) - for i in range(0, len(eigenValues)): - t = str(eigenValues[i]) + ' ' + str(totalVariance[i]) + ' ' + str(totalVarianceCumulative[i]) - l.write(str(t) + str('\n')) - l.close() - try: - f = open(tblOut) - if cfg.osSCP.path.isfile(tblOut): - eM = f.read() - cfg.ui.report_textBrowser_2.setText(str(eM)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' PCA calculated') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # create covariance matrix - def createCovarianceMatrix(self, numberOfBands): - m = cfg.np.zeros((numberOfBands, numberOfBands)) - comb = cfg.itertoolsSCP.combinations(list(range(0, numberOfBands)), 2) - for i in comb: - v = cfg.rasterClassSignature['COV_BAND_' + str(i[0]) + '-' + str(i[1])] - m.itemset((int(i[0]), int(i[1])), v) - m.itemset((int(i[1]), int(i[0])), v) - for i in range(0, numberOfBands): - v = cfg.rasterClassSignature['COV_BAND_' + str(i) + '-' + str(i)] - m.itemset((int(i), int(i)), v) - return m - - # create correlation matrix - def createCorrelationMatrix(self, covarianceMatrix): - m = cfg.np.zeros(covarianceMatrix.shape) - for y in range(0, covarianceMatrix.shape[0]): - for x in range(0, covarianceMatrix.shape[1]): - v = covarianceMatrix[y, x] / cfg.np.sqrt(covarianceMatrix[y, y] * covarianceMatrix[x, x]) - m.itemset((y, x), v) - return m - - # calculate eigen vectors - def calculateEigenVectors(self, matrix): - val, vect = cfg.np.linalg.eigh(matrix) - sort = cfg.np.argsort(val) - comp = [] - totalVariance = [] - totalVarianceCumulative = [] - eVal = [] - for i in reversed(sort): - eVal.append(val[i]) - comp.append(vect[:, i]) - totalVariance.append(val[i]/val.sum() * 100) - totalVarianceCumulative.append(cfg.np.sum(totalVariance)) - return comp, totalVariance, totalVarianceCumulative, eVal - \ No newline at end of file diff --git a/maininterface/randomForestTab.py b/maininterface/randomForestTab.py deleted file mode 100644 index 2f5b2fc..0000000 --- a/maininterface/randomForestTab.py +++ /dev/null @@ -1,518 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ClassRandomForestTab: - - def __init__(self): - pass - - # Select classifier - def selectRFClassifier(self): - cfg.classRF = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a classifier'), '', 'class file (*.class);;xml file (*.xml)') - cfg.ui.classifier_lineEdit_.setText(cfg.classRF) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'classifier file: ' + str(cfg.classRF)) - - # Reset qml style path - def resetRFClassifier(self): - cfg.classRF = '' - cfg.ui.qml_lineEdit.setText(cfg.classRF) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reset classifier') - - # set variable for macroclass classification - def macroclassCheckbox(self): - if cfg.ui.macroclass_checkBox_rf.isChecked() is True: - cfg.ui.class_checkBox_rf.blockSignals(True) - cfg.ui.class_checkBox_rf.setCheckState(0) - cfg.ui.class_checkBox_rf.blockSignals(False) - cfg.macroclassCheckRF = 'Yes' - else: - cfg.ui.class_checkBox_rf.blockSignals(True) - cfg.ui.class_checkBox_rf.setCheckState(2) - cfg.ui.class_checkBox_rf.blockSignals(False) - cfg.macroclassCheckRF = 'No' - - # set variable for class classification - def classCheckbox(self): - if cfg.ui.class_checkBox_rf.isChecked() is True: - cfg.ui.macroclass_checkBox_rf.setCheckState(0) - cfg.macroclassCheckRF = 'No' - else: - cfg.ui.macroclass_checkBox_rf.setCheckState(2) - cfg.macroclassCheckRF = 'Yes' - - # create XML graph - def createXMLRandomForest(self, vectorList): - importVector = ''' - 1.0 - - Read - - - $input - GeoTIFF - - - ''' - refID = 'Read' - b = 0 - if len(vectorList) > 0: - for b in range(0, len(vectorList)): - nodeID = 'Import-Vector' + str(b) - xml = ''' - - Import-Vector - - - - - %s - false - - - ''' - importVector = importVector + xml % (nodeID, refID, vectorList[b]) - refID = 'Import-Vector' + str(b) - # add random forest - xml = ''' - - Random-Forest-Classifier - - - - - $treeCount - $numTrainSamples - $classifierName - $loadClassifier - false - 0.0 - 5.0 - 101 - false - - ${trainingVectors} - ${featureBands} - VectorNodeName - $evaluateClassifier - $evaluateFeaturePowerSet - $minPowerSetSize - $maxPowerSetSize - - - - Write - - - - - $output - GeoTIFF-BigTIFF - - - - - - - - - - - - - - - - ''' - importVector = importVector + xml % ('Import-Vector' + str(b)) - else: - xml = ''' - - Random-Forest-Classifier - - - - - $treeCount - $numTrainSamples - $classifierName - $loadClassifier - false - 0.0 - 5.0 - 101 - false - - false - ${featureBands} - VectorNodeName - $evaluateClassifier - $evaluateFeaturePowerSet - $minPowerSetSize - $maxPowerSetSize - - - - Write - - - - - $output - GeoTIFF-BigTIFF - - - - - - - - - - - - - - - - ''' - importVector = importVector + xml - tXml = cfg.utls.createTempRasterPath('xml') - with open(tXml, 'w') as f: - f.write(importVector) - return tXml - - # classification output - def performRandomForest(self): - bs = cfg.ui.band_set_comb_spinBox_13.value() - 1 - self.randomForestClassification(bandSetNumber = bs, classPath = cfg.classRF) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform random forest classification ') - - # create to shapefile from memory layer - def createShapefileFromTraining(self, mcID = 'Yes'): - if mcID == 'Yes': - outList = [] - reclassList = [] - nameSeq = '' - b = 0 - cfg.SCPD.createMCIDList() - for mc in cfg.MCID_List: - v = [] - for id, val in cfg.treeDockItm.items(): - if int(mc[0]) == int(cfg.ROI_MC_ID[id]): - v.append(id) - path = cfg.utls.featuresToShapefile(v) - if path is not None: - shpName = cfg.utls.fileNameNoExt(path) - nameSeq = nameSeq + shpName + ',' - outList.append(path) - reclassList.append([b, int(mc[0])]) - b = b + 1 - else: - outList = [] - reclassList = [] - nameSeq = '' - b = 0 - for id, val in cfg.treeDockItm.items(): - v = [id] - path = cfg.utls.featuresToShapefile(v) - if path is not None: - shpName = cfg.utls.fileNameNoExt(path) - outList.append(path) - reclassList.append([b, int(val.text(1))]) - nameSeq = nameSeq + shpName + ',' - b = b + 1 - return [outList, nameSeq.rstrip(','), reclassList] - - # random forest - def randomForestClassification(self, batch = 'No', outputFile = None, bandSetNumber = None, numberTrainingSamples = None, treeCount = None, evalClassifier = None, evalFeaturePowerSet = None, minPowerSize = None, maxPowerSize = None, macroclass = None, classPath = '', saveClassifier = None): - # gpt executable - if not cfg.osSCP.path.isfile(cfg.SNAPGPT): - gpt = cfg.snap.findSNAPGPT() - if gpt == 'No': - return 'No' - if saveClassifier is None: - if cfg.ui.save_classifier_checkBox.isChecked(): - saveClassifier = 'Yes' - else: - saveClassifier = 'No' - if len(classPath) == 0: - classPath = cfg.classRF - if len(classPath) == 0: - if cfg.shpLay is None: - cfg.mx.msgErr59() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Error training') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB != 'Yes': - return 'No' - if outputFile is None: - rstrOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save classification'), '', '*.tif', 'tif') - if rstrOut is False: - return 'No' - else: - rstrOut = outputFile - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(rstrOut)) - # disable map canvas render for speed - if batch == 'No': - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.addProgressBar() - # SNAP conversion - if cfg.actionCheck == 'Yes': - if macroclass is None: - macroclass = cfg.macroclassCheckRF - bandList = [] - featBandList = '' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - for b in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - referenceRasterName = cfg.bandSetsList[bandSetNumber][3][b] - r = cfg.utls.selectLayerbyName(referenceRasterName, 'Yes') - referenceRasterPath = cfg.utls.layerSource(r) - bandList.append(referenceRasterPath) - featBandList = featBandList + 'band_' + str(b+1) + ',' - tR = cfg.utls.createTempRasterPath('tif') - st = cfg.utls.mergeRasterBands(bandList, tR, compress = 'No') - else: - for b in range(0, len(cfg.bandSetsList[bandSetNumber][3])): - featBandList = featBandList + 'band_' + str(b+1) + ',' - imageName = cfg.bandSetsList[bandSetNumber][8] - img = cfg.utls.selectLayerbyName(imageName, 'Yes') - tR = cfg.utls.layerSource(img) - featBandList = featBandList.rstrip(',') - # export training to vector - vectorList, trainingVect, reclassList = self.createShapefileFromTraining(macroclass) - xmlFile = self.createXMLRandomForest(vectorList) - if numberTrainingSamples is None: - numberTrainingSamples = str(int(cfg.ui.number_training_samples_SpinBox.value())) - if treeCount is None: - treeCount = str(int(cfg.ui.number_trees_SpinBox.value())) - if evalClassifier is None: - if cfg.ui.evaluate_classifier_checkBox.isChecked(): - evalClassifier = 'true' - if evalFeaturePowerSet is None: - if cfg.ui.evaluate_feature_power_set_checkBox.isChecked(): - evalFeaturePowerSet = 'true' - else: - evalFeaturePowerSet = 'false' - else: - evalClassifier = 'false' - evalFeaturePowerSet = 'false' - if minPowerSize is None: - minPowerSize = str(int(cfg.ui.rf_power_min_SpinBox.value())) - if maxPowerSize is None: - maxPowerSize = str(int(cfg.ui.rf_power_max_SpinBox.value())) - # process raster - cfg.uiUtls.updateBar(0, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Random forest classification')) - tempOut = cfg.utls.createTempRasterPath('tif') - outTxt = self.processGPTRandomForest(xmlFile, tR, tempOut, treeCount, numberTrainingSamples, trainingVect, featBandList, evalClassifier, evalFeaturePowerSet, minPowerSize, maxPowerSize, classPath) - if outTxt == 'No': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR: cancel') - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - cfg.uiUtls.updateBar(90) - # split bands - if cfg.osSCP.path.isfile(tempOut): - try: - iL = cfg.utls.rasterToBands(tempOut, cfg.tmpDir) - except Exception as err: - cfg.mx.msgErr38(rstrOut) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - else: - cfg.mx.msgErr38(rstrOut) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error: unable to load raster' + str(rstrOut)) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - # reclassification - o = cfg.utls.multiProcessRaster(rasterPath = iL[0], functionBand = 'No', functionRaster = cfg.utls.reclassifyRaster, outputRasterList = [rstrOut], nodataValue = cfg.NoDataVal, functionBandArgument = reclassList, functionVariable = cfg.variableName, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reclassify'), compress = cfg.rasterCompression, dataType = 'UInt16') - # copy confidence raster - if cfg.rasterCompression != 'No': - try: - cfg.utls.GDALCopyRaster(iL[1], cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '_conf.tif', 'GTiff', cfg.rasterCompression, 'LZW') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - cfg.shutilSCP.copy(iL[1], cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '_conf.tif') - if evalClassifier == 'true': - try: - cfg.shutilSCP.copy(outTxt, cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '_val.txt') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - f = open(outTxt) - eM = f.read() - cfg.ui.report_textBrowser_5.setText(str(eM)) - cfg.ui.toolBox_random_forest.setCurrentIndex(1) - except: - pass - # remove temp - try: - int(0) - cfg.osSCP.remove(tRxs) - cfg.osSCP.remove(tR) - cfg.osSCP.remove(tempOut) - cfg.osSCP.remove(iL[0]) - cfg.osSCP.remove(iL[1]) - except: - pass - if cfg.actionCheck == 'Yes': - # load raster bands - v = cfg.utls.addRasterLayer(cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '_conf.tif') - r = cfg.utls.addRasterLayer(rstrOut) - # apply symbology - #cfg.utls.rasterSymbolSingleBandGray(v) - sL = cfg.classTab.getSignatureList(bandSetNumber) - cfg.classTab.applyClassSymbology(r, macroclass, cfg.qmlFl, sL) - # save qml file - cfg.utls.saveQmlStyle(r, cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '.qml') - if saveClassifier == 'Yes': - try: - cfg.shutilSCP.copy(cfg.reSCP.sub(r'\.txt$', '', str(outTxt)) + '.class', cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '.class') - cfg.shutilSCP.copy(cfg.reSCP.sub(r'\.txt$', '', str(outTxt)) + '.xml', cfg.reSCP.sub(r'\.tif$', '', str(rstrOut)) + '.xml') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # process GPT - def processGPTRandomForest(self, xmlFile, inputRaster, outputRaster, treeCount, numTrainSamples, trainingVectors, featureBands, evaluateClassifier, evaluateFeaturePowerSet, minPowerSetSize, maxPowerSetSize, classifierPath = ''): - dT = cfg.utls.getTime() - classifierName = 'scp' + dT - loadClassifier = 'false' - if len(classifierPath) > 0: - loadClassifier = 'true' - classifierName = cfg.utls.fileNameNoExt(classifierPath) - cfg.utls.makeDirectory(cfg.tmpDir + '/auxdata/classifiers/RandomForest/') - xml = cfg.tmpDir + '/auxdata/classifiers/RandomForest/' + classifierName + '.xml' - cl = cfg.tmpDir + '/auxdata/classifiers/RandomForest/' + classifierName + '.class' - # copy files - try: - cfg.shutilSCP.copy(cfg.osSCP.path.dirname(classifierPath) + '/' + classifierName + '.xml', xml) - cfg.shutilSCP.copy(cfg.osSCP.path.dirname(classifierPath) + '/' + classifierName + '.class', cl) - except: - return 'No' - d = '"' + cfg.SNAPGPT + '" -q ' + str(cfg.threads) + ' -c ' + str(cfg.RAMValue) + 'M ' + ' -Dsnap.userdir="' + cfg.tmpDir + '" "' + xmlFile + '" -Pinput="' + inputRaster + '" -PtreeCount=' + str(treeCount) + ' -PnumTrainSamples=' + str(numTrainSamples) + ' -PclassifierName="' + str(classifierName) + '" -PloadClassifier=' + str(loadClassifier) + ' -PtrainingVectors="' + str(trainingVectors) + '" -PfeatureBands=' + str(featureBands) + ' -PevaluateClassifier=' + str(evaluateClassifier) + ' -PevaluateFeaturePowerSet=' + str(evaluateFeaturePowerSet) + ' -PminPowerSetSize=' + str(minPowerSetSize) + ' -PmaxPowerSetSize=' + str(maxPowerSetSize) + ' -Poutput="' + outputRaster + '"' - outTxt = cfg.tmpDir + '/auxdata/classifiers/RandomForest/' + classifierName + '.txt' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' d: ' + str(d)) - if cfg.sysSCPNm != 'Windows': - d = cfg.shlexSCP.split(d) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' RF d: ' + str(d)) - tPMD = cfg.utls.createTempRasterPath('txt') - stF = open(tPMD, 'a') - sPL = len(cfg.subprocDictProc) - # issue on Windows - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, startupinfo = startupinfo, stdout=stF, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, stdout=stF) - progress = 0 - while True: - line = '' - with open(tPMD, 'r') as rStF: - for line in rStF: - pass - poll = cfg.subprocDictProc['proc_'+ str(sPL)].poll() - if poll != None: - break - else: - try: - progress = int(line.replace('.','').split('%')[-2]) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Random forest classification') + dots) - except: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Random forest classification') + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: cancel') - return 'No' - cfg.timeSCP.sleep(1) - stF.close() - # get error - out, err = cfg.subprocDictProc['proc_'+ str(sPL)].communicate() - if err is not None: - if len(err) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: ' + str(err)) - outTxt = 'No' - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' classification: ' + str(outputRaster)) - return outTxt - \ No newline at end of file diff --git a/maininterface/reclassificationTab.py b/maininterface/reclassificationTab.py deleted file mode 100644 index 479f10a..0000000 --- a/maininterface/reclassificationTab.py +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ReclassificationTab: - - def __init__(self): - pass - - # reclassify - def reclassifyAction(self): - self.reclassify() - - # reclassify - def reclassify(self, batch = 'No', rasterInput = None, rasterOutput = None, valueString = None): - if batch == 'No': - self.clssfctnNm = cfg.ui.reclassification_name_combo.currentText() - i = cfg.utls.selectLayerbyName(self.clssfctnNm, 'Yes') - try: - classificationPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - listC = self.getValuesTable() - tW = cfg.ui.reclass_values_tableWidget - c = tW.rowCount() - else: - if cfg.osSCP.path.isfile(rasterInput): - classificationPath = rasterInput - else: - return 'No' - listC = [] - values = valueString.split(',') - for v in values: - val = v.split('_') - listC.append([val[0], val[1]]) - c = 1 - if c > 0: - if batch == 'No': - out = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - out = rasterOutput - # virtual raster - vrtR = 'No' - if out is not False: - if out.lower().endswith('.vrt'): - vrtR = 'Yes' - elif out.lower().endswith('.tif'): - pass - else: - out = out + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(out)) - reclassList = self.createReclassificationStringFromList(listC) - o = cfg.utls.multiProcessRaster(rasterPath = classificationPath, functionBand = 'No', functionRaster = cfg.utls.reclassifyRaster, outputRasterList = [out], nodataValue = cfg.NoDataVal, functionBandArgument = reclassList, functionVariable = cfg.variableName, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reclassify'), virtualRaster = vrtR, compress = cfg.rasterCompression) - if cfg.osSCP.path.isfile(out): - r =cfg.utls.addRasterLayer(out) - else: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - return 'No' - # create symbol - if cfg.ui.apply_symbology_checkBox.isChecked() is True: - if str(cfg.ui.class_macroclass_comboBox_2.currentText()) == cfg.fldMacroID_class_def: - mc = 'Yes' - sL = cfg.SCPD.createMCIDList() - else: - mc = 'No' - sL = cfg.classTab.getSignatureList() - cfg.utls.rasterSymbol(r, sL, mc) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' reclassification ended') - - def calculateUniqueValues(self): - self.clssfctnNm = cfg.ui.reclassification_name_combo.currentText() - i = cfg.utls.selectLayerbyName(self.clssfctnNm, 'Yes') - try: - classificationPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - try: - clssRstrSrc = str(classificationPath) - ck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - ck = 'No' - if ck == 'No': - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - else: - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = clssRstrSrc, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = cfg.NoDataVal, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - pass - values = cfg.np.unique(values).tolist() - cfg.uiUtls.updateBar(80) - if cfg.ui.CID_MCID_code_checkBox.isChecked() is True: - uniq = cfg.utls.calculateUnique_CID_MCID() - if uniq == 'No': - uniq = self.createValueList(values) - else: - uniq = self.createValueList(values) - self.addValuesToTable(uniq) - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' values calculated') - - def incrementalNewValues(self): - self.clssfctnNm = cfg.ui.reclassification_name_combo.currentText() - i = cfg.utls.selectLayerbyName(self.clssfctnNm, 'Yes') - try: - classificationPath = cfg.utls.layerSource(i) - except Exception as err: - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - try: - clssRstrSrc = str(classificationPath) - ck = 'Yes' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - ck = 'No' - if ck == 'No': - cfg.mx.msg4() - cfg.utls.refreshClassificationLayer() - else: - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = clssRstrSrc, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = cfg.NoDataVal, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - pass - values = cfg.np.unique(values).tolist() - cfg.uiUtls.updateBar(80) - uniq = self.createValueList(values, 'Yes') - self.addValuesToTable(uniq) - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' values calculated') - - def createValueList(self, listC, incremental = 'No'): - unique = [] - if incremental == 'No': - for i in sorted(listC): - g = str(i).split('.0') - try: - t = g[1] - p = i - except: - p = g[0] - unique.append([p, p]) - else: - v = 1 - for i in sorted(listC): - g = str(i).split('.0') - try: - t = g[1] - if len(t) > 0: - p = i - else: - p = g[0] - except: - p = g[0] - unique.append([p,str(v)]) - v = v + 1 - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' unique' + str(unique)) - return unique - - def addValuesToTable(self, valuesList): - cfg.ReclassTabEdited = 'No' - tW = cfg.ui.reclass_values_tableWidget - cfg.utls.clearTable(tW) - c = tW.rowCount() - for i in valuesList: - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, str(i[0]), c, 0) - cfg.utls.addTableItem(tW, str(i[1]), c, 1) - c = c + 1 - cfg.ReclassTabEdited = 'Yes' - - def getValuesTable(self): - tW = cfg.ui.reclass_values_tableWidget - c = tW.rowCount() - listC = [] - for row in range(0, c): - old = tW.item(row, 0).text() - new = tW.item(row, 1).text() - listC.append([old, new]) - return listC - - def createReclassificationStringFromList(self, listC): - reclassList = [] - for i in listC: - try: - cond = float(i[0]) - except: - cond = str(i[0]) - reclassList.append([cond, float(i[1])]) - return reclassList - - def addRowToTable(self): - cfg.ReclassTabEdited = 'No' - tW = cfg.ui.reclass_values_tableWidget - # add item to table - c = tW.rowCount() - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, '0', c, 0) - cfg.utls.addTableItem(tW, '0', c, 1) - cfg.ReclassTabEdited = 'Yes' - - def removePointFromTable(self): - cfg.utls.removeRowsFromTable(cfg.ui.reclass_values_tableWidget) - - def editedCell(self, row, column): - if cfg.ReclassTabEdited == 'Yes': - tW = cfg.ui.reclass_values_tableWidget - val = tW.item(row, column).text() - if column == 1: - try: - val = float(val) - except: - cfg.ReclassTabEdited = 'No' - cfg.utls.setTableItem(tW, row, column, '0') - cfg.ReclassTabEdited = 'Yes' - elif column == 0: - c = val.replace(cfg.variableName, 'rasterSCPArrayfunctionBand') - rasterSCPArrayfunctionBand = cfg.np.arange(9).reshape(3, 3) - try: - eval('cfg.np.where(' + c + ', 1, rasterSCPArrayfunctionBand)') - except: - cfg.ReclassTabEdited = 'No' - cfg.utls.setTableItem(tW, row, column, '0') - cfg.ReclassTabEdited = 'Yes' - cfg.mx.msgWar16() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'edited cell' + str(row) + ';' + str(column)) - - # import reclass from file - def importReclass(self): - file = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a reclassification file'), '', 'CSV (*.csv)') - if len(file) > 0: - self.importReclassFile(file) - - # import reclass - def importReclassFile(self, file): - try: - f = open(file) - if cfg.osSCP.path.isfile(file): - file = f.readlines() - if '\t' in file[0]: - sep = '\t' - else: - sep = ',' - tW = cfg.ui.reclass_values_tableWidget - for b in range(0, len(file)): - # rule list - p = file[b].strip().split(sep) - oldV = 0 - newV = 0 - try: - oldV = p[0] - newV = p[1] - except: - pass - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, oldV, c, 0) - cfg.utls.addTableItem(tW, newV, c, 1) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rules imported') - except Exception as err: - cfg.mx.msgErr19() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # export reclass list to file - def exportReclass(self): - listFile = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save the reclassification list to file'), '', '*.csv', 'csv') - try: - if listFile.lower().endswith('.csv'): - pass - else: - listFile = listFile + '.csv' - tW = cfg.ui.reclass_values_tableWidget - c = tW.rowCount() - f = open(listFile, 'w') - txt = '' - for i in range(0, c): - sep = ',' - X = tW.item(i,0).text() - Y = tW.item(i,1).text() - try: - oldV = tW.item(i,0).text() - newV = tW.item(i,1).text() - except: - pass - txt = txt + oldV + sep + newV + '\n' - f.write(txt) - f.close() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' point list exported') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - \ No newline at end of file diff --git a/maininterface/reprojectrasterbands.py b/maininterface/reprojectrasterbands.py deleted file mode 100644 index 8d76cae..0000000 --- a/maininterface/reprojectrasterbands.py +++ /dev/null @@ -1,346 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ReprojectRasterBands: - - def __init__(self): - pass - - def reprojectRasterBands(self): - bandSet = cfg.ui.band_set_comb_spinBox_14.value() - 1 - sameExtent = 'No' - outName = cfg.ui.reproj_output_name_lineEdit.text() - if len(outName) > 0: - outName = str(outName.encode('ascii','replace'))[2:-1] - else: - outName = None - alignRaster = None - EPSG = None - if cfg.ui.use_align_raster_checkBox.isChecked() is True: - # use align - referenceRasterName = cfg.ui.raster_align_comboBox.currentText() - try: - sL = cfg.utls.selectLayerbyName(referenceRasterName) - alignRaster = cfg.utls.layerSource(sL) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if cfg.ui.same_extent_raster_checkBox.isChecked() is True: - sameExtent = 'Yes' - # use EPSG - elif cfg.ui.use_epsg_checkBox.isChecked() is True: - # spatial reference - referenceRasterName = None - try: - EPSG = int(cfg.ui.epsg_code_lineEdit.text()) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - if cfg.ui.change_nodata_checkBox.isChecked() is True: - noData = cfg.ui.nodata_spinBox_14.value() - else: - noData = None - if cfg.ui.resample_checkBox.isChecked() is True: - try: - resPixelSize = float(cfg.ui.resample_lineEdit.text()) - except: - resPixelSize = None - else: - resPixelSize = None - xResolution = cfg.ui.x_resolution_lineEdit.text() - yResolution = cfg.ui.y_resolution_lineEdit.text() - # resampling method - resampling = cfg.ui.resampling_method_comboBox.currentText() - if resampling == 'nearest_neighbour': - resample = 'near' - elif resampling == 'average': - resample = 'average' - elif resampling == 'sum': - resample = 'sum' - gdalV = cfg.utls.getGDALVersion() - if float(gdalV[0] + '.' + gdalV[1]) < 3.1: - cfg.mx.msgErr68() - return 'No' - elif resampling == 'maximum': - resample = 'max' - elif resampling == 'minimum': - resample = 'min' - elif resampling == 'mode': - resample = 'mode' - elif resampling == 'median': - resample = 'med' - elif resampling == 'first_quartile': - resample = 'q1' - elif resampling == 'third_quartile': - resample = 'q3' - # resampling type - type = cfg.ui.raster_type_combo_2.currentText() - if type.lower() == 'auto': - type = None - self.reprojectRasters('No', None, alignRaster, sameExtent, EPSG, xResolution, yResolution, resPixelSize, resample, type, noData, outName, bandSet) - - # reproject multiple rasters - def reprojectRasters(self, batch = 'No', outputDirectory = None, alignRasterPath = None, sameExtent = 'No', EPSGCode = None, xResolution = None, yResolution = None, resamplePixelFactor = None, resamplingMethod = None, outputType = None, noDataValue = None, outputName = None, bandSetNumber = None, outFormat = 'GTiff'): - EPSG = None - if bandSetNumber is None: - bandSet = cfg.ui.band_set_comb_spinBox_14.value() - bandSetNumber = bandSet - 1 - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - if resamplePixelFactor is None: - resamplePixelFactor = 1 - try: - resamplePixelFactor = float(resamplePixelFactor) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr67() - return 'No' - # list of images - rT = [] - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - rT = cfg.bandSetsList[bandSetNumber][3] - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters to be projected' + str(rT)) - if len(rT) == 0: - cfg.mx.msgWar15() - return 'No' - if batch == 'No': - oD = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory where to save projected rasters')) - else: - oD = outputDirectory - if len(oD) > 0: - if outputName is None: - outputName = cfg.reprojNm - else: - return 'No' - cfg.utls.makeDirectory(oD) - if alignRasterPath is not None: - # raster extent and pixel size - try: - left, right, top, bottom, pX, pY, rP, unit = cfg.utls.imageGeoTransform(alignRasterPath) - # check projections - rPSys =cfg.osrSCP.SpatialReference(wkt=rP) - rPSys.AutoIdentifyEPSG() - EPSG = 'No' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr67() - return 'No' - pX = pX * resamplePixelFactor - pY = pY * resamplePixelFactor - extra = '-tr ' + str(pX) + ' ' + str(pY) + ' -te ' + str(left) + ' ' + str(bottom) + ' ' + str(right) + ' ' + str(top) - else: - cfg.mx.msgWar15() - return 'No' - if batch == 'No': - cfg.uiUtls.addProgressBar() - outList = [] - n = 0 - for l in rT: - prog = int(n / len(rT)) - lC = cfg.utls.selectLayerbyName(l, 'Yes') - bLS = cfg.utls.layerSource(lC) - # calculate minimal extent - if alignRasterPath is not None: - # raster extent and pixel size - try: - leftS, rightS, topS, bottomS, pXS, pYS, rPS, unitS = cfg.utls.imageGeoTransform(bLS) - rPSC =cfg.osrSCP.SpatialReference(wkt=rPS) - leftSP, topSP = cfg.utls.projectPointCoordinatesOGR(leftS, topS, rPSC, rPSys) - rightSP, bottomSP = cfg.utls.projectPointCoordinatesOGR(rightS, bottomS, rPSC, rPSys) - # Error latitude or longitude exceeded limits - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr61(lC) - return 'No' - if sameExtent == 'No': - # minimum extent - if leftSP < left: - leftR = left - int(2 + (left - leftSP) / pX) * pX - else: - leftR = left + int((leftSP- left) / pX - 2) * pX - if rightSP > right: - rightR = right + int(2 + (rightSP - right) / pX) * pX - else: - rightR = right - int((right - rightSP) / pX - 2) * pX - if topSP > top: - topR = top + int(2 + (topSP - top) / pY) * pY - else: - topR = top - int((top - topSP) / pY - 2) * pY - if bottomSP > bottom: - bottomR = bottom + int((bottomSP - bottom) / pY - 2) * pY - else: - bottomR = bottom - int(2 + (bottom - bottomSP) / pY) * pY - else: - leftR, rightR, topR, bottomR, pXR, pYR, rPR, unitR = cfg.utls.imageGeoTransform(alignRasterPath) - extra = '-tr ' + str(pX) + ' ' + str(pY) + ' -te ' + str(leftR) + ' ' + str(bottomR) + ' ' + str(rightR) + ' ' + str(topR) - # use EPSG - elif EPSGCode is not None: - # spatial reference - extra = None - try: - EPSG = int(EPSGCode) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr67() - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - return 'No' - if sameExtent == 'No': - try: - extra = '-tr ' + str(float(xResolution)) + ' ' + str(float(yResolution)) - except: - pass - else: - leftR, rightR, topR, bottomR, pXR, pYR, rPR, unitR = cfg.utls.imageGeoTransform(alignRasterPath) - try: - extra = '-tr ' + str(float(xResolution)) + ' ' + str(float(yResolution)) + ' -te ' + str(leftR) + ' ' + str(bottomR) + ' ' + str(rightR) + ' ' + str(topR) - except: - pass - # resample - else: - if EPSG == 'No': - pass - else: - EPSG = None - # raster extent and pixel size - try: - leftS, rightS, topS, bottomS, pXS, pYS, rPS, unitS = cfg.utls.imageGeoTransform(bLS) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.mx.msgErr61(lC) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - return 'No' - pX = pXS * resamplePixelFactor - pY = pYS * resamplePixelFactor - if sameExtent == 'No': - try: - extra = '-tr ' + str(pX) + ' ' + str(pY) - except: - pass - else: - leftR, rightR, topR, bottomR, pXR, pYR, rPR, unitR = cfg.utls.imageGeoTransform(alignRasterPath) - try: - extra = '-tr ' + str(pX) + ' ' + str(pY) + ' -te ' + str(leftR) + ' ' + str(bottomR) + ' ' + str(rightR) + ' ' + str(topR) - except: - pass - if str(l).lower().endswith('.tif'): - pass - else: - l = l + '.tif' - f = oD + '/' + outputName + '_' + cfg.utls.fileName(l) - tRxs = cfg.utls.createTempRasterPath('tif') - if EPSG is not None: - if EPSG == 'No': - outEPSG = rP - else: - outEPSG = 'EPSG:' + str(EPSG) - else: - outEPSG = None - if resamplingMethod is None: - resamplingMethod = 'near' - cfg.utls.GDALReprojectRaster(input = bLS, output = tRxs, outFormat = outFormat, s_srs = None, t_srs = outEPSG, additionalParams = extra, resampleMethod = resamplingMethod, rasterDataType = outputType, noDataVal = noDataValue) - try: - cfg.shutilSCP.move(tRxs, f) - outList.append(f) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(prog) - n = n + 1 - try: - for oU in outList: - cfg.utls.addRasterLayer(oU) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' rasters reprojected' ) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - - # checkbox changed - def checkboxAlignChanged(self): - cfg.ui.use_align_raster_checkBox.blockSignals(True) - cfg.ui.use_epsg_checkBox.blockSignals(True) - if cfg.ui.use_align_raster_checkBox.isChecked(): - cfg.ui.use_epsg_checkBox.setCheckState(0) - cfg.ui.use_align_raster_checkBox.blockSignals(False) - cfg.ui.use_epsg_checkBox.blockSignals(False) - - # checkbox changed - def checkboxEPSGChanged(self): - cfg.ui.use_align_raster_checkBox.blockSignals(True) - cfg.ui.use_epsg_checkBox.blockSignals(True) - if cfg.ui.use_epsg_checkBox.isChecked(): - cfg.ui.use_align_raster_checkBox.setCheckState(0) - cfg.ui.use_align_raster_checkBox.blockSignals(False) - cfg.ui.use_epsg_checkBox.blockSignals(False) - - def refreshClassificationLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.raster_align_comboBox.clear() - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - cfg.dlg.project_raster_combo(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster layers refreshed') - \ No newline at end of file diff --git a/maininterface/rgblistTab.py b/maininterface/rgblistTab.py deleted file mode 100644 index a27e3d9..0000000 --- a/maininterface/rgblistTab.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class RGBListTab: - - def __init__(self): - self.tableEdited = 'Yes' - - # Create RGB list table - def RGBListTable(self, list): - l = cfg.ui.RGB_tableWidget - self.tableEdited = 'No' - l.blockSignals(True) - cfg.utls.clearTable(l) - x = 0 - for i in list: - if i != "-": - cfg.utls.insertTableRow(l, x) - cfg.utls.addTableItem(l, i, x, 0) - x = x + 1 - l.blockSignals(False) - self.tableEdited = 'Yes' - - # edited table - def editedTable(self, row, column): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - if self.tableEdited == 'Yes': - tW = cfg.ui.RGB_tableWidget - t = tW.item(row, column).text() - try: - check = cfg.utls.createRGBColorComposite(t) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - check = 'No' - if check == 'Yes': - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - id = cfg.rgb_combo.findText(t) - cfg.rgb_combo.setCurrentIndex(id) - else: - cfg.RGBLT.RGBListTable(cfg.RGBList) - - # read RGB List table - def readRGBListTable(self): - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - tW = cfg.ui.RGB_tableWidget - c = tW.rowCount() - list = [] - list.append("-") - for b in range(0, c): - t = tW.item(b, 0).text() - list.append(t) - return list - - # add RGB - def addRGBToTable(self): - tW = cfg.ui.RGB_tableWidget - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, "0-0-0", c, 0) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "added RGB " + str(c + 1)) - - # remove RGB - def removeRGBFromTable(self): - cfg.utls.removeRowsFromTable(cfg.ui.RGB_tableWidget) - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - - # sort RGB - def sortRGBName(self): - listA = cfg.RGBList - sortRGB = sorted(listA) - cfg.RGBList = sortRGB - cfg.RGBLT.RGBListTable(cfg.RGBList) - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - - # clear the band set - def clearTableAction(self): - self.clearTable() - - # clear Table - def clearTable(self, question = 'Yes'): - if question == 'Yes': - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Reset RGB list"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to clear the RGB list?")) - else: - a = 'Yes' - if a == 'Yes': - tW = cfg.ui.RGB_tableWidget - cfg.utls.clearTable(tW) - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - - # move up selected RGB - def moveUpRGB(self): - tW = cfg.ui.RGB_tableWidget - self.tableEdited = 'No' - tW.blockSignals(True) - c = tW.rowCount() - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() - 1) - try: - for b in range(0, c): - if tW.item(b, 0).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b - 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b - 1, 0).setText(str(bNU)) - tW.clearSelection() - v = list(set(ns)) - for i in range (0, len(v)): - tW.selectRow(v[i]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - self.tableEdited = 'Yes' - tW.blockSignals(False) - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " RGB moved") - - # move down selected RGB - def moveDownRGB(self): - tW = cfg.ui.RGB_tableWidget - self.tableEdited = 'No' - tW.blockSignals(True) - c = tW.rowCount() - s = tW.selectedItems() - # create list for new selection after move - ns = [] - for i in range (0, len(s)): - ns.append(s[i].row() + 1) - try: - for b in reversed(list(range(0, c))): - if tW.item(b, 0).isSelected(): - bNU = tW.item(b, 0).text() - bND = tW.item(b + 1, 0).text() - tW.item(b, 0).setText(str(bND)) - tW.item(b + 1, 0).setText(str(bNU)) - tW.clearSelection() - v = list(set(ns)) - for i in range (0, len(v)): - tW.selectRow(v[i]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - tW.clearSelection() - self.tableEdited = 'Yes' - tW.blockSignals(False) - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " RGB moved") - - # all RGB List - def allRGBListAction(self): - self.allRGBList() - - # all RGB List - def allRGBList(self, question = 'Yes', bandSetNumber = None): - if question == 'Yes': - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "RGB list"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Calculate all the RGB combinations?")) - else: - a = 'Yes' - if a == 'Yes': - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - perm = list(cfg.itertoolsSCP.permutations(list(range(1, len(cfg.bandSetsList[bandSetNumber][3])+1)), 3)) - tW = cfg.ui.RGB_tableWidget - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.clearTable(tW) - for x in perm: - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, str(x[0]) + "-" + str(x[1]) + "-" + str(x[2]), c, 0) - self.tableEdited = 'Yes' - tW.blockSignals(False) - listA = self.readRGBListTable() - cfg.RGBList = listA - cfg.utls.writeProjectVariable("SCP_RGBList", str(cfg.RGBList)) - cfg.utls.setComboboxItems(cfg.rgb_combo, cfg.RGBList) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - -# export RGB list to file - def exportRGBList(self): - file = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Save the RGB list to file"), "", "*.csv", "csv") - if file is not False: - if file.lower().endswith(".csv"): - pass - else: - file = file + ".csv" - try: - f = open(file, 'w') - f.write("") - f.close() - f = open(file, 'a') - for i in cfg.RGBList: - if i != "-": - txt = i + "\n" - f.write(txt) - f.close() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list exported") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - - # import RGB from file - def importRGB(self): - file = cfg.utls.getOpenFileName(None , "Select a RGB list file", "", "CSV (*.csv)") - try: - f = open(file) - if cfg.osSCP.path.isfile(file): - file = f.readlines() - tW = cfg.ui.RGB_tableWidget - # RGB list - for b in range(1, len(file)): - # add item to table - c = tW.rowCount() - # add list items to table - tW.setRowCount(c + 1) - cfg.utls.addTableItem(tW, file[b].strip(), c, 0) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list imported") - except Exception as err: - cfg.mx.msgErr19() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - \ No newline at end of file diff --git a/maininterface/sentinel1Tab.py b/maininterface/sentinel1Tab.py deleted file mode 100644 index 97e6fe1..0000000 --- a/maininterface/sentinel1Tab.py +++ /dev/null @@ -1,431 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Sentinel1Tab: - - def __init__(self): - pass - - # Sentinel-1 input - def inputSentinel(self): - i = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a Sentinel-1 file'), '', 'Sentinel-1 file .zip (*.zip)') - cfg.ui.S1_label_87.setText(str(i)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # XML input - def inputXML(self): - m = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a XML file'), '', 'XML file .xml (*.xml)') - cfg.ui.S1_label_96.setText(str(m)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(m)) - - # sentinel-1 output - def performSentinelConversion(self): - if len(cfg.ui.S1_label_87.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.sentinel1(cfg.ui.S1_label_87.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform sentinel-1 conversion: ' + str(cfg.ui.S1_label_87.text())) - - # sentinel-1 conversion - def sentinel1(self, inputFile, outputDirectory, batch = 'No', bandSetNumber = None, xmlGPT = None): - # gpt executable - if not cfg.osSCP.path.isfile(cfg.SNAPGPT): - gpt = cfg.snap.findSNAPGPT() - if gpt == 'No': - return 'No' - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - if batch == 'No': - cfg.cnvs.setRenderFlag(False) - if xmlGPT is None: - xml = cfg.ui.S1_label_96.text() - xmlVVVH = xml - if str(xml) == '': - xml = cfg.plgnDir + '/modules/snap/S1_process.xml' - xmlVVVH = cfg.plgnDir + '/modules/snap/S1_process_VVVH.xml' - else: - xml = xmlGPT - xmlVVVH = xmlGPT - cfg.uiUtls.updateBar(5) - inp = inputFile - out = outputDirectory - cfg.utls.makeDirectory(out) - # output raster list - outputRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - bandNumberList = [] - # SNAP conversion - if cfg.actionCheck == 'Yes': - if cfg.ui.VH_checkBox_S1.isChecked() is True and cfg.ui.VV_checkBox_S1.isChecked() is True: - cfg.uiUtls.updateBar(30, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + ' ' + inputFile) - tVH, tVV, date = self.processGPT(inp, out, xmlVVVH, 'VVVH') - outputRasterList.append(tVH) - bandSetList.append(1) - outputRasterList.append(tVV) - bandSetList.append(2) - bandSetNameList.append(cfg.utls.fileNameNoExt(tVH)) - bandSetNameList.append(cfg.utls.fileNameNoExt(tVV)) - elif cfg.ui.VH_checkBox_S1.isChecked() is True: - cfg.uiUtls.updateBar(0, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + ' ' + inputFile) - tVH, date = self.processGPT(inp, out, xml, 'VH') - outputRasterList.append(tVH) - bandSetList.append(1) - bandSetNameList.append(cfg.utls.fileNameNoExt(tVH)) - elif cfg.ui.VV_checkBox_S1.isChecked() is True: - cfg.uiUtls.updateBar(50, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + ' ' + inputFile) - tVV, date = self.processGPT(inp, out, xml, 'VV') - outputRasterList.append(tVV) - bandSetList.append(2) - bandSetNameList.append(cfg.utls.fileNameNoExt(tVV)) - cfg.uiUtls.updateBar(90) - if cfg.actionCheck == 'Yes': - # load raster bands - check = 'Yes' - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - check = 'No' - # create band set - if cfg.ui.S1_create_bandset_checkBox.isChecked() is True and check == 'Yes': - satName = cfg.satSentinel1 - if cfg.ui.add_new_bandset_checkBox_6.isChecked() is True: - if bandSetNumber is None: - bandSetNumber = cfg.bst.addBandSetTab() - elif bandSetNumber >= len(cfg.bandSetsList): - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - bandSetNameList = sorted(bandSetNameList) - bandSetNameList = [list for (number, list) in sorted(zip(bandSetList, bandSetNameList))] - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, date) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - bandSetList = sorted(bandSetList) - cfg.bst.setSatelliteWavelength(satName, bandSetList, bandSetNumber) - cfg.bst.bandSetTools(out) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # process GPT - def processGPT(self, inputRaster, outputDirectory, xmlFile, polarization): - # date time for temp name - dT = cfg.utls.getTime() - tVsnap = cfg.utls.createTempRasterPath('tif') - tVsnap2 = cfg.utls.createTempRasterPath('tif') - # get orbit - try: - with cfg.zipfileSCP.ZipFile(inputRaster) as zOpen: - for flName in zOpen.namelist(): - zipF = zOpen.open(flName) - fileName = cfg.utls.fileName(flName) - if fileName.lower() == 'manifest.safe': - zipO = open(cfg.tmpDir + '/' + dT + fileName, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - break - doc = cfg.minidomSCP.parse(cfg.tmpDir + '/' + dT + fileName) - entries = doc.getElementsByTagName('s1:pass') - for entry in entries: - orbit = entry.firstChild.data - entries2 = doc.getElementsByTagName('safe:relativeOrbitNumber') - for entry2 in entries2: - relativeOrbit = entry2.firstChild.data - try: - entries3 = doc.getElementsByTagName('s1sarl1:sliceNumber') - for entry3 in entries3: - sliceNumber = entry3.firstChild.data - except: - sliceNumber = '' - try: - entries4 = doc.getElementsByTagName('safe:number') - for entry4 in entries4: - satelliteN = str(entry4.firstChild.data) - except: - satelliteN = '' - try: - entries5 = doc.getElementsByTagName('safe:startTime') - for entry5 in entries5: - date = entry5.firstChild.data - except: - date = '' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No', '' - if polarization == 'VVVH': - outputRasterVV = outputDirectory + '/grd' + date.split('T')[0] + '_s' + orbit[0] + '_' + satelliteN + 'o' + relativeOrbit + '_' + satelliteN + 's' + sliceNumber + '_' + 'VV' + '.tif' - outputRasterVH = outputDirectory + '/grd' + date.split('T')[0] + '_s' + orbit[0] + '_' + satelliteN + 'o' + relativeOrbit + '_' + satelliteN + 's' + sliceNumber + '_' + 'VH' + '.tif' - d = '"' + cfg.SNAPGPT + '" -q ' + str(cfg.threads) + ' -c ' + str(cfg.RAMValue) + 'M "' + xmlFile + '" -Pinput="' + inputRaster + '" -PoutputVH="' + tVsnap + '" -PoutputVV="' + tVsnap2 + '"' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' S1 d: ' + d) - if cfg.sysSCPNm != 'Windows': - d = cfg.shlexSCP.split(d) - tPMD = cfg.utls.createTempRasterPath('txt') - stF = open(tPMD, 'a') - sPL = len(cfg.subprocDictProc) - # issue on Windows - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, startupinfo = startupinfo, stdout=stF, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, stdout=stF) - progress = 0 - while True: - line = '' - with open(tPMD, 'r') as rStF: - for line in rStF: - pass - poll = cfg.subprocDictProc['proc_'+ str(sPL)].poll() - if poll != None: - break - else: - try: - progress = int(line.replace('.','').split('%')[-2]) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + inputRaster + dots) - except: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: cancel') - return 'No', '', '' - cfg.timeSCP.sleep(1) - stF.close() - # get error - out, err = cfg.subprocDictProc['proc_'+ str(sPL)].communicate() - if err is not None: - if len(err) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image: ' + str(tVsnap)) - self.processS1toDB(tVsnap, outputRasterVH) - self.processS1toDB(tVsnap2, outputRasterVV) - # remove temp - try: - cfg.osSCP.remove(tVsnap) - except: - pass - try: - cfg.osSCP.remove(tVsnap2) - except: - pass - return outputRasterVH, outputRasterVV, date.split('T')[0] - else: - outputRaster = outputDirectory + '/grd' + date.split('T')[0] + '_s' + orbit[0] + '_' + satelliteN + 'o' + relativeOrbit + '_' + satelliteN + 's' + sliceNumber + '_' + polarization + '.tif' - d = '"' + cfg.SNAPGPT + '" -q ' + str(cfg.threads) + ' -c ' + str(cfg.RAMValue) + 'M "' + xmlFile + '" -Pinput="' + inputRaster + '" -Poutput="' + tVsnap + '" -Ppolarization=' + polarization - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' S1 d: ' + d) - if cfg.sysSCPNm != 'Windows': - d = cfg.shlexSCP.split(d) - tPMD = cfg.utls.createTempRasterPath('txt') - stF = open(tPMD, 'a') - sPL = len(cfg.subprocDictProc) - # issue on Windows - if cfg.sysSCPNm == 'Windows': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, startupinfo = startupinfo, stdout=stF, stdin = cfg.subprocessSCP.DEVNULL) - else: - cfg.subprocDictProc['proc_'+ str(sPL)] = cfg.subprocessSCP.Popen(d, shell=False, stdout=stF) - progress = 0 - while True: - line = '' - with open(tPMD, 'r') as rStF: - for line in rStF: - pass - poll = cfg.subprocDictProc['proc_'+ str(sPL)].poll() - if poll != None: - break - else: - try: - progress = int(line.replace('.','').split('%')[-2]) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + inputRaster + dots) - except: - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar(progress, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion') + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: cancel') - return 'No', '' - cfg.timeSCP.sleep(1) - stF.close() - # get error - out, err = cfg.subprocDictProc['proc_'+ str(sPL)].communicate() - if err is not None: - if len(err) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' error: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' image: ' + str(tVsnap)) - self.processS1toDB(tVsnap, outputRaster) - # remove temp - try: - cfg.osSCP.remove(tVsnap) - except: - pass - return outputRaster, date.split('T')[0] - - # process db - def processS1toDB(self, inputRaster, outputRaster): - bandSetNumber = cfg.ui.band_set_comb_spinBox_11.value() - 1 - # No data value - if cfg.ui.S1_nodata_checkBox.isChecked() is True: - nD = cfg.ui.S1_nodata_spinBox.value() - e = 'cfg.np.where("raster" == ' + str(nD) + ", " + str(cfg.NoDataVal) + ', ("raster") )' - else: - nD = None - e = '("raster")' - if cfg.ui.convert_to_db_checkBox.isChecked() is True: - e = e.replace('("raster")', '10 * cfg.np.log10("raster")' ) - # reproject - reproject = 'No' - if cfg.ui.projection_checkBox_S1.isChecked() is True: - rEPSG = None - # band set - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - try: - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][3][0], 'Yes') - rast = cfg.utls.layerSource(b) - # image EPSG - rCrs = cfg.utls.getCrsGDAL(rast) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - except: - cfg.mx.msgWar25(str(bandSetNumber + 1)) - else: - b = cfg.utls.selectLayerbyName(cfg.bandSetsList[bandSetNumber][8]) - rast = cfg.utls.layerSource(b) - rCrs = cfg.utls.getCrsGDAL(rast) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - eCrs = cfg.utls.getCrsGDAL(inputRaster) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - if nD is None: - nD = cfg.NoDataVal - reproject = 'Yes' - variableList = [] - # conversion - if e != '("raster")': - if cfg.outTempRastFormat == 'VRT' and reproject == 'Yes': - tPMD1 = cfg.utls.createTempRasterPath('vrt') - vrtR = 'Yes' - else: - tPMD1 = cfg.utls.createTempRasterPath('tif') - vrtR = 'No' - oM = tPMD1 - variableList.append(['"raster"', '"raster"']) - try: - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.bandCalculation, outputRasterList = [tPMD1], nodataValue = nD, functionBandArgument = e, functionVariable = variableList, progressMessage = 'Conversion ', virtualRaster = vrtR, compress = cfg.rasterCompression, compressFormat = 'LZW') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - else: - oM = inputRaster - # reprojection - if reproject == 'Yes': - tPMD2 = cfg.utls.createTempRasterPath('tif') - cfg.utls.GDALReprojectRaster(input = oM, output = tPMD2, outFormat = 'GTiff', s_srs = None, t_srs = str(rEPSG.ExportToWkt()), rasterDataType = 'Float32', noDataVal = nD) - # remove temp - try: - cfg.osSCP.remove(oM) - except: - pass - oM = tPMD2 - try: - cfg.shutilSCP.move(oM, outputRaster) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - # remove temp - try: - cfg.osSCP.remove(tPMD1) - except: - pass - for tRL in cfg.tmpList: - try: - cfg.osSCP.remove(tRL) - except: - pass - return outputRaster - \ No newline at end of file diff --git a/maininterface/sentinel2Tab.py b/maininterface/sentinel2Tab.py deleted file mode 100644 index 644a637..0000000 --- a/maininterface/sentinel2Tab.py +++ /dev/null @@ -1,348 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Sentinel2Tab: - - def __init__(self): - self.nodataCalc = cfg.NoDataValFloat32 - - # Sentinel-2 input - def inputSentinel(self): - i = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Select a directory")) - cfg.ui.S2_label_86.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # XML input MTD_SAFL1C - def inputXML2(self): - m = cfg.utls.getOpenFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Select a XML file"), "", "XML file .xml (*.xml)") - cfg.ui.S2_label_94.setText(str(m)) - if len(cfg.ui.S2_label_86.text()) > 0: - self.populateTable(cfg.ui.S2_label_86.text()) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(m)) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - sat = 'Sentinel-2A' - # dt = '' - # sE = '' - # esd = '' - dEsunB = {'ESUN_BAND01': 1913.57, 'ESUN_BAND02': 1941.63, 'ESUN_BAND03': 1822.61, 'ESUN_BAND04': 1512.79, 'ESUN_BAND05': 1425.56, 'ESUN_BAND06': 1288.32, 'ESUN_BAND07': 1163.19, 'ESUN_BAND08': 1036.39, 'ESUN_BAND8A': 955.19, 'ESUN_BAND09': 813.04, 'ESUN_BAND10': 367.15, 'ESUN_BAND11': 245.59, 'ESUN_BAND12': 85.25} - quantVal = 10000 - dU = 1 - cfg.ui.S2_satellite_lineEdit.setText(sat) - cfg.ui.S2_product_lineEdit.setText('') - cfg.ui.date_lineEdit_3.setText('') - l = cfg.ui.sentinel_2_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 450]]) - cfg.utls.clearTable(l) - inp = input - if len(inp) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - if len(cfg.ui.S2_label_94.text()) == 0: - MTD_SAFL1C = None - for f in cfg.osSCP.listdir(inp): - if f.lower().endswith('.xml') and 'mtd_msil1c' in f.lower() or 'mtd_safl1c' in f.lower() or 'mtd_msil2a' in f.lower(): - MTD_SAFL1C = inp + '/' + str(f) - else: - MTD_SAFL1C = cfg.ui.S2_label_94.text() - # open metadata file - try: - if MTD_SAFL1C is not None: - doc2 = cfg.minidomSCP.parse(MTD_SAFL1C) - SPACECRAFT_NAME = doc2.getElementsByTagName('SPACECRAFT_NAME')[0] - sat = SPACECRAFT_NAME.firstChild.data - cfg.ui.S2_satellite_lineEdit.setText(sat) - PRODUCT_START_TIME = doc2.getElementsByTagName('PRODUCT_START_TIME')[0] - date = PRODUCT_START_TIME.firstChild.data - cfg.ui.date_lineEdit_3.setText(date.split('T')[0]) - PRODUCT_TYPE = doc2.getElementsByTagName('PRODUCT_TYPE')[0] - productType = PRODUCT_TYPE.firstChild.data - cfg.ui.S2_product_lineEdit.setText(productType) - paramU = doc2.getElementsByTagName('U')[0] - dU = paramU.firstChild.data - QUANTIFICATION_VALUE = doc2.getElementsByTagName('QUANTIFICATION_VALUE')[0] - quantVal = QUANTIFICATION_VALUE.firstChild.data - SOLAR_IRRADIANCE = doc2.getElementsByTagName('SOLAR_IRRADIANCE') - dEsunB = {'ESUN_BAND01': SOLAR_IRRADIANCE[0].firstChild.data, 'ESUN_BAND02': SOLAR_IRRADIANCE[1].firstChild.data, 'ESUN_BAND03': SOLAR_IRRADIANCE[2].firstChild.data, 'ESUN_BAND04': SOLAR_IRRADIANCE[3].firstChild.data, 'ESUN_BAND05': SOLAR_IRRADIANCE[4].firstChild.data, 'ESUN_BAND06': SOLAR_IRRADIANCE[5].firstChild.data, 'ESUN_BAND07': SOLAR_IRRADIANCE[6].firstChild.data, 'ESUN_BAND08': SOLAR_IRRADIANCE[7].firstChild.data, 'ESUN_BAND8A': SOLAR_IRRADIANCE[8].firstChild.data, 'ESUN_BAND09': SOLAR_IRRADIANCE[9].firstChild.data, 'ESUN_BAND10': SOLAR_IRRADIANCE[10].firstChild.data, 'ESUN_BAND11': SOLAR_IRRADIANCE[11].firstChild.data, 'ESUN_BAND12': SOLAR_IRRADIANCE[12].firstChild.data} - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - #if '2A' in cfg.ui.S2_product_lineEdit.text(): - # pass - #else: - # cfg.mx.msgWar21() - # check = 'No' - # bands - dBs = {} - bandNames = [] - for f in cfg.osSCP.listdir(inp): - if f.lower().endswith('.jp2') or f.lower().endswith('.tif'): - # check band number - bNmb = str(f[-6:-4]) - if str(bNmb).lower() in ['01','02','03','04','05','06','07','08','8a','09','10','11','12']: - bandNames.append(f) - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0, 'No') - cfg.utls.addTableItem(l, quantVal, b, 1) - eS = str(dEsunB['ESUN_BAND' + str(band[-6:-4])]) - cfg.utls.addTableItem(l, eS, b, 2) - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - # edited satellite - def editedSatellite(self): - sat = cfg.ui.S2_satellite_lineEdit.text() - if str(sat).lower() in ['sentinel_2a', 'sentinel-2a', 'sentinel_2b', 'sentinel-2b']: - cfg.ui.S2_satellite_lineEdit.setStyleSheet('color : black') - else: - cfg.ui.S2_satellite_lineEdit.setStyleSheet('color : red') - - # remove band - def removeHighlightedBand(self): - l = cfg.ui.sentinel_2_tableWidget - cfg.utls.removeRowsFromTable(l) - - # edited cell - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.sentinel_2_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText('') - - # sentinel-2 output - def performSentinelConversion(self): - if len(cfg.ui.S2_label_86.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.sentinel2(cfg.ui.S2_label_86.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "Perform sentinel-2 conversion: " + str(cfg.ui.S2_label_86.text())) - - # sentinel-2 conversion - def sentinel2(self, inputDirectory, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - if batch == 'No': - cfg.cnvs.setRenderFlag(False) - self.sA = '' - self.eSD = '' - sat = cfg.ui.S2_satellite_lineEdit.text() - productType = cfg.ui.S2_product_lineEdit.text() - dt = cfg.ui.date_lineEdit_3.text() - if str(sat) == "": - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No satellite error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - cfg.uiUtls.updateBar(5) - l = cfg.ui.sentinel_2_tableWidget - inp = inputDirectory - out = outputDirectory - cfg.utls.makeDirectory(out) - # name prefix - pre = "RT_" - # input bands - c = l.rowCount() - # temp raster - tempRasterList = [] - # output raster list - outputRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - inputList = [] - resampleList = [] - functionList = [] - variableList = [] - # No data value - if cfg.ui.S2_nodata_checkBox.isChecked() is True: - nD = cfg.ui.S2_nodata_spinBox.value() - else: - nD = cfg.NoDataVal - for i in range(0, c): - if cfg.actionCheck == 'Yes': - bNmb = str(l.item(i,0).text()[-6:-4]) - processBand = 'Yes' - if bNmb in ['01', '09', '10']: - if cfg.ui.preprocess_b_1_9_10_checkBox.isChecked() is True: - processBand = 'Yes' - else: - processBand = 'No' - if processBand == 'Yes': - bNm = str(l.item(i,0).text()[0:-4]) - inputRaster = inp + '/' + l.item(i,0).text() - oNm = pre + bNm - outputRaster = out + '/' + oNm + '.tif' - quantificationValue = float(l.item(i,1).text()) - radC = 1 / float(quantificationValue) - ESUN = float(l.item(i,2).text()) - if cfg.ui.DOS1_checkBox_S2.isChecked() is False or (cfg.ui.DOS1_checkBox_S2.isChecked() is True and '2A' in productType): - # calculate reflectance = DN / quantVal - e = 'cfg.np.where(raster == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( ( raster /' + str(quantificationValue) + ') , 0, 1))' - functionList.append(e) - variableList.append(['raster']) - DOScheck = 'No' - else: - # calculate DOS1 corrected reflectance - # reflectance = DN / quantificationValue = DN * radC - # radiance = reflectance * ESUNλ * cosθs / (π * d^2) = DN * radC * ESUNλ * cosθs / (π * d^2) - # path radiance Lp = (LDNm * radC - 0.01) * ESUNλ * cosθs / (π * d^2) - # land surface reflectance ρ = [π * (Lλ - Lp) * d^2]/ (ESUNλ * cosθs) = DN * radC - (LDNm * radC - 0.01) - e = 'cfg.np.where(raster == ' + str(nD) + ', ' + str(self.nodataCalc) + ', cfg.np.clip( ( raster * ' + str("%.16f" % radC) + ' - (- 0.01 + ' + str('%.16f' % radC) + ' * LDNm) ), 0, 1) )' - functionList.append(e) - variableList.append(["raster"]) - DOScheck = 'Yes' - resample = '' - resampleList.append(resample) - bandNumberD = {'01': 1, '02': 2, '03': 3, '04': 4, '05': 5, '06': 6, '07': 7, '07': 7, '08': 8, '8a': 9, '09': 10, '10': 11, '11': 12, '12': 13} - bandSetList.append(str(bandNumberD[str(bNmb).lower()])) - bandSetNameList.append(oNm) - inputList.append(inputRaster) - outputRasterList.append(outputRaster) - try: - tPMD = cfg.utls.createTempVirtualRaster(inputList, 'No', 'Yes', 'Yes', 0, 'No', 'No') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - # conversion - ck = self.sentinelReflectance(tPMD, outputRasterList, functionList, variableList, resampleList, nD, DOScheck) - cfg.uiUtls.updateBar(90) - if cfg.actionCheck == 'Yes': - # load raster bands - check = 'Yes' - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + "-" + (cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "WARNING: unable to load raster" + str(outR)) - check = 'No' - # create band set - if cfg.ui.S2_create_bandset_checkBox.isChecked() is True and check == 'Yes': - if str(sat).lower() in ['sentinel_2a', 'sentinel-2a', 'sentinel_2b', 'sentinel-2b']: - satName = cfg.satSentinel2 - else: - satName = 'No' - if satName != 'No': - if cfg.ui.add_new_bandset_checkBox_2.isChecked() is True: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - bandSetNameList = sorted(bandSetNameList) - bandSetNameList = [list for (number, list) in sorted(zip(bandSetList, bandSetNameList))] - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, dt) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - bandSetList = sorted(bandSetList) - cfg.bst.setSatelliteWavelength(satName, bandSetList, bandSetNumber) - cfg.bst.bandSetTools(out) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # calculate DOS1 reflectance - def sentinelReflectance(self, inputRaster, outputRasterList, functionList, variableList, resampleList, NoData, DOS1Check = 'No'): - oM = cfg.utls.createTempRasterList(len(outputRasterList)) - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(inputRaster, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, oM, cfg.NoDataValFloat32, 'GTiff', 'Float32', 0, None, compress = cfg.rasterCompression, compressFormat = 'DEFLATE') - rD = None - if DOS1Check == 'No': - argumentList = functionList - else: - # find DNmin - LDNmList = cfg.utls.findDNmin(inputRaster, NoData) - argumentList = [] - for t in range(0, len(outputRasterList)): - e = functionList[t].replace('LDNm', str(LDNmList[t])) - argumentList.append(e) - o = cfg.utls.multiProcessRaster(rasterPath = inputRaster, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = oM, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.shutilSCP.move(oM[t], outputRasterList[t]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - # remove temporary files - try: - for t in oM: - cfg.osSCP.remove(t) - except: - pass - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(inputRaster)) - return 'Yes' - \ No newline at end of file diff --git a/maininterface/sentinel3Tab.py b/maininterface/sentinel3Tab.py deleted file mode 100644 index 3338808..0000000 --- a/maininterface/sentinel3Tab.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Sentinel3Tab: - - def __init__(self): - pass - - # Sentinel-3 input - def inputSentinel(self): - i = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - cfg.ui.S3_label_87.setText(str(i)) - self.populateTable(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), str(i)) - - # populate table - def populateTable(self, input, batch = 'No'): - check = 'Yes' - sat = 'Sentinel-3A' - prod = 'OLCI' - cfg.ui.S3_satellite_lineEdit.setText(sat) - cfg.ui.S3_product_lineEdit.setText(prod) - l = cfg.ui.sentinel_3_tableWidget - cfg.utls.setColumnWidthList(l, [[0, 450]]) - cfg.utls.clearTable(l) - inp = input - if len(inp) == 0: - cfg.mx.msg14() - else: - if batch == 'No': - cfg.uiUtls.addProgressBar() - cfg.ui.S3_satellite_lineEdit.setText(sat) - # bands - dBs = {} - bandNames = [] - for f in cfg.osSCP.listdir(inp): - if f.lower().endswith('.nc'): - f = f[0:-3] - # check band number - bNmb = str(f[2:4]) - try: - if int(bNmb) in range(0,22): - bandNames.append(f) - except: - bNmb = str(f[-2:]) - try: - if int(bNmb) in range(0,22): - bandNames.append(f) - except: - pass - cfg.uiUtls.updateBar(50) - # add band items to table - b = 0 - for band in sorted(bandNames): - l.insertRow(b) - l.setRowHeight(b, 20) - cfg.utls.addTableItem(l, band, b, 0) - b = b + 1 - if batch == 'No': - cfg.uiUtls.removeProgressBar() - - # edited satellite - def editedSatellite(self): - sat = cfg.ui.S3_satellite_lineEdit.text() - if str(sat).lower() in ['sentinel_3a', 'sentinel-3a', 'sentinel_3b', 'sentinel-3b']: - cfg.ui.S3_satellite_lineEdit.setStyleSheet('color : black') - else: - cfg.ui.S3_satellite_lineEdit.setStyleSheet('color : red') - - # remove band - def removeHighlightedBand(self): - l = cfg.ui.sentinel_3_tableWidget - cfg.utls.removeRowsFromTable(l) - - # edited cell - def editedCell(self, row, column): - if column != 0: - l = cfg.ui.sentinel_3_tableWidget - val = l.item(row, column).text() - try: - float(val) - except: - l.item(row, column).setText('') - - # sentinel-3 output - def performSentinelConversion(self): - if len(cfg.ui.S3_label_87.text()) == 0: - cfg.mx.msg14() - else: - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) == 0: - cfg.mx.msg14() - else: - self.sentinel3(cfg.ui.S3_label_87.text(), o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Perform sentinel-3 conversion: ' + str(cfg.ui.S3_label_87.text())) - - # sentinel-3 conversion - def sentinel3(self, inputDirectory, outputDirectory, batch = 'No', bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - if batch == 'No': - cfg.cnvs.setRenderFlag(False) - SZA = None - dEsunB = None - gcpList = None - # output raster list - outputRasterList = [] - # band list - bandSetList = [] - bandSetNameList = [] - bandNumberList = [] - sat = cfg.ui.S3_satellite_lineEdit.text() - productType = cfg.ui.S3_product_lineEdit.text() - if str(sat) == '': - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' No satellite error') - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.cnvs.setRenderFlag(True) - cfg.mx.msgErr37() - return 'No' - cfg.uiUtls.updateBar(5, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion')) - l = cfg.ui.sentinel_3_tableWidget - inp = inputDirectory - out = outputDirectory - # input - for f in cfg.osSCP.listdir(inp): - cfg.QtWidgetsSCP.qApp.processEvents() - if f.lower().endswith('.nc') and 'qualityflags' in f.lower(): - pass - elif f.lower().endswith('.nc') and 'geo_coordinates' in f.lower(): - # get pixel coordinates - geo_coordinates = inp + '/' + f - # open input with GDAL - rDGC = cfg.gdalSCP.Open(geo_coordinates, cfg.gdalSCP.GA_ReadOnly) - rDGCSub = rDGC.GetSubDatasets() - for sb in rDGCSub: - nm = sb[0] - if 'latitude' in str(nm): - # open input with GDAL - rDLat = cfg.gdalSCP.Open(nm) - rDLatB = rDLat.GetRasterBand(1) - elif 'longitude' in str(nm): - # open input with GDAL - rDLon = cfg.gdalSCP.Open(nm) - rDLonB = rDLon.GetRasterBand(1) - # set GCPs - gcpList = [] - z = 0 - x10 = int(rDLon.RasterXSize/10) - y10 = int(rDLon.RasterYSize/10) - rX = list(range(0, rDLon.RasterXSize, x10)) - rY = list(range(0, rDLon.RasterYSize, y10)) - rX.append(rDLon.RasterXSize-1) - rY.append(rDLon.RasterYSize-1) - # read points - for pX in rX: - for pY in rY: - x = cfg.utls.readArrayBlock(rDLonB, pX, pY, 1, 1) - y = cfg.utls.readArrayBlock(rDLatB, pX, pY, 1, 1) - try: - gcp = cfg.gdalSCP.GCP(float(x), float(y), z, pX, pY) - gcpList.append(gcp) - except: - pass - sr = cfg.osrSCP.SpatialReference() - sr.ImportFromEPSG(4326) - gcpProj = sr.ExportToWkt() - rDLatB = None - rDLat = None - bLLonB = None - rDLon = None - rDSub = None - rD = None - elif f.lower().endswith('.nc') and 'tie_geometries' in f.lower(): - tie_geometries = inp + '/' + f - # open input with GDAL - rDTG = cfg.gdalSCP.Open(tie_geometries, cfg.gdalSCP.GA_ReadOnly) - rDTGSub = rDTG.GetSubDatasets() - for sb in rDTGSub: - nm = sb[0] - if 'SZA' in str(nm): - # open input with GDAL - rDSZA = cfg.gdalSCP.Open(nm) - rDSZAB = rDSZA.GetRasterBand(1) - # get the mean value of sun zenith angle - bSt = rDSZAB.GetStatistics(True, True) - SZA = bSt[2] / 1000000 - rDTGSub = None - rDTG = None - elif f.lower().endswith('.nc') and 'instrument_data' in f.lower(): - instrument_data = inp + '/' + f - # open input with GDAL - rDID = cfg.gdalSCP.Open(instrument_data, cfg.gdalSCP.GA_ReadOnly) - rDIDSub = rDID.GetSubDatasets() - # Esun - dEsunB = {} - for sb in rDIDSub: - nm = sb[0] - if 'solar_flux' in str(nm): - # open input with GDAL - rDSolF = cfg.gdalSCP.Open(nm) - rDSolFB = rDSolF.GetRasterBand(1) - # get the mean value of solar flux for each band - for y in range(0, rDSolF.RasterYSize): - esun = cfg.utls.readArrayBlock(rDSolFB, int(rDSolF.RasterXSize / 2), y, 1, 1) - dEsunB['ESUN_BAND' + str(y + 1)] = float(esun) - rDIDSub = None - rDID = None - cfg.uiUtls.updateBar(20) - if SZA is None or bool(dEsunB) is False or gcpList is None: - if batch == 'No': - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr37() - else: - cfg.mx.msgErr37() - return - # name prefix - pre = 'RT_' - oDir = cfg.utls.makeDirectory(out) - l = cfg.ui.sentinel_3_tableWidget - # input bands - c = l.rowCount() - # output raster list - outputRasterList = [] - convInputList = [] - nodataValue = 0 - for i in range(0, c): - iBand = l.item(i,0).text() - iBandN = int(iBand[-2:]) - sBand = inp + '/' + iBand + '.nc' - # open input with GDAL - rDB = cfg.gdalSCP.Open(sBand, cfg.gdalSCP.GA_ReadOnly) - rDMeta = rDB.GetMetadata_List() - for metadata in rDMeta: - if 'scale_factor' in metadata: - scale_factor = metadata.split('=')[1] - elif 'add_offset' in metadata: - add_offset = metadata.split('=')[1] - elif '_FillValue' in metadata: - fillValue = metadata.split('=')[1] - elif 'start_time' in metadata: - date = metadata.split('=')[1].split('T')[0] - eSun = float(dEsunB['ESUN_BAND' + str(iBandN)]) - # temp files - tPMD = cfg.utls.createTempRasterPath('tif') - e = self.sentinel3reflectance(scale_factor, add_offset, fillValue, eSun, SZA, date, tPMD) - outputRaster = oDir + '/' + pre + iBand + '.tif' - convInputList.append([sBand, e, outputRaster]) - # band list - bandSetList.append(iBandN) - bandSetNameList.append(pre + iBand) - outputRasterList.append(outputRaster) - xSize = rDB.RasterXSize - ySize = rDB.RasterYSize - rDB = None - if len(convInputList) > 0: - # conversion - inputList = [] - functionList = [] - variableList = [] - bandList = [] - # reference system - rSrc = cfg.osrSCP.SpatialReference() - rSrc.SetProjCS('proj') - rSrc.SetWellKnownGeogCS('WGS84') - self.rSr = rSrc.ExportToWkt() - for inP in convInputList: - inputList.append(inP[0]) - functionList.append(inP[1]) - variableList.append(['"raster"', '"raster"']) - bandList.append(1) - tPMDN = cfg.utls.createTempVirtualRaster(inputList, bandList, 'Yes', 'Yes', 0, self.rSr, 'No') - # No data value - if cfg.ui.S3_nodata_checkBox.isChecked() is True: - NoData = cfg.ui.S2_nodata_spinBox_2.value() - else: - NoData = cfg.NoDataVal - # DOS 1 - if cfg.ui.DOS1_checkBox_S3.isChecked() is True: - LDNmList = cfg.utls.findDNmin(tPMDN, NoData) - argumentList = [] - for dnM in range(0, len(LDNmList)): - e = functionList[dnM].replace('LDNm', str(LDNmList[dnM])) - argumentList.append(e) - else: - argumentList = functionList - # create temporary rasters - tempRasterList = cfg.utls.createTempRasterList(len(inputList)) - self.createGeoreferencedRaster(tempRasterList, xSize, ySize, gcpList, gcpProj, 0) - o = cfg.utls.multiProcessRaster(rasterPath = tPMDN, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = tempRasterList, nodataValue = NoData, functionBandArgument = argumentList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Conversion'), parallel = cfg.parallelRaster) - if cfg.actionCheck == 'Yes': - for t in range(0, len(outputRasterList)): - cfg.utls.GDALReprojectRaster(tempRasterList[t], outputRasterList[t], 'GTiff', None, 'EPSG:4326', '-ot Float32 -dstnodata ' + str(NoData)) - #cfg.shutilSCP.move(tempRasterList[t], outputRasterList[t]) - # load raster bands - for outR in outputRasterList: - if cfg.osSCP.path.isfile(outR): - cfg.utls.addRasterLayer(outR) - else: - cfg.mx.msgErr38(outR) - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'WARNING: unable to load raster' + str(outR)) - # create band set - if cfg.ui.S3_create_bandset_checkBox.isChecked() is True: - if cfg.ui.add_new_bandset_checkBox_3.isChecked() is True: - bandSetNumber = cfg.bst.addBandSetTab() - cfg.bst.rasterBandName() - cfg.bst.setBandSet(bandSetNameList, bandSetNumber, date) - cfg.bandSetsList[bandSetNumber][0] = 'Yes' - cfg.bst.setSatelliteWavelength(cfg.satSentinel3, bandSetList, bandSetNumber) - if bandSetNumber is None: - bandSetNumber = cfg.ui.Band_set_tabWidget.currentIndex() - tW = eval('cfg.ui.tableWidget__' + cfg.bndSetTabList[bandSetNumber]) - tW.clearSelection() - cfg.bst.bandSetTools(oDir) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - - # conversion to Reflectance - def sentinel3reflectance(self, scale_factor, add_offset, fillValue, eSun, SZA, date, outputRaster): - eSD = None - # date format - dFmt = '%Y-%m-%d' - try: - eSD = float(cfg.utls.calculateEarthSunDistance(date, dFmt)) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # cosine solar zenith angle - sA = cfg.np.cos(SZA * cfg.np.pi / 180) - # No data value - if cfg.ui.S3_nodata_checkBox.isChecked() is True: - nD = cfg.ui.S2_nodata_spinBox_2.value() - else: - nD = cfg.NoDataVal - m = float(scale_factor) - a = float(add_offset) - # TOA reflectance with correction for sun angle - if cfg.ui.DOS1_checkBox_S3.isChecked() is False: - e = 'cfg.np.clip(cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ( "raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')) * ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % eSD) + ' * ' + str('%.16f' % eSD) + '/ (' + str('%.16f' % eSun)+ ' * ' + str(sA) + ' ) ), 0, 1)' - # DOS atmospheric correction - else: - # radiance calculation - e = 'cfg.np.where("raster" == ' + str(nD) + ', ' + str(cfg.NoDataVal) + ', ("raster" *' + str('%.16f' % m) + '+ (' + str('%.16f' % a) + ')))' - # path radiance Lp = ML* DNm + AL – 0.01* ESUNλ * cosθs / (π * d^2) - Lp = str(m) + ' * LDNm + ' + str(a - 0.01 * eSun * sA / (cfg.np.pi * eSD * eSD)) - # land surface reflectance ρ = [π * (Lλ - Lp) * d^2]/ (ESUNλ * cosθs) - e = 'cfg.np.clip((' + e + ' - (' + Lp + ' ) )* ' + str('%.16f' % cfg.np.pi) + ' * ' + str('%.16f' % eSD) + ' * ' + str('%.16f' % eSD) + ' / ( ' + str('%.16f' % eSun)+ ' * ' + str(sA) + ' ), 0, 1)' - return e - - # georeferenced raster - def createGeoreferencedRaster(self, outputList, RasterXSize, RasterYSize, gcpList, gcpProj, nodataValue): - for output in outputList: - tD = cfg.gdalSCP.GetDriverByName('GTiff') - oD = tD.Create(output, RasterXSize, RasterYSize, 1, cfg.gdalSCP.GDT_Float32, ['COMPRESS=LZW']) - oD.SetGCPs(gcpList, gcpProj) - oBnd = oD.GetRasterBand(1) - oBnd.SetNoDataValue(nodataValue) - oBnd.Fill(nodataValue) - oBnd = None - oD = None - \ No newline at end of file diff --git a/maininterface/settings.py b/maininterface/settings.py deleted file mode 100644 index a323249..0000000 --- a/maininterface/settings.py +++ /dev/null @@ -1,652 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Settings: - - def __init__(self): - self.getGDALDLLPath() - - # Get GDAL DLL Path - def getGDALDLLPath(self): - if cfg.gdalDLLPath is None: - cfg.gdalDLLPath = cfg.osSCP.environ['PATH'].replace('\\', '/') - - # Change ROI color - def changeROIColor(self): - c = cfg.QtWidgetsSCP.QColorDialog.getColor() - if c.isValid(): - cfg.utls.setQGISRegSetting(cfg.regROIClr, c.name()) - cfg.ROIClrVal = self.getQGISRegSetting(cfg.regROIClr, cfg.ROIClrValDefault) - cfg.ui.change_color_Button.setStyleSheet('background-color :' + cfg.ROIClrVal) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi colour changed to: ' + str(cfg.ROIClrVal)) - - # ROI transparency - def changeROITransparency(self): - cfg.ROITrnspVal = cfg.ui.transparency_Slider.value() - cfg.ui.transparency_Label.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Transparency ') + str(cfg.ROITrnspVal) + '%') - cfg.utls.setQGISRegSetting(cfg.regROITransp, cfg.ROITrnspVal) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi transparency changed to: ' + str(cfg.ROITrnspVal) + '%') - - # copy the Log file - def copyLogFile(self): - out = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save Log file'), '', '*.txt', 'txt') - if out is not False: - if out.lower().endswith('.txt'): - pass - else: - out = out + '.txt' - if cfg.osSCP.path.isfile(cfg.logFile): - try: - cfg.shutilSCP.copy(cfg.logFile, out) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr20() - - # get QGIS registry value - def getQGISRegSetting(self, key, defaultValue): - q = cfg.QSettingsSCP() - v = q.value(key, defaultValue) - return v - - # field ID name - def IDFieldNameChange(self): - cfg.fldID_class = cfg.ui.ID_field_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regIDFieldName, cfg.fldID_class) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'IDFieldName changed to: ' + str(cfg.fldID_class)) - - # field Macro ID name - def MacroIDFieldNameChange(self): - cfg.fldMacroID_class = cfg.ui.MID_field_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regMacroIDFieldName, cfg.fldMacroID_class) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'macroclassIDFieldName changed to: ' + str(cfg.fldMacroID_class)) - - # macroclass field Info name - def MacroInfoFieldNameChange(self): - cfg.fldROIMC_info = cfg.ui.MCInfo_field_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regMCInfoFieldName, cfg.fldROIMC_info) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Macroclass IDFieldName changed to: ' + str(cfg.fldROIMC_info)) - - # variable name - def VariableNameChange(self): - cfg.variableName = cfg.ui.variable_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regVariableName, cfg.variableName) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Variable name changed to: ' + str(cfg.variableName)) - - # group name - def GroupNameChange(self): - cfg.grpNm = cfg.ui.group_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regGroupName, cfg.grpNm) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'group name changed to: ' + str(cfg.grpNm)) - - # field class Info name - def InfoFieldNameChange(self): - cfg.fldROI_info = cfg.ui.Info_field_name_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regInfoFieldName, cfg.fldROI_info) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'IDFieldName changed to: ' + str(cfg.fldROI_info)) - - # raster data type change - def rasterDataTypeChange(self): - cfg.rasterDataType = cfg.ui.raster_precision_combo.currentText() - cfg.utls.setQGISRegSetting(cfg.regRasterDataType, cfg.rasterDataType) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster data type changed to: ' + str(cfg.rasterDataType)) - - # checkbox switch log - def logCheckbox(self): - # log setting - if cfg.ui.log_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.regLogKey, 'Yes') - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'LOG ACTIVE' + cfg.sysSCPInfo) - elif cfg.ui.log_checkBox.isChecked() is False: - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'LOG DISABLED') - cfg.utls.setQGISRegSetting(cfg.regLogKey, 'No') - cfg.logSetVal = self.getQGISRegSetting(cfg.regLogKey, 'Yes') - - # download news - def downloadNewsCheckbox(self): - # log setting - if cfg.ui.download_news_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.downNewsKey, '2') - elif cfg.ui.download_news_checkBox.isChecked() is False: - cfg.utls.setQGISRegSetting(cfg.downNewsKey, '0') - cfg.downNewsVal = self.getQGISRegSetting(cfg.downNewsKey, '2') - - # virtual raster - def virtualRasterCheckbox(self): - # log setting - if cfg.ui.virtual_raster_load_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.vrtRstProjKey, '2') - elif cfg.ui.virtual_raster_load_checkBox.isChecked() is False: - cfg.utls.setQGISRegSetting(cfg.vrtRstProjKey, '0') - cfg.vrtRstProjVal = self.getQGISRegSetting(cfg.vrtRstProjKey, '0') - - # checkbox switch sound - def soundCheckbox(self): - # sound setting - if cfg.ui.sound_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.regSound, '2') - elif cfg.ui.sound_checkBox.isChecked() is False: - cfg.utls.setQGISRegSetting(cfg.regSound, '0') - cfg.soundVal = self.getQGISRegSetting(cfg.regSound, '2') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sound: ' + str(cfg.soundVal)) - - # RAM setting - def RAMSettingChange(self): - cfg.RAMValue = cfg.ui.RAM_spinBox.value() - cfg.utls.setQGISRegSetting(cfg.regRAMValue, cfg.RAMValue) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ram value changed to: ' + str(cfg.RAMValue)) - - # set processing setting - def setProcessSetting(self, threads = None, ram = None): - if threads is not None: - cfg.threads = threads - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'threads value changed to: ' + str(cfg.threads)) - if ram is not None: - cfg.RAMValue = ram - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'ram value changed to: ' + str(cfg.RAMValue)) - - # thread setting - def threadSettingChange(self): - cfg.threads = cfg.ui.CPU_spinBox.value() - cfg.utls.setQGISRegSetting(cfg.regThreadsValue, cfg.threads) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'threads value changed to: ' + str(cfg.threads)) - - # reset field names - def resetFieldNames(self): - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset field names'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset field names?')) - if a == 'Yes': - cfg.ui.ID_field_name_lineEdit.setText(cfg.fldID_class_def) - cfg.ui.Info_field_name_lineEdit.setText(cfg.fldROI_info_def) - cfg.ui.MID_field_name_lineEdit.setText(cfg.fldMacroID_class_def) - cfg.ui.MCInfo_field_name_lineEdit.setText(cfg.fldROIMC_info_def) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'field Info name reset') - - # reset variable names - def resetVariableName(self): - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset variable name'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset variable name?')) - if a == 'Yes': - cfg.ui.variable_name_lineEdit.setText(cfg.variableName_def) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'variable name reset') - - # reset group name - def resetGroupName(self): - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset group name'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset group name?')) - if a == 'Yes': - cfg.ui.group_name_lineEdit.setText(cfg.grpNm_def) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'group name reset') - - # change temporary directory - def changeTempDir(self): - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Change temporary directory'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to change the temporary directory?')) - if a == 'Yes': - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - if len(o) != 0: - if cfg.QDirSCP(o).exists(): - dT = cfg.utls.getTime() - oDir = cfg.utls.makeDirectory(o + '/' + dT) - if oDir is None: - cfg.mx.msgWar17() - return 'No' - cfg.tmpDir = o + '/' + dT - cfg.ui.temp_directory_label.setText(o) - cfg.utls.setQGISRegSetting(cfg.regTmpDir, o) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'change temporary directory') - - # reset temporary directory - def resetTempDir(self): - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset temporary directory'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset the temporary directory?')) - if a == 'Yes': - cfg.tmpDir = str(cfg.QDirSCP.tempPath() + '/' + cfg.tempDirName) - cfg.utls.setQGISRegSetting(cfg.regTmpDir, cfg.tmpDir) - cfg.ui.temp_directory_label.setText(cfg.tmpDir) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'reset temporary directory') - - # Reset qml style path - def resetROIStyle(self): - cfg.utls.setQGISRegSetting(cfg.regROIClr, cfg.ROIClrValDefault) - cfg.utls.setQGISRegSetting(cfg.regROITransp, str(cfg.ROITrnspValDefault)) - cfg.ROITrnspVal = cfg.ROITrnspValDefault - cfg.ROIClrVal = cfg.ROIClrValDefault - cfg.ui.change_color_Button.setStyleSheet('background-color :' + cfg.ROIClrVal) - cfg.ui.transparency_Label.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Transparency ') + str(cfg.ROITrnspVal) + '%') - cfg.ui.transparency_Slider.setValue(cfg.ROITrnspValDefault) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'roi color reset') - - # test required dependencies - def testDependencies(self): - testNumpy = self.testNumpy() - testScipy = self.testScipy() - testMatplotlib = self.testMatplotlib() - testGDAL = self.testGDAL() - testGDALSubprocess = self.testGDALSubprocess() - testSNAPSubprocess = self.testSNAPSubprocess() - testMultiprocess = self.testMultiprocess() - testGDALMultiprocess = self.testGDALMultiprocess() - testInternet = self.testInternetConnection() - message = '-GDAL: ' + testGDAL + '\n' + '-GDAL subprocess: ' + testGDALSubprocess + '\n' + '-SNAP subprocess: ' + testSNAPSubprocess + '\n' + '-Python multiprocess: ' + testMultiprocess + '\n' + '-GDAL multiprocess: ' + testGDALMultiprocess + '\n' + '-NumPy: ' + testNumpy + '\n' + '-SciPy: ' + testScipy + '\n' + '-Matplotlib: ' + testMatplotlib + '\n' + '-Internet connection: ' + testInternet - cfg.mx.msgTest(message) - - # test GDAL - def testGDAL(self): - test = 'Success' - if cfg.testGDALV is not None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(cfg.testGDALV)) - test = 'Fail' - else: - v = cfg.utls.getGDALVersion() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' gdal version:' + str(v[0]) + '.' + str(v[1]) ) - if int(v[0]) == 1 and int(v[1]) < 10: - test = 'Success (GDAL version outdated ' + str(v[0]) + '.' + str(v[1]) + ')' - # check OGR drivers - d = cfg.ogrSCP.GetDriverByName('ESRI Shapefile') - if d is None: - test = 'Fail (missing drivers)' - try: - from osgeo import gdal - gdal.Translate - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test multiprocess - def multiprocessRunTest(self): - # pool - cfg.pool = cfg.poolSCP(processes=1) - p = 0 - wrtP = [[p, cfg.gdalDLLPath]] - results = [] - c = cfg.pool.apply_async(self.importTest, args=(wrtP)) - results.append([c, p]) - for r in results: - res = r[0].get() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' multiprocess res: ' + str(res)) - cfg.pool.close() - cfg.pool.terminate() - return res - - # test multiprocess import - def importTest(self, writerLog): - import os - for d in writerLog[1].split(';'): - try: - os.add_dll_directory(d) - except: - pass - try: - from osgeo import gdal - gdal.Translate - import numpy as np - return 'Yes' - except Exception as err: - return str(err) - - # test multiprocess - def testMultiprocess(self): - test = 'Success' - r = cfg.plgnDir + cfg.debugRasterPath - if cfg.osSCP.path.isfile(r) is False: - test = 'Unable to test' - return test - # Mac OS - if cfg.sysSCPNm == 'Darwin': - dPaths = cfg.osSCP.environ['PATH'].split(':') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' python environ path: ' + str(dPaths)) - if len(cfg.ui.python_path_lineEdit.text()) > 0: - flPrefPy = cfg.ui.python_path_lineEdit.text() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' python environ path preset: ' + str(flPrefPy)) - if cfg.osSCP.path.isfile(flPrefPy): - cfg.uiUtls.addProgressBar() - cfg.multiPSCP.set_executable(flPrefPy) - res = self.multiprocessRunTest() - if res != 'Yes': - test = 'Fail' - try: - tPMD = cfg.utls.createTempRasterPath('vrt') - oM = cfg.utls.createTempRasterPath('tif') - # open input with GDAL - rD = cfg.gdalSCP.Open(r, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, [oM], cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None) - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = r, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = [oM], functionBandArgument = ['raster * 2'], functionVariable = [['raster']], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Test'), parallel = cfg.parallelRaster) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' o : ' + str(o)) - test = 'Success' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - else: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' python path not found: ' + str(flPrefPy)) - test = 'Fail' - cfg.uiUtls.removeProgressBar() - else: - try: - if len(cfg.ui.python_path_lineEdit.text()) > 0: - dPref = cfg.ui.python_path_lineEdit.text() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' python environ path preset: ' + str(dPref)) - if not cfg.osSCP.path.isfile(dPref): - test = 'Fail' - return test - cfg.uiUtls.addProgressBar() - res = self.multiprocessRunTest() - if res != 'Yes': - test = 'Fail' - tPMD = cfg.utls.createTempRasterPath('vrt') - oM = cfg.utls.createTempRasterPath('tif') - # open input with GDAL - rD = cfg.gdalSCP.Open(r, cfg.gdalSCP.GA_ReadOnly) - # output rasters - cfg.utls.createRasterFromReference(rD, 1, [oM], cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None) - rD = None - o = cfg.utls.multiProcessRaster(rasterPath = r, functionBand = 'No', functionRaster = cfg.utls.calculateRaster, outputRasterList = [oM], functionBandArgument = ['raster * 2'], functionVariable = [['raster']], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Test'), parallel = cfg.parallelRaster) - cfg.uiUtls.removeProgressBar() - except Exception as err: - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test GDAL subprocess - def testGDALSubprocess(self): - dT = cfg.utls.getTime() - test = 'Success' - tPMD = cfg.utls.createTempRasterPath('vrt') - r = cfg.plgnDir + cfg.debugRasterPath - if cfg.osSCP.path.isfile(r) is False: - test = 'Unable to test' - return test - try: - cfg.utls.getGDALForMac() - a = cfg.gdalPath + 'gdalbuildvrt -separate "' + str(tPMD) + '" ' + str(r) - if cfg.sysSCPNm != 'Windows': - a = cfg.shlexSCP.split(a) - sP = cfg.subprocessSCP.Popen(a, shell=False) - sP.wait() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test SNAP subprocess - def testSNAPSubprocess(self): - dT = cfg.utls.getTime() - test = 'Success' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' SNAPGPT: ' + str(cfg.SNAPGPT)) - try: - a = '"' + cfg.SNAPGPT + '"' - b = a - if cfg.sysSCPNm != 'Windows': - b = cfg.shlexSCP.split(a) - if cfg.sysSCPNm == 'Windows' or cfg.sysSCPNm == 'Darwin': - startupinfo = cfg.subprocessSCP.STARTUPINFO() - startupinfo.dwFlags = cfg.subprocessSCP.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = cfg.subprocessSCP.SW_HIDE - sP = cfg.subprocessSCP.Popen(b, shell=False, startupinfo = startupinfo, stdin = cfg.subprocessSCP.DEVNULL) - else: - sP = cfg.subprocessSCP.Popen(b, shell=False) - v = sP.wait() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' subprocess: ' + str(v)) - if v != 0: - # trigger exception - v = exception - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # attempt shell = true - try: - sP = cfg.subprocessSCP.Popen(a, shell=True) - v = sP.wait() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' subprocess: ' + str(v)) - if v != 0: - test = 'Fail' - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test GDAL multiprocess - def testGDALMultiprocess(self): - dT = cfg.utls.getTime() - test = 'Success' - r = cfg.plgnDir + cfg.debugRasterPath - if cfg.osSCP.path.isfile(r) is False: - test = 'Unable to test' - return test - try: - cfg.utls.GDALCopyRaster(str(r), cfg.tmpDir + '/' + dT + 'test.tif', 'GTiff', cfg.rasterCompression, 'DEFLATE -co PREDICTOR=2 -co ZLEVEL=1') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test internet connection - def testInternetConnection(self): - dT = cfg.utls.getTime() - check = cfg.utls.downloadFile('https://semiautomaticgit.github.io/SemiAutomaticClassificationPluginWelcome/changelog.html', cfg.tmpDir + '//' + dT + '_changelog.html', dT + '_changelog.html', 50) - if check == 'Yes': - test = 'Success' - else: - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test Numpy - def testNumpy(self): - test = 'Success' - if cfg.testNumpyV is not None: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(cfg.testNumpyV)) - test = 'Fail' - # check if NumPy is updated - else: - try: - cfg.np.count_nonzero([1,1,0]) - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - test = 'Success (NumPy is outdated)' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test Scipy - def testScipy(self): - test = 'Success' - if cfg.testScipyV is not None: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(cfg.testScipyV)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # test Matplotlib - def testMatplotlib(self): - test = 'Success' - if cfg.testMatplotlibV is not None: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(cfg.testMatplotlibV)) - test = 'Fail' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' test: ' + str(test)) - return test - - # set variable for virtual raster format - def virtualRasterFormatCheckbox(self): - if cfg.ui.virtual_raster_checkBox.isChecked() is True: - cfg.outTempRastFormat = 'VRT' - else: - cfg.outTempRastFormat = 'GTiff' - cfg.utls.setQGISRegSetting(cfg.regTempRasterFormat, cfg.outTempRastFormat) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.outTempRastFormat)) - - # set variable for raster compression - def rasterCompressionCheckbox(self): - if cfg.ui.raster_compression_checkBox.isChecked() is True: - cfg.rasterCompression = 'Yes' - else: - cfg.rasterCompression = 'No' - cfg.utls.setQGISRegSetting(cfg.regRasterCompression, cfg.rasterCompression) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.rasterCompression)) - - # set variable for parallel writing - def parallelWritingCheckbox(self): - if cfg.ui.parallel_writing_checkBox.isChecked() is True: - cfg.parallelWritingCheck = 'Yes' - else: - cfg.parallelWritingCheck = 'No' - cfg.utls.setQGISRegSetting(cfg.regparallelWritingCheck, cfg.parallelWritingCheck) - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' checkbox set: ' + str(cfg.parallelWritingCheck)) - - # smtp server - def SMTPServerChange(self): - cfg.SMTPServer = cfg.ui.smtp_server_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regSMTPServer, cfg.SMTPServer) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'SMTP server changed to: ' + str(cfg.SMTPServer)) - - # smtp to emails - def SMTPtoEmailsChange(self): - cfg.SMTPtoEmails = cfg.ui.to_email_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regSMTPtoEmails, cfg.SMTPtoEmails) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'SMTP server changed to: ' + str(cfg.SMTPtoEmails)) - - # user - def rememberUser(self): - if cfg.ui.remeber_settings_checkBox.isChecked(): - cfg.SMTPUser = cfg.ui.smtp_user_lineEdit.text() - cfg.SMTPPassword = cfg.utls.encryptPassword(cfg.ui.smtp_password_lineEdit.text()) - cfg.utls.setQGISRegSetting(cfg.regSMTPUser, cfg.SMTPUser) - cfg.utls.setQGISRegSetting(cfg.regSMTPPassword, cfg.SMTPPassword) - - # checkbox remember user - def rememberUserCheckbox(self): - if cfg.ui.remeber_settings_checkBox.isChecked(): - self.rememberUser() - else: - cfg.utls.setQGISRegSetting(cfg.regSMTPUser, '') - cfg.utls.setQGISRegSetting(cfg.regSMTPPassword, '') - - # checkbox SMTP - def SMTPCheckbox(self): - # sound setting - if cfg.ui.smtp_checkBox.isChecked() is True: - cfg.utls.setQGISRegSetting(cfg.regSMTPCheck, '2') - elif cfg.ui.smtp_checkBox.isChecked() is False: - cfg.utls.setQGISRegSetting(cfg.regSMTPCheck, '0') - cfg.SMTPCheck = self.getQGISRegSetting(cfg.regSMTPCheck, '2') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'sound: ' + str(cfg.SMTPCheck)) - - # GDAL setting - def GDALPathSettingChange(self): - if len(cfg.ui.gdal_path_lineEdit.text()) == 0: - cfg.gdalPath = '' - else: - cfg.gdalPath = cfg.ui.gdal_path_lineEdit.text().rstrip('/') + '/' - cfg.utls.setQGISRegSetting(cfg.regGDALPathSettings, cfg.gdalPath) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'gdal path changed to: ' + str(cfg.gdalPath)) - - # Python setting - def PythonPathSettingChange(self): - cfg.PythonPathSettings = cfg.ui.python_path_lineEdit.text() - cfg.utls.setQGISRegSetting(cfg.regPythonPathSettings, cfg.PythonPathSettings) - if len(cfg.PythonPathSettings) == 0: - cfg.PythonPathSettings = str(cfg.sysSCP.executable) - cfg.multiPSCP.set_executable(cfg.PythonPathSettings) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'python path changed to: ' + str(cfg.PythonPathSettings)) - - # Python setting - def PythonModulePathSettingChange(self): - cfg.PythonModulesPathSettings = cfg.ui.python_path_lineEdit_2.text() - cfg.utls.setQGISRegSetting(cfg.regPythonModulesPathSettings, cfg.PythonModulesPathSettings) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'python modules path changed to: ' + str(cfg.PythonModulesPathSettings)) - \ No newline at end of file diff --git a/maininterface/sieveTab.py b/maininterface/sieveTab.py deleted file mode 100644 index 6583554..0000000 --- a/maininterface/sieveTab.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SieveRaster: - - def __init__(self): - pass - - # sieve classification - def sieveClassificationAction(self): - self.sieveClassification() - - # sieve classification - def sieveClassification(self, batch = 'No', rasterInput = None, rasterOutput = None): - if batch == 'No': - outputRaster = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save output'), '', '*.tif', 'tif') - else: - outputRaster = rasterOutput - if outputRaster is not False: - if outputRaster.lower().endswith('.tif'): - pass - else: - outputRaster = outputRaster + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - raster = cfg.ui.sieve_raster_name_combo.currentText() - b = cfg.utls.selectLayerbyName(raster, 'Yes') - else: - b = 'No' - if b is not None: - if batch == 'No': - rSource = cfg.utls.layerSource(b) - else: - if cfg.osSCP.path.isfile(rasterInput): - rSource = rasterInput - else: - return 'No' - cfg.uiUtls.updateBar(40) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(outputRaster)) - pixelThreshold = cfg.ui.sieve_threshold_spinBox.value() - connect = cfg.ui.sieve_connection_combo.currentText() - cfg.utls.rasterSieve(rSource, outputRaster, pixelThreshold, connect) - if cfg.osSCP.path.isfile(outputRaster): - r =cfg.utls.addRasterLayer(outputRaster) - else: - return 'No' - if b != 'No': - cfg.utls.copyRenderer(b, r) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.updateBar(100) - cfg.uiUtls.removeProgressBar() - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.utls.refreshClassificationLayer() - cfg.mx.msgErr9() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error raster not found') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode()) - \ No newline at end of file diff --git a/maininterface/signatureThresholdTab.py b/maininterface/signatureThresholdTab.py deleted file mode 100644 index b3932a4..0000000 --- a/maininterface/signatureThresholdTab.py +++ /dev/null @@ -1,230 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SigThresholdTab: - - def __init__(self): - pass - - # Create signature list table - def signatureThresholdListTable(self): - l = cfg.ui.signature_threshold_tableWidget - self.tableEdited = 'No' - l.blockSignals(True) - cfg.utls.clearTable(l) - x = 0 - for k in list(cfg.signIDs.values()): - cfg.utls.insertTableRow(l, x) - cfg.utls.addTableItem(l, int(cfg.signList['MACROCLASSID_' + str(k)]), x, 0, 'No') - cfg.utls.addTableItem(l, str(cfg.signList['MACROCLASSINFO_' + str(k)]), x, 1, 'No') - cfg.utls.addTableItem(l, int(cfg.signList['CLASSID_' + str(k)]), x, 2, 'No') - cfg.utls.addTableItem(l, str(cfg.signList['CLASSINFO_' + str(k)]), x, 3, 'No') - cfg.utls.addTableItem(l, str(cfg.signList['MD_THRESHOLD_' + str(k)]), x, 4) - cfg.utls.addTableItem(l, str(cfg.signList['ML_THRESHOLD_' + str(k)]), x, 5) - cfg.utls.addTableItem(l, str(cfg.signList['SAM_THRESHOLD_' + str(k)]), x, 6) - cfg.utls.addTableItem(l, str(cfg.signIDs['ID_' + str(k)]), x, 7, 'No') - x = x + 1 - l.blockSignals(False) - self.tableEdited = 'Yes' - cfg.utls.sortTableColumn(l, 7) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' signature list threshold created') - - # read threshold table - def readThresholdTable(self): - tAW = cfg.ui.signature_threshold_tableWidget - c = tAW.rowCount() - for b in range(0, c): - try: - wI = tAW.item(b, 4).text() - wIML = tAW.item(b, 5).text() - wISAM = tAW.item(b, 6).text() - id = tAW.item(b, 7).text() - cfg.signList['MD_THRESHOLD_' + str(id)] = wI - cfg.signList['ML_THRESHOLD_' + str(id)] = wIML - cfg.signList['SAM_THRESHOLD_' + str(id)] = wISAM - except: - pass - - # edited threshold table - def editedThresholdTable(self, row, column): - if self.tableEdited == 'Yes': - tW = cfg.ui.signature_threshold_tableWidget - t = tW.item(row, column).text() - try: - tr = float(t) - except: - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, '0') - tW.blockSignals(False) - self.tableEdited = 'Yes' - cfg.signT.readThresholdTable() - return 0 - if column == 5: - if tr > 100: - cfg.mx.msg10() - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, '100') - tW.blockSignals(False) - self.tableEdited = 'Yes' - elif column == 6: - if tr > 90: - cfg.mx.msg11() - self.tableEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, '90') - tW.blockSignals(False) - self.tableEdited = 'Yes' - cfg.signT.readThresholdTable() - - # reset thresholds - def resetThresholds(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Reset thresholds'), cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Are you sure you want to reset thresholds?')) - if a == 'Yes': - tW = cfg.ui.signature_threshold_tableWidget - v = tW.rowCount() - self.tableEdited = 'No' - tW.blockSignals(True) - for c in range(0, v): - cfg.utls.setTableItem(tW, c, 4, '0') - cfg.utls.setTableItem(tW, c, 5, '0') - cfg.utls.setTableItem(tW, c, 6, '0') - tW.blockSignals(False) - self.tableEdited = 'Yes' - cfg.signT.readThresholdTable() - - # set thresholds - def setThresholds(self): - self.tableEdited = 'No' - i = None - tW = cfg.ui.signature_threshold_tableWidget - tW.setSortingEnabled(False) - iR = [] - for i in tW.selectedIndexes(): - iR.append([i.row(), i.column()]) - self.tableEdited = 'No' - tW.blockSignals(True) - if len(iR) > 0: - for c in reversed(iR): - if c[1] == 6: - wvSAM = cfg.ui.threshold_doubleSpinBox.value() - if wvSAM > 90: - cfg.mx.msg11() - wvSAM = 90 - try: - cfg.utls.setTableItem(tW, c[0], 6, str(wvSAM)) - except: - pass - elif c[1] == 5: - wvML = cfg.ui.threshold_doubleSpinBox.value() - if wvML > 100: - cfg.mx.msg10() - wvML = 100 - try: - cfg.utls.setTableItem(tW, c[0], 5, str(wvML)) - except: - pass - else: - wv = cfg.ui.threshold_doubleSpinBox.value() - try: - cfg.utls.setTableItem(tW, c[0], 4, str(wv)) - except: - pass - else: - pass - tW.setSortingEnabled(True) - tW.blockSignals(False) - self.tableEdited = 'Yes' - self.readThresholdTable() - - # set weights based on variance - def setAllWeightsVariance(self): - tW = cfg.ui.signature_threshold_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append([i.row(), i.column()]) - if len(iR) > 0: - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - for c in reversed(iR): - id = tW.item(c[0], 7).text() - # wavelength - wlg = cfg.signList['WAVELENGTH_' + str(id)] - val = cfg.signList['VALUES_' + str(id)] - # counter - n = 0 - m = [] - # mean plus standard deviation - mPS = [] - mMS = [] - for s in wlg: - m.append(val[n * 2]) - sd = val[n * 2 +1] - mPS.append(val[n * 2] + sd) - mMS.append(val[n * 2] - sd) - n = n + 1 - if c[1] == 6: - angleP = cfg.utls.spectralAngle(m, mPS) - angleM = cfg.utls.spectralAngle(m, mMS) - valueTSAM = cfg.ui.multiplicative_threshold_doubleSpinBox.value() * max([angleP, angleM]) - if valueTSAM > 90: - valueTSAM = 90 - cfg.utls.setTableItem(tW, c[0], 6, str(valueTSAM)) - elif c[1] == 4: - distP = cfg.utls.euclideanDistance(m, mPS) - distM = cfg.utls.euclideanDistance(m, mMS) - valueT = cfg.ui.multiplicative_threshold_doubleSpinBox.value() * max([distP, distM]) - cfg.utls.setTableItem(tW, c[0], 4, str(valueT)) - tW.setSortingEnabled(True) - tW.blockSignals(False) - self.tableEdited = 'Yes' - try: - vOrd = self.orderColumn - except: - vOrd = 7 - cfg.utls.sortTableColumn(tW, vOrd, tW.horizontalHeader().sortIndicatorOrder()) - cfg.signT.readThresholdTable() - - # ordered table - def orderedTable(self, column): - self.orderColumn = column - \ No newline at end of file diff --git a/maininterface/spectraldistancebandsets.py b/maininterface/spectraldistancebandsets.py deleted file mode 100644 index bcb777f..0000000 --- a/maininterface/spectraldistancebandsets.py +++ /dev/null @@ -1,234 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SpectralDistanceBandsets: - - def __init__(self): - pass - - # calculate distance band sets - def calculateDistanceAction(self): - self.spectralDistBandSets() - - # miniumum distance radioButton button changed - def radioMinDistChanged(self): - cfg.ui.min_distance_radioButton_2.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton_2.blockSignals(True) - cfg.ui.min_distance_radioButton_2.setChecked(True) - cfg.ui.spectral_angle_map_radioButton_2.setChecked(False) - cfg.ui.min_distance_radioButton_2.blockSignals(False) - cfg.ui.spectral_angle_map_radioButton_2.blockSignals(False) - - # SAM radioButton button changed - def radioSAMChanged(self): - cfg.ui.min_distance_radioButton_2.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton_2.blockSignals(True) - cfg.ui.spectral_angle_map_radioButton_2.setChecked(True) - cfg.ui.min_distance_radioButton_2.setChecked(False) - cfg.ui.min_distance_radioButton_2.blockSignals(False) - cfg.ui.spectral_angle_map_radioButton_2.blockSignals(False) - thresh = cfg.ui.thresh_doubleSpinBox_2.value() - if thresh > 90: - cfg.mx.msg11() - cfg.ui.thresh_doubleSpinBox_2.setValue(90) - - # calculate distance band sets - def spectralDistBandSets(self, firstBandSet = None, secondBandSet = None, outputRaster = None, batch = 'No'): - if firstBandSet is None: - bandSet = cfg.ui.band_set_comb_spinBox_6.value() - firstBandSet = bandSet - 1 - if secondBandSet is None: - bandSet = cfg.ui.band_set_comb_spinBox_7.value() - secondBandSet = bandSet - 1 - bSL = [] - bSL.append(firstBandSet) - bSL.append(secondBandSet) - if batch == 'No': - specRstPath = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save distance raster output'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - else: - specRstPath = outputRaster - # virtual raster - vrtR = 'No' - if specRstPath.lower().endswith('.vrt'): - vrtR = 'Yes' - if specRstPath is not False: - o = cfg.osSCP.path.dirname(specRstPath) - outputName = cfg.utls.fileNameNoExt(specRstPath) + str(firstBandSet + 1)+ "_" + str(secondBandSet + 1) - if batch == 'No': - cfg.uiUtls.addProgressBar() - bndSetSources = [] - bndSetIf = [] - # create list of rasters - for bandSetNumber in bSL: - try: - cfg.bandSetsList[bandSetNumber][0] - except: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - bndSetIf.append('Yes') - else: - ckB = cfg.utls.checkImageBandSet(bandSetNumber) - bndSetIf.append('No') - if ckB == 'Yes': - bndSetSources.append(cfg.bndSetLst) - if len(bndSetSources) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(10) - rCrs = cfg.utls.getCrsGDAL(bndSetSources[0][0]) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if rEPSG is None: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - cfg.uiUtls.updateBar(20) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(specRstPath)) - # No data value - NoDataVal = cfg.NoDataVal - for bst in bndSetSources: - if len(bst) != len(bndSetSources[0]): - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - bstIndex = bndSetSources.index(bst) - for b in range(0, len(bst)): - eCrs = cfg.utls.getCrsGDAL(bst[b]) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - if cfg.bandSetsList[bstIndex][0] == 'Yes': - nD = cfg.utls.imageNoDataValue(bst[b]) - if nD is None: - nD = NoDataVal - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(bst[b], tPMD, str(rCrs)) - cfg.mx.msg9() - #tPMD = cfg.utls.createTempRasterPath('tif') - #cfg.utls.GDALReprojectRaster(bst[b], tPMD, "GTiff", None, "EPSG:" + str(rEPSG), "-ot Float32 -dstnodata " + str(nD)) - if cfg.osSCP.path.isfile(tPMD): - bndSetSources[bstIndex][b] = tPMD - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - else: - nD = cfg.utls.imageNoDataValue(bst[b]) - if nD is None: - nD = NoDataVal - tPMD = cfg.utls.createTempRasterPath('tif') - cfg.utls.GDALReprojectRaster(bst[b], tPMD, "GTiff", None, rCrs, '-ot Float32 -dstnodata ' + str(nD)) - if cfg.osSCP.path.isfile(tPMD): - for bb in range(0, len(bst)): - bndSetSources[bstIndex][bb] = tPMD - break - else: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr60() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Warning") - return 'No' - cfg.uiUtls.updateBar(40) - bList = [] - bandNumberList = [] - for x in range(0, len(bndSetSources)): - for y in range(0, len(bndSetSources[0])): - if bndSetIf[x] == 'Yes': - bList.append(bndSetSources[x][y]) - bandNumberList.append(1) - else: - bList.append(bndSetSources[x][y]) - bandNumberList.append(y + 1) - if cfg.ui.min_distance_radioButton_2.isChecked() is True: - alg = cfg.algMinDist - else: - alg = cfg.algSAM - if cfg.ui.distance_threshold_checkBox.isChecked() is True: - thresh = cfg.ui.thresh_doubleSpinBox_2.value() - else: - thresh = 0 - if vrtR == 'Yes': - rstrOut = o + '/' + outputName + '.vrt' - else: - rstrOut = o + '/' + outputName + '.tif' - # create virtual raster - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'Yes') - oo = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.spectralDistanceProcess, outputRasterList = [rstrOut], nodataValue = None, functionBandArgument = NoDataVal, functionVariable = [alg], progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Spectral distance'), virtualRaster = vrtR, compress = cfg.rasterCompression, compressFormat = 'LZW') - if cfg.osSCP.path.isfile(rstrOut): - # add raster to layers - cfg.utls.addRasterLayer(rstrOut) - if cfg.ui.distance_threshold_checkBox.isChecked() is True: - e = 'cfg.np.where("raster" > ' + str(thresh) + ', 1, 0 )' - variableList = [] - variableList.append(['"raster"', '"raster"']) - if vrtR == 'Yes': - rstrOut2 = o + '/' + outputName + '_change' + '.vrt' - else: - rstrOut2 = o + '/' + outputName + '_change' + '.tif' - oo2 = cfg.utls.multiProcessRaster(rasterPath = rstrOut, functionBand = 'No', functionRaster = cfg.utls.bandCalculation, outputRasterList = [rstrOut2], functionBandArgument = e, functionVariable = variableList, progressMessage = 'Threshold ', virtualRaster = vrtR, compress = cfg.rasterCompression, compressFormat = 'LZW') - if cfg.osSCP.path.isfile(rstrOut2): - # add raster to layers - c = cfg.utls.addRasterLayer(rstrOut2) - rasterSymbol = cfg.utls.rasterScatterSymbol([[1,"#FF0000"]]) - cfg.utls.setRasterScatterSymbol(c, rasterSymbol) - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.updateBar(100) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() diff --git a/maininterface/splitTab.py b/maininterface/splitTab.py deleted file mode 100644 index 3e1bb9c..0000000 --- a/maininterface/splitTab.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SplitTab: - - def __init__(self): - pass - - # raster name - def rasterLayerName(self): - self.rstrLyNm = cfg.ui.raster_name_combo.currentText() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster name: ' + self.rstrLyNm) - - def refreshClassificationLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.raster_name_combo.clear() - # raster name - self.rstrLyNm = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() > 1: - cfg.dlg.raster_layer_combo(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'raster layers refreshed') - - # split raster button - def splitRaster(self): - try: - i = len(cfg.ui.raster_name_combo.currentText()) - except: - self.refreshClassificationLayer() - return 'No' - if i > 0: - self.splitRasterToBands(self.rstrLyNm) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' split raster layer to band') - else: - self.refreshClassificationLayer() - - # split raster to bands - def splitRasterToBands(self, rasterName, batch = 'No', inputFile = None, outputDirectory = None): - if batch == 'No': - o = cfg.utls.getExistingDirectory(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Select a directory')) - else: - o = outputDirectory - outputName = cfg.ui.output_name_lineEdit.text() - if len(outputName) > 0: - outputName = str(outputName.encode('ascii','replace'))[2:-1] + '_' - if len(o) > 0: - oDir = cfg.utls.makeDirectory(o) - if oDir is None: - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr58() - return 'No' - if batch == 'No': - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.uiUtls.addProgressBar() - i = cfg.utls.selectLayerbyName(rasterName, 'Yes') - rPath = cfg.utls.layerSource(i) - else: - rPath = inputFile - try: - iL = cfg.utls.rasterToBands(rPath, cfg.tmpDir, outputName + rasterName, 'Yes') - for r in iL: - if cfg.rasterCompression != 'No': - try: - cfg.utls.GDALCopyRaster(r, o + '/' + cfg.utls.fileName(r), 'GTiff', cfg.rasterCompression, 'LZW') - except Exception as err: - cfg.shutilSCP.copy(r, o + '/' + cfg.utls.fileName(r)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - else: - cfg.shutilSCP.copy(r, o + '/' + cfg.utls.fileName(r)) - cfg.utls.addRasterLayer(o + '/' + cfg.utls.fileName(r)) - cfg.osSCP.remove(r) - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' end split raster layer to band') - except Exception as err: - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - cfg.mx.msgErr32() - return 'No' - \ No newline at end of file diff --git a/maininterface/stackrasterbands.py b/maininterface/stackrasterbands.py deleted file mode 100644 index 337d0b7..0000000 --- a/maininterface/stackrasterbands.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class StackRasterBands: - - def __init__(self): - pass - - # stack raster - def stackAction(self): - self.stackRasters() - - # stack multiple rasters - def stackRasters(self, batch = 'No', outputFile = None, bandSetNumber = None): - if bandSetNumber is None: - bandSetNumber = cfg.bndSetNumber - if bandSetNumber >= len(cfg.bandSetsList): - cfg.mx.msgWar25(bandSetNumber + 1) - return 'No' - cfg.uiUtls.addProgressBar() - if cfg.bandSetsList[bandSetNumber][0] == 'Yes': - ckB = cfg.utls.checkBandSet(bandSetNumber) - if ckB == 'Yes': - if len(cfg.bndSetLst) == 0: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - cfg.mx.msgWar28() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' Warning') - return 'No' - if outputFile is None: - rstrOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster'), '', 'TIF file (*.tif);;VRT file (*.vrt)') - if rstrOut is False: - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - else: - rstrOut = outputFile - else: - cfg.mx.msgWar15() - if batch == 'No': - cfg.uiUtls.removeProgressBar() - return 'No' - if rstrOut is not False: - if rstrOut.lower().endswith('.vrt'): - outputFormat = 'vrt' - elif rstrOut.lower().endswith('.tif'): - outputFormat = 'GTiff' - else: - rstrOut = rstrOut + '.tif' - outputFormat = 'GTiff' - if outputFile is None: - cfg.uiUtls.addProgressBar() - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(rstrOut)) - st = cfg.utls.mergeRasterBands(cfg.bndSetLst, rstrOut, compress = 'Yes', outFormat = outputFormat) - if cfg.osSCP.path.isfile(rstrOut): - cfg.cnvs.setRenderFlag(False) - cfg.utls.addRasterLayer(rstrOut) - cfg.cnvs.setRenderFlag(True) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " raster: " + str(st)) - cfg.uiUtls.updateBar(100) - if outputFile is None: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - \ No newline at end of file diff --git a/maininterface/vectortorasterTab.py b/maininterface/vectortorasterTab.py deleted file mode 100644 index 3520768..0000000 --- a/maininterface/vectortorasterTab.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class VectorToRasterTab: - - def __init__(self): - pass - - # convert to raster - def convertToRasterAction(self): - self.convertToRaster() - - # convert to raster - def convertToRaster(self, batch = 'No', rasterOutput = None, vectorPath = None, fieldName = None, rasterPath = None): - if batch == 'No': - vector = cfg.ui.vector_name_combo.currentText() - l = cfg.utls.selectLayerbyName(vector) - referenceRasterName = cfg.ui.reference_raster_name_combo.currentText() - r = cfg.utls.selectLayerbyName(referenceRasterName) - if l is None or r is None: - cfg.utls.refreshVectorLayer() - cfg.utls.refreshClassificationLayer() - return - vectorSource = cfg.utls.layerSource(l) - referenceRasterPath = cfg.utls.layerSource(r) - fd = cfg.ui.field_comboBox.currentText() - if len(fd) == 0 and cfg.ui.field_checkBox.isChecked(): - cfg.utls.refreshVectorLayer() - return - rstrOut = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save raster output'), '', '*.tif', 'tif') - else: - vectorSource = vectorPath - referenceRasterPath = rasterPath - referenceRasterName = 'No' - rstrOut = rasterOutput - fd = fieldName - if rstrOut is not False: - if rstrOut.lower().endswith('.tif'): - pass - else: - rstrOut = rstrOut + '.tif' - if batch == 'No': - cfg.uiUtls.addProgressBar() - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - # vector EPSG - if 'Polygon?crs=' in str(vectorSource) or 'memory?geometry=' in str(vectorSource): - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - l = cfg.utls.saveMemoryLayerToShapefile(l, tSHP, format = 'GPKG') - vectorSource = tSHP - if cfg.ui.field_checkBox.isChecked(): - burnValues = None - else: - burnValues = cfg.ui.constant_value_spinBox.value() - cfg.uiUtls.updateBar(10) - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(rstrOut)) - if cfg.ui.conversion_type_combo.currentText() == cfg.centerOfPixels: - conversionType = None - else: - conversionType = 'ALL_TOUCHED' - if cfg.ui.extent_checkBox_2.isChecked(): - extentR = 'Yes' - else: - extentR = None - # convert vector layer to raster - check = cfg.utls.vectorToRaster(fd, vectorSource, referenceRasterName, rstrOut, referenceRasterPath, conversionType, 'GTiff', burnValues, extent = extentR, compress = cfg.rasterCompression, compressFormat = 'DEFLATE') - cfg.uiUtls.updateBar(100) - # add raster to layers - if cfg.osSCP.path.isfile(rstrOut): - rstr = cfg.utls.addRasterLayer(rstrOut) - else: - return 'No' - #cfg.utls.rasterSymbolSingleBandGray(rstr) - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'finished') - - # reload vector list - def reloadVectorList(self): - cfg.utls.refreshVectorLayer() - - # checkbox changed - def checkboxConstantValueChanged(self): - cfg.ui.field_checkBox.blockSignals(True) - cfg.ui.constant_value_checkBox.blockSignals(True) - if cfg.ui.constant_value_checkBox.isChecked(): - cfg.ui.field_checkBox.setCheckState(0) - else: - cfg.ui.field_checkBox.setCheckState(2) - cfg.ui.field_checkBox.blockSignals(False) - cfg.ui.constant_value_checkBox.blockSignals(False) - - # checkbox changed - def checkboxFieldChanged(self): - cfg.ui.field_checkBox.blockSignals(True) - cfg.ui.constant_value_checkBox.blockSignals(True) - if cfg.ui.field_checkBox.isChecked(): - cfg.ui.constant_value_checkBox.setCheckState(0) - else: - cfg.ui.constant_value_checkBox.setCheckState(2) - cfg.ui.field_checkBox.blockSignals(False) - cfg.ui.constant_value_checkBox.blockSignals(False) \ No newline at end of file diff --git a/maininterface/zonalStatRasterTab.py b/maininterface/zonalStatRasterTab.py deleted file mode 100644 index 804fcf4..0000000 --- a/maininterface/zonalStatRasterTab.py +++ /dev/null @@ -1,432 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class ZonalStatRasterTab: - - def __init__(self): - pass - - # calculate zonal stat action - def zonalStatRasterAction(self): - self.zonalStatRaster() - - # calculate zonal stat raster - def zonalStatRaster(self, batch = 'No', inputRaster = None, reference = None, shapefileField = None, rasterOutput = None, statName = None, statPerc = None, NoDataValue = None): - if inputRaster is None: - inputRasterNm = cfg.ui.classification_name_combo_5.currentText() - iClass = cfg.utls.selectLayerbyName(inputRasterNm, 'Yes') - if iClass is None: - cfg.mx.msgErr38(inputRasterNm) - return 'No' - inputRaster = cfg.utls.layerSource(iClass) - else: - iClass = cfg.utls.addRasterLayer(inputRaster) - if reference is None: - referenceNm = cfg.ui.reference_name_combo_3.currentText() - l = cfg.utls.selectLayerbyName(referenceNm) - reference = cfg.utls.selectLayerbyName(referenceNm, 'Yes') - else: - try: - # open input with GDAL - rD = cfg.gdalSCP.Open(reference, cfg.gdalSCP.GA_ReadOnly) - if rD is None: - l = cfg.utls.addVectorLayer(reference, cfg.utls.fileName(reference), "ogr") - else: - l = cfg.utls.addRasterLayer(reference) - reml = l - rD = None - except: - cfg.mx.msgErr38(reference) - return 'No' - # statistic name - if statName is None: - statName = cfg.ui.statistic_name_combobox.currentText() - for i in cfg.statisticList: - if i[0].lower() == statName.lower(): - statNp = i[1] - if i[0].lower() == 'percentile': - if statPerc is None: - statPerc = cfg.ui.statistic_lineEdit.text() - try: - statPerc = int(statPerc) - break - except: - cfg.mx.msgErr66() - return 'No' - else: - break - if batch == 'No': - zonalRstPath = cfg.utls.getSaveFileName(None, cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save zonal stat raster output'), '', '*.tif', 'tif') - else: - zonalRstPath = rasterOutput - if zonalRstPath is not False: - if zonalRstPath.lower().endswith('.tif'): - pass - else: - zonalRstPath = zonalRstPath + '.tif' - cfg.utls.makeDirectory(cfg.osSCP.path.dirname(zonalRstPath)) - if iClass is not None and l is not None: - if batch == 'No': - cfg.uiUtls.addProgressBar() - # if not reference shapefile - if l.type() != cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - # check projections - rCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(l)) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - eCrs = cfg.utls.getCrsGDAL(cfg.utls.layerSource(iClass)) - EPSG = cfg.osrSCP.SpatialReference() - EPSG.ImportFromWkt(eCrs) - if EPSG.IsSame(rEPSG) != 1: - tPMD = cfg.utls.createTempRasterPath('vrt') - cfg.utls.createWarpedVrt(cfg.utls.layerSource(iClass), tPMD, str(rCrs)) - cfg.mx.msg9() - remiClass2 = cfg.utls.addRasterLayer(tPMD) - iClass = remiClass2 - inputRaster = tPMD - else: - # vector EPSG - if 'Polygon?crs=' in str(cfg.utls.layerSource(l)) or 'memory?geometry=' in str(cfg.utls.layerSource(l)): - # temp shapefile - tSHP = cfg.utls.createTempRasterPath('gpkg') - l = cfg.utls.saveMemoryLayerToShapefile(l, tSHP, format = 'GPKG') - vCrs = cfg.utls.getCrsGDAL(tSHP) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - else: - ql = cfg.utls.layerSource(l) - vCrs = cfg.utls.getCrsGDAL(ql) - vEPSG = cfg.osrSCP.SpatialReference() - vEPSG.ImportFromWkt(vCrs) - dT = cfg.utls.getTime() - # in case of reprojection - qll = cfg.utls.layerSource(l) - reprjShapefile = cfg.tmpDir + '/' + dT + cfg.utls.fileName(qll) - qlll = cfg.utls.layerSource(iClass) - rCrs = cfg.utls.getCrsGDAL(qlll) - rEPSG = cfg.osrSCP.SpatialReference() - rEPSG.ImportFromWkt(rCrs) - if vEPSG.IsSame(rEPSG) != 1: - if cfg.osSCP.path.isfile(reprjShapefile): - pass - else: - try: - qllll = cfg.utls.layerSource(l) - cfg.utls.repojectShapefile(qllll, vEPSG, reprjShapefile, rEPSG) - except Exception as err: - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr9() - return 'No' - l = cfg.utls.addVectorLayer(reprjShapefile, cfg.utls.fileName(reprjShapefile) , 'ogr') - if batch == 'No': - # disable map canvas render for speed - cfg.cnvs.setRenderFlag(False) - cfg.QtWidgetsSCP.qApp.processEvents() - # temp raster layer - tRC = cfg.utls.createTempRasterPath('tif') - cfg.uiUtls.updateBar(10) - # if reference shapefile - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - if batch == 'No': - fd = cfg.ui.class_field_comboBox_4.currentText() - else: - fd = shapefileField - if batch == 'No': - # convert reference layer to raster - qlllll = cfg.utls.layerSource(l) - qllllll = cfg.utls.layerSource(iClass) - vect = cfg.utls.vectorToRaster(fd, str(qlllll), inputRaster, str(tRC), str(qllllll), extent = 'Yes') - else: - qlllllll = cfg.utls.layerSource(l) - vect = cfg.utls.vectorToRaster(fd, str(qlllllll), inputRaster, str(tRC), inputRaster, extent = 'Yes') - if vect == 'No': - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR vector') - cfg.mx.msgErr9() - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - return 'No' - referenceRaster = tRC - # if reference raster - elif l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer: - if batch == 'No': - referenceRaster = cfg.utls.layerSource(l) - else: - referenceRaster = reference - # No data value - if NoDataValue is not None: - nD = NoDataValue - elif cfg.ui.nodata_checkBox_10.isChecked() is True: - nD = cfg.ui.nodata_spinBox_12.value() - else: - nD = cfg.utls.imageNoDataValue(referenceRaster) - if nD is None: - nD = cfg.NoDataVal - cfg.parallelArrayDict = {} - o = cfg.utls.multiProcessRaster(rasterPath = referenceRaster, functionBand = 'No', functionRaster = cfg.utls.rasterUniqueValuesWithSum, nodataValue = nD, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Unique values'), deleteArray = 'No') - # calculate unique values - values = cfg.np.array([]) - for x in sorted(cfg.parallelArrayDict): - try: - for ar in cfg.parallelArrayDict[x]: - values = cfg.np.append(values, ar[0][0, ::]) - except: - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR values') - cfg.mx.msgErr9() - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - return 'No' - rasterBandUniqueVal = cfg.np.unique(values).tolist() - classes = sorted(rasterBandUniqueVal) - # get integer values - intClass = [] - for c in classes: - try: - if int(c) == c: - intClass.append(int(c)) - else: - intClass.append(c) - except: - intClass.append(c) - classes = intClass - cfg.uiUtls.updateBar(30) - # create functions - bList = [referenceRaster, inputRaster] - bListNum = [1, 1] - functionList = [] - variableList = [] - bandNumberList = [] - for c in classes: - if c != nD: - for b in range(1, len(bList)): - e = 'cfg.np.where(rasterSCPArrayfunctionBand[::, ::, ' + str(0) + '] == ' + str(c) + ', rasterSCPArrayfunctionBand[::, ::, ' + str(b) + '], cfg.np.nan)' - ee = statNp.replace('array', e) - try: - statPerc = int(statPerc) - ee = ee.replace(cfg.statPerc, str(statPerc)) - except: - pass - functionList.append(ee) - variableList.append('rasterSCPArrayfunctionBand') - bandNumberList.append([0, b]) - # create virtual raster - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bListNum, 'Yes', 'Yes', 0, 'No', 'Yes') - # calculation statistic - o = cfg.utls.multiProcessNoBlocks(rasterPath = vrtCheck, bandNumberList = bandNumberList, functionRaster = cfg.utls.noBlocksCalculation, nodataValue = nD, functionBandArgument = functionList, functionVariable = variableList, progressMessage = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Raster statistics')) - cfg.uiUtls.updateBar(60) - # write report - colStat = statName - if statPerc is not None: - colStat = statName + str(statPerc) - l = open(zonalRstPath[:-4] + '_report.csv', 'w') - t = cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Class') + ' ' + colStat + str('\n') - l.write(t) - # get values - for c in classes: - if c != nD: - for b in range(1, len(bList)): - e = 'cfg.np.where(rasterSCPArrayfunctionBand[::, ::, ' + str(0) + '] == ' + str(c) + ', rasterSCPArrayfunctionBand[::, ::, ' + str(b) + '], cfg.np.nan)' - ee = statNp.replace('array', e) - try: - statPerc = int(statPerc) - ee = ee.replace(cfg.statPerc, str(statPerc)) - except: - pass - try: - if o[ee] is None: - value = cfg.NoDataVal - else: - value = float(o[ee]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - # output rasters - outRaster = zonalRstPath[:-4] + str(c) + '.tif' - oM = [] - oM.append(outRaster) - try: - rDD = cfg.gdalSCP.Open(vrtCheck, cfg.gdalSCP.GA_ReadOnly) - oMR = cfg.utls.createRasterFromReference(rDD, 1, oM, cfg.NoDataVal, 'GTiff', cfg.rasterDataType, 0, None, cfg.rasterCompression, 'LZW', constantValue = value) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - if batch == 'No': - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.uiUtls.removeProgressBar() - return 'No' - # close GDAL rasters - for b in range(0, len(oMR)): - oMR[b] = None - # add raster to layers - rstr = cfg.utls.addRasterLayer(outRaster) - t = str(c) + ' ' + str(value) + str('\n') - l.write(t) - l.close() - rDD = None - # remove temp - try: - cfg.osSCP.remove(tRC) - except: - pass - cfg.uiUtls.updateBar(100) - # remove temp layers - try: - cfg.utls.removeLayerByLayer(reml) - except: - pass - try: - cfg.utls.removeLayerByLayer(remiClass2) - except: - pass - if batch == 'No': - # enable map canvas render - cfg.cnvs.setRenderFlag(True) - cfg.utls.finishSound() - cfg.utls.sendSMTPMessage(None, str(__name__)) - cfg.uiUtls.removeProgressBar() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " zonal stat calculated") - - # classification name - def classificationLayerName(self): - self.clssfctnNm = cfg.ui.classification_name_combo_5.currentText() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "classification name: " + str(self.clssfctnNm)) - - # reference layer name - def referenceLayerName(self): - cfg.referenceLayer3 = cfg.ui.reference_name_combo_3.currentText() - cfg.ui.class_field_comboBox_4.clear() - l = cfg.utls.selectLayerbyName(cfg.referenceLayer3) - try: - if l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer: - f = l.dataProvider().fields() - for i in f: - if str(i.typeName()).lower() != 'string': - cfg.dlg.class_field_combo_4(str(i.name())) - except: - pass - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "reference layer name: " + str(cfg.referenceLayer3)) - - # refresh reference layer name - def refreshReferenceLayer(self): - ls = cfg.qgisCoreSCP.QgsProject.instance().mapLayers().values() - cfg.ui.reference_name_combo_3.clear() - # reference layer name - cfg.referenceLayer3 = None - for l in sorted(ls, key=lambda c: c.name()): - if (l.type() == cfg.qgisCoreSCP.QgsMapLayer.VectorLayer): - if (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.Polygon) or (l.wkbType() == cfg.qgisCoreSCP.QgsWkbTypes.MultiPolygon): - cfg.dlg.reference_layer_combo_3(l.name()) - elif (l.type() == cfg.qgisCoreSCP.QgsMapLayer.RasterLayer): - if l.bandCount() == 1: - cfg.dlg.reference_layer_combo_3(l.name()) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "reference layers refreshed") - - # stat combo - def loadStatisticCombo(self): - cfg.ui.statistic_name_combobox.blockSignals(True) - cfg.ui.statistic_name_combobox.clear() - for i in cfg.statisticList: - cfg.dlg.statistic_name_combo(i[0]) - cfg.ui.statistic_name_combobox.blockSignals(False) - \ No newline at end of file diff --git a/map_pointers/classification_preview_pointer.py b/map_pointers/classification_preview_pointer.py new file mode 100755 index 0000000..4ac8cd2 --- /dev/null +++ b/map_pointers/classification_preview_pointer.py @@ -0,0 +1,46 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from PyQt5.QtCore import Qt, pyqtSignal +from qgis.gui import QgsMapTool + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# noinspection PyArgumentList,PyPep8Naming +class ClassificationPreview(QgsMapTool): + rightClicked = pyqtSignal(['QgsPointXY']) + leftClicked = pyqtSignal(['QgsPointXY']) + + def __init__(self, canvas): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + + def canvasReleaseEvent(self, event): + point = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + # click + if event.button() == Qt.RightButton: + self.rightClicked.emit(point) + else: + self.leftClicked.emit(point) diff --git a/map_pointers/clip_bands_pointer.py b/map_pointers/clip_bands_pointer.py new file mode 100755 index 0000000..a35e2d6 --- /dev/null +++ b/map_pointers/clip_bands_pointer.py @@ -0,0 +1,46 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from PyQt5.QtCore import Qt, pyqtSignal +from qgis.gui import QgsMapTool + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# noinspection PyArgumentList,PyPep8Naming +class ClipBandsPointer(QgsMapTool): + rightClicked = pyqtSignal(['QgsPointXY']) + leftClicked = pyqtSignal(['QgsPointXY']) + + def __init__(self, canvas): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + + def canvasReleaseEvent(self, event): + point = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + # click + if event.button() == Qt.RightButton: + self.rightClicked.emit(point) + else: + self.leftClicked.emit(point) diff --git a/map_pointers/download_products_pointer.py b/map_pointers/download_products_pointer.py new file mode 100755 index 0000000..e29f474 --- /dev/null +++ b/map_pointers/download_products_pointer.py @@ -0,0 +1,46 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from PyQt5.QtCore import Qt, pyqtSignal +from qgis.gui import QgsMapTool + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# noinspection PyArgumentList,PyPep8Naming +class DownloadProductsPointer(QgsMapTool): + rightClicked = pyqtSignal(['QgsPointXY']) + leftClicked = pyqtSignal(['QgsPointXY']) + + def __init__(self, canvas): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + + def canvasReleaseEvent(self, event): + point = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + # click + if event.button() == Qt.RightButton: + self.rightClicked.emit(point) + else: + self.leftClicked.emit(point) diff --git a/map_pointers/manual_roi_pointer.py b/map_pointers/manual_roi_pointer.py new file mode 100755 index 0000000..913ea4e --- /dev/null +++ b/map_pointers/manual_roi_pointer.py @@ -0,0 +1,60 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from PyQt5.QtCore import Qt, pyqtSignal +from qgis.gui import QgsMapTool + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# noinspection PyArgumentList,PyPep8Naming +class ManualROIPointer(QgsMapTool): + rightClicked = pyqtSignal(['QgsPointXY']) + leftClicked = pyqtSignal(['QgsPointXY']) + moved = pyqtSignal(['QgsPointXY']) + + def __init__(self, canvas): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + + def canvasMoveEvent(self, event): + point = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + self.moved.emit(point) + + def canvasReleaseEvent(self, event): + pnt = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + # click + if event.button() == Qt.RightButton: + self.rightClicked.emit(pnt) + else: + self.leftClicked.emit(pnt) + + @staticmethod + def keyPressEvent(event): + if event.key() == Qt.Key_Control: + cfg.ctrl_click = True + elif event.key() == (Qt.Key_Control and Qt.Key_Z): + cfg.scp_dock.delete_last_roi() diff --git a/map_pointers/region_growing_pointer.py b/map_pointers/region_growing_pointer.py new file mode 100755 index 0000000..df74a05 --- /dev/null +++ b/map_pointers/region_growing_pointer.py @@ -0,0 +1,60 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from PyQt5.QtCore import Qt, pyqtSignal +from qgis.gui import QgsMapTool + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +# noinspection PyArgumentList,PyPep8Naming +class RegionGrowingPointer(QgsMapTool): + rightClicked = pyqtSignal(['QgsPointXY']) + leftClicked = pyqtSignal(['QgsPointXY']) + moved = pyqtSignal(['QgsPointXY']) + + def __init__(self, canvas): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + + def canvasMoveEvent(self, event): + point = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + self.moved.emit(point) + + def canvasReleaseEvent(self, event): + pnt = self.canvas.getCoordinateTransform().toMapCoordinates( + event.pos() + ) + # click + if event.button() == Qt.RightButton: + self.rightClicked.emit(pnt) + else: + self.leftClicked.emit(pnt) + + @staticmethod + def keyPressEvent(event): + if event.key() == Qt.Key_Control: + cfg.ctrl_click = True + elif event.key() == (Qt.Key_Control and Qt.Key_Z): + cfg.scp_dock.delete_last_roi() diff --git a/metadata.txt b/metadata.txt old mode 100644 new mode 100755 index 7b671a7..c0cbaf7 --- a/metadata.txt +++ b/metadata.txt @@ -2,8 +2,8 @@ name=Semi-Automatic Classification Plugin qgisMinimumVersion=3.00 description=The Semi-Automatic Classification Plugin (SCP) allows for the supervised classification of remote sensing images, providing tools for the download, the preprocessing and postprocessing of images. -version=7.10.11 -about=Developed by Luca Congedo, the Semi-Automatic Classification Plugin (SCP) allows for the supervised classification of remote sensing images, providing tools for the download, the preprocessing and postprocessing of images. Search and download is available for ASTER, GOES, Landsat, MODIS, Sentinel-1, Sentinel-2, and Sentinel-3 images. Several algorithms are available for the land cover classification. This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib. Some tools require also the installation of SNAP (ESA Sentinel Application Platform). For more information please visit https://fromgistors.blogspot.com . +version=8.0.0 +about=Developed by Luca Congedo, the Semi-Automatic Classification Plugin (SCP) allows for the supervised classification of remote sensing images, providing tools for the download, the preprocessing and postprocessing of images. Search and download is available for Landsat, Sentinel-2 images. Several algorithms are available for the land cover classification. This plugin requires the installation of Remotior Sensus, GDAL, OGR, Numpy, SciPy, and Matplotlib. For more information please visit https://fromgistors.blogspot.com . author=Luca Congedo email=ing.congedoluca@gmail.com @@ -11,570 +11,51 @@ category=Raster icon=semiautomaticclassificationplugin.png -; start of optional metadata changelog= - 7.10.11 - -fixed QgsRubberBand issue with new QGIS versions - - 7.10.10 - -fixed issue with file name in Clip multiple raster - -fixed French translation issue - - 7.10.9 - -fixed issue with ROI transparency - - 7.10.8 - -fixed issue with raster creation - - 7.10.7 - -preprocessing of Landsat and Sentinel-2 bands are now converted to Float32 to prevent issues related to postprocessing - -changed the option GDAL_NUM_THREADS to avoid triggering Georeferencer plugin issue - -other bug fixes - - 7.10.6 - -updated the Landsat tool for preprocessing Landsat 9 data - -fixed issue for TOA conversion of Landsat 5 and 7 data - - 7.10.5 - -fixed regression raster name in Cross classification - -fixed issue with LCS classification - - 7.10.4 - -in Cross classification added option for linear regression and creating raster from regression coefficients - -updated Batch for Cross classification - - 7.10.3 - -fixed Batch process_settings and other minor fixes - - 7.10.2 - -when QGIS project is loaded a new function allows for automatically running a file batch.txt, if found in the plugin directory, as batch command - -batch added function send_notification for sending a smtp message during processes - - 7.10.1 - -in Band calc added option NoData mask, if checked, every NoData pixel in input will be NoData pixel in output - -fixed issue with classification and calculations - -fixed edit raster with scale and offset - - 7.10.0 - -added option to Download products for downloading as virtual raster the portion of the image defined with search coordinates (for Landsat and Sentinel-2) - -Stack raster bands can now export virtual raster if output extension is .vrt - -in Batch the function create_bandset if the option date is 'auto' it tries to get the date of the image from the directory name - -in Band set list added button to sort Band sets by date if defined - -fixed Scatter plot - -fixed Band combination - -small fixes to Clip multiple rasters - - 7.9.10 - -added Batch function process_settings to set the number of threads and RAM value in MB - -fixed Band combination and Band calc NoData issue - -fixed functions of Batch - - 7.9.9 - -added linear regression to Cross raster output - -fixed Zonal Stat Raster percentile - - 7.9.8 - -fixed Sentinel-2 previews in Download products - - 7.9.7 - -updated references - - 7.9.6 - -fixed Sentinel-1 preprocessing reprojection issue - -fixed clustering ISODATA issue - - 7.9.5 - -fixed Landsat processing error - - 7.9.4 - -fixed accuracy overall metrics - -various bugfixing - - 7.9.3 - -fixed clip multiple rasters - - 7.9.2 - -fixed scale value 0.0001 for Landsat and Sentinel-2 - - 7.9.1 - -fixed Landsat 8 band 1 band set - - 7.9.0 - -preprocessing of Landsat and Sentinel-2 bands are now converted to UInt16 with scale 0.00001 to reduce file size - -added Landsat 8 band 1 processing - -fixed clip multiple rasters by coordinates - -fixed Classification report for degree unit - - 7.8.36 - -fixed multiple ROI creation multiprocess - - 7.8.35 - -fixed Classification and clustering issue with multiprocess - - 7.8.34 - -fixed Band combination NoData issue - - 7.8.33 - -other fixes to issue importing GDAL with Python > 3.8 - - 7.8.32 - -fixed issue importing GDAL with Python > 3.8 - - 7.8.31 - -tool Neighbor pixels fixed nodata value - - 7.8.30 - -improved Band combination - - 7.8.29 - -improved Band combination - - 7.8.28 - -fixed virtual raster NoData issue - - 7.8.27 - -fixed ASTER preprocessing regression - - 7.8.26 - -added setting option for additional Python path of dependencies - -fixed ASTER conversion for thermal bands only list - -fixed virtual raster relative path - -fixed virtual raster warp scale and offset - - 7.8.25 - -fixed regression of several tools - - 7.8.24 - -fixed ROI creation issue - -in Band calc added option of selection calculation data type - -improved Band combination and cross classification tools - - 7.8.23 - -fixed scale and offset reprojecting with gdalwarp - - 7.8.22 - -optimized cross classification - -optimized band combination - -optimized classification erosion - -fixed regression in Accuracy - -fixed vector to raster compression - -in several tools allow different projections of input - - 7.8.21 - -fixed regression in Accuracy and Land cover change - - 7.8.20 - -improved Cross classification and Band combination performance - - 7.8.19 - -in Classification dilatation replaced pixel connection option with circle - -improved Classification dilatation performance - -add Batch variable !temp_dir! for temporary directory of SPC - - 7.8.18 - -improved peformance in tool Neigbor pixels - - 7.8.17 - -in tool Neigbor pixels added option for circular matrix (default square) - -fixed projection issues in several tools - -fixed search of Sentinel products if not available - - 7.8.16 - -minor fixes to messagebar and batch checking - - 7.8.15 - -fixed write raster function for data type - - 7.8.14 - -fixed Batch variables with spaces - - 7.8.13 - -fixed Band calc check expression for spaces - -fixed Mosaic tool batch - -added output directory creation for several tools - -added Batch option to remove all the band sets - -added Batch option to unload bands from QGIS when removing band from band sets or removing band sets - - 7.8.12 - -in Mosaic tool added option for virtual raster output - - 7.8.11 - -fixed clip multiple raster issue - - 7.8.10 - -fixed minor issue layer id - - 7.8.9 - -improved division of raster sections for multiprocessing - - 7.8.8 - -fixed clip multiple raster for multiband rasters - -fixed band calc for multiband rasters - - 7.8.7 - -improved the multiprocessing performance - -added option for virtual raster output in several tools - -improved reprojection if required in several tools - - 7.8.6 - -fixed issue band combination - -fixed issue cross classification - -updated smtp to use TLS on port 587 - - 7.8.5 - -fixed issue with conversion to raster - - 7.8.4 - -fixed scale in raster output - - 7.8.3 - -fixed reclassification output format - - 7.8.2 - -zonal stat raster also saves a csv with values - - 7.8.1 - -fixed issue with QGIS 3.18 while removing training input during project save - -fixed issue with refreshLayerLegend - -fixed issue with Random Forest using classification file - - 7.8.0 - -new tool for analysis of neighbor pixel with convolution matrix - -improved performance with multiprocessing calculations - -fixed conversion to vector - - 7.7.1 - -fixed issue importing shapefile - -fixed scatter plot issue - - 7.7.0 - -added undo and redo buttons in SCP Dock to undo the last 10 changes in the ROI list - -added alternative search for Sentinel-2 image - -the backup file of training input is created when the QGIS is closed - -fixed row height in tables - -fixed Sentinel-1 preprocessing issue - - 7.6.3 - -fixed regression in managing scp file - - 7.6.2 - -fixed check crs - -several bug fixes - - 7.6.1 - -fixed issue random forest - -USGS library ordered alphabetically - -improved import signatures - - 7.6.0 - -training input vector is saved as gpkg - -export signatures as gpkg - -better compatibility with custom projections - -general use of gpkg - -fixed issue in DOS1 correction - -attempt to fix subprocess issue in Windows - - 7.5.7 - -fixed subprocess issues in Windows for random forest, Sentinel-1 preprocessing, and other processes - - 7.5.6 - -in tab Reclassification added buttons for importing and exporting reclassification table - -fixed issue with custom variable name in reclass multiprocess - - 7.5.5 - -added settings for checking subprocess SNAP - -fixed issue Band calc refresh list - - 7.5.4 - -fixed Sentinel-1 preprocessing - - 7.5.3 - -improved Sentinel-1 and Sentinel-3 download settings - -fixed update issue - - 7.5.2 - -improved Sentinel-2 download for using primarly Google APIs for downloading bands - - 7.5.1 - -improved context menu in SCP dock - - 7.5.0 - -added context menu in SCP dock - -fixed issue with SCP dock editing of macroclasses - -fixed issue with classification band set - -fixed issue with autosave ROI - - 7.4.10 - -added option for extent as reference in tab vector to raster - -fixed mosaic issue - - 7.4.9 - -Landsat preprocessing fixed compatibility with Collection 2 products - - 7.4.8 - -fixed settings - - 7.4.7 - -fixed settings - - 7.4.6 - -fixed settings - - 7.4.5 - -fixed settings - - 7.4.4 - -fixed settings - - 7.4.3 - -fixed settings - - 7.4.2 - -fixed settings - - 7.4.1 - -fixed settings - - 7.4.0 - -in Settings added line edit for paths of Python executable and GDAL directory - -unit test for Mac OS - - 7.3.7 - -fixed issue with multiple ROI calculation - -fixed write raster scale in band calc - - 7.3.6 - -fixed write raster scale in band calc - -attempt to fix MacOS multiprocessing issue - - 7.3.5 - -attempt to fix MacOS multiprocessing issue - - 7.3.4 - -insert html in band calc for allowing multiple lines with br - -attempt to fix MacOS multiprocessing issue - - 7.3.3 - -fixed classification sieve issue with path containing special characters - - 7.3.2 - -fixed multiple ROI creation issue with coordinate reference system - - 7.3.1 - -fixed vegetation USGS library - - 7.3.0 - -updated Download USGS spectral library tool for USGS spectral library version 7 - -window and splitter sizes are saved in registry - - 7.2.7 - -fixed classification to vector - -set window size - - 7.2.6 - -fixed issue with random point creation - - 7.2.5 - -fixed issue with clustering isodata - - 7.2.4 - -fixed issue with clustering isodata - - 7.2.3 - -fixed issue with clustering with nan values - - 7.2.2 - -fixed classification mask reset box - - 7.2.1 - -fixed class signature memory issue - -fixed issue with DOS1 calculation - -fixed issue with clustering of multiband raster - - 7.2.0 - -converted to multiprocess the tool classification dilation - -converted to multiprocess the tool classification erosion - -converted to multiprocess the tool cloud mask - -converted to multiprocess the tool class signature - -converted to multiprocess the tool mosaic - -converted to multiprocess the tool PCA - -converted to multiprocess the tool scatter plot - -in Band calc improved the variable bandset{LIST_OF_BANDSETS}bNUMBER_OF_BANDSET e.g. sum(bandset{1,2,3}b1) for the sum of the first bands of the bandsets 1, 2, and 3, or similarly using ranges e.g. sum(bandset{1:3}b1) or list of ranges e.g. sum(bandset{1:2, 3:4}b1) - -fixed issue of tool zonal stat raster - -fixed issue of nan values in spectral plot - -fixed issue related to classification to vectory symbology - -fixed land cover change and cross classification reports - - 7.1.1 - -added splitter to several tabs of the main interface and plots - - 7.1.0 - -added import of gpkg - -fixed issue with maximum likelihood threshold - -fixed issue with clip multiple raster name - -fixed issue with stratified point creation - - 7.0.15 - -fixed regression in clustering tab - - 7.0.14 - -fixed issue with scatter plot of multiband raster - -fixed issue changing color of ROIs - -fixed regression clip multiple rasters - - 7.0.13 - -fixed regression with band set - - 7.0.12 - -fixed issue with Random Forest - -fixed issue #130 with band set and band calc expressions - - 7.0.11 - -fixed issue with class signature tool - -fixed issue with news on startup - -fixed issue with classification mask - - 7.0.10 - -fixed issue with localization of algorithm names - - 7.0.9 - -updated clustering to multiprocess - - 7.0.8 - -fixed an issue with clustering on Windows - - 7.0.7 - -fixed an issue with clustering - -improvements to French translation thanks to Antoine Denis - - 7.0.6 - -fixed an issue with clip multiple rasters - -fixed an issue with spectral plot of signatures - - 7.0.5 - -fixed an issue with menu and localization - -improvements to French translation thanks to Antoine Denis - - 7.0.4 - -fixed an issue with isodata clustering - - 7.0.3 - -fixed an issue with classification tab and thresholds - -accuracy and land cover change are multiprocess - - 7.0.2 - -fixed an issue with accuracy and land cover change tabs - - 7.0.1 - -fixed an issue in classification tab - - 7.0.0 - New version with several improvements - - New tools - - Band set list tab for managing band sets and double click to define active band set and functions to import export band sets and button to display RGB composite - - Random forest tab for classifying the band set using training input with Random Forest (ESA SNAP required) - - Sentinel-1 tab for processing Sentinel-1 GRD products polarizations VH and VV (ESA SNAP required) based on the preprocessing steps in https://developers.google.com/earth-engine/sentinel1 - - GOES tab for processing GOES 16 and GOES 17 images - - Zonal stat raster tab for calculating raster statistic in zones defined by a reference vector or raster and for each zone value creating rasters filled woth the corresponding output statistic, named as outputnameZoneValue (e.g. output1, output2, output3) - - Classification tab that replaces the classification dock - - Reproject raster bands that allows for reprojecting a band set to a new projection with the option of using a reference raster for alignment and extent or setting the EPSG value and pixel resolution manually; methods of resampling: nearest_neighbour, average, sum, maximum, minimum, mode, median, first_quartile, third_quartile - - Implemented parallel processing for several tools - - Classification - - Band calc - - ASTER preprocessing - - GOES preprocessing - - Landsat preprocessing - - MODIS preprocessing - - Sentinel-2 preprocessing - - Sentinel-3 preprocessing - - Clip multiple rasters - - Zonal stat raster - - Reclassification - - Cross classification - - Band combination - - Classification to vector - - ROI creation and signature calculation - - Spectral distance of band sets - - Main interface window - - Renewed interface with tree view menu, a filter for searching tools, and a new tab Help for displaying the guide of tools - - SCP Dock - - ROI signature list structured as tree of macroclasses - - added table filter for ROIs - - new button for removing training input - - Classification moved to main interface - - Tab Band calc - - added the iteration of calculations over band sets entering in the first line forbandsets e.g. forbandsets[1:3] for iterating over a range or forbandsets[1,2,3] for iterating selected band sets; it is possible to enter a string after ] to filter names of first band in band set (e.g. forbandsets[1,2,3]RT) - - added the iteration of calculations over dates (format yyyy-mm-dd) of band sets entering in the first line forbsdates e.g. forbsdates[2020-01-01:2020-03-30] for iterating over a range or forbsdates[2020-02-01,2020-03-11,2020-04-21] for iterating selected dates, also list of ranges such as forbsdates[2010-01-01:2010-03-30, 2010-08-01:2010-08-31, 2010-10-01:2010-12-31]; it is possible to enter a string after ] to filter names of first band in band set - - added the iteration of bands in a band set or a range of band sets entering in the first line forbandsinbandset (e.g. forbandsinbandset[1] for iterating over bands in the first band set) and in the following expression the variable #BAND# to refer to the iterated band (e.g. where("#BAND#">1, 1, 2) @"#BAND#") - - added the possibility to use the output name of calculation as variable for following calculations - - added the possibility to add the calculation result to a band set using the number in the output name such as @output1 or to current band set with # such as @output# - - added the possibility to set the output path defining the output name with this structure @path@name, also with the variable #BANDSET# such as @#BANDSET#@name to save the calculation in the directory containing the first band of the current band set. It is recommended to avoid the use of characters # and @ in the raster name - - added the possibility to create temporary output defining the output path (i.e. temp) and output name with this structure @temp@name - - added the option to create virtual raster output (i.e. .vrt files) made of .tif files from parallel processing - - added the variable "bandset#b*" for using all the bands of active band set in expressions such as np.max("bandset#b*") - - added the variable "bandsetNb*" for using all the bands of band set N in expressions such as np.max("bandset1b*") - - added the variable "bandsetNbL" for referring to band set N and Band L in expressions such as "bandset1b1" - - added the variable "bandset*bL" for using the L band of all the band sets in expressions such as np.max("bandset*b1") - - added the variable "bandset{date}bL" for using the L band of all the band sets in the list of dates or range of dates e.g. median("bandset{2019-01-01,2019-03-30}b1") - - added table filter for band names - - added the possibility to enter !function! followed by an expression of Batch to execute a function using raster names (also previous output names) in the command and the variables !directory! and !file! to refer to the output directory (defined after Run) and relative output file name (defined with @ after the command) respectively e.g. !function! stack_raster_bands;band_set : 1;output_raster_path : '!directory!' ; it is required to use section character $ instead of apostrophe ' and !! instead of ; for functions ' e.g. !function! add_raster!!input_raster_name : $#NIR#$!!band_set : 1 - - added the option to select output raster type as Float32, Int32, Int16, UInt32, UInt16, Byte - - added settings for output nodata value - - added settings for scale and offset values directly in the output .tif file - - the option Input NoData as value allows for using NoData values as regular values - - the option Use NoData value allows for defining a regular value to be used as NoData during calculation - - Tab Download products - - the Sentinel-2 search works also without search coordinates if a string is entered in Advanced search (e.g. 33TTG) - - Sentinel-2 level 2A can be filtered entering S2A_MSIL2A* in Advanced search - - Sentinel-2 are downloaded also from Google public service https://storage.googleapis.com/gcp-public-data-sentinel-2 - - added table filter for names - - added search and download of Sentinel-1 GRD products - - added search and download of GOES 16 and GOES 17 products downloaded from Amazon Web Services https://registry.opendata.aws/noaa-goes/ - - Tab Preprocessing Landsat - - tha panchromatic band is preprocessed only if pansharpening is checked - - Tab Preprocessing Sentinel-2 - - added checkbox for processing also bands 1, 9, 10 - - if Add bands in a new band set is checked an existing empty band set is used first - - Tab Band set - - added the date field (optional) to store image acquisition date (format yyyy-mm-dd) that can be used for expressions in Band calc - - added table filter for band names - - added Sentinel-2 list with all the bands - - Tab Batch - - added function qgis_processing to access QGIS Processing tools (e.g. qgis_processing;command : 'grass7:v.dissolve';parameters : 'input': 'input_path', 'column': 'cat','output': 'output_path') - - added function !for_directory_in! to iterate commands for all the directories in a directory path (e.g. !for_directory_in!;'directoryPath') with the variables !directory_name! to use the current directory name and !directory! to use the current directory path. The commands are performed in batch until the command !end_for_directory! . Optionally a directory level and a name filter can be set (e.g. !for_directory_in!;'directoryPath';2;'name'). Multiple name filters can be set with | (e.g. !for_directory_in!;'directoryPath';2;'name1|name2'). It is possible to filter by date if the name ends with the date format yyyy-mm-dd using a range (e.g. 2020-01-01:2020-03-31) - - added function !for_file_in!;directoryPath to iterate commands for all the files (calling !file! in a command) in a directoryPath until !end_for_file! . Optionally a directory level and a file filter (e.g. !for_file_in!;'directoryPath';0;'jpg'). Multiple name filters can be set with | (e.g. !for_file_in!;'directoryPath';0;'jpg|tif'). It is possible to filter by date if the name ends with the date format yyyy-mm-dd using a range (e.g. 2020-01-01:2020-03-31). Also !file_directory! can be used to refer to the parent directory of the file - - added function '!start_for_band_set!';bandsetNumber to iterate commands for all the band sets (calling '!band_set!' in a command) until !end_for_band_set! . It is possible to enter a list of numbers (separated by commas), a range separated by colon, or a list of ranges (e.g. !start_for_band_set!;'2:3' add_new_bandset;band_set : !band_set! !end_for_band_set! - - added the function !temp_raster_#! (replacing # with a number or string e.g. !temp_raster_1!) to create a temporary raster to be used with other functions such as band_calc;expression : '"raster1"';output_raster_path : '!temp_raster_1!'. !temp_raster_1! replaces the path to the raster and temp_raster_1 is the actual name of the raster - - added the possibility to create custom variables entering a line such as !customName! = value (value can be either number or text), for instance !number! = 20, this variable !number! will be replaced in the following parts of the batch script - - added the function remove_band_from_bandset to remove bands from a band set (e.g. remove_band_from_bandset;band_set : 1;band_list : '1, 2') - - the function to create band set accepts a directory and a file name filter as raster_path_list option (e.g. '/dir, tif') - - the function to create band set accepts the satellite name as center_wavelength option to set the band wavelength center - - the function add_raster allows to add the raster to an existing band set (band_set) and optionally set the wavelength (center_wavelength) - - if using Band calc function, it is required to use section character $ instead of apostrophe ' and !! instead of ; for functions expressions - - Tab Reclassification - - added new button Incremental new value for calculating a new unique value for every old value - - Tab Settings - - added option to create RGB composite of band set when a project is loaded - - added option for using multiple CPU threads (it is recommended to set a value lower than the number of available CPUs) + 8.0.0 + -new version based on Remotior Sensus (i.e. a Python library developed for remote sensing) as main processing framework + -the whole code has been substantially rewritten and improved + -improved the interface for managing Band sets, which support dates, and multiple band sets can be directly managed + -band sets, and therefore all the tools using band sets, no longer require the bands to be previously loaded in QGIS, therefore bands can be loaded directly selecting the files + -training input has been improved to be integrated with Remotior Sensus' management of spectral signatures + -download of products relies on Remotior Sensus tools, which allow for the moment the download of Copernicus Sentinel-2 and NASA Harmonized Landsat and Sentinel-2 data + -available preprocessing tools: + --"Clip raster bands" for creating image subsets + --new unified interface named "Image conversion" allows for image preprocessing conversion of Landsat and Sentinel-2 images + --"Masking bands" for masking images based on raster values or vector + --"Reproject raster bands" for resampling and reprojecting images + --"Split raster bands" for splitting multiband images + --"Stack raster bands" for creating a multiband raster + --"Vector to raster" for rasterization + -available processing tools: + --unified interface for "Classification" which includes Random Forest, Multilayer Perceptron, Support Vector Machine + --scikit-learn and PyTorch are used as machine learning libraries + --"Classification" tool allows for training the classifier, optionally saving the classifier for later use, and of course performing the classification + --"Combination" for calculating band combinations of values + --"Dilation" for calculating band dilation of values based on desired size + --"Erosion" for calculating band erosion of values based on desired size + --"Sieve" for filtering isolated pixel values + --"Neighbor" for calculating functions on pixels considering a desired neighbor distance + --"PCA" for Principal Component Analysis + -available postprocessing tools: + --"Accuracy" for calculating classification accuracy based on reference data + --"Classification report" for calculating area statistics of raster classes + --"Classification to vector" for converting a raster band to vector + --"Cross classification" for crossing two raster bands and calculate the combination of values or linear regression + --"Reclassification" for calculating new values for raster classes + -a few tools, such as clustering and edit raster have been removed and will be reintroduced when available in Remotior Sensus + -"Band calc" interface has been improved adding several options that are available through the Remotior Sensus library, such as the optional definition of extent coordinates for limiting the calculation, or the output pixel size + -new tab "Script" is linked to most of the tools allowing for the display of the Python code to run the equivalent commands in Remotior Sensus (pasting the code in a Python shell), which can be useful to automate tasks and creating scripts + -integration of several tools in the QGIS Processing, which allows for creating models and workflows between the several libraries available in QGIS experimental=False deprecated=False -tags = Raster, Classification, Land Cover, Remote Sensing, Analysis, ASTER, GOES, Landsat, Sentinel, Supervised classification, Spectral signature, Mask, Clip, Accuracy, Landscape, Copernicus, Random Forest, SNAP, Processing +tags = Raster, Classification, Land Cover, Remote Sensing, Analysis, Landsat, Sentinel, Supervised classification, Spectral signature, Mask, Clip, Accuracy, Landscape, Copernicus, Random Forest, Processing, Remotior Sensus homepage=https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html tracker=https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/issues repository=https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin + +hasProcessingProvider=yes diff --git a/modules/modules.py b/modules/modules.py deleted file mode 100644 index 917b2a1..0000000 --- a/modules/modules.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' -import os -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Modules: - - def __init__(self): - pass - - # load - def loading(self): - dirF = os.path.dirname(str(__file__)) - for r, d, f in cfg.osSCP.walk(dirF): - for x in f: - if x.endswith('.py') and str(str(__name__).split('.')[1]) not in x: - xL = 'from .' + x.split('.')[0] +' import ' + x.split('.')[0] - exec(xL) - exec('cfg.' + x.split('.')[0] +' = ' + x.split('.')[0] + '()') - exec('cfg.' + x.split('.')[0] +' .loading()') \ No newline at end of file diff --git a/modules/qgisprocessing.py b/modules/qgisprocessing.py deleted file mode 100644 index b7c44d7..0000000 --- a/modules/qgisprocessing.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class qgisprocessing: - - def __init__(self): - pass - - # load service - def loading(self): - cfg.pluginPathProcessing = cfg.qgisCoreSCP.QgsApplication.pkgDataPath() + '/python/plugins' - cfg.prefixPathProcessing = cfg.qgisCoreSCP.QgsApplication.prefixPath() - # replace funtions - cfg.functionNames.append([['QGIS Processing']]) - cfg.functionNames.append([['qgis_processing', 'cfg.qgisprocessing.performProcessingAlg', 'cfg.qgisprocessing.runProcessingAlg',['command : \'\'', 'parameters : \'\'', 'load_results : 1']]]) - - - # run algorithm - def runProcessingAlg(self, command, parameters, loadResults = 'Yes'): - if ' {' not in parameters: - parameters = ' {' + parameters + '}' - parameters = eval(parameters) - cfg.uiUtls.updateBar(10, command) - # pool - cfg.pool = cfg.poolSCP(processes=1) - p = 0 - results = [] - c = cfg.pool.apply_async(self.processingThread, args=(cfg.pluginPathProcessing, cfg.prefixPathProcessing, command, parameters)) - results.append([c, p]) - cfg.QtWidgetsSCP.qApp.processEvents() - while cfg.actionCheck == 'Yes': - pR = [] - for r in results: - pR.append(r[0].ready()) - if all(pR): - break - cfg.timeSCP.sleep(1) - try: - dots = dots + '.' - if len(dots) > 3: - dots = '' - except: - dots = '' - cfg.uiUtls.updateBar('', command + dots) - cfg.QtWidgetsSCP.qApp.processEvents() - if cfg.actionCheck != 'Yes': - cfg.mx.msgWar33() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'error: cancel ') - return 'No' - for r in results: - if cfg.actionCheck == 'Yes': - res = r[0].get() - if len(str(res[1])) > 0: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'Error proc '+ str(p) + '-' + str(res[1])) - cfg.mx.msgBarError(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Error'), 'Processing: ' + str(res[1])) - return 'No' - else: - cfg.pool.close() - cfg.pool.terminate() - return 'No' - cfg.pool.close() - cfg.pool.terminate() - result = res[0] - if loadResults == 'Yes': - outR = result['OUTPUT'] - try: - r = cfg.utls.addRasterLayer(outR) - except: - try: - vl = cfg.utls.addVectorLayer(outR) - cfg.utls.addLayerToMap(vl) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.uiUtls.updateBar(100, command) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' result ' + str(result)) - return result - - # processing thread - def processingThread(self, pluginPath, prefixPath, command, parameters): - import sys - from qgis.core import QgsProcessingRegistry - from qgis.analysis import QgsNativeAlgorithms - from qgis.core import QgsApplication - QgsApplication.setPrefixPath(prefixPath, True) - qgs = QgsApplication([], False) - qgs.initQgis() - sys.path.append(pluginPath) - from processing.core.Processing import Processing - Processing.initialize() - QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) - import processing - try: - from processing.algs.grass7.Grass7Utils import Grass7Utils - Grass7Utils.checkGrassIsInstalled() - except: - pass - try: - result = processing.run(command, parameters) - return result, '' - except Exception as err: - return '', str(err) - - # perform algorithm - def performProcessingAlg(self, paramList): - parameters = [] - loadResults = '\'Yes\'' - for p in paramList: - pSplit = p.split(':', 1) - pName = pSplit[0].lower().replace(' ', '') - if pName == 'command': - pSplitX = pSplit[1] - if len(pSplitX) > 0: - command = pSplit[1] - else: - return 'No', 'command' - # load results (1 'Yes' or 0 'No') - elif pName == 'load_results': - if pSplit[1].replace(' ', '') == '1': - loadResults = '\'Yes\'' - elif pSplit[1].replace(' ', '') == '0': - loadResults = '\'No\'' - else: - return 'No', pName - elif pName == 'parameters': - pSplitX = pSplit[1] - if len(pSplitX) > 0: - param = pSplitX - try: - eval(param) - except: - param = '"' + pSplitX + '"' - try: - eval(param) - except: - param = '\'' + pSplitX + '\'' - try: - eval(param) - except: - return 'No', 'parameters' - else: - return 'No', 'parameters' - else: - if len(pName.strip()) > 0: - return 'No', pName - # append parameters - try: - parameters.append(command) - parameters.append(param) - parameters.append(loadResults) - except: - return 'No', 'qgis_processing' - return 'Yes', parameters - \ No newline at end of file diff --git a/modules/snap.py b/modules/snap.py deleted file mode 100644 index c4202f4..0000000 --- a/modules/snap.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class snap: - - def __init__(self): - pass - - # load service - def loading(self): - # registry - cfg.regSNAPGPT= 'SemiAutomaticClassificationPlugin/SNAPGPT' - cfg.SNAPGPT = '' - cfg.SNAPGPT = cfg.utls.readRegistryKeys(cfg.regSNAPGPT, cfg.SNAPGPT) - # set gpt - cfg.ui.SNAP_GPT_lineEdit.setText(cfg.SNAPGPT) - cfg.ui.SNAP_GPT_lineEdit.editingFinished.connect(self.rememberSNAPGPT) - - # root - def rememberSNAPGPT(self): - cfg.SNAPGPT = cfg.ui.SNAP_GPT_lineEdit.text() - if cfg.osSCP.path.isfile(cfg.SNAPGPT): - cfg.ui.SNAP_GPT_lineEdit.setStyleSheet('color : black') - else: - cfg.ui.SNAP_GPT_lineEdit.setStyleSheet('color : red') - cfg.utls.setQGISRegSetting(cfg.regSNAPGPT, cfg.SNAPGPT) - - # root - def findSNAPGPT(self): - if cfg.sysSCPNm == 'Windows': - gpt = 'C:/snap/bin/gpt.exe' - if not cfg.osSCP.path.isfile(gpt): - gpt = 'C:/Program Files/snap/bin/gpt.exe' - else: - gpt = '/usr/local/snap/bin/gpt' - if cfg.osSCP.path.isfile(gpt): - cfg.SNAPGPT = gpt - cfg.ui.SNAP_GPT_lineEdit.setText(cfg.SNAPGPT) - cfg.utls.setQGISRegSetting(cfg.regSNAPGPT, cfg.SNAPGPT) - return 'Yes' - else: - cfg.mx.msgWar31() - return 'No' \ No newline at end of file diff --git a/modules/snap/S1_process.xml b/modules/snap/S1_process.xml deleted file mode 100644 index 44591f0..0000000 --- a/modules/snap/S1_process.xml +++ /dev/null @@ -1,143 +0,0 @@ - - 1.0 - - Read - - - $input - SENTINEL-1 - - - - Apply-Orbit-File - - - - - Sentinel Restituted (Auto Download) - 3 - true - - - - Remove-GRD-Border-Noise - - - - - $polarization - 500 - 0.5 - - - - ThermalNoiseRemoval - - - - - $polarization - true - false - - - - Calibration - - - - - - Product Auxiliary File - - false - false - false - false - $polarization - true - false - false - - - - Terrain-Correction - - - - - - SRTM 3Sec - - 0.0 - true - BILINEAR_INTERPOLATION - BILINEAR_INTERPOLATION - 10.0 - 8.983152841195215E-5 - GEOGCS["WGS84(DD)", - DATUM["WGS84", - SPHEROID["WGS84", 6378137.0, 298.257223563]], - PRIMEM["Greenwich", 0.0], - UNIT["degree", 0.017453292519943295], - AXIS["Geodetic longitude", EAST], - AXIS["Geodetic latitude", NORTH]] - false - 0.0 - 0.0 - true - false - false - false - false - false - true - false - false - false - false - false - Use projected local incidence angle from DEM - Use projected local incidence angle from DEM - Latest Auxiliary File - - - - - Write - - - - - $output - GeoTIFF-BigTIFF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/snap/S1_process_VVVH.xml b/modules/snap/S1_process_VVVH.xml deleted file mode 100644 index 5170b96..0000000 --- a/modules/snap/S1_process_VVVH.xml +++ /dev/null @@ -1,249 +0,0 @@ - - 1.0 - - Read - - - $input - SENTINEL-1 - - - - Apply-Orbit-File - - - - - Sentinel Restituted (Auto Download) - 3 - true - - - - Remove-GRD-Border-Noise - - - - - VV - 500 - 0.5 - - - - ThermalNoiseRemoval - - - - - VV - true - false - - - - Calibration - - - - - - Product Auxiliary File - - false - false - false - false - VV - true - false - false - - - - Terrain-Correction - - - - - Sigma0_VV - SRTM 3Sec - - 0.0 - true - BILINEAR_INTERPOLATION - BILINEAR_INTERPOLATION - 10.0 - 8.983152841195215E-5 - GEOGCS["WGS84(DD)", - DATUM["WGS84", - SPHEROID["WGS84", 6378137.0, 298.257223563]], - PRIMEM["Greenwich", 0.0], - UNIT["degree", 0.017453292519943295], - AXIS["Geodetic longitude", EAST], - AXIS["Geodetic latitude", NORTH]] - false - 0.0 - 0.0 - true - false - false - false - false - false - true - false - false - false - false - false - Use projected local incidence angle from DEM - Use projected local incidence angle from DEM - Latest Auxiliary File - - - - - Write - - - - - $outputVV - GeoTIFF-BigTIFF - - - - Remove-GRD-Border-Noise - - - - - VH - 500 - 0.5 - - - - ThermalNoiseRemoval - - - - - VH - true - false - - - - Calibration - - - - - - Product Auxiliary File - - false - false - false - false - - true - false - false - - - - Terrain-Correction - - - - - Sigma0_VH - SRTM 3Sec - - 0.0 - true - BILINEAR_INTERPOLATION - BILINEAR_INTERPOLATION - 10.0 - 8.983152841195215E-5 - GEOGCS["WGS84(DD)", - DATUM["WGS84", - SPHEROID["WGS84", 6378137.0, 298.257223563]], - PRIMEM["Greenwich", 0.0], - UNIT["degree", 0.017453292519943295], - AXIS["Geodetic longitude", EAST], - AXIS["Geodetic latitude", NORTH]] - false - 0.0 - 0.0 - true - false - false - false - false - false - true - false - false - false - false - false - Use projected local incidence angle from DEM - Use projected local incidence angle from DEM - Latest Auxiliary File - - - - - Write - - - - - $outputVH - GeoTIFF-BigTIFF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/qgis_processing/accuracy.py b/qgis_processing/accuracy.py new file mode 100644 index 0000000..6502804 --- /dev/null +++ b/qgis_processing/accuracy.py @@ -0,0 +1,158 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProject, QgsProcessingParameterRasterLayer, + QgsProcessingParameterVectorLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class Accuracy(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'accuracy' + + @staticmethod + def displayName(): + return 'Accuracy' + + @staticmethod + def shortDescription(): + return ( + 'Perform the accuracy assessment. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER_2, + description=self.translate('Reference raster'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterVectorLayer( + name=self.INPUT_VECTOR, + description=self.translate('Reference vector'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Vector field'), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_accuracy_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return Accuracy() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + root = QgsProject.instance().layerTreeRoot() + if rs.files_directories.is_file(classification) is False: + layer_x = root.findLayer(classification) + classification = layer_x.layer().source() + reference = self.parameterAsFile( + parameters, self.INPUT_RASTER_2, context + ) + if reference is None: + reference = self.parameterAsFile( + parameters, self.INPUT_VECTOR, context + ) + else: + if rs.files_directories.is_file(reference) is False: + layer_x = root.findLayer(reference) + reference = layer_x.layer().source() + field = self.parameterAsString(parameters, self.TEXT, context) + if len(field) == 0: + field = None + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + output = rs.cross_classification( + classification_path=classification, reference_path=reference, + output_path=output_path, vector_field=field, nodata_value=nodata, + error_matrix=True + ) + if output.check: + paths = output.paths + layer = QgsRasterLayer(paths[0], Path(paths[0]).name) + QgsProject.instance().addMapLayer(layer) + self.feedback.pushInfo('Output table: ' + str(paths[1])) + + return {self.OUTPUT: output_path} diff --git a/qgis_processing/algorithm_template.py b/qgis_processing/algorithm_template.py new file mode 100644 index 0000000..b977169 --- /dev/null +++ b/qgis_processing/algorithm_template.py @@ -0,0 +1,246 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +import multiprocessing +import platform +import sys +from os import path + +from PyQt5.QtWidgets import QApplication +# noinspection PyUnresolvedReferences +from processing.core.ProcessingConfig import ProcessingConfig +from qgis.core import QgsProcessingAlgorithm, Qgis, QgsMessageLog + +try: + import remotior_sensus +except Exception as error: + str(error) + QgsMessageLog.logMessage(str(error), 'remotior_sensus', Qgis.Info) + + +class AlgorithmTemplate(QgsProcessingAlgorithm): + + def __init__(self): + super().__init__() + self.rs = None + self.remaining_time = None + self.feedback = None + self.INPUT_RASTER = 'INPUT_RASTER' + self.INPUT_RASTER_2 = 'INPUT_RASTER_2' + self.INPUT_FILE = 'INPUT_FILE' + self.INPUT_FILE_2 = 'INPUT_FILE_2' + self.INPUT_DIRECTORY = 'INPUT_DIRECTORY' + self.INPUT_VECTOR = 'INPUT_VECTOR' + self.MULTIPLE_LAYERS = 'MULTIPLE_LAYERS' + self.INPUT_LIST = 'INPUT_LIST' + self.INPUT_LIST_2 = 'INPUT_LIST_2' + self.OUTPUT = 'OUTPUT' + self.VALUE = 'VALUE' + self.VALUE_2 = 'VALUE_2' + self.VALUE_3 = 'VALUE_3' + self.VALUE_4 = 'VALUE_4' + self.VALUE_5 = 'VALUE_5' + self.VALUE_6 = 'VALUE_6' + self.VALUE_7 = 'VALUE_7' + self.VALUE_8 = 'VALUE_8' + self.VALUE_9 = 'VALUE_9' + self.TEXT = 'TEXT' + self.TEXT_2 = 'TEXT_2' + self.TEXT_3 = 'TEXT_3' + self.TEXT_4 = 'TEXT_4' + self.TEXT_5 = 'TEXT_5' + self.BOOL = 'BOOL' + self.BOOL_2 = 'BOOL_2' + self.BOOL_3 = 'BOOL_3' + self.BOOL_4 = 'BOOL_4' + self.BOOL_5 = 'BOOL_5' + self.BOOL_6 = 'BOOL_6' + self.BOOL_7 = 'BOOL_7' + self.BOOL_8 = 'BOOL_8' + self.BOOL_9 = 'BOOL_9' + self.BOOL_10 = 'BOOL_10' + self.ENUMERATOR = 'ENUMERATOR' + self.ENUMERATOR_2 = 'ENUMERATOR_2' + self.ENUMERATOR_3 = 'ENUMERATOR_3' + + @staticmethod + def group(): + return 'Remotior Sensus' + + # noinspection PyPep8Naming + @staticmethod + def groupId(): + return 'remotior_sensus' + + # noinspection PyTypeChecker + @staticmethod + def translate(text): + return QApplication.translate( + 'semiautomaticclassificationplugin', + text + ) + + def start_remotior_sensus_session(self): + try: + multiprocessing.set_start_method('spawn') + except Exception as err: + str(err) + if platform.system() == 'Windows': + try: + python_path = path.abspath( + path.join(sys.exec_prefix, 'pythonw.exe') + ) + if path.isfile(python_path): + multiprocessing.set_executable(python_path) + else: + # from https://trac.osgeo.org/osgeo4w/ticket/392 + python_path = path.abspath( + path.join(sys.exec_prefix, '../../bin/pythonw.exe') + ) + if path.isfile(python_path): + multiprocessing.set_executable(python_path) + else: + self.feedback.reportError( + 'Error. Python library not found' + ) + except Exception as err: + str(err) + self.feedback.pushDebugInfo( + 'SCP_N_PROCESSES %s' + % ProcessingConfig.getSetting('SCP_N_PROCESSES') + ) + self.feedback.pushDebugInfo( + 'SCP_MEMORY' + str(ProcessingConfig.getSetting('SCP_MEMORY')) + ) + rs = remotior_sensus.Session( + n_processes=int(ProcessingConfig.getSetting('SCP_N_PROCESSES')), + log_level=20, + available_ram=int(ProcessingConfig.getSetting('SCP_MEMORY')), + multiprocess_module=multiprocessing, + progress_callback=self.print_progress, + messages_callback=MessagesCallback(self.feedback) + ) + rs.configurations.logger.log.info = self.feedback.pushConsoleInfo + rs.configurations.logger.log.debug = self.feedback.pushDebugInfo + rs.configurations.logger.log.error = self.feedback.reportError + return rs + + # print progress always in a new line + def print_progress( + self, process=None, step=None, message=None, percentage=None, + elapsed_time=None, previous_step=None, start=None, end=None, + ping=0 + ): + progress_symbols = ['○', '◔', '◑', '◕', '⬤', '⚙'] + colon = [' ', ':'] + if start: + text = ( + '{} [{}%]{}{}:{} {}'.format( + process, str(100).rjust(3, ' '), '', '', + message, progress_symbols[-2] + ) + ) + try: + if self.feedback.isCanceled(): + self.rs.configurations.action = False + self.feedback.setProgressText(text) + except Exception as err: + str(err) + elif end: + self.feedback.setProgressText('') + self.feedback.setProgress(100) + else: + if not percentage and percentage is not None: + percentage = -25 + if elapsed_time is not None: + e_time = (' [elapsed {}min{}sec]'.format( + int(elapsed_time / 60), str( + int( + 60 * ( + (elapsed_time / 60) + - int(elapsed_time / 60)) + ) + ).rjust(2, '0') + )) + if previous_step < step: + try: + remaining_time = ( + (100 - int(step)) * elapsed_time / int(step)) + minutes = int(remaining_time / 60) + seconds = round( + 60 * ((remaining_time / 60) + - int(remaining_time / 60)) + ) + if seconds == 60: + seconds = 0 + minutes += 1 + remaining = ' [remaining {}min{}sec]'.format( + minutes, str(seconds).rjust(2, '0') + ) + self.remaining_time = remaining + except Exception as err: + str(err) + remaining = '' + else: + remaining = self.remaining_time + else: + e_time = '' + remaining = '' + try: + text = ( + '{} [{}%]{}{}{}{} {}'.format( + process, str(step).rjust(3, ' '), e_time, remaining, + colon[ping], + message, progress_symbols[int(percentage / 25)] + ) + ) + except Exception as err: + str(err) + text = (str(process)) + try: + if self.feedback.isCanceled(): + self.rs.configurations.action = False + self.feedback.setProgress(int(step)) + self.feedback.setProgressText(text) + except Exception as err: + str(err) + + +""" Class for messages """ + + +class MessagesCallback: + + def __init__(self, feedback): + self.feedback = feedback + + def warning(self, text): + self.feedback.pushWarning(text) + return text + + def info(self, text): + self.feedback.pushDebugInfo(text) + return text + + def error(self, text): + self.feedback.reportError(text) + return text diff --git a/qgis_processing/band_calc.py b/qgis_processing/band_calc.py new file mode 100644 index 0000000..b58759d --- /dev/null +++ b/qgis_processing/band_calc.py @@ -0,0 +1,337 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFileDestination, QgsProcessingParameterRasterLayer, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandCalc(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_calc' + + @staticmethod + def displayName(): + return 'Band calc' + + @staticmethod + def shortDescription(): + return ( + 'Perform calculations between raster bands. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Raster names used in expression, separated by comma, ' + 'in the same order as input list' + ), + defaultValue='b1, b2', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Expression'), + defaultValue='"b1" + "b2"', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Input NoData as value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Use value as NoData'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR, self.translate('Calculation data type'), + ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR_2, self.translate('Output data type'), + ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_2, + description=self.translate('Output NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR_3, self.translate('NoData mask'), + ['False', 'True', 'None'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_3, + description=self.translate('Set scale'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_4, + description=self.translate('Set offset'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Align raster'), + optional=True + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER_2, + description=self.translate('Extent raster'), + optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST_2, + description=self.translate( + 'Coordinates left, top, right, bottom, separated by comma' + ), + defaultValue=None, multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Extent intersection'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_5, + description=self.translate('Pixel resolution'), + defaultValue=None, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Calculation output'), + fileFilter=self.translate( + 'tif file (*.tif);; vrt file (*.vrt)' + ) + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/semiautomaticclassificationplugin_bandcalc_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandCalc() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + input_names = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + input_name_list = [] + for name in input_names[0].split(','): + input_name_list.append(name.strip()) + if parameters[self.BOOL] is None: + input_nodata_as_value = None + else: + input_nodata_as_value = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.VALUE] is None: + use_value_as_nodata = None + else: + use_value_as_nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.ENUMERATOR] is None: + calc_datatype = None + else: + types = ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'] + data_type = self.parameterAsInt( + parameters, self.ENUMERATOR, context + ) + calc_datatype = types[data_type] + if parameters[self.ENUMERATOR_2] is None: + output_datatype = None + else: + types = ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'] + data_type = self.parameterAsInt( + parameters, self.ENUMERATOR_2, context + ) + output_datatype = types[data_type] + if parameters[self.VALUE_2] is None: + output_nodata = None + else: + output_nodata = self.parameterAsInt( + parameters, self.VALUE_2, context + ) + if parameters[self.VALUE_3] is None: + use_scale = None + else: + use_scale = self.parameterAsInt( + parameters, self.VALUE_3, context + ) + if parameters[self.VALUE_4] is None: + use_offset = None + else: + use_offset = self.parameterAsInt( + parameters, self.VALUE_4, context + ) + if parameters[self.ENUMERATOR_3] is None: + any_nodata_mask = None + else: + types = ['False', 'True', 'None'] + enum = self.parameterAsInt( + parameters, self.ENUMERATOR_3, context + ) + if types[enum] == 'False': + any_nodata_mask = False + elif types[enum] == 'True': + any_nodata_mask = True + else: + any_nodata_mask = None + expression = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.INPUT_RASTER_2] is None: + extent_raster = None + else: + extent_raster = self.parameterAsFile( + parameters, self.INPUT_RASTER_2, context + ) + if parameters[self.INPUT_LIST_2] is None: + extent_list = None + else: + extent_text = self.parameterAsStrings( + parameters, self.INPUT_LIST_2, context + ) + if len(extent_text) > 0: + extent_list = [] + for extent in extent_text[0].split(','): + extent_list.append(float(extent.strip())) + else: + extent_list = None + if parameters[self.BOOL_2] is None: + extent_intersection = None + else: + extent_intersection = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + if parameters[self.INPUT_RASTER] is None: + align_raster = None + else: + align_raster = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + if parameters[self.VALUE_5] is None: + xy_resolution_list = None + else: + xy_resolution = self.parameterAsDouble( + parameters, self.VALUE_5, context + ) + xy_resolution_list = [xy_resolution, xy_resolution] + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_calc( + expression_string=expression, output_path=output_path, + input_raster_list=input_bands, + input_name_list=input_name_list, align_raster=align_raster, + use_value_as_nodata=use_value_as_nodata, + input_nodata_as_value=input_nodata_as_value, + extent_raster=extent_raster, extent_list=extent_list, + extent_intersection=extent_intersection, + calc_datatype=calc_datatype, output_datatype=output_datatype, + output_nodata=output_nodata, any_nodata_mask=any_nodata_mask, + use_scale=use_scale, use_offset=use_offset, + xy_resolution_list=xy_resolution_list + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_clip.py b/qgis_processing/band_clip.py new file mode 100644 index 0000000..80492a6 --- /dev/null +++ b/qgis_processing/band_clip.py @@ -0,0 +1,181 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterVectorLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandClip(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_clip' + + @staticmethod + def displayName(): + return 'Clip raster bands' + + @staticmethod + def shortDescription(): + return ( + 'Perform the clipping of raster bands based on a vector or extent ' + 'coordinate list. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Extent coordinates (in the order Minimum X, Maximum Y, ' + 'Maximum X, Minimum Y), separated by comma' + ), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterVectorLayer( + name=self.INPUT_VECTOR, + description=self.translate('Reference vector'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Vector field'), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_2, + description=self.translate('Output name'), + defaultValue='clip_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_clip_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandClip() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + input_coordinates = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + values = [] + for name in input_coordinates[0].split(','): + values.append(int(name.strip())) + if len(values) == 0: + values = None + if self.INPUT_VECTOR is None: + reference = None + else: + reference = self.parameterAsFile( + parameters, self.INPUT_VECTOR, context + ) + field = self.parameterAsString(parameters, self.TEXT, context) + if len(field) == 0: + field = None + output_name = self.parameterAsString( + parameters, self.TEXT_2, context + ) + if parameters[self.BOOL] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_clip( + input_bands=input_bands, output_path=output_path, + vector_path=reference, vector_field=field, + prefix=output_name, extent_list=values, + virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_combination.py b/qgis_processing/band_combination.py new file mode 100644 index 0000000..7bfcf50 --- /dev/null +++ b/qgis_processing/band_combination.py @@ -0,0 +1,145 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandCombination(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_combination' + + @staticmethod + def displayName(): + return 'Combination' + + @staticmethod + def shortDescription(): + return ( + 'Combines classifications in order to get a raster where each ' + 'value corresponds to a combination of class values. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Strings, separated by comma, corresponding to input ' + 'bands used as column names in output table' + ), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_band_combination_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandCombination() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + column_names = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + if column_names is None: + column_name_list = None + else: + column_name_list = column_names[0].split(',') + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_combination( + input_bands=input_bands, output_path=output_path, + nodata_value=nodata, column_name_list=column_name_list + ) + if output.check: + paths = output.paths + layer = QgsRasterLayer(paths[0], Path(paths[0]).name) + QgsProject.instance().addMapLayer(layer) + self.feedback.pushInfo('Output table: ' + str(paths[1])) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_dilation.py b/qgis_processing/band_dilation.py new file mode 100644 index 0000000..d89c2a5 --- /dev/null +++ b/qgis_processing/band_dilation.py @@ -0,0 +1,181 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandDilation(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_dilation' + + @staticmethod + def displayName(): + return 'Dilation' + + @staticmethod + def shortDescription(): + return ( + 'Perform the spatial dilation, through a moving window, ' + 'of band pixels selected by values. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Class values, separated by comma' + ), + defaultValue='', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Size in pixels'), + defaultValue=1, minValue=1 + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Circular'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output name'), + defaultValue='dilation_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_classification_dilation.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandDilation() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + input_classes = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + values = [] + for name in input_classes[0].split(','): + values.append(int(name.strip())) + if parameters[self.VALUE] is None: + size = None + else: + size = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.BOOL] is None: + circular = None + else: + circular = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.BOOL_2] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_dilation( + input_bands=input_bands, value_list=values, size=size, + output_path=output_path, circular_structure=circular, + prefix=output_name, virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_erosion.py b/qgis_processing/band_erosion.py new file mode 100644 index 0000000..58f860c --- /dev/null +++ b/qgis_processing/band_erosion.py @@ -0,0 +1,181 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandErosion(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_erosion' + + @staticmethod + def displayName(): + return 'Erosion' + + @staticmethod + def shortDescription(): + return ( + 'Perform the spatial erosion, through a moving window, ' + 'of band pixels selected by values. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Class values, separated by comma' + ), + defaultValue='', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Size in pixels'), + defaultValue=1, minValue=1 + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Circular'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output name'), + defaultValue='erosion_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_classification_erosion.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandErosion() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + input_classes = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + values = [] + for name in input_classes[0].split(','): + values.append(int(name.strip())) + if parameters[self.VALUE] is None: + size = None + else: + size = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.BOOL] is None: + circular = None + else: + circular = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.BOOL_2] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_erosion( + input_bands=input_bands, value_list=values, size=int(size), + output_path=output_path, circular_structure=circular, + prefix=output_name, virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_neighbor.py b/qgis_processing/band_neighbor.py new file mode 100644 index 0000000..1fbaaf6 --- /dev/null +++ b/qgis_processing/band_neighbor.py @@ -0,0 +1,204 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandNeighbor(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_neighbor' + + @staticmethod + def displayName(): + return 'Neighbor' + + @staticmethod + def shortDescription(): + return ( + 'Perform the calculation of a function over neighbor pixels ' + 'defined by size (i.e. number of pixels) or a structure. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Neighbor distance in pixels'), + defaultValue=1, minValue=1 + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Circular structure'), + defaultValue=None, optional=True + ) + ) + try: + from remotior_sensus.core import configurations + stat_list = [] + for i in configurations.statistics_list: + stat_list.append(i[0]) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR, self.translate('Statistic'), + stat_list, defaultValue=[0], allowMultiple=False + ) + ) + except Exception as err: + str(err) + + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_2, + description=self.translate('Percentile'), + defaultValue=50, minValue=0, maxValue=100, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output name'), + defaultValue='neighbor_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_neighbor_pixels.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandNeighbor() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + if parameters[self.VALUE] is None: + size = None + else: + size = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.VALUE_2] is None: + stat_percentile = None + else: + stat_percentile = self.parameterAsInt( + parameters, self.VALUE_2, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.ENUMERATOR] is None: + stat_name = None + else: + types = [] + for i in rs.configurations.statistics_list: + types.append(i[0]) + enum = self.parameterAsInt( + parameters, self.ENUMERATOR, context + ) + stat_name = types[enum] + if parameters[self.BOOL] is None: + circular_structure = None + else: + circular_structure = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.BOOL_2] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_neighbor_pixels( + input_bands=input_bands, size=size, structure=None, + stat_percentile=stat_percentile, output_path=output_path, + prefix=output_name, circular_structure=circular_structure, + stat_name=stat_name, virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_pca.py b/qgis_processing/band_pca.py new file mode 100644 index 0000000..78fbf64 --- /dev/null +++ b/qgis_processing/band_pca.py @@ -0,0 +1,142 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandPCA(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_pca' + + @staticmethod + def displayName(): + return 'PCA' + + @staticmethod + def shortDescription(): + return ( + 'Perform the calculation of Principal Components Analysis on ' + 'input bands, producing rasters corresponding to the principal ' + 'components. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Number of components'), + minValue=2, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_2, + description=self.translate('NoData value'), + optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_pca_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandPCA() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + if parameters[self.VALUE] is None: + components_number = None + else: + components_number = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.VALUE_2] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE_2, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_pca( + input_bands=input_bands, output_path=output_path, + nodata_value=nodata, number_components=components_number + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/band_sieve.py b/qgis_processing/band_sieve.py new file mode 100644 index 0000000..b3fbb87 --- /dev/null +++ b/qgis_processing/band_sieve.py @@ -0,0 +1,167 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class BandSieve(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'band_sieve' + + @staticmethod + def displayName(): + return 'Sieve' + + @staticmethod + def shortDescription(): + return ( + 'Perform the sieve of raster bands removing patches having size ' + 'lower than a threshold. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Size threshold'), + defaultValue=2, minValue=2 + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output name'), + defaultValue='sieve_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR, self.translate('Pixel connection'), + ['4', '8'], defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_classification_sieve.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return BandSieve() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + if parameters[self.VALUE] is None: + size = None + else: + size = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.BOOL] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.ENUMERATOR] is None: + connection = None + else: + types = ['4', '8'] + enum = self.parameterAsInt( + parameters, self.ENUMERATOR, context + ) + connection = types[enum] + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_sieve( + input_bands=input_bands, size=size, output_path=output_path, + connected=connection, prefix=output_name, + virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/classification.py b/qgis_processing/classification.py new file mode 100644 index 0000000..0828284 --- /dev/null +++ b/qgis_processing/classification.py @@ -0,0 +1,513 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFileDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum, + QgsProcessingParameterFile +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class Classification(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'classification' + + @staticmethod + def displayName(): + return 'Classification' + + @staticmethod + def shortDescription(): + return ( + 'Perform calculations between raster bands. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterFile( + name=self.INPUT_FILE, + description=self.translate('Training input file'), + fileFilter=self.translate('scpx file (*.scpx)'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR, self.translate('Input normalization'), + ['z-score', 'linear scaling'], + defaultValue=None, allowMultiple=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate( + 'Use Macroclass value (if False is Class value)' + ), defaultValue=True, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR_2, self.translate('Algorithm'), + ['minimum distance', 'maximum likelihood', + 'spectral angle mapping', 'random forest', + 'support vector machine', + 'multi-layer perceptron', 'pytorch multi-layer perceptron'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate( + 'Use single threshold (Minimum Distance, ' + 'Maximum Likelihood, Spectral Angle Mapping' + ), + defaultValue=None, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate( + 'Signature threshold (Minimum Distance, ' + 'Maximum Likelihood, Spectral Angle Mapping' + ), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_3, + description=self.translate( + 'Save signature raster (Minimum Distance, ' + 'Maximum Likelihood, Spectral Angle Mapping' + ), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_4, + description=self.translate( + 'Calculate classification confidence raster' + ), defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Multi-Layer Perceptron: Hidden layer sizes (values ' + 'separated by comma)' + ), defaultValue=100, multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_2, + description=self.translate( + 'Multi-Layer Perceptron: max iter size' + ), defaultValue=200, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate( + 'Multi-Layer Perceptron: activation' + ), defaultValue='relu', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_3, + description=self.translate('Multi-Layer Perceptron: alpha'), + defaultValue=0.01, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_4, + description=self.translate( + 'Multi-Layer Perceptron: training portion' + ), + defaultValue=0.9, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_2, + description=self.translate( + 'Multi-Layer Perceptron: batch size' + ), defaultValue='auto', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_5, + description=self.translate( + 'Multi-Layer Perceptron: learning rate init' + ), + defaultValue=0.001, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_5, + description=self.translate( + 'Cross validation (Multi-Layer Perceptron, Random Forest, ' + 'Support Vector Machine)' + ), defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_7, + description=self.translate('Random Forest: number of trees'), + defaultValue=10, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_8, + description=self.translate( + 'Random Forest: minimum number to split' + ), defaultValue=2, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_3, + description=self.translate( + 'Random Forest: max features' + ), defaultValue=None, multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_6, + description=self.translate( + 'Random Forest: One-Vs-Rest' + ), defaultValue=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_9, + description=self.translate( + 'Support Vector Machine: regularization parameter C' + ), + defaultValue=1, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_4, + description=self.translate( + 'Support Vector Machine: kernel' + ), defaultValue='rbf', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_5, + description=self.translate( + 'Support Vector Machine: gamma' + ), defaultValue='scale', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_6, + description=self.translate( + 'Find best estimator with steps (Multi-Layer Perceptron, ' + 'Random Forest, Support Vector Machine)' + ), defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_7, + description=self.translate( + 'Balanced class weight (Random Forest, ' + 'Support Vector Machine)' + ), defaultValue=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFile( + name=self.INPUT_FILE_2, + description=self.translate('Classifier file'), + fileFilter=self.translate('rsmo file (*.rsmo)'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Calculation output'), + fileFilter=self.translate( + 'tif file (*.tif);; vrt file (*.vrt)' + ) + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/semiautomaticclassificationplugin_classification.svg' + % Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return Classification() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + if self.INPUT_FILE is None: + training_path = None + else: + training_path = self.parameterAsFile( + parameters, self.INPUT_FILE, context + ) + if len(training_path) == 0: + training_path = None + if parameters[self.ENUMERATOR] is None: + input_normalization = None + else: + types = [rs.configurations.z_score, + rs.configurations.linear_scaling] + norm_type = self.parameterAsInt( + parameters, self.ENUMERATOR, context + ) + input_normalization = types[norm_type] + if parameters[self.BOOL] is None: + macroclass = None + else: + macroclass = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.ENUMERATOR_2] is None: + classifier_name = 'minimum distance' + else: + alg_types = [ + 'minimum distance', 'maximum likelihood', + 'spectral angle mapping', 'random forest', + 'support vector machine', 'multi-layer perceptron', + 'pytorch multi-layer perceptron' + ] + alg_type = self.parameterAsInt( + parameters, self.ENUMERATOR_2, context + ) + classifier_name = alg_types[alg_type] + if parameters[self.VALUE] is None: + threshold = None + else: + threshold = self.parameterAsDouble( + parameters, self.VALUE, context + ) + if parameters[self.BOOL_2] is not None: + thresholds = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + if thresholds is True: + threshold = True + if parameters[self.BOOL_3] is None: + signature_raster = None + else: + signature_raster = self.parameterAsBool( + parameters, self.BOOL_3, context + ) + if parameters[self.BOOL_4] is None: + classification_confidence = None + else: + classification_confidence = self.parameterAsBool( + parameters, self.BOOL_4, context + ) + hidden_layers = self.parameterAsString( + parameters, self.INPUT_LIST, context + ) + mlp_hidden_layer_sizes = None + if hidden_layers is not None: + try: + mlp_hidden_layer_sizes = eval('[%s]' % hidden_layers) + except Exception as err: + str(err) + raise 'mlp hidden layer sizes' + if parameters[self.VALUE_2] is None: + mlp_max_iter = None + else: + mlp_max_iter = self.parameterAsInt( + parameters, self.VALUE_2, context + ) + mlp_activation = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.VALUE_3] is None: + mlp_alpha = None + else: + mlp_alpha = self.parameterAsDouble( + parameters, self.VALUE_3, context + ) + if parameters[self.VALUE_4] is None: + mlp_training_portion = None + else: + mlp_training_portion = self.parameterAsDouble( + parameters, self.VALUE_4, context + ) + mlp_batch_size = self.parameterAsString( + parameters, self.TEXT_2, context + ) + if parameters[self.VALUE_5] is None: + mlp_learning_rate_init = None + else: + mlp_learning_rate_init = self.parameterAsDouble( + parameters, self.VALUE_5, context + ) + if parameters[self.BOOL_5] is None: + cross_validation = None + else: + cross_validation = self.parameterAsBool( + parameters, self.BOOL_5, context + ) + if parameters[self.VALUE_6] is None: + find_best_estimator = None + else: + find_best_estimator = self.parameterAsInt( + parameters, self.VALUE_6, context + ) + if parameters[self.VALUE_7] is None: + rf_number_trees = None + else: + rf_number_trees = self.parameterAsInt( + parameters, self.VALUE_7, context + ) + if parameters[self.VALUE_8] is None: + rf_min_samples_split = None + else: + rf_min_samples_split = self.parameterAsInt( + parameters, self.VALUE_8, context + ) + rf_max_features = self.parameterAsString( + parameters, self.TEXT_3, context + ) + if parameters[self.BOOL_6] is not None: + rf_ovr = self.parameterAsBool( + parameters, self.BOOL_6, context + ) + if rf_ovr is True: + classifier_name = 'random forest ovr' + class_weight = None + if parameters[self.BOOL_7] is None: + class_weight = None + else: + class_weight_bool = self.parameterAsBool( + parameters, self.BOOL_7, context + ) + if class_weight_bool is True: + class_weight = 'balanced' + if parameters[self.VALUE_9] is None: + svm_c = None + else: + svm_c = self.parameterAsDouble( + parameters, self.VALUE_9, context + ) + svm_kernel = self.parameterAsString( + parameters, self.TEXT_4, context + ) + svm_gamma = self.parameterAsString( + parameters, self.TEXT_5, context + ) + load_classifier = None + if self.INPUT_FILE_2 is None: + load_classifier = None + else: + classifier = self.parameterAsFile( + parameters, self.INPUT_FILE_2, context + ) + if len(classifier) == 0: + load_classifier = None + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_classification( + input_bands=input_bands, output_path=output_path, + spectral_signatures=training_path, macroclass=macroclass, + algorithm_name=classifier_name, threshold=threshold, + signature_raster=signature_raster, + cross_validation=cross_validation, + input_normalization=input_normalization, + load_classifier=load_classifier, + class_weight=class_weight, find_best_estimator=find_best_estimator, + rf_max_features=rf_max_features, rf_number_trees=rf_number_trees, + rf_min_samples_split=rf_min_samples_split, svm_c=svm_c, + svm_gamma=svm_gamma, svm_kernel=svm_kernel, + mlp_training_portion=mlp_training_portion, + mlp_alpha=mlp_alpha, mlp_learning_rate_init=mlp_learning_rate_init, + mlp_max_iter=mlp_max_iter, mlp_batch_size=mlp_batch_size, + mlp_activation=mlp_activation, + mlp_hidden_layer_sizes=mlp_hidden_layer_sizes, + classification_confidence=classification_confidence + ) + if output.check: + raster = output.path + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/cross_classification.py b/qgis_processing/cross_classification.py new file mode 100644 index 0000000..b53d8e2 --- /dev/null +++ b/qgis_processing/cross_classification.py @@ -0,0 +1,199 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProject, QgsProcessingParameterBoolean, + QgsProcessingParameterRasterLayer, QgsProcessingParameterVectorLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class CrossClassification(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'cross_classification' + + @staticmethod + def displayName(): + return 'Cross classification' + + @staticmethod + def shortDescription(): + return ( + 'Perform the cross classification which is similar to band ' + 'combination, but it is executed between two files only. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER_2, + description=self.translate('Reference raster'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterVectorLayer( + name=self.INPUT_VECTOR, + description=self.translate('Reference vector'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Vector field'), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Error matrix'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Cross matrix'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_3, + description=self.translate('Regression raster'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_cross_classification.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return CrossClassification() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + root = QgsProject.instance().layerTreeRoot() + if rs.files_directories.is_file(classification) is False: + layer_x = root.findLayer(classification) + classification = layer_x.layer().source() + reference = self.parameterAsFile( + parameters, self.INPUT_RASTER_2, context + ) + if reference is None: + reference = self.parameterAsFile( + parameters, self.INPUT_VECTOR, context + ) + else: + if rs.files_directories.is_file(reference) is False: + layer_x = root.findLayer(reference) + reference = layer_x.layer().source() + field = self.parameterAsString(parameters, self.TEXT, context) + if len(field) == 0: + field = None + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.BOOL] is None: + error_matrix = None + else: + error_matrix = self.parameterAsBool( + parameters, self.BOOL, context + ) + if parameters[self.BOOL_2] is None: + cross_matrix = None + else: + cross_matrix = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + if parameters[self.BOOL_3] is None: + regression_raster = None + else: + regression_raster = self.parameterAsBool( + parameters, self.BOOL_3, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + output = rs.cross_classification( + classification_path=classification, reference_path=reference, + output_path=output_path, vector_field=field, nodata_value=nodata, + error_matrix=error_matrix, cross_matrix=cross_matrix, + regression_raster=regression_raster + ) + if output.check: + paths = output.paths + layer = QgsRasterLayer(paths[0], Path(paths[0]).name) + QgsProject.instance().addMapLayer(layer) + self.feedback.pushInfo('Output table: ' + str(paths[1])) + + return {self.OUTPUT: output_path} diff --git a/qgis_processing/image_conversion.py b/qgis_processing/image_conversion.py new file mode 100644 index 0000000..abc7a24 --- /dev/null +++ b/qgis_processing/image_conversion.py @@ -0,0 +1,151 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, QgsProcessingParameterFile, + QgsRasterLayer, QgsProcessingParameterNumber, + QgsProject, QgsProcessingParameterBoolean +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class ImageConversion(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'image_conversion' + + @staticmethod + def displayName(): + return 'Image conversion' + + @staticmethod + def shortDescription(): + return ( + 'Perform the preprocessing of products. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFile( + name=self.INPUT_DIRECTORY, + description=self.translate('Directory containing bands'), + behavior=QgsProcessingParameterFile.Folder + ) + ) + self.addParameter( + QgsProcessingParameterFile( + name=self.INPUT_FILE, + description=self.translate('Metadata file'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate( + 'Apply DOS1 atmospheric correction' + ), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_landsat8_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return ImageConversion() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_path = self.parameterAsString( + parameters, self.INPUT_DIRECTORY, context + ) + if rs.files_directories.is_directory(input_path) is False: + raise 'input directory' + if self.INPUT_FILE is None: + metadata = None + else: + metadata = self.parameterAsFile( + parameters, self.INPUT_FILE, context + ) + if len(metadata) == 0: + metadata = None + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.BOOL] is None: + dos1_correction = None + else: + dos1_correction = self.parameterAsBool( + parameters, self.BOOL, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + output = rs.preprocess_products.preprocess( + input_path=input_path, output_path=output_path, + metadata_file_path=metadata, nodata_value=nodata, + dos1_correction=dos1_correction, output_prefix='RT_' + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/masking_bands.py b/qgis_processing/masking_bands.py new file mode 100644 index 0000000..e86e259 --- /dev/null +++ b/qgis_processing/masking_bands.py @@ -0,0 +1,190 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, QgsProcessingParameterRasterLayer, + QgsProcessingParameterNumber, QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class MaskingBands(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'masking_bands' + + @staticmethod + def displayName(): + return 'Masking bands' + + @staticmethod + def shortDescription(): + return ( + 'Perform the masking of bands based on a raster mask. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.INPUT_LIST, + description=self.translate( + 'Mask class values, separated by comma' + ), + defaultValue='', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Size in pixels'), + defaultValue=1, minValue=1 + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('Output NoData value'), + defaultValue=-32768, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output name'), + defaultValue='mask_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_cloud_masking_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return MaskingBands() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + input_classes = self.parameterAsStrings( + parameters, self.INPUT_LIST, context + ) + values = [] + for name in input_classes[0].split(','): + values.append(int(name.strip())) + if parameters[self.VALUE] is None: + size = None + else: + size = self.parameterAsInt( + parameters, self.VALUE, context + ) + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT, context + ) + if parameters[self.BOOL] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_mask( + input_bands=input_bands, input_mask=classification, + mask_values=values, + output_path=output_path, prefix=output_name, buffer=size, + nodata_value=nodata, virtual_output=virtual_output + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/raster_reclassification.py b/qgis_processing/raster_reclassification.py new file mode 100644 index 0000000..dc688ec --- /dev/null +++ b/qgis_processing/raster_reclassification.py @@ -0,0 +1,129 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFileDestination, QgsProcessingParameterRasterLayer, + QgsProject, QgsProcessingParameterString, + QgsProcessingParameterFile, QgsRasterLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class RasterReclassification(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'raster_reclassification' + + @staticmethod + def displayName(): + return 'Reclassification' + + @staticmethod + def shortDescription(): + return ( + 'Reclassification of a raster based on a reclassification table. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterFile( + name=self.INPUT_FILE, + description=self.translate('Input reclassification table'), + fileFilter=self.translate( + 'csv file (*.csv);; txt file (*.txt)' + ) + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Separator'), + defaultValue=',', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Calculation output'), + fileFilter=self.translate( + 'tif file (*.tif);; vrt file (*.vrt)' + ) + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons' + '/semiautomaticclassificationplugin_reclassification_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return RasterReclassification() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + root = QgsProject.instance().layerTreeRoot() + if rs.files_directories.is_file(classification) is False: + layer_x = root.findLayer(classification) + classification = layer_x.layer().source() + csv_path = self.parameterAsFile( + parameters, self.INPUT_FILE, context + ) + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + separator = self.parameterAsString( + parameters, self.TEXT, context + ) + output = rs.raster_reclassification( + raster_path=classification, output_path=output_path, + csv_path=csv_path, separator=separator + ) + if output.check: + raster = output.path + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/raster_report.py b/qgis_processing/raster_report.py new file mode 100644 index 0000000..0321567 --- /dev/null +++ b/qgis_processing/raster_report.py @@ -0,0 +1,111 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFileDestination, QgsProcessingParameterRasterLayer, + QgsProcessingParameterNumber, QgsProject +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class RasterReport(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'raster_report' + + @staticmethod + def displayName(): + return 'Classification report' + + @staticmethod + def shortDescription(): + return ('Calculate report of classes. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Classification report'), + fileFilter=self.translate('csv file (*.csv)') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/semiautomaticclassificationplugin_report_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return RasterReport() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + root = QgsProject.instance().layerTreeRoot() + if rs.files_directories.is_file(classification) is False: + layer_x = root.findLayer(classification) + classification = layer_x.layer().source() + if parameters[self.VALUE] is None: + nodata = None + else: + nodata = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + rs.raster_report( + raster_path=classification, output_path=output_path, + nodata_value=nodata + ) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/raster_to_vector.py b/qgis_processing/raster_to_vector.py new file mode 100644 index 0000000..96a0d26 --- /dev/null +++ b/qgis_processing/raster_to_vector.py @@ -0,0 +1,117 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFileDestination, QgsProcessingParameterRasterLayer, + QgsProject, QgsProcessingParameterBoolean, + QgsVectorLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class RasterToVector(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'raster_to_vector' + + @staticmethod + def displayName(): + return 'Classification to vector' + + @staticmethod + def shortDescription(): + return ('Conversion from raster to vector. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Dissolve'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Output vector'), + fileFilter=self.translate('gpkg file (*.gpkg)') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons' + '/semiautomaticclassificationplugin_class_to_vector_tool.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return RasterToVector() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + classification = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + root = QgsProject.instance().layerTreeRoot() + if rs.files_directories.is_file(classification) is False: + layer_x = root.findLayer(classification) + classification = layer_x.layer().source() + if parameters[self.BOOL] is None: + dissolve = None + else: + dissolve = self.parameterAsBool( + parameters, self.BOOL, context + ) + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + output = rs.raster_to_vector( + raster_path=classification, output_path=output_path, + dissolve=dissolve + ) + if output.check: + vector = output.path + layer = QgsVectorLayer(vector, Path(vector).name, 'ogr') + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/reproject_raster_bands.py b/qgis_processing/reproject_raster_bands.py new file mode 100644 index 0000000..dc4b1b9 --- /dev/null +++ b/qgis_processing/reproject_raster_bands.py @@ -0,0 +1,285 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterString, QgsRasterLayer, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum, + QgsProcessingParameterRasterLayer, QgsProcessingParameterNumber + +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class ReprojectRasterBands(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'reproject_raster_bands' + + @staticmethod + def displayName(): + return 'Reproject raster bands' + + @staticmethod + def shortDescription(): + return ( + 'Perform the resampling and reprojection of bands. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Align raster'), optional=True + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL, + description=self.translate('Same extent as reference'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('EPSG code'), + defaultValue='', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE, + description=self.translate('X resolution'), + defaultValue=None, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_2, + description=self.translate('Y resolution'), + defaultValue=None, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_3, + description=self.translate('Resample pixel factor'), + defaultValue=None, optional=True, + type=QgsProcessingParameterNumber.Double + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR, self.translate('Resampling method'), + ['nearest_neighbour', 'average', 'sum', 'maximum', 'minimum', + 'mode', 'median', 'first_quartile', 'third_quartile'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterEnum( + self.ENUMERATOR_2, self.translate('Output data type'), + ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'], + defaultValue=[0], allowMultiple=False + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + name=self.VALUE_4, + description=self.translate('Output NoData value'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_2, + description=self.translate('Output name'), + defaultValue='reproj_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterBoolean( + name=self.BOOL_2, + description=self.translate('Virtual output'), + defaultValue=None, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT_3, + description=self.translate('Compression'), + defaultValue='LZW', multiLine=False, optional=True + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_reproject_raster_bands.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return ReprojectRasterBands() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + if parameters[self.INPUT_RASTER] is None: + align_raster = None + else: + align_raster = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + if parameters[self.BOOL_2] is None: + same_extent = None + else: + same_extent = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + epsg = self.parameterAsString(parameters, self.TEXT, context) + if len(epsg) == 0: + epsg = None + if parameters[self.VALUE] is None: + x_y_resolution = None + else: + x_res = self.parameterAsDouble( + parameters, self.VALUE, context + ) + if parameters[self.VALUE_2] is None: + x_y_resolution = None + else: + y_res = self.parameterAsDouble( + parameters, self.VALUE, context + ) + x_y_resolution = [x_res, y_res] + if parameters[self.VALUE] is None: + resample_pixel_factor = None + else: + resample_pixel_factor = self.parameterAsDouble( + parameters, self.VALUE, context + ) + if parameters[self.ENUMERATOR] is None: + resampling = None + else: + types = [ + 'nearest_neighbour', 'average', 'sum', 'maximum', 'minimum', + 'mode', 'median', 'first_quartile', 'third_quartile' + ] + enum = self.parameterAsInt( + parameters, self.ENUMERATOR, context + ) + resampling = types[enum] + if parameters[self.ENUMERATOR_2] is None: + raster_type = None + else: + types = ['Float32', 'Int32', 'UInt32', 'Int16', 'UInt16', 'Byte'] + enum = self.parameterAsInt( + parameters, self.ENUMERATOR_2, context + ) + raster_type = types[enum] + if parameters[self.VALUE_4] is None: + nodata_value = None + else: + nodata_value = self.parameterAsInt( + parameters, self.VALUE, context + ) + output_name = self.parameterAsString( + parameters, self.TEXT_2, context + ) + if parameters[self.BOOL_2] is None: + virtual_output = None + else: + virtual_output = self.parameterAsBool( + parameters, self.BOOL_2, context + ) + compress_format = self.parameterAsString( + parameters, self.TEXT_3, context + ) + compress = True + if len(compress_format) == 0: + compress_format = None + compress = False + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_resample( + input_bands=input_bands, output_path=output_path, + prefix=output_name, epsg_code=epsg, align_raster=align_raster, + resampling=resampling, nodata_value=nodata_value, + x_y_resolution=x_y_resolution, + resample_pixel_factor=resample_pixel_factor, + output_data_type=raster_type, same_extent=same_extent, + virtual_output=virtual_output, compress=compress, + compress_format=compress_format + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/scp_algorithm_provider.py b/qgis_processing/scp_algorithm_provider.py new file mode 100644 index 0000000..25598d9 --- /dev/null +++ b/qgis_processing/scp_algorithm_provider.py @@ -0,0 +1,137 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QApplication +# noinspection PyUnresolvedReferences +from processing.core.ProcessingConfig import ProcessingConfig, Setting +from qgis.core import QgsProcessingProvider, QgsRuntimeProfiler + +from .accuracy import Accuracy +from .band_calc import BandCalc +from .band_clip import BandClip +from .band_combination import BandCombination +from .band_dilation import BandDilation +from .band_erosion import BandErosion +from .band_pca import BandPCA +from .band_neighbor import BandNeighbor +from .band_sieve import BandSieve +from .classification import Classification +from .cross_classification import CrossClassification +from .image_conversion import ImageConversion +from .masking_bands import MaskingBands +from .raster_report import RasterReport +from .raster_reclassification import RasterReclassification +from .raster_to_vector import RasterToVector +from .reproject_raster_bands import ReprojectRasterBands +from .split_bands import SplitBands +from .stack_bands import StackBands + + +""" Class to manage QGIS Processing algorithms """ + + +# noinspection PyPep8Naming +class SCPAlgorithmProvider(QgsProcessingProvider): + + def __init__(self): + super().__init__() + self.algorithm_list = [ + Accuracy, BandCalc, BandClip, BandCombination, BandErosion, + BandPCA, BandDilation, BandNeighbor, BandSieve, Classification, + CrossClassification, ImageConversion, MaskingBands, RasterReport, + RasterReclassification, RasterToVector, ReprojectRasterBands, + SplitBands, StackBands + ] + + def load(self): + with QgsRuntimeProfiler.profile('SCP Provider'): + group = self.name() + ProcessingConfig.settingIcons[group] = self.icon() + ProcessingConfig.setGroupIcon(self.name(), self.icon()) + ProcessingConfig.addSetting( + Setting( + group, 'SCP_N_PROCESSES', + self.translate('Number of parallel processes'), 2, + valuetype=Setting.INT + ) + ) + ProcessingConfig.addSetting( + Setting( + group, 'SCP_MEMORY', + self.translate('Available RAM in MB'), + 2048, valuetype=Setting.INT + ) + ) + ProcessingConfig.addSetting( + Setting(group, 'SCP_ACTIVATE', 'Activate', True) + ) + ProcessingConfig.readSettings() + self.refreshAlgorithms() + return True + + @staticmethod + def unload(): + ProcessingConfig.removeSetting('SCP_N_PROCESSES') + ProcessingConfig.removeSetting('SCP_MEMORY') + ProcessingConfig.removeSetting('SCP_ACTIVATE') + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/semiautomaticclassificationplugin.svg' % + Path(__file__).parent.parent + ) + + # noinspection PyTypeChecker + @staticmethod + def translate(text): + return QApplication.translate( + 'semiautomaticclassificationplugin', + text + ) + + def loadAlgorithms(self): + for algorithm in self.algorithm_list: + self.addAlgorithm(algorithm()) + + @staticmethod + def name(): + return 'Semi-Automatic Classification Plugin' + + @staticmethod + def longName(): + return 'Semi-Automatic Classification Plugin' + + @staticmethod + def id(): + return 'scp_8' + + @staticmethod + def versionInfo(): + return '8.0.0' + + @staticmethod + def isActive(): + return ProcessingConfig.getSetting('SCP_ACTIVATE') diff --git a/qgis_processing/split_bands.py b/qgis_processing/split_bands.py new file mode 100644 index 0000000..bd5c28c --- /dev/null +++ b/qgis_processing/split_bands.py @@ -0,0 +1,114 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsProcessingParameterFolderDestination, + QgsProcessingParameterString, QgsRasterLayer, QgsProject, + QgsProcessingParameterRasterLayer +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class SplitBands(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'split_bands' + + @staticmethod + def displayName(): + return 'Split raster bands' + + @staticmethod + def shortDescription(): + return ( + 'Perform the split of a raster to single bands. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterRasterLayer( + name=self.INPUT_RASTER, + description=self.translate('Input raster') + ) + ) + self.addParameter( + QgsProcessingParameterString( + name=self.TEXT, + description=self.translate('Output prefix'), + defaultValue='split_', multiLine=False + ) + ) + self.addParameter( + QgsProcessingParameterFolderDestination( + name=self.OUTPUT, + description=self.translate('Calculation output') + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_split_raster.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return SplitBands() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + reference = self.parameterAsFile( + parameters, self.INPUT_RASTER, context + ) + prefix = self.parameterAsString( + parameters, self.TEXT, context + ) + output_path = self.parameterAsString( + parameters, self.OUTPUT, context + ) + try: + if rs.files_directories.is_directory(output_path) is False: + rs.files_directories.create_directory(output_path) + except Exception as err: + str(err) + output = rs.raster_split( + raster_path=reference, prefix=prefix, output_path=output_path + ) + if output.check: + paths = output.paths + for raster in paths: + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/qgis_processing/stack_bands.py b/qgis_processing/stack_bands.py new file mode 100644 index 0000000..7c7929c --- /dev/null +++ b/qgis_processing/stack_bands.py @@ -0,0 +1,109 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + +from pathlib import Path + +from PyQt5.QtGui import QIcon +from qgis.core import ( + QgsRasterLayer, QgsProcessingParameterFileDestination, + QgsProcessingParameterMultipleLayers, QgsProcessing, QgsProject +) + +from .algorithm_template import AlgorithmTemplate + + +# noinspection PyPep8Naming +class StackBands(AlgorithmTemplate): + + def __init__(self): + super().__init__() + + @staticmethod + def name(): + return 'stack_bands' + + @staticmethod + def displayName(): + return 'Stack bands' + + @staticmethod + def shortDescription(): + return ( + 'Perform stack of raster bands. ' + 'Tool description') # noqa: E501 + + # noinspection PyUnusedLocal + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterMultipleLayers( + name=self.MULTIPLE_LAYERS, + description=self.translate('Input raster list'), + layerType=QgsProcessing.TypeRaster + ) + ) + self.addParameter( + QgsProcessingParameterFileDestination( + name=self.OUTPUT, + description=self.translate('Calculation output'), + fileFilter=self.translate( + 'tif file (*.tif);; vrt file (*.vrt)' + ) + ) + ) + + @staticmethod + def icon(): + return QIcon( + '%s/ui/icons/' + 'semiautomaticclassificationplugin_stack_raster.svg' % + Path(__file__).parent.parent + ) + + @staticmethod + def createInstance(): + return StackBands() + + def processAlgorithm(self, parameters, context, feedback): + self.feedback = feedback + rs = self.start_remotior_sensus_session() + input_raster_list = self.parameterAsFileList( + parameters, self.MULTIPLE_LAYERS, context + ) + output_path = self.parameterAsFileOutput( + parameters, self.OUTPUT, context + ) + root = QgsProject.instance().layerTreeRoot() + input_bands = [] + for raster in input_raster_list: + if rs.files_directories.is_file(raster) is False: + layer_x = root.findLayer(raster) + input_bands.append(layer_x.layer().source()) + else: + input_bands.append(raster) + output = rs.band_stack( + input_bands=input_bands, output_path=output_path + ) + if output.check: + raster = output.path + layer = QgsRasterLayer(raster, Path(raster).name) + QgsProject.instance().addMapLayer(layer) + return {self.OUTPUT: output_path} diff --git a/semiautomaticclassificationplugin.png b/semiautomaticclassificationplugin.png index f512a49..1d46d8d 100644 Binary files a/semiautomaticclassificationplugin.png and b/semiautomaticclassificationplugin.png differ diff --git a/semiautomaticclassificationplugin.py b/semiautomaticclassificationplugin.py old mode 100644 new mode 100755 index 13baf9b..e51cb78 --- a/semiautomaticclassificationplugin.py +++ b/semiautomaticclassificationplugin.py @@ -1,1649 +1,1589 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ +import multiprocessing +import platform +import sys +from os import path, makedirs -''' +import qgis.utils as qgis_utils +# import the PyQt libraries +from PyQt5.QtCore import ( + Qt, QFileInfo, QSettings, QSize, qVersion, QTranslator, QCoreApplication, + QDir, QDate +) +from PyQt5.QtGui import QFont, QColor +from PyQt5.QtWidgets import QApplication, QHeaderView, QLineEdit +# import the QGIS libraries +from qgis.core import ( + Qgis, QgsWkbTypes, QgsApplication, QgsProject, QgsSettings +) +from qgis.gui import QgsRubberBand +# import plugin version +from .__init__ import version as semiautomaticclass_version +# import SemiAutomaticClassificationPlugin +from .core import config as cfg, util_qgis, util_qt, utils, util_gdal, messages +from .core.ui_utils import UiUtils +from .interface import ( + input_interface, scp_dock, bandset_tab, accuracy_tab, stack_bandset_tab, + classification_report_tab, classification_to_vector_tab, split_bands_tab, + cross_classification_tab, band_dilation_tab, band_erosion_tab, settings, + band_sieve_tab, band_combination_tab, band_calc_tab, band_neighbor_tab, + band_pca_tab, reclassification_tab, vector_to_raster_tab, clip_bands_tab, + reproject_bandset_tab, masking_bands_tab, download_products_tab, + mosaic_bandsets_tab, image_conversion_tab, script_tab, classification_tab, + rgb_composite_tab, signature_threshold_tab, multiple_roi_tab +) +from .map_pointers.classification_preview_pointer import ClassificationPreview +from .map_pointers.clip_bands_pointer import ClipBandsPointer +from .map_pointers.download_products_pointer import DownloadProductsPointer +from .map_pointers.manual_roi_pointer import ManualROIPointer +from .map_pointers.region_growing_pointer import RegionGrowingPointer +from .qgis_processing.scp_algorithm_provider import SCPAlgorithmProvider +from .spectral_signature import ( + spectral_signature_plot, scatter_plot, signature_importer +) +# initialize Qt ui +from .ui.semiautomaticclassificationplugindialog import ( + SemiAutomaticClassificationPluginDialog, SpectralSignatureDialog, + ScatterPlotDialog, DockClassDialog, WidgetDialog +) -global PluginCheck -PluginCheck = 'Yes' -import os -import sys -try: - from .core import config as cfg -except: - PluginCheck = 'No' -# try importing different path -from PyQt5.QtCore import QSettings -rK = QSettings() -mPythonSettings = rK.value(cfg.regPythonModulesPathSettings, str(cfg.PythonModulesPathSettings)) -if len(mPythonSettings) > 0: - for ppS in mPythonSettings.split(';'): - if len(ppS) > 0: - sys.path.insert(1, ppS) -import platform -import inspect -import shutil -import time -import datetime -import subprocess -import numpy as np -import urllib -import requests -import ssl -import smtplib -import gc -from http.cookiejar import CookieJar -import itertools -import zipfile -import tarfile -import base64 -import random -import re -import xml.etree.cElementTree as ET -from xml.dom import minidom -import json -import hashlib -import ctypes -import shlex -from collections import Counter -import multiprocessing as mp +global plugin_check try: - mp.set_start_method('spawn') -except: - pass -from multiprocessing import Pool, Manager -# Import the PyQt libraries -from PyQt5 import QtCore, QtGui, QtWidgets -from PyQt5.QtCore import Qt, QObject, QFileInfo, QSettings, QDir, QDate, QVariant, pyqtSignal -from PyQt5.QtWidgets import QApplication, QTreeWidgetItem -from PyQt5.QtNetwork import QNetworkRequest -# Import the QGIS libraries -import qgis.core as qgisCore -import qgis.gui as qgisGui -import qgis.utils as qgisUtils -from osgeo import gdal -from osgeo import ogr -from osgeo import osr -# Initialize Qt ui -from .ui.resources_rc import * -from .ui.ui_semiautomaticclassificationplugin import Ui_SemiAutomaticClassificationPlugin -from .ui.ui_semiautomaticclassificationplugin_welcome import Ui_SCP_Welcome -from .ui.semiautomaticclassificationplugindialog import SemiAutomaticClassificationPluginDialog -from .ui.semiautomaticclassificationplugindialog import SpectralSignatureDialog -from .ui.semiautomaticclassificationplugindialog import WelcomeDialog -from .ui.semiautomaticclassificationplugindialog import ScatterPlotDialog -from .ui.semiautomaticclassificationplugindialog import DockClassDialog -# Import plugin version -from .__init__ import version as semiautomaticclassVersion + import remotior_sensus - -# required by other modules -cfg.QObjectSCP = QObject -cfg.pyqtSignalSCP = pyqtSignal + plugin_check = True +except Exception as error: + str(error) + plugin_check = False + # noinspection PyTypeChecker + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', QApplication.translate( + 'semiautomaticclassificationplugin', + 'Error. Please, install the required Python library ' + 'remotior_sensus' + ), + level=Qgis.Info + ) +try: + multiprocessing.set_start_method('spawn') +except Exception as error: + str(error) -if PluginCheck == 'Yes': - try: - from .core.messages import Messages as msgs - from .core.utils import Utils - from .core.signature_importer import Signature_Importer - from .maininterface.downloadproductpointer import DownloadProductPointer - from .maininterface.downloadproducts import DownloadProducts - from .spectralsignature.spectralsignatureplot import SpectralSignaturePlot - from .spectralsignature.scatter_plot import Scatter_Plot - from .dock.manualroi import ManualROI - from .dock.regionroi import RegionROI - from .dock.scpdock import SCPDock - from .dock.classificationpreview import ClassificationPreview - from .maininterface.multipleroiTab import MultipleROITab - from .spectralsignature.usgs_spectral_lib import USGS_Spectral_Lib - from .maininterface.landsatTab import LandsatTab - from .maininterface.asterTab import ASTERTab - from .maininterface.modisTab import MODISTab - from .maininterface.sentinel1Tab import Sentinel1Tab - from .maininterface.sentinel2Tab import Sentinel2Tab - from .maininterface.sentinel3Tab import Sentinel3Tab - from .maininterface.GOESTab import GOESTab - from .maininterface.accuracy import Accuracy - from .maininterface.crossclassificationTab import CrossClassification - from .maininterface.bandcombination import BandCombination - from .maininterface.splitTab import SplitTab - from .maininterface.reprojectrasterbands import ReprojectRasterBands - from .maininterface.pcaTab import PcaTab - from .maininterface.clusteringTab import ClusteringTab - from .maininterface.classSignatureTab import ClassSignatureTab - from .maininterface.zonalStatRasterTab import ZonalStatRasterTab - from .maininterface.vectortorasterTab import VectorToRasterTab - from .maininterface.bandsetTab import BandsetTab - from .maininterface.algorithmWeightTab import AlgWeightTab - from .maininterface.signatureThresholdTab import SigThresholdTab - from .maininterface.LCSignatureThresholdTab import LCSigThresholdTab - from .maininterface.rgblistTab import RGBListTab - from .maininterface.bandsetlistTab import BandSetListTab - from .maininterface.LCSignaturePixel import LCSigPixel - from .maininterface.LCSignaturePixel2 import LCSigPixel2 - from .maininterface.bandcalcTab import BandCalcTab - from .maininterface.batchTab import BatchTab - from .maininterface.clipmultiplerasters import ClipMultipleRasters - from .maininterface.stackrasterbands import StackRasterBands - from .maininterface.mosaicbandsets import MosaicBandSets - from .maininterface.cloudmasking import CloudMasking - from .maininterface.spectraldistancebandsets import SpectralDistanceBandsets - from .maininterface.randomForestTab import ClassRandomForestTab - from .maininterface.editraster import EditRaster - from .maininterface.sieveTab import SieveRaster - from .maininterface.erosionTab import ErosionRaster - from .maininterface.dilationTab import DilationRaster - from .maininterface.neighborpixelsTab import NeighborPixels - from .maininterface.clipmultiplerasterspointer import ClipMultiplerastersPointer - from .maininterface.landcoverchange import LandCoverChange - from .maininterface.classreportTab import ClassReportTab - from .maininterface.classificationTab import ClassificationTab - from .maininterface.classtovectorTab import ClassToVectorTab - from .maininterface.reclassificationTab import ReclassificationTab - from .maininterface.settings import Settings - from .core.input import Input - from .ui.ui_utils import Ui_Utils - except: - PluginCheck = 'No' - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Please, restart QGIS for executing the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Info) - try: - import scipy.stats.distributions as statdistr - from scipy.spatial.distance import cdist - from scipy import signal - from scipy.ndimage import label - from scipy.cluster.vq import vq, kmeans, whiten - cfg.scipyCheck = 'Yes' - except: - cfg.scipyCheck = 'No' - try: - from matplotlib.ticker import MaxNLocator - import matplotlib.pyplot as mplplt - import matplotlib.colors as mplcolors - cfg.matplotlibCheck = 'Yes' - except Exception as err: - cfg.testMatplotlibV = err - cfg.matplotlibCheck = 'No' - +# noinspection PyPep8Naming class SemiAutomaticClassificationPlugin: - def __init__(self, iface): - try: - cfg.osSCP = os - cfg.sysSCP = sys - cfg.platformSCP = platform - cfg.shutilSCP = shutil - cfg.inspectSCP = inspect - cfg.timeSCP = time - cfg.datetimeSCP = datetime - cfg.subprocessSCP = subprocess - cfg.urllibSCP = urllib - cfg.requestsSCP = requests - cfg.itertoolsSCP = itertools - cfg.zipfileSCP = zipfile - cfg.tarfileSCP = tarfile - cfg.base64SCP = base64 - cfg.randomSCP = random - cfg.QtCoreSCP = QtCore - cfg.QtGuiSCP = QtGui - cfg.QtWidgetsSCP = QtWidgets - cfg.QTreeWidgetItemSCP = QTreeWidgetItem - cfg.QNetworkRequestSCP = QNetworkRequest - cfg.QtSCP = Qt - cfg.QVariantSCP = QVariant - cfg.QFileInfoSCP = QFileInfo - cfg.QSettingsSCP = QSettings - cfg.QDirSCP = QDir - cfg.QDateSCP = QDate - cfg.qgisCoreSCP = qgisCore - cfg.qgisGuiSCP = qgisGui - cfg.gdalSCP = gdal - cfg.ogrSCP = ogr - cfg.osrSCP = osr - cfg.sslSCP = ssl - cfg.smtplibSCP = smtplib - cfg.CookieJarSCP = CookieJar - cfg.gcSCP = gc - cfg.reSCP = re - cfg.ETSCP = ET - cfg.minidomSCP = minidom - cfg.jsonSCP = json - cfg.hashlibSCP = hashlib - cfg.ctypesSCP = ctypes - cfg.shlexSCP = shlex - cfg.counterSCP = Counter - cfg.multiPSCP = mp - cfg.poolSCP = Pool - cfg.MultiManagerSCP = Manager - except: - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Please, restart QGIS for executing the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Info) - return - try: - cfg.np = np - except: - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Error. Check Python Numpy installation for the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Critical) - try: - if cfg.scipyCheck == 'Yes': - cfg.statdistrSCP = statdistr - cfg.cdistSCP = cdist - cfg.signalSCP = signal - cfg.labelSCP = label - cfg.vqSCP = vq - cfg.kmeansSCP = kmeans - cfg.whitenSCP = whiten - if cfg.matplotlibCheck == 'Yes': - cfg.MaxNLocatorSCP = MaxNLocator - cfg.mplpltSCP = mplplt - cfg.mplcolorsSCP = mplcolors - except: - pass - if cfg.scipyCheck == 'No': - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Error. Check Python Scipy installation for the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Critical) - if cfg.matplotlibCheck == 'No': - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Error. Check Python Matplotlib installation for the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Critical) - if PluginCheck == 'Yes': - # reference to QGIS interface - cfg.iface = iface - # reference to map canvas - cfg.cnvs = iface.mapCanvas() - # create the dialog - cfg.dlg = SemiAutomaticClassificationPluginDialog() - # reference to ui - cfg.ui = cfg.dlg.ui - # class dock dialog - cfg.dockclassdlg = DockClassDialog(cfg.iface.mainWindow(), cfg.iface) - # reference dock class ui - cfg.uidc = cfg.dockclassdlg.ui - # welcome dialog - cfg.welcomedlg = WelcomeDialog() - # spectral signature plot dialog - cfg.spectralplotdlg = SpectralSignatureDialog() - cfg.uisp = cfg.spectralplotdlg.ui - # scatter plot dialog - cfg.scatterplotdlg = ScatterPlotDialog() - cfg.uiscp = cfg.scatterplotdlg.ui - cfg.mx = msgs(cfg.iface) - cfg.utls = Utils() - cfg.SCPD = SCPDock() - cfg.classPrev = ClassificationPreview(cfg.cnvs) - cfg.spSigPlot = SpectralSignaturePlot() - cfg.scaPlT = Scatter_Plot() - cfg.multiROI = MultipleROITab() - cfg.usgsLib = USGS_Spectral_Lib() - cfg.acc = Accuracy() - cfg.crossC = CrossClassification() - cfg.bsComb = BandCombination() - cfg.splitT = SplitTab() - cfg.rprjRstBndsT = ReprojectRasterBands() - cfg.pcaT = PcaTab() - cfg.clusteringT = ClusteringTab() - cfg.classSigT = ClassSignatureTab() - cfg.znlSttRstT = ZonalStatRasterTab() - cfg.vctRstrT = VectorToRasterTab() - cfg.bst = BandsetTab() - cfg.algWT = AlgWeightTab() - cfg.signT = SigThresholdTab() - cfg.LCSignT = LCSigThresholdTab() - cfg.RGBLT = RGBListTab() - cfg.bstLT = BandSetListTab() - cfg.bCalc = BandCalcTab() - cfg.batchT = BatchTab() - cfg.clipMulti = ClipMultipleRasters() - cfg.stackRstr = StackRasterBands() - cfg.mosaicBS = MosaicBandSets() - cfg.cloudMsk = CloudMasking() - cfg.spclDstBS = SpectralDistanceBandsets() - cfg.rndmFrst = ClassRandomForestTab() - cfg.editRstr = EditRaster() - cfg.sieveRstr = SieveRaster() - cfg.ersnRstr = ErosionRaster() - cfg.dltnRstr = DilationRaster() - cfg.clssNghbr = NeighborPixels() - cfg.downProd = DownloadProducts() - cfg.landsatT = LandsatTab() - cfg.ASTERT = ASTERTab() - cfg.MODIST = MODISTab() - cfg.sentinel1T = Sentinel1Tab() - cfg.sentinel2T = Sentinel2Tab() - cfg.sentinel3T = Sentinel3Tab() - cfg.goesT = GOESTab() - cfg.landCC = LandCoverChange() - cfg.classRep = ClassReportTab() - cfg.classTab = ClassificationTab() - cfg.classVect = ClassToVectorTab() - cfg.reclassification = ReclassificationTab() - cfg.sigImport = Signature_Importer() - cfg.mnlROI = ManualROI(cfg.cnvs) - cfg.regionROI = RegionROI(cfg.cnvs) - cfg.dwnlPrdPnt = DownloadProductPointer(cfg.cnvs) - cfg.clipMultiP = ClipMultiplerastersPointer(cfg.cnvs) - cfg.LCSPixel = LCSigPixel(cfg.cnvs) - cfg.LCSPixel2 = LCSigPixel2(cfg.cnvs) - cfg.sets = Settings() - cfg.uiUtls = Ui_Utils() - cfg.ipt = Input() - # connect when map is clicked - cfg.mnlROI.rightClicked.connect(cfg.SCPD.clckR) - cfg.mnlROI.leftClicked.connect(cfg.SCPD.clckL) - cfg.mnlROI.moved.connect(cfg.SCPD.movedPointer) - cfg.regionROI.ROIleftClicked.connect(cfg.SCPD.pointerClickROI) - cfg.regionROI.ROIrightClicked.connect(cfg.SCPD.pointerRightClickROI) - cfg.regionROI.moved.connect(cfg.SCPD.movedPointer) - cfg.clipMultiP.leftClicked.connect(cfg.clipMulti.pointerLeftClick) - cfg.clipMultiP.rightClicked.connect(cfg.clipMulti.pointerRightClick) - cfg.dwnlPrdPnt.leftClicked.connect(cfg.downProd.pointerLeftClick) - cfg.dwnlPrdPnt.rightClicked.connect(cfg.downProd.pointerRightClick) - cfg.classPrev.leftClicked.connect(cfg.SCPD.pointerClickPreview) - cfg.classPrev.rightClicked.connect(cfg.SCPD.pointerRightClickPreview) - cfg.LCSPixel.MaprightClicked.connect(cfg.LCSignT.pointerLeftClick) - cfg.LCSPixel.MapleftClicked.connect(cfg.LCSignT.pointerLeftClick) - cfg.LCSPixel2.MaprightClicked.connect(cfg.spSigPlot.pointerLeftClick) - cfg.LCSPixel2.MapleftClicked.connect(cfg.spSigPlot.pointerLeftClick) - # system variables - cfg.utls.findSystemSpecs() - cfg.utls.readVariables() - # set font - try: - f, s, i = cfg.utls.readQGISVariableFont() - font = cfg.QtGuiSCP.QFont() - font.setFamily(f) - font.setPointSize(int(s)) - cfg.dlg.setFont(font) - cfg.ui.menu_treeWidget.setFont(font) - except: - pass - # initialize plugin directory - cfg.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + '/python/plugins/' + str(__name__).split('.')[0] - # locale name - lclNm = cfg.QSettingsSCP().value('locale/userLocale')[0:2] - self.registryKeys() - if len(cfg.PythonPathSettings) > 0: - mp.set_executable(cfg.PythonPathSettings) - # temporary directory - tmpDir = cfg.utls.getTempDirectory() - cfg.ui.temp_directory_label.setText(tmpDir) - # log file path - cfg.logFile = cfg.tmpDir.replace('//', '/') + '/__0semiautomaticclass.log' - # locale - lclPth = '' - if cfg.QFileInfoSCP(cfg.plgnDir).exists(): - lclPth = cfg.plgnDir + '/i18n/semiautomaticclassificationplugin_' + lclNm + '.qm' - if cfg.QFileInfoSCP(lclPth).exists(): - trnsltr = cfg.QtCoreSCP.QTranslator() - trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(trnsltr) - # info - cfg.sysSCPInfo = str(' SemiAutomaticClass ' + semiautomaticclassVersion() + ' - QGIS v. ' + str(cfg.QGISVer) + ' L:' + lclNm + ' - OS ' + str(cfg.sysSCPNm) + ' - 64bit =' + cfg.sysSCP64bit) - # multiprocess Windows - if cfg.sysSCPNm == 'Windows': - mp.set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - # Mac OS - elif cfg.sysSCPNm == 'Darwin': - dPref = os.environ['PATH'].split(':') - for flPref in dPref: - flPrefPy = os.path.join(flPref, 'python3') - # first test - if os.path.isfile(flPrefPy): - mp.set_executable(flPrefPy) - cfg.sysSCPInfo = cfg.sysSCPInfo + ' - python path =' + flPrefPy - # second test - if 'library' in flPref.lower(): - if os.path.isfile(flPrefPy): - mp.set_executable(flPrefPy) - cfg.sysSCPInfo = cfg.sysSCPInfo + ' - python path =' + flPrefPy - break - # GDAL config - try: - #cfg.gdalSCP.SetConfigOption('GDAL_NUM_THREADS', str(cfg.threads)) - cfg.gdalSCP.SetCacheMax(int(cfg.RAMValue * 0.3 * 1000000)) - cfg.gdalSCP.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'TRUE') - cfg.gdalSCP.SetConfigOption('GDAL_CACHEMAX', '4') - cfg.gdalSCP.SetConfigOption('VSI_CACHE', 'FALSE') - except: - pass + # noinspection PyArgumentList,PyTypeChecker + def __init__(self, iface): + # system information + cfg.system_platform = platform.system() + # QGIS version + qgis_ver = Qgis.QGIS_VERSION_INT + if plugin_check is True: + # set multiprocess path + python_path = None + if cfg.system_platform == 'Windows': + try: + python_path = path.abspath( + path.join(sys.exec_prefix, 'pythonw.exe') + ) + if path.isfile(python_path): + multiprocessing.set_executable(python_path) + else: + # from https://trac.osgeo.org/osgeo4w/ticket/392 + python_path = path.abspath( + path.join(sys.exec_prefix, '../../bin/pythonw.exe') + ) + if path.isfile(python_path): + multiprocessing.set_executable(python_path) + else: + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Error. Python library not found' + ), + level=Qgis.Info + ) + except Exception as err: + str(err) + # reference to QGIS interface + cfg.iface = iface + # reference to map canvas + cfg.map_canvas = iface.mapCanvas() + try: + # create the dialog + cfg.dialog = SemiAutomaticClassificationPluginDialog() + # class dock dialog + cfg.dock_class_dlg = DockClassDialog( + cfg.iface.mainWindow(), cfg.iface + ) + cfg.input_interface = input_interface + # welcome dialog + cfg.widget_dialog = WidgetDialog() + except Exception as err: + str(err) + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Please, restart QGIS for executing the ' + 'Semi-Automatic Classification Plugin' + ), + level=Qgis.Info + ) + cfg.utils = utils + cfg.util_qgis = util_qgis + cfg.util_qt = util_qt + cfg.util_gdal = util_gdal + # spectral signature plot dialog + cfg.spectral_plot_dlg = SpectralSignatureDialog() + # scatter plot dialog + cfg.scatter_plot_dlg = ScatterPlotDialog() + cfg.settings = settings + cfg.ui_utils = UiUtils() + cfg.translate = cfg.ui_utils.translate + cfg.bst = bandset_tab + cfg.signature_plot = spectral_signature_plot + cfg.scatter_plot = scatter_plot + cfg.signature_importer = signature_importer + cfg.usgs_spectral_lib = signature_importer.USGSSpectralLib() + cfg.accuracy = accuracy_tab + cfg.class_report = classification_report_tab + cfg.class_vector = classification_to_vector_tab + cfg.cross_classification = cross_classification_tab + cfg.rgb_composite = rgb_composite_tab + cfg.signature_threshold = signature_threshold_tab + cfg.multiple_roi = multiple_roi_tab + cfg.band_calc = band_calc_tab + cfg.dilation = band_dilation_tab + cfg.stack_bandset = stack_bandset_tab + cfg.split_bands = split_bands_tab + cfg.reproject_bands = reproject_bandset_tab + cfg.masking_bands = masking_bands_tab + cfg.image_conversion = image_conversion_tab + cfg.clip_bands = clip_bands_tab + cfg.clip_bands_pointer = ClipBandsPointer(cfg.map_canvas) + cfg.classification_preview_pointer = ClassificationPreview( + cfg.map_canvas + ) + cfg.download_products = download_products_tab + cfg.download_products_pointer = DownloadProductsPointer( + cfg.map_canvas + ) + cfg.region_growing_pointer = RegionGrowingPointer(cfg.map_canvas) + cfg.manual_roi_pointer = ManualROIPointer(cfg.map_canvas) + cfg.mosaic_bandsets = mosaic_bandsets_tab + cfg.vector_to_raster = vector_to_raster_tab + cfg.erosion = band_erosion_tab + cfg.sieve = band_sieve_tab + cfg.neighbor = band_neighbor_tab + cfg.pca_tab = band_pca_tab + cfg.reclassification = reclassification_tab + cfg.band_combination = band_combination_tab + cfg.classification = classification_tab + cfg.script = script_tab + cfg.scp_dock = scp_dock + # roi rubber band + cfg.scp_dock_rubber_roi = QgsRubberBand( + cfg.map_canvas, QgsWkbTypes.LineGeometry + ) + cfg.scp_dock_rubber_roi.setColor(QColor(0, 255, 255)) + cfg.scp_dock_rubber_roi.setWidth(2) + # set font + try: + q_set = QgsSettings() + f = q_set.value('qgis/stylesheet/fontFamily') + s = q_set.value('qgis/stylesheet/fontPointSize') + font = QFont() + font.setFamily(f) + font.setPointSize(int(s)) + cfg.dialog.setFont(font) + cfg.dialog.ui.menu_treeWidget.setFont(font) + except Exception as err: + str(err) + # plugin directory + cfg.plugin_dir = ('%s/python/plugins/%s' % ( + QFileInfo( + QgsApplication.qgisUserDatabaseFilePath() + ).path(), str(__name__).split('.')[0]) + ) + # locale + locale_settings = QSettings().value('locale/userLocale')[0:2] + registry_keys() + # temporary directory + cfg.temp_dir = get_temporary_directory() + cfg.mx = messages + try: + cfg.rs = remotior_sensus.Session( + n_processes=cfg.qgis_registry[cfg.reg_threads_value], + log_level=20, temporary_directory=cfg.temp_dir, + available_ram=cfg.qgis_registry[cfg.reg_ram_value], + multiprocess_module=multiprocessing, + progress_callback=cfg.ui_utils.update_bar, + messages_callback=cfg.mx + ) + except Exception as err: + str(err) + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Error starting Remotior Sensus' + ), + level=Qgis.Info + ) + if cfg.rs is not None: + # logger + cfg.logger = cfg.rs.configurations.logger + # create BandSet Catalog + cfg.bandset_catalog = cfg.rs.bandset_catalog() + cfg.dialog.ui.temp_directory_label.setText(cfg.temp_dir) + cfg.spectral_signature_plotter = ( + cfg.signature_plot.SpectralSignaturePlot() + ) + cfg.scatter_plotter = ( + cfg.scatter_plot.ScatterPlot() + ) + # locale + locale_path = '' + if QFileInfo(cfg.plugin_dir).exists(): + locale_path = ( + '%s/i18n/semiautomaticclassificationplugin_%s.qm' + % (cfg.plugin_dir, locale_settings) + ) + if QFileInfo(locale_path).exists(): + transl = QTranslator() + transl.load(locale_path) + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(transl) + # info + sys_info = str( + 'SCP %s; QGIS v. %s; L: %s; OS: %s; python: %s' + % (semiautomaticclass_version(), str(qgis_ver), + locale_settings, cfg.system_platform, str(python_path)) + ) + cfg.scp_processing_provider = SCPAlgorithmProvider() + cfg.logger.log.info(sys_info) + + # init GUI + # noinspection PyArgumentList,PyTypeChecker + def initGui(self): + if plugin_check is True and cfg.rs is not None: + try: + cfg.iface.addDockWidget( + Qt.LeftDockWidgetArea, + cfg.dock_class_dlg + ) + except Exception as err: + str(err) + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Please restart QGIS for installing the ' + 'Semi-Automatic Classification Plugin' + ), + level=Qgis.Info + ) + # bandset tab + cfg.bst.add_satellite_to_combo(cfg.rs.configurations.sat_band_list) + cfg.bst.add_unit_to_combo(cfg.rs.configurations.unit_list) + cfg.input_interface.load_input_toolbar() + ''' menu ''' + cfg.input_interface.load_menu() + # set plugin version + cfg.dialog.ui.plugin_version_label.setText( + semiautomaticclass_version() + ) + cfg.dock_class_dlg.ui.plugin_version_label2.setText( + 'SCP %s' % semiautomaticclass_version() + ) + # row height + cfg.dialog.ui.download_images_tableWidget.verticalHeader( + ).setDefaultSectionSize(24) + cfg.dialog.ui.tableWidget_band_calc.verticalHeader( + ).setDefaultSectionSize(24) + cfg.dialog.ui.tableWidget_band_calc.setColumnHidden(1, True) + cfg.band_calc.add_functions_to_table(cfg.band_calc_functions) + cfg.band_calc.add_functions_to_table( + cfg.qgis_registry[cfg.reg_custom_functions] + ) + cfg.dialog.ui.bands_tableWidget.verticalHeader( + ).setDefaultSectionSize(24) + # spectral signature threshold table + cfg.util_qt.insert_table_column( + cfg.dialog.ui.signature_threshold_tableWidget, 7, + cfg.signature_id_column_name, 20, True + ) + sig_table = cfg.dialog.ui.signature_threshold_tableWidget + sig_table.verticalHeader( + ).setDefaultSectionSize(24) + cfg.dialog.ui.point_tableWidget.verticalHeader( + ).setDefaultSectionSize(24) + sig_list = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + # spectral signature plot list + cfg.util_qt.insert_table_column( + sig_list, 6, cfg.signature_id_column_name, 20, True + ) + cfg.util_qt.sort_table_column(sig_list, 3) + cfg.util_qt.set_column_width_list( + sig_list, [[0, 20], [1, 40], [2, 120], [3, 40], [4, 120], + [5, 20]] + ) + sig_list.verticalHeader().setDefaultSectionSize(24) + # scatter plot table + sc_p_list = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + cfg.util_qt.insert_table_column( + sc_p_list, 6, cfg.signature_id_column_name, None, True + ) + try: + sig_list.horizontalHeader().setSectionResizeMode( + 2, QHeaderView.Stretch + ) + sig_list.horizontalHeader().setSectionResizeMode( + 4, QHeaderView.Stretch + ) + except Exception as err: + str(err) + # passwords + cfg.dialog.ui.smtp_password_lineEdit.setEchoMode( + QLineEdit.Password + ) + cfg.dialog.ui.password_earthdata_lineEdit.setEchoMode( + QLineEdit.Password + ) + scatter = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + # scatter plot list + cfg.util_qt.insert_table_column( + scatter, 6, cfg.signature_id_column_name, None, True + ) + cfg.util_qt.sort_table_column(scatter, 3) + cfg.util_qt.set_column_width_list( + scatter, [[0, 30], [1, 40], [2, 100], [3, 40], [4, 100], + [5, 30]] + ) + try: + scatter.horizontalHeader().setSectionResizeMode( + 2, QHeaderView.Stretch + ) + scatter.horizontalHeader().setSectionResizeMode( + 4, QHeaderView.Stretch + ) + except Exception as err: + str(err) + # signature threshold + cfg.util_qt.insert_table_column( + sig_table, 7, + cfg.signature_id_column_name, None, True + ) + cfg.util_qt.set_column_width_list( + sig_table, [[4, 100], [5, 100], [6, 100]] + ) + try: + sig_table.horizontalHeader().setSectionResizeMode( + 1, QHeaderView.Stretch + ) + sig_table.horizontalHeader().setSectionResizeMode( + 3, QHeaderView.Stretch + ) + except Exception as err: + str(err) + # product download tab + cfg.util_qt.set_column_width_list( + cfg.dialog.ui.download_images_tableWidget, + [[0, 100], [1, 400]] + ) + # set log state + cfg.dialog.ui.log_checkBox.setCheckState( + int(cfg.qgis_registry[cfg.reg_log_key]) + ) + if cfg.rs is not None: + if cfg.qgis_registry[cfg.reg_log_key] == 2: + # debug + cfg.rs.set(log_level=10) + cfg.mx.msg_inf_3() + else: + # info + cfg.rs.set(log_level=20) + cfg.logger.log.debug( + 'logger: %s' % cfg.qgis_registry[cfg.reg_log_key] + ) + # set download news state + cfg.dialog.ui.download_news_checkBox.setCheckState( + int(cfg.qgis_registry[cfg.reg_download_news]) + ) + # set raster compression + cfg.dialog.ui.raster_compression_checkBox.setCheckState( + int(cfg.qgis_registry[cfg.reg_raster_compression]) + ) + # set ROI transparency + cfg.dialog.ui.transparency_Slider.setValue( + int(cfg.qgis_registry[cfg.reg_roi_transparency]) + ) + # gdal path + cfg.dialog.ui.gdal_path_lineEdit.setText( + cfg.qgis_registry[cfg.reg_gdal_path] + ) + # ROI color + cfg.dialog.ui.change_color_Button.setStyleSheet( + 'background-color :' + cfg.qgis_registry[cfg.reg_roi_color] + ) + cfg.dialog.ui.transparency_Label.setText( + QApplication.translate( + 'semiautomaticclassificationplugin', 'Transparency ' + ) + str(cfg.qgis_registry[cfg.reg_roi_transparency]) + '%' + ) + cfg.dialog.ui.transparency_Slider.setValue( + cfg.qgis_registry[cfg.reg_roi_transparency] + ) + # set SMTP checkbox state + cfg.dialog.ui.smtp_checkBox.setCheckState( + int(cfg.qgis_registry[cfg.reg_smtp_check]) + ) + if cfg.qgis_registry[cfg.reg_smtp_check] == 2: + cfg.smtp_notification = True + else: + cfg.smtp_notification = False + # set sound state + cfg.dialog.ui.sound_checkBox.setCheckState( + int(cfg.qgis_registry[cfg.reg_sound]) + ) + # raster variable name + cfg.dialog.ui.variable_name_lineEdit.setText( + cfg.qgis_registry[cfg.reg_raster_variable_name] + ) + # group name + cfg.dialog.ui.group_name_lineEdit.setText( + cfg.qgis_registry[cfg.reg_group_name] + ) + # hide tabs + cfg.dialog.ui.SCP_tabs.setStyleSheet( + 'QTabBar::tab {padding: 0px; max-height: 0px;}' + ) + # set window size + cfg.dialog.blockSignals(True) + cfg.dialog.resize( + int(cfg.qgis_registry[cfg.reg_window_size_w]), + int(cfg.qgis_registry[cfg.reg_window_size_h]) + ) + cfg.dialog.blockSignals(False) + cfg.dialog.ui.widget.setMinimumSize(QSize(50, 0)) + cfg.dialog.ui.widget.setMaximumSize(QSize(400, 16777215)) + cfg.dialog.ui.splitter.setSizes( + cfg.qgis_registry[cfg.reg_splitter_sizes] + ) + cfg.dialog.ui.splitter.splitterMoved.connect( + cfg.input_interface.moved_splitter + ) + # set RAM value + cfg.dialog.ui.RAM_spinBox.setValue( + int(cfg.qgis_registry[cfg.reg_ram_value]) + ) + # set CPU value + cfg.dialog.ui.CPU_spinBox.setValue( + cfg.qgis_registry[cfg.reg_threads_value] + ) + try: + # set SMTP server + cfg.dialog.ui.smtp_server_lineEdit.setText( + cfg.qgis_registry[cfg.reg_smtp_server] + ) + # set SMTP to emails + cfg.dialog.ui.to_email_lineEdit.setText( + cfg.qgis_registry[cfg.reg_smtp_emails] + ) + # set SMTP user and password + cfg.dialog.ui.smtp_user_lineEdit.setText( + cfg.qgis_registry[cfg.reg_smtp_user] + ) + if len(cfg.qgis_registry[cfg.reg_smtp_password]) > 0: + smtp_password = cfg.utils.decrypt_password( + cfg.qgis_registry[ + cfg.reg_smtp_password].decode('UTF-8') + ) + cfg.dialog.ui.smtp_password_lineEdit.setText( + smtp_password.decode('UTF-8') + ) + # overwrite registry + cfg.qgis_registry[ + cfg.reg_smtp_password] = cfg.utils.encrypt_password( + smtp_password.decode('UTF-8') + ) + cfg.smtp_password = ( + smtp_password.decode('UTF-8') + ) + except Exception as err: + str(err) + cfg.smtp_user = cfg.qgis_registry[ + cfg.reg_smtp_user] + cfg.smtp_recipients = cfg.qgis_registry[ + cfg.reg_smtp_emails] + cfg.smtp_server = cfg.qgis_registry[ + cfg.reg_smtp_server] + try: + # set earthdata user and password + cfg.dialog.ui.user_earthdata_lineEdit.setText( + cfg.qgis_registry[cfg.reg_earthdata_user] + ) + if cfg.qgis_registry[cfg.reg_earthdata_pass] is not None: + earthdata_pass = cfg.utils.decrypt_password( + cfg.qgis_registry[ + cfg.reg_earthdata_pass].decode('UTF-8') + ) + cfg.dialog.ui.password_earthdata_lineEdit.setText( + earthdata_pass.decode('UTF-8') + ) + except Exception as err: + str(err) + cfg.dialog.ui.dateEdit_to.setDate(QDate.currentDate()) + cfg.dialog.ui.dateEdit_from.setDate( + QDate.currentDate().addDays(-365) + ) + # add satellite list to combo + for product in cfg.rs.configurations.product_list: + cfg.dialog.ui.landsat_satellite_combo.addItem(product) + # add color list to combo + cfg.scatter_plot.add_colormap_to_combo(cfg.scatter_color_map) + cfg.usgs_spectral_lib.add_spectral_library_to_combo() + cfg.neighbor.load_statistic_combo() + # bandset virtual raster + cfg.virtual_bandset_name = cfg.translate('Virtual Band Set ') + cfg.bandset_tab_name = cfg.translate('Band set ') + cfg.scp_layer_name = cfg.translate('SCP training layer') + # connect to project loaded + QgsProject.instance().readProject.connect( + self.project_loaded + ) + # connect to project saved + QgsProject.instance().projectSaved.connect( + self.project_saved + ) + cfg.iface.newProjectCreated.connect(self.new_project_loaded) + cfg.dialog.ui.help_textBrowser.setSearchPaths([cfg.temp_dir]) + registry = QgsApplication.instance().processingRegistry() + registry.addProvider(cfg.scp_processing_provider) + # welcome message + if cfg.first_install == 1: + cfg.input_interface.welcome_text( + 'https://semiautomaticgit.github.io' + '/SemiAutomaticClassificationPluginWelcome/changelog.html' + ) + else: + date_string = cfg.utils.get_date() + cfg.input_interface.welcome_text( + 'https://semiautomaticgit.github.io' + '/SemiAutomaticClassificationPluginWelcome/welcome_%s.html' + % date_string, + 'https://semiautomaticgit.github.io' + '/SemiAutomaticClassificationPluginWelcome/welcome.html' + ) + cfg.logger.log.debug('init GUI') + connect_gui() + else: + dock_class_dlg = DockClassDialog( + qgis_utils.iface.mainWindow(), qgis_utils.iface + ) + qgis_utils.iface.removeDockWidget(dock_class_dlg) + + # save tables when saving project + # noinspection PyArgumentList + @staticmethod + def project_saved(): + cfg.logger.log.debug('project_saved') + cfg.project_registry[ + cfg.reg_bandset_count] = cfg.bandset_catalog.get_bandset_count() + + # download table + cfg.download_products.save_download_table() + for r in cfg.project_registry: + cfg.util_qgis.write_project_variable(r, cfg.project_registry[r]) + # save bandset table + for bandset_number in range( + 1, cfg.project_registry[cfg.reg_bandset_count] + 1 + ): + xml = cfg.bandset_catalog.export_bandset_as_xml( + bandset_number=bandset_number + ) + xml = xml.replace('\n', '') + cfg.util_qgis.write_project_variable( + '%s%s' % (cfg.reg_bandset, bandset_number), xml + ) + + # new project + @staticmethod + def new_project_loaded(): + cfg.logger.log.debug('new_project_loaded') + reset_scp() + + # read project variables + @staticmethod + def project_loaded(): + cfg.logger.log.debug('project_loaded') + reset_scp() + + # remove plugin menu and icon + # noinspection PyTypeChecker + @staticmethod + def unload(): + # write registry keys + try: + for r in cfg.qgis_registry: + cfg.util_qt.write_registry_keys(r, cfg.qgis_registry[r]) + except Exception as err: + try: + cfg.logger.log.error(str(err)) + except Exception as err: + str(err) + try: + cfg.logger.log.debug('unload') + cfg.rs.close() + except Exception as err: + str(err) + try: + qgis_utils.iface.removeDockWidget(cfg.dock_class_dlg) + # remove temp files + except Exception as err: + str(err) + if plugin_check is True: + qgis_utils.iface.messageBar().pushMessage( + 'Semi-Automatic Classification Plugin', + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Please, restart QGIS for executing the ' + 'Semi-Automatic Classification Plugin' + ), + level=Qgis.Info + ) + + +# get first installation +# noinspection PyArgumentList +def get_first_installation(): + cfg.first_install = cfg.util_qt.read_registry_keys( + cfg.reg_first_install, 1 + ) + if cfg.first_install == 1: + cfg.util_qt.write_registry_keys(cfg.reg_first_install, 0) + cfg.utils.find_available_ram() + cfg.utils.find_available_processors() + + +# get temporary directory +# noinspection PyArgumentList +def get_temporary_directory(): + if cfg.temp_dir is None: + temp_dir = str(QDir.tempPath() + '/' + cfg.temp_dir_name) + else: + temp_dir = cfg.temp_dir + if not QDir(temp_dir).exists(): + try: + makedirs(temp_dir) + except Exception as err: + str(err) + cfg.util_qt.write_registry_keys(cfg.reg_temp_dir, temp_dir) + cfg.temp_dir = str(QDir.tempPath() + '/' + cfg.temp_dir_name) + temp_dir = cfg.temp_dir + if not QDir(temp_dir).exists(): + makedirs(temp_dir) + return temp_dir + + +# read registry keys +def registry_keys(): + cfg.temp_dir = cfg.util_qt.read_registry_keys( + cfg.reg_temp_dir, cfg.temp_dir + ) + for r in cfg.qgis_registry: + cfg.qgis_registry[r] = cfg.util_qt.read_registry_keys( + r, cfg.qgis_registry[r] + ) + get_first_installation() + + +def connect_gui(): + cfg.clip_bands_pointer.leftClicked.connect( + cfg.clip_bands.pointer_left_click + ) + cfg.clip_bands_pointer.rightClicked.connect( + cfg.clip_bands.pointer_right_click + ) + cfg.classification_preview_pointer.leftClicked.connect( + cfg.classification.pointer_left_click + ) + cfg.classification_preview_pointer.rightClicked.connect( + cfg.classification.pointer_right_click + ) + cfg.download_products_pointer.leftClicked.connect( + cfg.download_products.pointer_left_click + ) + cfg.download_products_pointer.rightClicked.connect( + cfg.download_products.pointer_right_click + ) + cfg.region_growing_pointer.leftClicked.connect( + cfg.scp_dock.left_click_region_growing + ) + cfg.region_growing_pointer.rightClicked.connect( + cfg.scp_dock.right_click_region_growing + ) + cfg.region_growing_pointer.moved.connect( + cfg.scp_dock.calculate_pixel_expression + ) + cfg.manual_roi_pointer.leftClicked.connect( + cfg.scp_dock.left_click_manual + ) + cfg.manual_roi_pointer.rightClicked.connect( + cfg.scp_dock.right_click_manual + ) + cfg.manual_roi_pointer.moved.connect( + cfg.scp_dock.calculate_pixel_expression + ) + cfg.dialog.resizeEvent = cfg.input_interface.resize_event + cfg.dialog.ui.SCP_tabs.currentChanged.connect( + cfg.input_interface.scp_tab_changed + ) + cfg.dialog.ui.main_tabWidget.currentChanged.connect( + cfg.input_interface.main_tab_changed + ) + cfg.dialog.ui.menu_treeWidget.itemSelectionChanged.connect( + cfg.input_interface.menu_index + ) + cfg.dialog.ui.f_filter_lineEdit.textChanged.connect( + cfg.input_interface.filter_tree + ) + """ Band set""" + cfg.dialog.ui.toolButton_input_raster.clicked.connect( + cfg.bst.add_file_to_band_set_action + ) + # add loaded bands question box + cfg.widget_dialog.ui.buttonBox.accepted.connect(cfg.bst.check_accepted) + cfg.widget_dialog.ui.select_all_toolButton.clicked.connect( + cfg.bst.select_all_bands + ) + cfg.dialog.ui.add_loaded_bands_pushButton.clicked.connect( + cfg.bst.add_loaded_band_to_bandset + ) + cfg.dialog.ui.toolButton_custom_wavelength.clicked.connect( + cfg.bst.set_custom_wavelength_action + ) + cfg.dialog.ui.clear_bandset_toolButton.clicked.connect( + cfg.bst.clear_bandset_action + ) + cfg.dialog.ui.move_up_toolButton.clicked.connect(cfg.bst.move_up_band) + cfg.dialog.ui.move_down_toolButton.clicked.connect(cfg.bst.move_down_band) + cfg.dialog.ui.sort_by_name_toolButton.clicked.connect( + cfg.bst.sort_bands_by_name + ) + cfg.dialog.ui.remove_toolButton.clicked.connect(cfg.bst.remove_band) + cfg.dialog.ui.add_band_set_toolButton.clicked.connect( + cfg.bst.add_bandset_tab_action + ) + cfg.dialog.ui.import_bandset_toolButton.clicked.connect( + cfg.bst.import_bandset + ) + cfg.dialog.ui.export_bandset_toolButton.clicked.connect( + cfg.bst.export_bandset + ) + cfg.dialog.ui.wavelength_sat_combo.currentIndexChanged.connect( + cfg.bst.satellite_wavelength + ) + cfg.dialog.ui.unit_combo.currentIndexChanged.connect( + cfg.bst.satellite_unit + ) + cfg.dialog.ui.bandset_dateEdit.dateChanged.connect( + cfg.bst.set_bandset_date + ) + cfg.dialog.ui.band_set_process_toolButton.clicked.connect( + cfg.bst.perform_bandset_tools + ) + cfg.dialog.ui.band_set_filter_lineEdit.textChanged.connect( + cfg.bst.filter_table + ) + cfg.dialog.ui.bandset_number_spinBox.valueChanged.connect( + cfg.bst.change_bandset_tab_action + ) + cfg.dialog.ui.bandset_tableWidget.doubleClicked.connect( + cfg.bst.change_bandset_table_action + ) + cfg.dialog.ui.bandset_date_lineEdit.editingFinished.connect( + cfg.bst.edit_bandset_date + ) + cfg.dialog.ui.root_dir_lineEdit.editingFinished.connect( + cfg.bst.edit_bandset_root + ) + cfg.dialog.ui.remove_bandset_toolButton.clicked.connect( + cfg.bst.remove_bandsets + ) + cfg.dialog.ui.move_down_toolButton_4.clicked.connect( + cfg.bst.move_down_bandset + ) + cfg.dialog.ui.move_up_toolButton_4.clicked.connect(cfg.bst.move_up_bandset) + cfg.dialog.ui.sort_by_date.clicked.connect(cfg.bst.sort_bandsets_by_date) + cfg.dialog.ui.rgb_toolButton.clicked.connect(cfg.bst.add_composite) + + """ SCP dock """ + cfg.dock_class_dlg.ui.bandset_toolButton.clicked.connect( + cfg.input_interface.bandset_tab + ) + cfg.dock_class_dlg.ui.band_processing_toolButton.clicked.connect( + cfg.input_interface.band_processing_tab + ) + cfg.dock_class_dlg.ui.preprocessing_toolButton_2.clicked.connect( + cfg.input_interface.pre_processing_tab + ) + cfg.dock_class_dlg.ui.postprocessing_toolButton_2.clicked.connect( + cfg.input_interface.post_processing_tab + ) + cfg.dock_class_dlg.ui.bandcalc_toolButton_2.clicked.connect( + cfg.input_interface.band_calc_tab + ) + cfg.dock_class_dlg.ui.download_images_toolButton_2.clicked.connect( + cfg.input_interface.select_download_products_tab + ) + cfg.dock_class_dlg.ui.basic_tools_toolButton.clicked.connect( + cfg.input_interface.basic_tools_tab + ) + cfg.dock_class_dlg.ui.batch_toolButton.clicked.connect( + cfg.input_interface.script_tab + ) + cfg.dock_class_dlg.ui.userguide_toolButton_2.clicked.connect( + cfg.input_interface.quick_guide + ) + cfg.dock_class_dlg.ui.help_toolButton_2.clicked.connect( + cfg.input_interface.ask_help + ) + cfg.dock_class_dlg.ui.tabWidget_dock.currentChanged.connect( + cfg.input_interface.dock_tab_changed + ) + cfg.dock_class_dlg.ui.button_new_input.clicked.connect( + cfg.scp_dock.create_training_input + ) + cfg.dock_class_dlg.ui.button_reset_input.clicked.connect( + cfg.scp_dock.reset_input + ) + cfg.dock_class_dlg.ui.button_Save_ROI.clicked.connect( + cfg.scp_dock.save_roi_to_training + ) + cfg.dock_class_dlg.ui.undo_save_Button.clicked.connect( + cfg.scp_dock.undo_saved_roi + ) + cfg.dock_class_dlg.ui.redo_save_Button.clicked.connect( + cfg.scp_dock.redo_saved_roi + ) + cfg.dock_class_dlg.ui.signature_checkBox.stateChanged.connect( + cfg.scp_dock.signature_checkbox + ) + cfg.dock_class_dlg.ui.scatterPlot_toolButton.clicked.connect( + cfg.scp_dock.add_roi_to_scatter_plot + ) + cfg.dock_class_dlg.ui.save_input_checkBox.stateChanged.connect( + cfg.scp_dock.save_input_checkbox + ) + cfg.dock_class_dlg.ui.trainingFile_toolButton.clicked.connect( + cfg.scp_dock.open_training_input_file + ) + cfg.dock_class_dlg.ui.export_signature_list_toolButton.clicked.connect( + cfg.input_interface.export_signatures_tab + ) + cfg.dock_class_dlg.ui.import_library_toolButton.clicked.connect( + cfg.input_interface.import_signatures_tab + ) + cfg.dock_class_dlg.ui.signature_spectral_plot_toolButton.clicked.connect( + cfg.scp_dock.add_signature_to_spectral_plot + ) + cfg.dock_class_dlg.ui.ROI_filter_lineEdit.textChanged.connect( + cfg.scp_dock.filter_tree + ) + cfg.dock_class_dlg.ui.delete_Signature_Button.clicked.connect( + cfg.scp_dock.remove_selected_signatures + ) + cfg.dock_class_dlg.ui.merge_signature_toolButton.clicked.connect( + cfg.scp_dock.merge_signatures + ) + cfg.dock_class_dlg.ui.calculate_signature_toolButton.clicked.connect( + cfg.scp_dock.calculate_signatures + ) + cfg.dock_class_dlg.ui.ROI_Macroclass_ID_spin.valueChanged.connect( + cfg.scp_dock.roi_macroclass_id_value + ) + cfg.dock_class_dlg.ui.max_buffer_spinBox.valueChanged.connect( + cfg.scp_dock.max_buffer + ) + cfg.dock_class_dlg.ui.ROI_Macroclass_line.editingFinished.connect( + cfg.scp_dock.roi_macroclass_name_info + ) + cfg.dock_class_dlg.ui.custom_index_lineEdit.editingFinished.connect( + cfg.scp_dock.custom_expression_edited + ) + cfg.dock_class_dlg.ui.ROI_ID_spin.valueChanged.connect( + cfg.scp_dock.roi_class_id_value + ) + cfg.dock_class_dlg.ui.ROI_Class_line.editingFinished.connect( + cfg.scp_dock.roi_class_name_info + ) + cfg.dock_class_dlg.ui.display_cursor_checkBox.stateChanged.connect( + cfg.scp_dock.vegetation_index_checkbox + ) + cfg.dock_class_dlg.ui.rapid_ROI_checkBox.stateChanged.connect( + cfg.scp_dock.rapid_roi_checkbox + ) + cfg.dock_class_dlg.ui.rapidROI_band_spinBox.valueChanged.connect( + cfg.scp_dock.rapid_roi_band + ) + + """ Download product""" + cfg.dialog.ui.find_images_toolButton.clicked.connect( + cfg.download_products.find_images + ) + cfg.dialog.ui.selectUL_toolButton_3.clicked.connect( + cfg.download_products.pointer_active + ) + cfg.dialog.ui.toolButton_display.clicked.connect( + cfg.download_products.display_images + ) + cfg.dialog.ui.toolButton_OSM.clicked.connect( + cfg.download_products.display_osm + ) + cfg.dialog.ui.remove_image_toolButton.clicked.connect( + cfg.download_products.remove_image_from_table + ) + cfg.dialog.ui.clear_table_toolButton.clicked.connect( + cfg.download_products.clear_table + ) + cfg.dialog.ui.download_images_Button.clicked.connect( + cfg.download_products.download_images_action + ) + cfg.dialog.ui.export_links_Button.clicked.connect( + cfg.download_products.export_links + ) + cfg.dialog.ui.import_table_pushButton.clicked.connect( + cfg.download_products.import_table_text + ) + cfg.dialog.ui.export_table_pushButton.clicked.connect( + cfg.download_products.export_table_to_text + ) + cfg.dialog.ui.show_area_radioButton_2.clicked.connect( + cfg.download_products.show_hide_area + ) + cfg.dialog.ui.check_toolButton_2.clicked.connect( + cfg.download_products.check_all_bands + ) + cfg.dialog.ui.remember_user_checkBox_3.stateChanged.connect( + cfg.download_products.remember_user_earthdata_checkbox + ) + cfg.dialog.ui.user_earthdata_lineEdit.editingFinished.connect( + cfg.download_products.remember_user_earthdata + ) + cfg.dialog.ui.password_earthdata_lineEdit.editingFinished.connect( + cfg.download_products.remember_user_earthdata + ) + cfg.dialog.ui.download_images_tableWidget.itemSelectionChanged.connect( + cfg.download_products.table_click + ) + cfg.dialog.ui.products_filter_lineEdit.textChanged.connect( + cfg.download_products.filter_table + ) + + """ Basic tools """ + + """ RGB composite """ + cfg.dialog.ui.RGB_tableWidget.cellChanged.connect( + cfg.rgb_composite.edited_table + ) + cfg.dialog.ui.add_RGB_pushButton.clicked.connect( + cfg.rgb_composite.add_composite_to_table + ) + cfg.dialog.ui.remove_RGB_toolButton.clicked.connect( + cfg.rgb_composite.remove_composite_from_table + ) + cfg.dialog.ui.sort_by_name_toolButton_2.clicked.connect( + cfg.rgb_composite.sort_composite_names + ) + cfg.dialog.ui.clear_RGB_list_toolButton.clicked.connect( + cfg.rgb_composite.clear_table_action + ) + cfg.dialog.ui.move_up_toolButton_3.clicked.connect( + cfg.rgb_composite.move_up_composite + ) + cfg.dialog.ui.move_down_toolButton_3.clicked.connect( + cfg.rgb_composite.move_down_composite + ) + cfg.dialog.ui.all_RGB_list_toolButton.clicked.connect( + cfg.rgb_composite.calculate_all_composites_action + ) + cfg.dialog.ui.export_RGB_List_toolButton.clicked.connect( + cfg.rgb_composite.export_rgb_list + ) + cfg.dialog.ui.import_RGB_List_toolButton.clicked.connect( + cfg.rgb_composite.import_rgb_list_from_file + ) + """ Signature threshold """ + cfg.dialog.ui.signature_threshold_tableWidget.cellChanged.connect( + cfg.signature_threshold.edited_threshold_table + ) + cfg.dialog.ui.automatic_threshold_pushButton.clicked.connect( + cfg.signature_threshold.set_all_weights_from_variance + ) + cfg.dialog.ui.set_threshold_value_pushButton.clicked.connect( + cfg.signature_threshold.set_thresholds + ) + cfg.dialog.ui.reset_threshold_pushButton.clicked.connect( + cfg.signature_threshold.reset_thresholds + ) + """ Export spectral signature """ + cfg.dialog.ui.export_SCP_pushButton.clicked.connect( + cfg.scp_dock.export_signature_file + ) + cfg.dialog.ui.export_SHP_pushButton.clicked.connect( + cfg.scp_dock.export_signature_vector + ) + cfg.dialog.ui.export_CSV_library_toolButton.clicked.connect( + cfg.scp_dock.export_signature_as_csv + ) + + """ Import spectral signature """ + cfg.dialog.ui.open_library_pushButton.clicked.connect( + cfg.scp_dock.import_library_file + ) + cfg.dialog.ui.open_shapefile_pushButton.clicked.connect( + cfg.scp_dock.open_vector + ) + cfg.dialog.ui.import_shapefile_pushButton.clicked.connect( + cfg.scp_dock.import_vector + ) + cfg.dialog.ui.usgs_chapter_comboBox.currentIndexChanged.connect( + cfg.usgs_spectral_lib.chapter_changed + ) + cfg.dialog.ui.usgs_library_comboBox.currentIndexChanged.connect( + cfg.usgs_spectral_lib.library_changed + ) + cfg.dialog.ui.add_usgs_library_pushButton.clicked.connect( + cfg.usgs_spectral_lib.add_signature_to_catalog + ) + """ Multiple ROI """ + cfg.dialog.ui.add_point_pushButton.clicked.connect( + cfg.multiple_roi.add_row_to_table + ) + cfg.dialog.ui.add_random_point_pushButton.clicked.connect( + cfg.multiple_roi.create_random_point + ) + cfg.dialog.ui.remove_point_pushButton.clicked.connect( + cfg.multiple_roi.remove_row_from_table + ) + cfg.dialog.ui.save_point_rois_pushButton.clicked.connect( + cfg.multiple_roi.create_roi_from_points + ) + cfg.dialog.ui.import_point_list_pushButton.clicked.connect( + cfg.multiple_roi.import_points_csv + ) + cfg.dialog.ui.export_point_list_pushButton.clicked.connect( + cfg.multiple_roi.export_point_list + ) + cfg.dialog.ui.signature_checkBox2.stateChanged.connect( + cfg.multiple_roi.signature_checkbox_2 + ) + cfg.dialog.ui.stratified_lineEdit.textChanged.connect( + cfg.multiple_roi.expression_text_edited + ) + + """ Preprocessing """ + + """ Clip raster bands """ + cfg.dialog.ui.clip_Button.clicked.connect(cfg.clip_bands.clip_bands_action) + cfg.dialog.ui.clip_multiple_rasters.clicked.connect( + cfg.clip_bands.set_script + ) + cfg.dialog.ui.selectUL_toolButton.clicked.connect( + cfg.clip_bands.pointer_active + ) + cfg.dialog.ui.toolButton_reload_8.clicked.connect( + cfg.clip_bands.refresh_layers + ) + cfg.dialog.ui.show_area_radioButton_3.clicked.connect( + cfg.clip_bands.show_hide_area + ) + cfg.dialog.ui.vector_radioButton.toggled.connect( + cfg.clip_bands.vector_changed + ) + cfg.dialog.ui.temporary_ROI_radioButton.toggled.connect( + cfg.clip_bands.roi_changed + ) + cfg.dialog.ui.coordinates_radioButton.toggled.connect( + cfg.clip_bands.coordinates_changed + ) + cfg.dialog.ui.shapefile_comboBox.currentIndexChanged.connect( + cfg.clip_bands.reference_layer_name + ) + """ Image conversion """ + cfg.dialog.ui.toolButton_directoryInput.clicked.connect( + cfg.image_conversion.input_image + ) + cfg.dialog.ui.toolButton_directoryInput_MTL.clicked.connect( + cfg.image_conversion.input_metadata + ) + cfg.dialog.ui.pushButton_Conversion.clicked.connect( + cfg.image_conversion.perform_conversion + ) + cfg.dialog.ui.landsat_conversion.clicked.connect( + cfg.image_conversion.set_script + ) + cfg.dialog.ui.pushButton_remove_band.clicked.connect( + cfg.image_conversion.remove_highlighted_band + ) + """ Masking bands """ + cfg.dialog.ui.cloud_mask_toolButton.clicked.connect( + cfg.masking_bands.mask_action + ) + cfg.dialog.ui.toolButton_reload_23.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.cloud_masking.clicked.connect(cfg.masking_bands.set_script) + cfg.dialog.ui.cloud_mask_classes_lineEdit.textChanged.connect( + cfg.masking_bands.text_changed + ) + """ Mosaic band sets """ + cfg.dialog.ui.mosaic_bandsets_toolButton.clicked.connect( + cfg.mosaic_bandsets.mosaic_action + ) + cfg.dialog.ui.mosaic_bandsets.clicked.connect( + cfg.mosaic_bandsets.set_script + ) + cfg.dialog.ui.mosaic_band_sets_lineEdit.textChanged.connect( + cfg.mosaic_bandsets.text_changed + ) + """ Vector to Raster""" + cfg.dialog.ui.toolButton_reload_16.clicked.connect( + cfg.vector_to_raster.reload_vector_list + ) + cfg.dialog.ui.toolButton_reload_17.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.convert_vector_toolButton.clicked.connect( + cfg.vector_to_raster.convert_to_raster_action + ) + cfg.dialog.ui.vector_to_raster.clicked.connect( + cfg.vector_to_raster.set_script + ) + cfg.dialog.ui.vector_name_combo.currentIndexChanged.connect( + cfg.utils.refresh_vector_fields + ) + """ Stack raster bands """ + cfg.dialog.ui.stack_Button.clicked.connect(cfg.stack_bandset.stack_action) + cfg.dialog.ui.stack_raster_bands.clicked.connect( + cfg.stack_bandset.set_script + ) + """ Split """ + cfg.dialog.ui.toolButton_reload_9.clicked.connect( + cfg.split_bands.refresh_reference_layer + ) + cfg.dialog.ui.split_Button.clicked.connect(cfg.split_bands.split_raster) + cfg.dialog.ui.split_raster_bands.clicked.connect( + cfg.split_bands.set_script + ) + """ Reproject raster bands """ + cfg.dialog.ui.toolButton_reload_25.clicked.connect( + cfg.reproject_bands.refresh_reference_layer + ) + cfg.dialog.ui.align_radioButton.toggled.connect( + cfg.reproject_bands.radio_align_changed + ) + cfg.dialog.ui.epsg_radioButton.toggled.connect( + cfg.reproject_bands.radio_epsg_changed + ) + cfg.dialog.ui.reproject_Button.clicked.connect( + cfg.reproject_bands.reproject_bands_action + ) + cfg.dialog.ui.reproject_raster_bands.clicked.connect( + cfg.reproject_bands.set_script + ) + + """ Band processing """ + + """ Classification """ + cfg.dialog.ui.toolBox_classification.currentChanged.connect( + cfg.classification.changed_tab + ) + + cfg.dialog.ui.macroclass_radioButton.toggled.connect( + cfg.classification.macroclass_radio + ) + cfg.dialog.ui.class_radioButton.toggled.connect( + cfg.classification.class_radio + ) + cfg.dialog.ui.linear_scaling_radioButton.toggled.connect( + cfg.classification.linear_scaling_radio + ) + cfg.dialog.ui.z_score_radioButton.toggled.connect( + cfg.classification.z_scaling_radio + ) + cfg.dialog.ui.signature_threshold_button_2.clicked.connect( + cfg.input_interface.signature_threshold_tab + ) + cfg.dialog.ui.signature_threshold_button_4.clicked.connect( + cfg.input_interface.signature_threshold_tab + ) + cfg.dialog.ui.signature_threshold_button_3.clicked.connect( + cfg.input_interface.signature_threshold_tab + ) + cfg.dialog.ui.load_classifier_Button.clicked.connect( + cfg.classification.open_classifier + ) + cfg.dialog.ui.button_classification.clicked.connect( + cfg.classification.run_classification_action + ) + cfg.dialog.ui.save_classifier_button.clicked.connect( + cfg.classification.save_classifier_action + ) + cfg.dialog.ui.classification.clicked.connect(cfg.classification.set_script) + """ Band set combination""" + cfg.dialog.ui.calculateBandSetComb_toolButton.clicked.connect( + cfg.band_combination.calculate_band_combination + ) + cfg.dialog.ui.band_combination.clicked.connect( + cfg.band_combination.set_script + ) + """ Band dilation""" + cfg.dialog.ui.band_dilation_toolButton.clicked.connect( + cfg.dilation.dilation_action + ) + cfg.dialog.ui.dilation_classes_lineEdit.textChanged.connect( + cfg.dilation.text_changed + ) + cfg.dialog.ui.band_dilation.clicked.connect(cfg.dilation.set_script) + """ Band erosion""" + cfg.dialog.ui.class_erosion_toolButton.clicked.connect( + cfg.erosion.band_erosion_action + ) + cfg.dialog.ui.erosion_classes_lineEdit.textChanged.connect( + cfg.erosion.text_changed + ) + cfg.dialog.ui.classification_erosion.clicked.connect( + cfg.erosion.set_script + ) + """ Band sieve""" + cfg.dialog.ui.sieve_toolButton.clicked.connect(cfg.sieve.band_sieve) + cfg.dialog.ui.classification_sieve.clicked.connect(cfg.sieve.set_script) + """ Band neighbor""" + cfg.dialog.ui.class_neighbor_toolButton.clicked.connect( + cfg.neighbor.band_neighbor_action + ) + cfg.dialog.ui.neighbor_pixels.clicked.connect(cfg.neighbor.set_script) + cfg.dialog.ui.toolButton_input_matrix.clicked.connect( + cfg.neighbor.input_matrix_file + ) + """ Band PCA""" + cfg.dialog.ui.pca_Button.clicked.connect(cfg.pca_tab.calculate_pca_action) + cfg.dialog.ui.pca.clicked.connect(cfg.pca_tab.set_script) + + """ Post processing""" + + """ Accuracy""" + cfg.dialog.ui.toolButton_reload_4.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.reference_name_combo.currentIndexChanged.connect( + cfg.accuracy.reference_layer_name + ) + cfg.dialog.ui.buttonReload_shape_4.clicked.connect( + cfg.accuracy.refresh_reference_layer + ) + cfg.dialog.ui.calculateMatrix_toolButton.clicked.connect( + cfg.accuracy.calculate_error_matrix + ) + cfg.dialog.ui.accuracy.clicked.connect(cfg.accuracy.set_script) + """ Classification report """ + cfg.dialog.ui.toolButton_reload_10.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.calculateReport_toolButton.clicked.connect( + cfg.class_report.calculate_classification_report + ) + cfg.dialog.ui.classification_report.clicked.connect( + cfg.class_report.set_script + ) + """ Classification to vector """ + cfg.dialog.ui.toolButton_reload_11.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.convert_toolButton.clicked.connect( + cfg.class_vector.convert_classification_to_vector_action + ) + cfg.dialog.ui.classification_to_vector.clicked.connect( + cfg.class_vector.set_script + ) + """ Cross classification""" + cfg.dialog.ui.toolButton_reload_21.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.reference_name_combo_2.currentIndexChanged.connect( + cfg.cross_classification.reference_layer_name + ) + cfg.dialog.ui.buttonReload_shape_5.clicked.connect( + cfg.cross_classification.refresh_reference_layer + ) + cfg.dialog.ui.calculatecrossClass_toolButton.clicked.connect( + cfg.cross_classification.cross_classification_action + ) + cfg.dialog.ui.cross_classification.clicked.connect( + cfg.cross_classification.set_script + ) + """ Reclassification """ + cfg.dialog.ui.toolButton_reload_12.clicked.connect( + cfg.utils.refresh_raster_layer + ) + cfg.dialog.ui.reclassify_toolButton.clicked.connect( + cfg.reclassification.reclassify_action + ) + cfg.dialog.ui.calculate_unique_values_toolButton.clicked.connect( + cfg.reclassification.calculate_unique_values + ) + cfg.dialog.ui.incremental_new_values_toolButton.clicked.connect( + cfg.reclassification.incremental_new_values + ) + cfg.dialog.ui.add_value_pushButton.clicked.connect( + cfg.reclassification.add_row + ) + cfg.dialog.ui.remove_row_pushButton.clicked.connect( + cfg.reclassification.remove_row + ) + cfg.dialog.ui.import_reclass_toolButton.clicked.connect( + cfg.reclassification.import_reclass + ) + cfg.dialog.ui.export_reclass_toolButton.clicked.connect( + cfg.reclassification.export_reclass + ) + cfg.dialog.ui.reclass_values_tableWidget.cellChanged.connect( + cfg.reclassification.edited_cell + ) + cfg.dialog.ui.reclassification.clicked.connect( + cfg.reclassification.set_script + ) + + """ Band Calc""" + cfg.dialog.ui.toolButton_reload_13.clicked.connect( + cfg.band_calc.raster_band_table + ) + cfg.dialog.ui.plainTextEdit_calc.textChanged.connect( + cfg.band_calc.text_changed + ) + cfg.dialog.ui.tableWidget_band_calc.doubleClicked.connect( + cfg.band_calc.double_click + ) + cfg.dialog.ui.bandcalc_filter_lineEdit.textChanged.connect( + cfg.band_calc.filter_table + ) + cfg.dialog.ui.toolButton_import_expression.clicked.connect( + cfg.band_calc.import_expression_list + ) + cfg.dialog.ui.band_calc_function_tableWidget.doubleClicked.connect( + cfg.band_calc.set_function + ) + cfg.dialog.ui.toolButton_calculate.clicked.connect( + cfg.band_calc.calculate_button + ) + + """ Script""" + cfg.dialog.ui.clear_batch_toolButton.clicked.connect(cfg.script.clear_text) + cfg.dialog.ui.copy_script.clicked.connect(cfg.script.copy_text) + cfg.dialog.ui.save_script_button.clicked.connect(cfg.script.save_script) + + """ Settings""" + cfg.dialog.ui.variable_name_lineEdit.textChanged.connect( + cfg.settings.raster_variable_name_change + ) + cfg.dialog.ui.group_name_lineEdit.textChanged.connect( + cfg.settings.group_name_change + ) + cfg.dialog.ui.smtp_server_lineEdit.textChanged.connect( + cfg.settings.smtp_server_change + ) + cfg.dialog.ui.to_email_lineEdit.textChanged.connect( + cfg.settings.smtp_to_emails_change + ) + cfg.dialog.ui.smtp_user_lineEdit.editingFinished.connect( + cfg.settings.remember_user + ) + cfg.dialog.ui.smtp_password_lineEdit.editingFinished.connect( + cfg.settings.remember_user + ) + cfg.dialog.ui.remeber_settings_checkBox.stateChanged.connect( + cfg.settings.remember_user_checkbox + ) + cfg.dialog.ui.smtp_checkBox.stateChanged.connect( + cfg.settings.smtp_checkbox + ) + cfg.dialog.ui.reset_variable_name_Button.clicked.connect( + cfg.settings.reset_raster_variable_name + ) + cfg.dialog.ui.reset_group_name_Button.clicked.connect( + cfg.settings.reset_group_name + ) + cfg.dialog.ui.log_checkBox.stateChanged.connect( + cfg.settings.log_checkbox_change + ) + cfg.dialog.ui.download_news_checkBox.stateChanged.connect( + cfg.settings.download_news_change + ) + cfg.dialog.ui.sound_checkBox.stateChanged.connect( + cfg.settings.sound_checkbox_change + ) + cfg.dialog.ui.raster_compression_checkBox.stateChanged.connect( + cfg.settings.raster_compression_checkbox + ) + cfg.dialog.ui.temp_directory_Button.clicked.connect( + cfg.settings.change_temp_dir + ) + cfg.dialog.ui.reset_temp_directory_Button.clicked.connect( + cfg.settings.reset_temp_dir + ) + cfg.dialog.ui.exportLog_Button.clicked.connect(cfg.settings.copy_log_file) + cfg.dialog.ui.test_dependencies_Button.clicked.connect( + cfg.settings.test_dependencies + ) + cfg.dialog.ui.RAM_spinBox.valueChanged.connect( + cfg.settings.ram_setting_change + ) + cfg.dialog.ui.CPU_spinBox.valueChanged.connect( + cfg.settings.threads_setting_change + ) + cfg.dialog.ui.gdal_path_lineEdit.textChanged.connect( + cfg.settings.gdal_path_change + ) + cfg.dialog.ui.change_color_Button.clicked.connect( + cfg.settings.change_roi_color + ) + cfg.dialog.ui.reset_color_Button.clicked.connect( + cfg.settings.reset_roi_style + ) + cfg.dialog.ui.transparency_Slider.valueChanged.connect( + cfg.settings.change_roi_transparency + ) - # read registry keys - def registryKeys(self): - ''' registry keys ''' - cfg.firstInstallVal = cfg.utls.readRegistryKeys(cfg.regFirstInstall, cfg.firstInstallVal) - cfg.logSetVal = cfg.utls.readRegistryKeys(cfg.regLogKey, cfg.logSetVal) - cfg.downNewsVal = cfg.utls.readRegistryKeys(cfg.downNewsKey, cfg.downNewsVal) - cfg.vrtRstProjVal = cfg.utls.readRegistryKeys(cfg.vrtRstProjKey, cfg.vrtRstProjVal) - cfg.ROIClrVal = cfg.utls.readRegistryKeys(cfg.regROIClr, cfg.ROIClrVal) - cfg.ROITrnspVal = int(cfg.utls.readRegistryKeys(cfg.regROITransp, cfg.ROITrnspVal)) - cfg.outTempRastFormat = cfg.utls.readRegistryKeys(cfg.regTempRasterFormat, str(cfg.outTempRastFormat)) - cfg.rasterCompression = cfg.utls.readRegistryKeys(cfg.regRasterCompression, str(cfg.rasterCompression)) - cfg.parallelWritingCheck = cfg.utls.readRegistryKeys(cfg.regparallelWritingCheck, str(cfg.parallelWritingCheck)) - cfg.RAMValue = int(cfg.utls.readRegistryKeys(cfg.regRAMValue, str(cfg.RAMValue))) - cfg.threads = int(cfg.utls.readRegistryKeys(cfg.regThreadsValue, str(cfg.threads))) - cfg.gdalPath = cfg.utls.readRegistryKeys(cfg.regGDALPathSettings, str(cfg.gdalPath)) - cfg.PythonPathSettings = cfg.utls.readRegistryKeys(cfg.regPythonPathSettings, str(cfg.PythonPathSettings)) - cfg.PythonModulesPathSettings = cfg.utls.readRegistryKeys(cfg.regPythonModulesPathSettings, str(cfg.PythonModulesPathSettings)) - cfg.tmpDir = cfg.utls.readRegistryKeys(cfg.regTmpDir, cfg.tmpDir) - cfg.fldID_class = cfg.utls.readRegistryKeys(cfg.regIDFieldName, cfg.fldID_class) - cfg.fldMacroID_class = cfg.utls.readRegistryKeys(cfg.regMacroIDFieldName, cfg.fldMacroID_class) - cfg.macroclassCheck = cfg.utls.readRegistryKeys(cfg.regConsiderMacroclass, cfg.macroclassCheck) - cfg.sentinelAlternativeSearch = cfg.utls.readRegistryKeys(cfg.regSentinelAlternativeSearch, cfg.sentinelAlternativeSearch) - cfg.LCsignatureCheckBox = cfg.utls.readRegistryKeys(cfg.regLCSignature, cfg.LCsignatureCheckBox) - cfg.fldROI_info = cfg.utls.readRegistryKeys(cfg.regInfoFieldName, cfg.fldROI_info) - cfg.fldROIMC_info = cfg.utls.readRegistryKeys(cfg.regMCInfoFieldName, cfg.fldROIMC_info) - cfg.variableName = cfg.utls.readRegistryKeys(cfg.regVariableName, cfg.variableName) - cfg.vectorVariableName = cfg.utls.readRegistryKeys(cfg.regVectorVariableName, cfg.vectorVariableName) - cfg.SMTPCheck = cfg.utls.readRegistryKeys(cfg.regSMTPCheck, cfg.SMTPCheck) - cfg.SMTPServer = cfg.utls.readRegistryKeys(cfg.regSMTPServer, cfg.SMTPServer) - cfg.SMTPtoEmails = cfg.utls.readRegistryKeys(cfg.regSMTPtoEmails, cfg.SMTPtoEmails) - cfg.SMTPUser = cfg.utls.readRegistryKeys(cfg.regSMTPUser, cfg.SMTPUser) - cfg.SMTPPassword = cfg.utls.readRegistryKeys(cfg.regSMTPPassword, cfg.SMTPPassword) - cfg.USGSUser = cfg.utls.readRegistryKeys(cfg.regUSGSUser, cfg.USGSUser) - cfg.USGSPass = cfg.utls.readRegistryKeys(cfg.regUSGSPass, cfg.USGSPass) - cfg.USGSUserASTER = cfg.utls.readRegistryKeys(cfg.regUSGSUserASTER, cfg.USGSUserASTER) - cfg.USGSPassASTER = cfg.utls.readRegistryKeys(cfg.regUSGSPassASTER, cfg.USGSPassASTER) - cfg.SciHubUser = cfg.utls.readRegistryKeys(cfg.regSciHubUser, cfg.SciHubUser) - cfg.SciHubService = cfg.utls.readRegistryKeys(cfg.regSciHubService, cfg.SciHubService) - cfg.SciHubPass = cfg.utls.readRegistryKeys(cfg.regSciHubPass, cfg.SciHubPass) - cfg.sigPLRoundCharList = cfg.roundCharList - cfg.scatPlRoundCharList = cfg.roundCharList - cfg.grpNm = cfg.utls.readRegistryKeys(cfg.regGroupName, cfg.grpNm) - cfg.rasterDataType = cfg.utls.readRegistryKeys(cfg.regRasterDataType, cfg.rasterDataType) - cfg.expressionListBC = cfg.utls.readRegistryKeys(cfg.regExpressionListBC, cfg.expressionListBC) - cfg.soundVal = cfg.utls.readRegistryKeys(cfg.regSound, cfg.soundVal) - cfg.windowSizeW = cfg.utls.readRegistryKeys(cfg.regWindowSizeW, cfg.windowSizeW) - cfg.windowSizeH = cfg.utls.readRegistryKeys(cfg.regWindowSizeH, cfg.windowSizeH) - cfg.splitterSizeS = cfg.utls.readRegistryKeys(cfg.regSplitterSizeS, cfg.splitterSizeS) + """ Spectral signature plot """ + cfg.spectral_plot_dlg.ui.band_lines_checkBox.stateChanged.connect( + cfg.spectral_signature_plotter.refresh_plot + ) + cfg.spectral_plot_dlg.ui.grid_checkBox.stateChanged.connect( + cfg.spectral_signature_plotter.grid_checkbox + ) + cfg.spectral_plot_dlg.ui.sigma_checkBox.stateChanged.connect( + cfg.spectral_signature_plotter.sigma_checkbox + ) + cfg.spectral_plot_dlg.ui.add_signature_list_pushButton.clicked.connect( + cfg.spectral_signature_plotter.add_to_signature_list + ) + cfg.spectral_plot_dlg.ui.remove_Signature_Button.clicked.connect( + cfg.spectral_signature_plotter.remove_signature + ) + cfg.spectral_plot_dlg.ui.fitToAxes_pushButton.clicked.connect( + cfg.spectral_signature_plotter.fit_plot_to_axes + ) + button_1 = cfg.spectral_plot_dlg.ui.calculate_spectral_distance_Button + button_1.clicked.connect( + cfg.spectral_signature_plotter.calculate_spectral_distances + ) + cfg.spectral_plot_dlg.ui.plot_text_spinBox.valueChanged.connect( + cfg.spectral_signature_plotter.set_plot_legend_length + ) + cfg.spectral_plot_dlg.ui.save_plot_pushButton.clicked.connect( + cfg.spectral_signature_plotter.save_plot + ) + table_1 = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + table_1.doubleClicked.connect( + cfg.spectral_signature_plotter.signature_list_double_click + ) + table_1.cellChanged.connect(cfg.spectral_signature_plotter.edited_cell) - def initGui(self): - if PluginCheck == 'Yes': - try: - cfg.iface.addDockWidget(cfg.QtSCP.LeftDockWidgetArea, cfg.dockclassdlg) - except: - msg = '' - try: - import scipy.stats.distributions as statdistr - except: - msg = 'SciPy' - try: - from matplotlib.ticker import MaxNLocator - except: - msg = 'Matplotlib' - try: - import numpy as np - except: - msg = 'NumPy' - try: - from osgeo import gdal - except: - msg = 'Gdal' - if len(msg) > 0: - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Semi-Automatic Classification Plugin possible missing dependecies: ' + msg), level=qgisCore.Qgis.Info) - else: - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Please restart QGIS for installing the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Info) - return - from .modules.modules import Modules - cfg.SCPModules = Modules() - cfg.SCPModules.loading() - cfg.ipt.loadInputToolbar() - cfg.algName = cfg.algMinDist - cfg.ui.algorithm_combo.setCurrentIndex(0) - # vector to raster type of conversion - cfg.ui.conversion_type_combo.addItem(cfg.convCenterPixels) - cfg.ui.conversion_type_combo.addItem(cfg.convAllPixelsTouch) - cfg.centerOfPixels = cfg.ui.conversion_type_combo.itemText(0) - ''' menu ''' - cfg.ipt.loadMenu() - # set plugin version - cfg.ui.plugin_version_label.setText(semiautomaticclassVersion()) - cfg.uidc.plugin_version_label2.setText('SCP ' + semiautomaticclassVersion()) - # row height - cfg.ui.download_images_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.ui.tableWidget_band_calc.verticalHeader().setDefaultSectionSize(24) - cfg.ui.landsat_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.ui.sentinel_2_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.utls.setColumnWidthList(cfg.ui.sentinel_2_tableWidget, [[0, 400], [1, 200], [2, 60]]) - cfg.ui.ASTER_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.utls.setColumnWidthList(cfg.ui.ASTER_tableWidget, [[0, 400], [1, 200], [2, 60]]) - cfg.ui.MODIS_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.utls.setColumnWidthList(cfg.ui.MODIS_tableWidget, [[0, 400], [1, 200], [2, 60]]) - cfg.ui.LCS_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.ui.signature_threshold_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.ui.point_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.ui.log_tableWidget.verticalHeader().setDefaultSectionSize(24) - cfg.utls.setColumnWidthList(cfg.ui.log_tableWidget, [[0, 100], [1, 200], [2, 800]]) - cfg.utls.setColumnWidthList(cfg.ui.band_set_list_tableWidget, [[0, 100], [1, 600], [2, 40]]) - # spectral signature plot list - cfg.utls.insertTableColumn(cfg.uisp.signature_list_plot_tableWidget, 6, cfg.tableColString, None, 'Yes') - cfg.utls.sortTableColumn(cfg.uisp.signature_list_plot_tableWidget, 3) - cfg.utls.setColumnWidthList(cfg.uisp.signature_list_plot_tableWidget, [[0, 30], [1, 40], [2, 100], [3, 40], [4, 100], [5, 30]]) - try: - cfg.uisp.signature_list_plot_tableWidget.horizontalHeader().setSectionResizeMode(2, cfg.QtWidgetsSCP.QHeaderView.Stretch) - cfg.uisp.signature_list_plot_tableWidget.horizontalHeader().setSectionResizeMode(4, cfg.QtWidgetsSCP.QHeaderView.Stretch) - except: - pass - cfg.SCPD.clearTree() - # passwords - cfg.ui.smtp_password_lineEdit.setEchoMode(cfg.QtWidgetsSCP.QLineEdit.Password) - cfg.ui.password_usgs_lineEdit.setEchoMode(cfg.QtWidgetsSCP.QLineEdit.Password) - cfg.ui.password_usgs_lineEdit_2.setEchoMode(cfg.QtWidgetsSCP.QLineEdit.Password) - cfg.ui.password_scihub_lineEdit.setEchoMode(cfg.QtWidgetsSCP.QLineEdit.Password) - # scatter plot list - cfg.utls.insertTableColumn(cfg.uiscp.scatter_list_plot_tableWidget, 6, cfg.tableColString, None, 'Yes') - cfg.utls.sortTableColumn(cfg.uiscp.scatter_list_plot_tableWidget, 3) - cfg.utls.setColumnWidthList(cfg.uiscp.scatter_list_plot_tableWidget, [[0, 30], [1, 40], [2, 100], [3, 40], [4, 100], [5, 30]]) - try: - cfg.uiscp.scatter_list_plot_tableWidget.horizontalHeader().setSectionResizeMode(2, cfg.QtWidgetsSCP.QHeaderView.Stretch) - cfg.uiscp.scatter_list_plot_tableWidget.horizontalHeader().setSectionResizeMode(4, cfg.QtWidgetsSCP.QHeaderView.Stretch) - except: - pass - # signature threshold - cfg.utls.insertTableColumn(cfg.ui.signature_threshold_tableWidget, 7, cfg.tableColString, None, 'Yes') - cfg.utls.setColumnWidthList(cfg.ui.signature_threshold_tableWidget, [[4, 100], [5, 100], [6, 100]]) - try: - cfg.ui.signature_threshold_tableWidget.horizontalHeader().setSectionResizeMode(1, cfg.QtWidgetsSCP.QHeaderView.Stretch) - cfg.ui.signature_threshold_tableWidget.horizontalHeader().setSectionResizeMode(3, cfg.QtWidgetsSCP.QHeaderView.Stretch) - except: - pass - # product download tab - cfg.utls.setColumnWidthList(cfg.ui.download_images_tableWidget, [[0, 100], [1, 400]]) - # USGS spectral lbrary - cfg.usgsLib.addSpectralLibraryToCombo(cfg.usgs_lib_list) - cfg.usgs_C1p = cfg.plgnDir + '/' + cfg.usgs_C1p - cfg.usgs_C2p = cfg.plgnDir + '/' + cfg.usgs_C2p - cfg.usgs_C3p = cfg.plgnDir + '/' + cfg.usgs_C3p - cfg.usgs_C4p = cfg.plgnDir + '/' + cfg.usgs_C4p - cfg.usgs_C5p = cfg.plgnDir + '/' + cfg.usgs_C5p - cfg.usgs_C6p = cfg.plgnDir + '/' + cfg.usgs_C6p - cfg.usgs_C7p = cfg.plgnDir + '/' + cfg.usgs_C7p - # band calc expression - cfg.bCalc.createExpressionList(cfg.expressionListBC) - cfg.batchT.addFunctionsToTable(cfg.functionNames) - cfg.bst.addSatelliteToCombo(cfg.satWlList) - cfg.downProd.addSatelliteToCombo(cfg.downProductList) - cfg.scaPlT.addColormapToCombo(cfg.scatterColorMap) - cfg.bst.addUnitToCombo(cfg.unitList) - cfg.SCPD.previewSize() - # set log state - if cfg.logSetVal == 'Yes': - cfg.ui.log_checkBox.setCheckState(2) - cfg.mx.msg19() - elif cfg.logSetVal == 'No': - cfg.ui.log_checkBox.setCheckState(0) - # set download news state - cfg.ui.download_news_checkBox.setCheckState(int(cfg.downNewsVal)) - # set download news state - cfg.ui.virtual_raster_load_checkBox.setCheckState(int(cfg.vrtRstProjVal)) - # set raster format - if cfg.outTempRastFormat == 'VRT': - cfg.ui.virtual_raster_checkBox.setCheckState(2) - elif cfg.outTempRastFormat == 'GTiff': - cfg.ui.virtual_raster_checkBox.setCheckState(0) - # set raster compression - if cfg.rasterCompression == 'Yes': - cfg.ui.raster_compression_checkBox.setCheckState(2) - elif cfg.rasterCompression == 'No': - cfg.ui.raster_compression_checkBox.setCheckState(0) - # set raster compression - if cfg.parallelWritingCheck == 'Yes': - cfg.ui.parallel_writing_checkBox.setCheckState(2) - elif cfg.parallelWritingCheck == 'No': - cfg.ui.parallel_writing_checkBox.setCheckState(0) - # set SMTP checkbox state - cfg.ui.smtp_checkBox.setCheckState(int(cfg.SMTPCheck)) - # set sound state - cfg.ui.sound_checkBox.setCheckState(int(cfg.soundVal)) - # connect to project loaded - cfg.qgisCoreSCP.QgsProject.instance().readProject.connect(self.projectLoaded) - cfg.qgisCoreSCP.QgsProject.instance().projectSaved.connect(self.projectSaved) - cfg.iface.newProjectCreated.connect(self.newProjectLoaded) - #cfg.qgisCoreSCP.QgsProject.instance().readMapLayer.connect(self.test) - #cfg.qgisCoreSCP.QgsProject.instance().layerLoaded.connect(self.test) - - ''' Help tab ''' - cfg.utls.makeDirectory(cfg.tmpDir + '/_images/') - cfg.ui.help_textBrowser.setSearchPaths([cfg.tmpDir]) - - ''' Docks ''' - # set ROI color - cfg.ui.change_color_Button.setStyleSheet('background-color :' + cfg.ROIClrVal) - # set ROI transparency - cfg.ui.transparency_Slider.setValue(cfg.ROITrnspVal) - # set RAM value - cfg.ui.RAM_spinBox.setValue(cfg.RAMValue) - # set CPU value - cfg.ui.CPU_spinBox.setValue(cfg.threads) - # macroclass checkbox - if cfg.macroclassCheck == 'No': - cfg.ui.macroclass_checkBox.setCheckState(0) - cfg.ui.class_checkBox.blockSignals(True) - cfg.ui.class_checkBox.setCheckState(2) - cfg.ui.class_checkBox.blockSignals(False) - elif cfg.macroclassCheck == 'Yes': - cfg.ui.macroclass_checkBox.setCheckState(2) - cfg.ui.class_checkBox.blockSignals(True) - cfg.ui.class_checkBox.setCheckState(0) - cfg.ui.class_checkBox.blockSignals(False) - # macroclass checkbox - if cfg.macroclassCheckRF == 'No': - cfg.ui.macroclass_checkBox_rf.setCheckState(0) - cfg.ui.class_checkBox_rf.blockSignals(True) - cfg.ui.class_checkBox_rf.setCheckState(2) - cfg.ui.class_checkBox_rf.blockSignals(False) - elif cfg.macroclassCheckRF == 'Yes': - cfg.ui.macroclass_checkBox_rf.setCheckState(2) - cfg.ui.class_checkBox_rf.blockSignals(True) - cfg.ui.class_checkBox_rf.setCheckState(0) - cfg.ui.class_checkBox_rf.blockSignals(False) - # LC signature checkbox - if cfg.LCsignatureCheckBox == 'No': - cfg.ui.LC_signature_checkBox.setCheckState(0) - elif cfg.LCsignatureCheckBox == 'Yes': - cfg.ui.LC_signature_checkBox.setCheckState(2) - try: - # set SMTP server - cfg.ui.smtp_server_lineEdit.setText(cfg.SMTPServer) - # set SMTP to emails - cfg.ui.to_email_lineEdit.setText(cfg.SMTPtoEmails) - # set SMTP user and password - cfg.ui.smtp_user_lineEdit.setText(cfg.SMTPUser) - if cfg.SMTPPassword is not None: - SMTPPsw = cfg.utls.decryptPassword(cfg.SMTPPassword[2:-1]) - cfg.ui.smtp_password_lineEdit.setText(str(SMTPPsw)[2:-1]) - cfg.SMTPPassword = str(SMTPPsw)[2:-1] - # set USGS user and password - cfg.ui.user_usgs_lineEdit.setText(cfg.USGSUser) - if cfg.USGSPass is not None: - USGSPsw = cfg.utls.decryptPassword(cfg.USGSPass[2:-1]) - cfg.ui.password_usgs_lineEdit.setText(str(USGSPsw)[2:-1]) - cfg.ui.user_usgs_lineEdit_2.setText(cfg.USGSUserASTER) - if cfg.USGSPassASTER is not None: - USGSPsw2 = cfg.utls.decryptPassword(cfg.USGSPassASTER[2:-1]) - cfg.ui.password_usgs_lineEdit_2.setText(str(USGSPsw2)[2:-1]) - # set SciHub user and password - cfg.ui.sentinel_service_lineEdit.setText(cfg.SciHubService) - cfg.ui.user_scihub_lineEdit.setText(cfg.SciHubUser) - if cfg.SciHubPass is not None: - sciHubPsw = cfg.utls.decryptPassword(cfg.SciHubPass[2:-1]) - cfg.ui.password_scihub_lineEdit.setText(str(sciHubPsw)[2:-1]) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.ui.sentinel2_alternative_search_checkBox.blockSignals(True) - cfg.ui.sentinel2_alternative_search_checkBox.setCheckState(int(cfg.sentinelAlternativeSearch)) - cfg.ui.sentinel2_alternative_search_checkBox.blockSignals(False) + """ Scatter plot""" + cfg.scatter_plot_dlg.ui.scatter_ROI_Button.clicked.connect( + cfg.scatter_plotter.calculate_scatter_plot + ) + cfg.scatter_plot_dlg.ui.bandX_spinBox.valueChanged.connect( + cfg.scatter_plotter.band_x_plot + ) + cfg.scatter_plot_dlg.ui.bandY_spinBox.valueChanged.connect( + cfg.scatter_plotter.band_y_plot + ) + table_w = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + table_w.doubleClicked.connect( + cfg.scatter_plotter.scatter_plot_double_click + ) + cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget.cellChanged.connect( + cfg.scatter_plotter.edited_cell + ) + cfg.scatter_plot_dlg.ui.remove_Signature_Button.clicked.connect( + cfg.scatter_plotter.remove_scatter + ) + cfg.scatter_plot_dlg.ui.save_plot_pushButton_2.clicked.connect( + cfg.scatter_plotter.save_plot + ) + cfg.scatter_plot_dlg.ui.fitToAxes_pushButton_2.clicked.connect( + cfg.scatter_plotter.fit_plot_to_axes + ) + cfg.scatter_plot_dlg.ui.plot_temp_ROI_pushButton.clicked.connect( + cfg.scatter_plotter.add_temp_roi_to_scatter_plot + ) + cfg.scatter_plot_dlg.ui.colormap_comboBox.currentIndexChanged.connect( + cfg.scatter_plotter.color_plot + ) + cfg.logger.log.debug('GUI connected') - ''' SCP tab ''' - cfg.ui.SCP_tabs.currentChanged.connect(cfg.ipt.SCPTabChanged) - cfg.ui.main_tabWidget.currentChanged.connect(cfg.ipt.mainTabChanged) - # hide tabs - cfg.ui.SCP_tabs.setStyleSheet('QTabBar::tab {padding: 0px; max-height: 0px;}') - # set window size - cfg.dlg.resize(int(cfg.windowSizeW), int(cfg.windowSizeH)) - cfg.ui.widget.setMinimumSize(cfg.QtCoreSCP.QSize(50, 0)) - cfg.ui.widget.setMaximumSize(cfg.QtCoreSCP.QSize(400, 16777215)) - cfg.ui.splitter.setSizes(eval(cfg.splitterSizeS)) - cfg.ui.splitter.splitterMoved.connect(cfg.ipt.movedSplitter) - cfg.ui.menu_treeWidget.itemSelectionChanged.connect(cfg.ipt.menuIndex) - cfg.ui.f_filter_lineEdit.textChanged.connect(cfg.ipt.filterTree) - ''' Multiple ROI tab ''' - # connect to add point - cfg.ui.add_point_pushButton.clicked.connect(cfg.multiROI.addPointToTable) - # connect to create random points - cfg.ui.add_random_point_pushButton.clicked.connect(cfg.multiROI.createRandomPoint) - # connect to remove point - cfg.ui.remove_point_pushButton.clicked.connect(cfg.multiROI.removePointFromTable) - # connect to save point ROIs - cfg.ui.save_point_rois_pushButton.clicked.connect(cfg.multiROI.createROIfromPoint) - # connect to import points - cfg.ui.import_point_list_pushButton.clicked.connect(cfg.multiROI.importPoints) - # connect to export point list - cfg.ui.export_point_list_pushButton.clicked.connect(cfg.multiROI.exportPointList) - # connect the signature calculation checkBox 2 - cfg.ui.signature_checkBox2.stateChanged.connect(cfg.multiROI.signatureCheckbox2) - # connect to text changed - cfg.ui.stratified_lineEdit.textChanged.connect(cfg.multiROI.textChanged) - ''' Import spectral signature tab ''' - # connect the import library - cfg.ui.open_library_pushButton.clicked.connect(cfg.SCPD.openLibraryFile) - # connect the open shapefile - cfg.ui.open_shapefile_pushButton.clicked.connect(cfg.sigImport.openShapefileI) - # connect the import shapefile - cfg.ui.import_shapefile_pushButton.clicked.connect(cfg.utls.importShapefile) - # connect the chapter changed - cfg.ui.usgs_chapter_comboBox.currentIndexChanged.connect(cfg.usgsLib.chapterChanged) - # connect the library changed - cfg.ui.usgs_library_comboBox.currentIndexChanged.connect(cfg.usgsLib.libraryChanged) - # connect the close library - cfg.ui.add_usgs_library_pushButton.clicked.connect(cfg.usgsLib.addSignatureToList) - ''' Export spectral signature tab ''' - # connect to export signature to SCP file - cfg.ui.export_SCP_pushButton.clicked.connect(cfg.SCPD.exportSignatureFile) - cfg.ui.export_SHP_pushButton.clicked.connect(cfg.SCPD.exportSignatureShapefile) - # connect to export signature to CSV - cfg.ui.export_CSV_library_toolButton.clicked.connect(cfg.SCPD.exportToCSVLibrary) - ''' Algorithm weight tab ''' - cfg.ui.reset_weights_pushButton.clicked.connect(cfg.algWT.resetWeights) - cfg.ui.set_weight_value_pushButton.clicked.connect(cfg.algWT.setWeights) - ''' Signature threshold tab ''' - # edited cell - cfg.ui.signature_threshold_tableWidget.cellChanged.connect(cfg.signT.editedThresholdTable) - cfg.ui.reset_threshold_pushButton.clicked.connect(cfg.signT.resetThresholds) - cfg.ui.automatic_threshold_pushButton.clicked.connect(cfg.signT.setAllWeightsVariance) - cfg.ui.set_threshold_value_pushButton.clicked.connect(cfg.signT.setThresholds) - cfg.ui.signature_threshold_tableWidget.horizontalHeader().sectionClicked.connect(cfg.signT.orderedTable) - ''' LC Signature threshold tab ''' - cfg.ui.LCS_tableWidget.cellChanged.connect(cfg.LCSignT.editedThresholdTable) - cfg.ui.LCS_tableWidget.horizontalHeader().sectionClicked.connect(cfg.LCSignT.orderedTable) - cfg.ui.automatic_threshold_pushButton_2.clicked.connect(cfg.LCSignT.setAllWeightsVariance) - # connect to activate pointer - cfg.ui.LCS_pointerButton.clicked.connect(cfg.LCSignT.pointerActive) - cfg.ui.LCS_ROI_button.clicked.connect(cfg.LCSignT.ROIThreshold) - cfg.ui.set_min_max_Button.clicked.connect(cfg.LCSignT.setMinimumMaximum) - # connect the include signature checkBox - cfg.ui.LCS_include_checkBox.stateChanged.connect(cfg.LCSignT.includeCheckbox) - cfg.ui.LCS_cut_checkBox.stateChanged.connect(cfg.LCSignT.cutCheckbox) - # add to spectral signature plot - cfg.ui.signature_spectral_plot_toolButton_2.clicked.connect(cfg.LCSignT.addSignatureToSpectralPlot) - ''' RGB List tab ''' - cfg.ui.RGB_tableWidget.cellChanged.connect(cfg.RGBLT.editedTable) - cfg.ui.add_RGB_pushButton.clicked.connect(cfg.RGBLT.addRGBToTable) - cfg.ui.remove_RGB_toolButton.clicked.connect(cfg.RGBLT.removeRGBFromTable) - cfg.ui.sort_by_name_toolButton_2.clicked.connect(cfg.RGBLT.sortRGBName) - cfg.ui.clear_RGB_list_toolButton.clicked.connect(cfg.RGBLT.clearTableAction) - cfg.ui.move_up_toolButton_3.clicked.connect(cfg.RGBLT.moveUpRGB) - cfg.ui.move_down_toolButton_3.clicked.connect(cfg.RGBLT.moveDownRGB) - cfg.ui.all_RGB_list_toolButton.clicked.connect(cfg.RGBLT.allRGBListAction) - cfg.ui.export_RGB_List_toolButton.clicked.connect(cfg.RGBLT.exportRGBList) - cfg.ui.import_RGB_List_toolButton.clicked.connect(cfg.RGBLT.importRGB) - ''' Band set List tab ''' - cfg.ui.add_bandset_pushButton.clicked.connect(cfg.bstLT.addBandSetToTable) - cfg.ui.rgb_toolButton.clicked.connect(cfg.bstLT.displayRGB) - cfg.ui.remove_bandset_toolButton.clicked.connect(cfg.bstLT.removeBandSetFromTable) - cfg.ui.move_up_toolButton_4.clicked.connect(cfg.bstLT.moveUpBandset) - cfg.ui.move_down_toolButton_4.clicked.connect(cfg.bstLT.moveDownBandset) - cfg.ui.sort_by_date.clicked.connect(cfg.bst.sortByDate) - # connect to double click - cfg.ui.band_set_list_tableWidget.doubleClicked.connect(cfg.bstLT.doubleClick) - cfg.ui.export_bandset_List_toolButton.clicked.connect(cfg.bstLT.exportList) - cfg.ui.import_bandset_List_toolButton.clicked.connect(cfg.bstLT.importList) - # connect to filter - cfg.ui.band_set_filter_lineEdit.textChanged.connect(cfg.bstLT.filterTable) - ''' Download product tab ''' - # connect to find images button - cfg.ui.find_images_toolButton.clicked.connect(cfg.downProd.findImages) - cfg.ui.selectUL_toolButton_3.clicked.connect(cfg.downProd.pointerActive) - # connect to display button - cfg.ui.toolButton_display.clicked.connect(cfg.downProd.displayImages) - cfg.ui.toolButton_OSM.clicked.connect(cfg.downProd.displayOSM) - cfg.ui.remove_image_toolButton.clicked.connect(cfg.downProd.removeImageFromTable) - cfg.ui.clear_table_toolButton.clicked.connect(cfg.downProd.clearTable) - cfg.ui.download_images_Button.clicked.connect(cfg.downProd.downloadImages) - cfg.ui.export_links_Button.clicked.connect(cfg.downProd.exportLinks) - cfg.ui.import_table_pushButton.clicked.connect(cfg.downProd.importTableText) - cfg.ui.export_table_pushButton.clicked.connect(cfg.downProd.exportTableText) - cfg.ui.check_toolButton.clicked.connect(cfg.downProd.checkAllBands) - cfg.ui.show_area_radioButton_2.clicked.connect(cfg.downProd.showHideArea) - cfg.ui.remember_user_checkBox_2.stateChanged.connect(cfg.downProd.rememberUserCheckbox) - cfg.ui.user_usgs_lineEdit.editingFinished.connect(cfg.downProd.rememberUser) - cfg.ui.password_usgs_lineEdit.editingFinished.connect(cfg.downProd.rememberUser) - cfg.ui.reset_sentinel_service_toolButton.clicked.connect(cfg.downProd.resetService) - cfg.ui.remember_user_checkBox.stateChanged.connect(cfg.downProd.rememberUserCheckboxSentinel2) - cfg.ui.sentinel2_alternative_search_checkBox.stateChanged.connect(cfg.downProd.alternativeCheckboxSentinel2) - cfg.ui.user_scihub_lineEdit.editingFinished.connect(cfg.downProd.rememberUserSentinel2) - cfg.ui.password_scihub_lineEdit.editingFinished.connect(cfg.downProd.rememberUserSentinel2) - cfg.ui.sentinel_service_lineEdit.editingFinished.connect(cfg.downProd.rememberService) - cfg.ui.check_toolButton_2.clicked.connect(cfg.downProd.checkAllBandsSentinel2) - cfg.ui.check_toolButton_3.clicked.connect(cfg.downProd.checkAllBandsSentinel3) - cfg.ui.check_toolButton_4.clicked.connect(cfg.downProd.checkAllBandsGOES) - cfg.ui.remember_user_checkBox_3.stateChanged.connect(cfg.downProd.rememberUserCheckboxEarthdata) - cfg.ui.user_usgs_lineEdit_2.editingFinished.connect(cfg.downProd.rememberUserEarthdata) - cfg.ui.password_usgs_lineEdit_2.editingFinished.connect(cfg.downProd.rememberUserEarthdata) - cfg.ui.download_images_tableWidget.itemSelectionChanged.connect(cfg.downProd.tableClick) - # connect to filter - cfg.ui.products_filter_lineEdit.textChanged.connect(cfg.downProd.filterTable) - ''' Classification dock ''' - # button band set - cfg.uidc.bandset_toolButton.clicked.connect(cfg.utls.bandSetTab) - cfg.uidc.band_processing_toolButton.clicked.connect(cfg.utls.bandProcessingTab) - cfg.uidc.preprocessing_toolButton_2.clicked.connect(cfg.utls.preProcessingTab) - cfg.uidc.postprocessing_toolButton_2.clicked.connect(cfg.utls.postProcessingTab) - cfg.uidc.bandcalc_toolButton_2.clicked.connect(cfg.utls.bandCalcTab) - cfg.uidc.download_images_toolButton_2.clicked.connect(cfg.utls.selectTabDownloadImages) - cfg.uidc.basic_tools_toolButton.clicked.connect(cfg.utls.basicToolsTab) - cfg.uidc.batch_toolButton.clicked.connect(cfg.utls.batchTab) - cfg.uidc.userguide_toolButton_2.clicked.connect(cfg.ipt.quickGuide) - cfg.uidc.help_toolButton_2.clicked.connect(cfg.ipt.askHelp) - cfg.uidc.support_toolButton.clicked.connect(cfg.ipt.supportSCP) - cfg.uidc.tabWidget_dock.currentChanged.connect(cfg.ipt.dockTabChanged) - # button new input - cfg.uidc.button_new_input.clicked.connect(cfg.SCPD.createInput) - # button reset - cfg.uidc.button_reset_input.clicked.connect(cfg.SCPD.resetInput) - # connect to save to shapefile - cfg.uidc.button_Save_ROI.clicked.connect(cfg.SCPD.saveROItoShapefile) - # connect to undo save ROI - cfg.uidc.undo_save_Button.clicked.connect(cfg.SCPD.undoSaveROI) - cfg.uidc.redo_save_Button.clicked.connect(cfg.SCPD.redoSaveROI) - # connect the signature calculation checkBox - cfg.uidc.signature_checkBox.stateChanged.connect(cfg.SCPD.signatureCheckbox) - cfg.uidc.scatterPlot_toolButton.clicked.connect(cfg.SCPD.addROIToScatterPlot) - # connect the save input checkBox - cfg.uidc.save_input_checkBox.stateChanged.connect(cfg.SCPD.saveInputCheckbox) - # connect to open training file - cfg.uidc.trainingFile_toolButton.clicked.connect(cfg.SCPD.openTrainingFile) - # connect to export signature list file - cfg.uidc.export_signature_list_toolButton.clicked.connect(cfg.utls.exportSignaturesTab) - # connect to import library file - cfg.uidc.import_library_toolButton.clicked.connect(cfg.utls.importSignaturesTab) - # add to spectral signature plot - cfg.uidc.signature_spectral_plot_toolButton.clicked.connect(cfg.SCPD.addSignatureToSpectralPlot) - # connect to filter - cfg.uidc.ROI_filter_lineEdit.textChanged.connect(cfg.SCPD.filterTree) - # connect to delete signature - cfg.uidc.delete_Signature_Button.clicked.connect(cfg.SCPD.removeSelectedSignatures) - # connect to merge signatures - cfg.uidc.merge_signature_toolButton.clicked.connect(cfg.SCPD.mergeSelectedSignatures) - cfg.uidc.calculate_signature_toolButton.clicked.connect(cfg.SCPD.calculateSignatures) - # connect the ROI macroclass ID - cfg.uidc.ROI_Macroclass_ID_spin.valueChanged.connect(cfg.SCPD.setROIMacroID) - # connect the ROI Macroclass - cfg.uidc.ROI_Macroclass_line.editingFinished.connect(cfg.SCPD.roiMacroclassInfo) - # custom expression - cfg.uidc.custom_index_lineEdit.editingFinished.connect(cfg.SCPD.customExpressionEdited) - # connect the ROI Class ID - cfg.uidc.ROI_ID_spin.valueChanged.connect(cfg.SCPD.setROIID) - # connect the ROI Class - cfg.uidc.ROI_Class_line.editingFinished.connect(cfg.SCPD.roiClassInfo) - # connect the rapid ROI checkBox - cfg.uidc.display_cursor_checkBox.stateChanged.connect(cfg.SCPD.vegetationIndexCheckbox) - # connect the vegetation index combo - cfg.uidc.vegetation_index_comboBox.currentIndexChanged.connect(cfg.SCPD.vegetationIndexName) - # connect the rapid ROI checkBox - cfg.uidc.rapid_ROI_checkBox.stateChanged.connect(cfg.SCPD.rapidROICheckbox) - # connect the vegetation index display checkbox - cfg.uidc.rapidROI_band_spinBox.valueChanged.connect(cfg.SCPD.rapidROIband) - ''' Classification tab ''' - # connect to algorithm weight button - cfg.ui.algorithm_weight_button.clicked.connect(cfg.utls.algorithmBandWeightTab) - # connect to threshold button - cfg.ui.algorithm_threshold_button.clicked.connect(cfg.utls.signatureThresholdTab) - # connect to LCS threshold button - cfg.ui.LC_signature_button.clicked.connect(cfg.utls.LCSThresholdTab) - # connect the algorithm combo - cfg.ui.algorithm_combo.currentIndexChanged.connect(cfg.classTab.algorithmName) - # connect the algorithm threshold - cfg.ui.alg_threshold_SpinBox.valueChanged.connect(cfg.classTab.algorithmThreshold) - # connect to run classification - cfg.ui.button_classification.clicked.connect(cfg.classTab.runClassificationAction) - cfg.ui.classification.clicked.connect(cfg.batchT.setFunctionButton) - # connect the macroclass checkBox - cfg.ui.macroclass_checkBox.stateChanged.connect(cfg.classTab.macroclassCheckbox) - cfg.ui.class_checkBox.stateChanged.connect(cfg.classTab.classCheckbox) - # connect the LC signature checkBox - cfg.ui.LC_signature_checkBox.stateChanged.connect(cfg.classTab.LCSignature_Checkbox) - # connect the mask checkBox - cfg.ui.mask_checkBox.stateChanged.connect(cfg.classTab.maskCheckbox) - # connect to reset qml button - cfg.ui.resetQmlButton.clicked.connect(cfg.classTab.resetQmlStyle) - # connect to reset mask button - cfg.ui.resetMaskButton.clicked.connect(cfg.classTab.resetMask) - # connect to qml button - cfg.ui.qml_Button.clicked.connect(cfg.classTab.selectQmlStyle) - ''' Spectral signature plot ''' - # connect the sigma checkBox - cfg.uisp.sigma_checkBox.stateChanged.connect(cfg.spSigPlot.sigmaCheckbox) - cfg.uisp.band_lines_checkBox.stateChanged.connect(cfg.spSigPlot.refreshPlot) - cfg.uisp.grid_checkBox.stateChanged.connect(cfg.spSigPlot.refreshPlot) - # connect to remove signature button - cfg.uisp.remove_Signature_Button.clicked.connect(cfg.spSigPlot.removeSignature) - # connect to calculate spectral distances button - cfg.uisp.calculate_spectral_distance_Button.clicked.connect(cfg.spSigPlot.calculateSpectralDistances) - # connect to fit to axes - cfg.uisp.fitToAxes_pushButton.clicked.connect(cfg.spSigPlot.fitPlotToAxes) - # connect to plot spinbox - cfg.uisp.plot_text_spinBox.valueChanged.connect(cfg.spSigPlot.setPlotLegendLenght) - # connect to value range - cfg.uisp.value_range_pushButton.clicked.connect(cfg.spSigPlot.editValueRange) - cfg.uisp.set_min_max_Button.clicked.connect(cfg.spSigPlot.setMinimumMaximum) - cfg.uisp.automatic_threshold_pushButton_2.clicked.connect(cfg.spSigPlot.setAllWeightsVariance) - # connect to activate pointer - cfg.uisp.LCS_pointerButton_2.clicked.connect(cfg.spSigPlot.pointerActive) - cfg.uisp.LCS_ROI_button_2.clicked.connect(cfg.spSigPlot.ROIThreshold) - # undo threshold - cfg.uisp.undo_threshold_Button.clicked.connect(cfg.spSigPlot.undoThreshold) - # connect the include signature checkBox - cfg.uisp.LCS_include_checkBox_2.stateChanged.connect(cfg.spSigPlot.includeCheckbox) - cfg.uisp.LCS_cut_checkBox_2.stateChanged.connect(cfg.spSigPlot.cutCheckbox) - # connect to add to signature list - cfg.uisp.add_signature_list_pushButton.clicked.connect(cfg.spSigPlot.addToSignatureList) - # connect to save plot - cfg.uisp.save_plot_pushButton.clicked.connect(cfg.spSigPlot.savePlot) - # connect to edited cell - cfg.uisp.signature_list_plot_tableWidget.cellChanged.connect(cfg.spSigPlot.editedCell) - cfg.uisp.signature_list_plot_tableWidget.horizontalHeader().sectionClicked.connect(cfg.spSigPlot.orderedTable) - # connect to signature plot list double click - cfg.uisp.signature_list_plot_tableWidget.doubleClicked.connect(cfg.spSigPlot.signatureListDoubleClick) - ''' Scatter plot tab ''' - # connect to scatter plot button - cfg.uiscp.scatter_ROI_Button.clicked.connect(cfg.scaPlT.scatterPlotCalc) - # connect to Band X spinbox - cfg.uiscp.bandX_spinBox.valueChanged.connect(cfg.scaPlT.bandXPlot) - # connect to Band Y spinbox - cfg.uiscp.bandY_spinBox.valueChanged.connect(cfg.scaPlT.bandYPlot) - # connect double click ROI list to zoom - cfg.uiscp.scatter_list_plot_tableWidget.doubleClicked.connect(cfg.scaPlT.scatterPlotDoubleClick) - # connect to edited cell - cfg.uiscp.scatter_list_plot_tableWidget.cellChanged.connect(cfg.scaPlT.editedCell) - # connect to remove signature button - cfg.uiscp.remove_Signature_Button.clicked.connect(cfg.scaPlT.removeScatter) - # connect to save plot - cfg.uiscp.save_plot_pushButton_2.clicked.connect(cfg.scaPlT.savePlot) - # connect to fit to axes - cfg.uiscp.fitToAxes_pushButton_2.clicked.connect(cfg.scaPlT.fitPlotToAxes) - cfg.uiscp.plot_temp_ROI_pushButton.clicked.connect(cfg.scaPlT.addTempROIToScatterPlot) - cfg.uiscp.plot_display_pushButton.clicked.connect(cfg.scaPlT.addDisplayToScatterPlot) - cfg.uiscp.plot_image_pushButton.clicked.connect(cfg.scaPlT.addImageToScatterPlot) - # connect to change color button - cfg.uiscp.polygon_color_Button.clicked.connect(cfg.scaPlT.changePolygonColor) - cfg.uiscp.plot_color_ROI_pushButton.clicked.connect(cfg.scaPlT.colorPlot) - # connect to select value range - cfg.uiscp.draw_polygons_pushButton.clicked.connect(cfg.scaPlT.selectRange) - cfg.uiscp.remove_polygons_pushButton.clicked.connect(cfg.scaPlT.removePolygons) - cfg.uiscp.show_polygon_area_pushButton.clicked.connect(cfg.scaPlT.showScatterPolygonArea) - cfg.uiscp.add_signature_list_pushButton.clicked.connect(cfg.scaPlT.addToSignatureList) - ''' Band set tab ''' - # connect to refresh button - cfg.ui.toolButton_reload_3.clicked.connect(cfg.bst.rasterBandName) - # button reload - cfg.ui.toolButton_reload.clicked.connect(cfg.ipt.checkRefreshRasterLayer) - # connect to add file button - cfg.ui.toolButton_input_raster.clicked.connect(cfg.bst.addFileToBandSetAction) - # connect to add raster band button - cfg.ui.add_raster_bands_Button.clicked.connect(cfg.bst.addBandToSet) - # connect to select all bands button - cfg.ui.select_all_bands_Button.clicked.connect(cfg.bst.selectAllBands) - # connect to clear band set button - cfg.ui.clear_bandset_toolButton.clicked.connect(cfg.bst.clearBandSetAction) - # connect to move up band button - cfg.ui.move_up_toolButton.clicked.connect(cfg.bst.moveUpBand) - # connect to move down band button - cfg.ui.move_down_toolButton.clicked.connect(cfg.bst.moveDownBand) - # connect to sort by name button - cfg.ui.sort_by_name_toolButton.clicked.connect(cfg.bst.sortBandName) - # connect to remove band button - cfg.ui.remove_toolButton.clicked.connect(cfg.bst.removeBand) - # connect add band set - cfg.ui.add_band_set_toolButton.clicked.connect(cfg.bst.addBandSetTabAction) - # connect to changed tab - cfg.ui.Band_set_tabWidget.currentChanged.connect(cfg.bst.tabBandSetChanged) - # connect close tab - cfg.ui.Band_set_tabWidget.tabCloseRequested.connect(cfg.bst.closeBandSetTab) - # combo layer - cfg.ui.image_raster_name_combo.currentIndexChanged.connect(cfg.bst.rasterLayerName) - # connect to import band set button - cfg.ui.import_bandset_toolButton.clicked.connect(cfg.bst.importBandSet) - # connect to export band set button - cfg.ui.export_bandset_toolButton.clicked.connect(cfg.bst.exportBandSet) - # connect to satellite wavelength combo - cfg.ui.wavelength_sat_combo.currentIndexChanged.connect(cfg.bst.satelliteWavelength) - # connect to unit combo - cfg.ui.unit_combo.currentIndexChanged.connect(cfg.bst.setBandUnit) - # connect to date edit - cfg.ui.bandset_dateEdit.dateChanged.connect(cfg.bst.setBandsetDate) - # connect to band set process button - cfg.ui.band_set_process_toolButton.clicked.connect(cfg.bst.performBandSetTools) - # connect to filter - cfg.ui.bands_filter_lineEdit.textChanged.connect(cfg.bst.filterTable) - ''' Pre processing tab ''' - ''' Clip multiple rasters ''' - # connect to clip button - cfg.ui.clip_Button.clicked.connect(cfg.clipMulti.clipRastersAction) - cfg.ui.clip_multiple_rasters.clicked.connect(cfg.batchT.setFunctionButton) - # connect to activate UL pointer - cfg.ui.selectUL_toolButton.clicked.connect(cfg.clipMulti.pointerActive) - # connect to refresh shape button - cfg.ui.toolButton_reload_8.clicked.connect(cfg.clipMulti.refreshShapeClip) - cfg.ui.show_area_radioButton_3.clicked.connect(cfg.clipMulti.showHideArea) - cfg.ui.shapefile_checkBox.stateChanged.connect(cfg.clipMulti.checkboxShapeChanged) - cfg.ui.temporary_ROI_checkBox.stateChanged.connect(cfg.clipMulti.checkboxTempROIChanged) - # connect the shapefile combo - cfg.ui.shapefile_comboBox.currentIndexChanged.connect(cfg.clipMulti.referenceLayerName) - ''' Stack raster bands ''' - # connect to stack button - cfg.ui.stack_Button.clicked.connect(cfg.stackRstr.stackAction) - cfg.ui.stack_raster_bands.clicked.connect(cfg.batchT.setFunctionButton) - ''' Spectral change band sets ''' - # connect to calculate button - cfg.ui.spectral_distance_bandsets_toolButton.clicked.connect(cfg.spclDstBS.calculateDistanceAction) - cfg.ui.spectral_distance.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.min_distance_radioButton_2.clicked.connect(cfg.spclDstBS.radioMinDistChanged) - cfg.ui.spectral_angle_map_radioButton_2.clicked.connect(cfg.spclDstBS.radioSAMChanged) - ''' Mosaic band sets ''' - # connect to mosaic button - cfg.ui.mosaic_bandsets_toolButton.clicked.connect(cfg.mosaicBS.mosaicAction) - cfg.ui.mosaic_bandsets.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.mosaic_band_sets_lineEdit.textChanged.connect(cfg.mosaicBS.textChanged) - ''' Cloud masking ''' - # connect to mask button - cfg.ui.cloud_mask_toolButton.clicked.connect(cfg.cloudMsk.maskAction) - cfg.ui.cloud_masking.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.cloud_mask_classes_lineEdit.textChanged.connect(cfg.cloudMsk.textChanged) - # connect to refresh button - cfg.ui.toolButton_reload_23.clicked.connect(cfg.utls.refreshClassificationLayer) - ''' ASTER tab ''' - # connect to input button - cfg.ui.toolButton_directoryInput_ASTER.clicked.connect(cfg.ASTERT.inputASTER) - cfg.ui.ASTER_tableWidget.cellChanged.connect(cfg.ASTERT.editedCell) - cfg.ui.earth_sun_dist_lineEdit_2.textChanged.connect(cfg.ASTERT.editedEarthSunDist) - cfg.ui.sun_elev_lineEdit_2.textChanged.connect(cfg.ASTERT.editedSunElevation) - cfg.ui.date_lineEdit_2.textChanged.connect(cfg.ASTERT.editedDate) - cfg.ui.pushButton_Conversion_3.clicked.connect(cfg.ASTERT.performASTERCorrection) - cfg.ui.aster_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.pushButton_remove_band_2.clicked.connect(cfg.ASTERT.removeHighlightedBand) - ''' MODIS tab ''' - # connect to input button - cfg.ui.toolButton_directoryInput_MODIS.clicked.connect(cfg.MODIST.inputMODIS) - cfg.ui.MODIS_tableWidget.cellChanged.connect(cfg.MODIST.editedCell) - cfg.ui.pushButton_Conversion_4.clicked.connect(cfg.MODIST.performMODISConversion) - cfg.ui.modis_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.pushButton_remove_band_3.clicked.connect(cfg.MODIST.removeHighlightedBand) - ''' Landsat tab ''' - # connect to input button - cfg.ui.toolButton_directoryInput.clicked.connect(cfg.landsatT.inputLandsat) - cfg.ui.toolButton_directoryInput_MTL.clicked.connect(cfg.landsatT.inputMTL) - cfg.ui.pushButton_Conversion.clicked.connect(cfg.landsatT.performLandsatCorrection) - cfg.ui.landsat_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.pushButton_remove_band.clicked.connect(cfg.landsatT.removeHighlightedBand) - cfg.ui.landsat_tableWidget.cellChanged.connect(cfg.landsatT.editedCell) - cfg.ui.earth_sun_dist_lineEdit.textChanged.connect(cfg.landsatT.editedEarthSunDist) - cfg.ui.sun_elev_lineEdit.textChanged.connect(cfg.landsatT.editedSunElevation) - cfg.ui.date_lineEdit.textChanged.connect(cfg.landsatT.editedDate) - cfg.ui.satellite_lineEdit.textChanged.connect(cfg.landsatT.editedSatellite) - ''' Sentinel-1 tab ''' - # connect to input button - cfg.ui.S1_toolButton_fileInput.clicked.connect(cfg.sentinel1T.inputSentinel) - cfg.ui.S1_toolButton_directoryInput_xml.clicked.connect(cfg.sentinel1T.inputXML) - cfg.ui.pushButton_Conversion_6.clicked.connect(cfg.sentinel1T.performSentinelConversion) - cfg.ui.sentinel1_conversion.clicked.connect(cfg.batchT.setFunctionButton) - ''' Sentinel-2 tab ''' - # connect to input button - cfg.ui.S2_toolButton_directoryInput.clicked.connect(cfg.sentinel2T.inputSentinel) - cfg.ui.pushButton_Conversion_2.clicked.connect(cfg.sentinel2T.performSentinelConversion) - cfg.ui.sentinel2_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.S2_satellite_lineEdit.textChanged.connect(cfg.sentinel2T.editedSatellite) - cfg.ui.S2_pushButton_remove_band.clicked.connect(cfg.sentinel2T.removeHighlightedBand) - cfg.ui.sentinel_2_tableWidget.cellChanged.connect(cfg.sentinel2T.editedCell) - cfg.ui.S2_toolButton_directoryInput_xml2.clicked.connect(cfg.sentinel2T.inputXML2) - ''' Sentinel-3 tab ''' - # connect to input button - cfg.ui.S3_toolButton_directoryInput.clicked.connect(cfg.sentinel3T.inputSentinel) - cfg.ui.pushButton_Conversion_5.clicked.connect(cfg.sentinel3T.performSentinelConversion) - cfg.ui.sentinel3_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.S3_pushButton_remove_band.clicked.connect(cfg.sentinel3T.removeHighlightedBand) - ''' GOES tab ''' - # connect to input button - cfg.ui.GOES_toolButton_directoryInput.clicked.connect(cfg.goesT.inputGOES) - cfg.ui.pushButton_Conversion_8.clicked.connect(cfg.goesT.performGOESConversion) - cfg.ui.goes_conversion.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.GOES_pushButton_remove_band.clicked.connect(cfg.goesT.removeHighlightedBand) - ''' Classification neighbor tab''' - cfg.ui.class_neighbor_toolButton.clicked.connect(cfg.clssNghbr.classNeighborAction) - cfg.ui.neighbor_pixels.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.toolButton_input_matrix.clicked.connect(cfg.clssNghbr.inputMatrixFile) - ''' Reproject raster bands tab ''' - # connect to refresh button - cfg.ui.toolButton_reload_25.clicked.connect(cfg.rprjRstBndsT.refreshClassificationLayer) - cfg.ui.use_align_raster_checkBox.stateChanged.connect(cfg.rprjRstBndsT.checkboxAlignChanged) - cfg.ui.use_epsg_checkBox.stateChanged.connect(cfg.rprjRstBndsT.checkboxEPSGChanged) - # connect to reproject raster button - cfg.ui.reproject_Button.clicked.connect(cfg.rprjRstBndsT.reprojectRasterBands) - cfg.ui.reproject_raster_bands.clicked.connect(cfg.batchT.setFunctionButton) - ''' Split tab ''' - # connect the classification combo - cfg.ui.raster_name_combo.currentIndexChanged.connect(cfg.splitT.rasterLayerName) - # connect to refresh button - cfg.ui.toolButton_reload_9.clicked.connect(cfg.splitT.refreshClassificationLayer) - # connect to split raster button - cfg.ui.split_Button.clicked.connect(cfg.splitT.splitRaster) - cfg.ui.split_raster_bands.clicked.connect(cfg.batchT.setFunctionButton) - ''' PCA tab ''' - # connect to PCA button - cfg.ui.pca_Button.clicked.connect(cfg.pcaT.calculatePCAAction) - cfg.ui.pca.clicked.connect(cfg.batchT.setFunctionButton) - ''' K-means tab ''' - # connect to kmeans button - cfg.ui.kmeans_Button.clicked.connect(cfg.clusteringT.calculateClusteringAction) - cfg.ui.clustering.clicked.connect(cfg.batchT.setFunctionButton) - # connect the algorithm combo - cfg.ui.kmean_minmax_radioButton.clicked.connect(cfg.clusteringT.radiokmean_minmaxChanged) - cfg.ui.kmean_siglist_radioButton.clicked.connect(cfg.clusteringT.radiokmean_siglistChanged) - cfg.ui.kmean_randomsiglist_radioButton.clicked.connect(cfg.clusteringT.radiokmean_randomsiglistChanged) - cfg.ui.kmeans_radioButton.clicked.connect(cfg.clusteringT.radioKmeansChanged) - cfg.ui.isodata_radioButton.clicked.connect(cfg.clusteringT.radioIsodataChanged) - cfg.ui.min_distance_radioButton.clicked.connect(cfg.clusteringT.radioMinDistChanged) - cfg.ui.spectral_angle_map_radioButton.clicked.connect(cfg.clusteringT.radioSAMChanged) - ''' Random forest tab ''' - # connect to calculate button - cfg.ui.button_random_forest.clicked.connect(cfg.rndmFrst.performRandomForest) - cfg.ui.random_forest.clicked.connect(cfg.batchT.setFunctionButton) - # connect the macroclass checkBox - cfg.ui.macroclass_checkBox_rf.stateChanged.connect(cfg.rndmFrst.macroclassCheckbox) - cfg.ui.class_checkBox_rf.stateChanged.connect(cfg.rndmFrst.classCheckbox) - cfg.ui.classifier_Button.clicked.connect(cfg.rndmFrst.selectRFClassifier) - # connect to reset classifier - cfg.ui.resetClassifierButton.clicked.connect(cfg.rndmFrst.resetRFClassifier) - ''' Vector to Raster tab ''' - cfg.ui.toolButton_reload_16.clicked.connect(cfg.vctRstrT.reloadVectorList) - cfg.ui.toolButton_reload_17.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.convert_vector_toolButton.clicked.connect(cfg.vctRstrT.convertToRasterAction) - cfg.ui.vector_to_raster.clicked.connect(cfg.batchT.setFunctionButton) - cfg.ui.vector_name_combo.currentIndexChanged.connect(cfg.utls.refreshVectorFields) - cfg.ui.field_checkBox.stateChanged.connect(cfg.vctRstrT.checkboxFieldChanged) - cfg.ui.constant_value_checkBox.stateChanged.connect(cfg.vctRstrT.checkboxConstantValueChanged) - ''' Post processing tab ''' - ''' accuracy tab ''' - # connect the classification combo - cfg.ui.classification_name_combo.currentIndexChanged.connect(cfg.acc.classificationLayerName) - # connect to refresh button - cfg.ui.toolButton_reload_4.clicked.connect(cfg.utls.refreshClassificationLayer) - # connect the reference combo - cfg.ui.reference_name_combo.currentIndexChanged.connect(cfg.acc.referenceLayerName) - # connect to refresh button - cfg.ui.buttonReload_shape_4.clicked.connect(cfg.acc.refreshReferenceLayer) - # connect to calculate error matrix button - cfg.ui.calculateMatrix_toolButton.clicked.connect(cfg.acc.calculateErrorMatrix) - cfg.ui.accuracy.clicked.connect(cfg.batchT.setFunctionButton) - ''' Land cover change ''' - # connect to refresh button reference classification - cfg.ui.toolButton_reload_5.clicked.connect(cfg.landCC.refreshClassificationReferenceLayer) - # connect to refresh button new classification - cfg.ui.toolButton_reload_6.clicked.connect(cfg.landCC.refreshNewClassificationLayer) - # connect the classification reference combo - cfg.ui.classification_reference_name_combo.currentIndexChanged.connect(cfg.landCC.classificationReferenceLayerName) - # connect the new classification combo - cfg.ui.new_classification_name_combo.currentIndexChanged.connect(cfg.landCC.newClassificationLayerName) - # connect the mask unchanged checkBox - cfg.ui.mask_unchanged_checkBox.stateChanged.connect(cfg.landCC.maskUnchangedCheckbox) - # connect to calculate land cover change button - cfg.ui.calculateLandCoverChange_toolButton.clicked.connect(cfg.landCC.landCoverChangeAction) - cfg.ui.land_cover_change.clicked.connect(cfg.batchT.setFunctionButton) - ''' Classification report ''' - # connect to refresh button - cfg.ui.toolButton_reload_10.clicked.connect(cfg.utls.refreshClassificationLayer) - # connect to calculate button - cfg.ui.calculateReport_toolButton.clicked.connect(cfg.classRep.calculateClassReport) - cfg.ui.classification_report.clicked.connect(cfg.batchT.setFunctionButton) - ''' Band set combination tab ''' - # connect to calculate button - cfg.ui.calculateBandSetComb_toolButton.clicked.connect(cfg.bsComb.calculateBandSetCombination) - cfg.ui.band_combination.clicked.connect(cfg.batchT.setFunctionButton) - ''' Cross classification tab ''' - # connect the classification combo - cfg.ui.classification_name_combo_2.currentIndexChanged.connect(cfg.crossC.classificationLayerName) - # connect to refresh button - cfg.ui.toolButton_reload_21.clicked.connect(cfg.utls.refreshClassificationLayer) - # connect the reference combo - cfg.ui.reference_name_combo_2.currentIndexChanged.connect(cfg.crossC.referenceLayerName) - # connect to refresh button - cfg.ui.buttonReload_shape_5.clicked.connect(cfg.crossC.refreshReferenceLayer) - # connect to calculate error matrix button - cfg.ui.calculatecrossClass_toolButton.clicked.connect(cfg.crossC.calculateCrossClassification) - cfg.ui.cross_classification.clicked.connect(cfg.batchT.setFunctionButton) - ''' Class signature ''' - # connect to calculate signature - cfg.ui.class_signature_Button.clicked.connect(cfg.classSigT.calculateClassSignatureAction) - cfg.ui.class_signature.clicked.connect(cfg.batchT.setFunctionButton) - # connect to refresh button - cfg.ui.toolButton_reload_22.clicked.connect(cfg.utls.refreshClassificationLayer) - ''' Classification to vector ''' - # connect to refresh button - cfg.ui.toolButton_reload_12.clicked.connect(cfg.utls.refreshClassificationLayer) - # connect to convert button - cfg.ui.convert_toolButton.clicked.connect(cfg.classVect.convertClassificationToVectorAction) - cfg.ui.classification_to_vector.clicked.connect(cfg.batchT.setFunctionButton) - ''' Reclassification ''' - # connect to refresh button - cfg.ui.toolButton_reload_11.clicked.connect(cfg.utls.refreshClassificationLayer) - # connect to reclassify button - cfg.ui.reclassify_toolButton.clicked.connect(cfg.reclassification.reclassifyAction) - cfg.ui.reclassification.clicked.connect(cfg.batchT.setFunctionButton) - # connect to calculate unique values button - cfg.ui.calculate_unique_values_toolButton.clicked.connect(cfg.reclassification.calculateUniqueValues) - # connect to incremental new values button - cfg.ui.incremental_new_values_toolButton.clicked.connect(cfg.reclassification.incrementalNewValues) - # connect to add value button - cfg.ui.add_value_pushButton.clicked.connect(cfg.reclassification.addRowToTable) - # connect to remove point - cfg.ui.remove_row_pushButton.clicked.connect(cfg.reclassification.removePointFromTable) - # connect to import band set button - cfg.ui.import_reclass_toolButton.clicked.connect(cfg.reclassification.importReclass) - # connect to export band set button - cfg.ui.export_reclass_toolButton.clicked.connect(cfg.reclassification.exportReclass) - # connect to edited cell - cfg.ui.reclass_values_tableWidget.cellChanged.connect(cfg.reclassification.editedCell) - ''' Edit Raster tab''' - # connect to set value - cfg.ui.raster_set_value_toolButton.clicked.connect(cfg.editRstr.setRasterValueAction) - cfg.ui.edit_raster_using_vector.clicked.connect(cfg.batchT.setFunctionButton) - # connect to refresh rasters button - cfg.ui.toolButton_reload_14.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.undo_edit_Button.clicked.connect(cfg.editRstr.undoEdit) - # connect the expression text - cfg.ui.expression_lineEdit.textChanged.connect(cfg.editRstr.textChanged) - cfg.ui.use_constant_val_checkBox.stateChanged.connect(cfg.editRstr.checkboxConstantValChanged) - cfg.ui.use_field_vector_checkBox.stateChanged.connect(cfg.editRstr.checkboxVectorFieldChanged) - cfg.ui.use_expression_checkBox.stateChanged.connect(cfg.editRstr.checkboxUseExpressionChanged) - cfg.ui.edit_val_use_ROI_radioButton.clicked.connect(cfg.editRstr.radioUseROIPolygonChanged) - cfg.ui.edit_val_use_vector_radioButton.clicked.connect(cfg.editRstr.radioUseVectorChanged) - cfg.ui.toolButton_reload_20.clicked.connect(cfg.editRstr.reloadVectorList) - cfg.ui.vector_name_combo_2.currentIndexChanged.connect(cfg.utls.refreshVectorFields2) - ''' Classification sieve tab''' - # connect to refresh rasters button - cfg.ui.toolButton_reload_15.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.sieve_toolButton.clicked.connect(cfg.sieveRstr.sieveClassificationAction) - cfg.ui.classification_sieve.clicked.connect(cfg.batchT.setFunctionButton) - ''' Classification erosion tab''' - # connect to refresh rasters button - cfg.ui.toolButton_reload_18.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.class_erosion_toolButton.clicked.connect(cfg.ersnRstr.erosionClassificationAction) - cfg.ui.classification_erosion.clicked.connect(cfg.batchT.setFunctionButton) - # connect the value text - cfg.ui.erosion_classes_lineEdit.textChanged.connect(cfg.ersnRstr.textChanged) - ''' Classification dilation tab''' - # connect to refresh rasters button - cfg.ui.toolButton_reload_19.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.class_dilation_toolButton.clicked.connect(cfg.dltnRstr.dilationClassificationAction) - cfg.ui.classification_dilation.clicked.connect(cfg.batchT.setFunctionButton) - # connect the value text - cfg.ui.dilation_classes_lineEdit.textChanged.connect(cfg.dltnRstr.textChanged) - ''' Classification zonal stat tab''' - # connect to refresh rasters button - cfg.ui.toolButton_reload_24.clicked.connect(cfg.utls.refreshClassificationLayer) - cfg.ui.buttonReload_shape_6.clicked.connect(cfg.znlSttRstT.refreshReferenceLayer) - cfg.ui.zonal_stat_raster_toolButton.clicked.connect(cfg.znlSttRstT.zonalStatRasterAction) - cfg.ui.zonal_stat_raster.clicked.connect(cfg.batchT.setFunctionButton) - # connect the classification combo - cfg.ui.classification_name_combo_5.currentIndexChanged.connect(cfg.znlSttRstT.classificationLayerName) - # connect the reference combo - cfg.ui.reference_name_combo_3.currentIndexChanged.connect(cfg.znlSttRstT.referenceLayerName) - ''' Band Calc tab ''' - # connect to refresh button - cfg.ui.toolButton_reload_13.clicked.connect(cfg.bCalc.rasterBandName) - # connect to calc button - cfg.ui.toolButton_calculate.clicked.connect(cfg.bCalc.calculateButton) - cfg.ui.band_calc.clicked.connect(cfg.batchT.setFunctionButton) - # connect to import expression button - cfg.ui.toolButton_import_expression.clicked.connect(cfg.bCalc.importExpressionList) - # connect the expression text - cfg.ui.plainTextEdit_calc.textChanged.connect(cfg.bCalc.textChanged) - # connect double click table - cfg.ui.tableWidget_band_calc.doubleClicked.connect(cfg.bCalc.doubleClick) - # connect the intersection checkBox - cfg.ui.intersection_checkBox.stateChanged.connect(cfg.bCalc.intersectionCheckbox) - # connect the extent checkBox - cfg.ui.extent_checkBox.stateChanged.connect(cfg.bCalc.extentCheckbox) - # connect to raster type combo - cfg.ui.raster_type_combo.currentIndexChanged.connect(cfg.bCalc.setRasterType) - # connect to expression buttons - cfg.ui.toolButton_plus.clicked.connect(cfg.bCalc.buttonPlus) - cfg.ui.toolButton_minus.clicked.connect(cfg.bCalc.buttonMinus) - cfg.ui.toolButton_product.clicked.connect(cfg.bCalc.buttonProduct) - cfg.ui.toolButton_ratio.clicked.connect(cfg.bCalc.buttonRatio) - cfg.ui.toolButton_power.clicked.connect(cfg.bCalc.buttonPower) - cfg.ui.toolButton_sqrt.clicked.connect(cfg.bCalc.buttonSQRT) - cfg.ui.toolButton_lbracket.clicked.connect(cfg.bCalc.buttonLbracket) - cfg.ui.toolButton_rbracket.clicked.connect(cfg.bCalc.buttonRbracket) - cfg.ui.toolButton_greater.clicked.connect(cfg.bCalc.buttonGreater) - cfg.ui.toolButton_less.clicked.connect(cfg.bCalc.buttonLower) - cfg.ui.toolButton_equal.clicked.connect(cfg.bCalc.buttonEqual) - cfg.ui.toolButton_unequal.clicked.connect(cfg.bCalc.buttonUnequal) - cfg.ui.band_calc_function_tableWidget.doubleClicked.connect(cfg.bCalc.setFunction) - # decision rules - cfg.ui.decision_rules_tableWidget.cellChanged.connect(cfg.bCalc.editedDecisionRulesTable) - cfg.ui.band_calc_tabWidget.currentChanged.connect(cfg.bCalc.tabChanged) - # connect to add rule - cfg.ui.add_rule_toolButton.clicked.connect(cfg.bCalc.addRowToTable) - cfg.ui.remove_rule_toolButton.clicked.connect(cfg.bCalc.removeHighlightedRule) - # connect to clear button - cfg.ui.clear_rules_toolButton.clicked.connect(cfg.bCalc.clearRulesAction) - cfg.ui.export_rules_toolButton.clicked.connect(cfg.bCalc.exportRules) - cfg.ui.import_rules_toolButton.clicked.connect(cfg.bCalc.importRules) - cfg.ui.move_up_toolButton_2.clicked.connect(cfg.bCalc.moveUpRule) - cfg.ui.move_down_toolButton_2.clicked.connect(cfg.bCalc.moveDownRule) - # connect to filter - cfg.ui.bandcalc_filter_lineEdit.textChanged.connect(cfg.bCalc.filterTable) - ''' Batch tab ''' - # connect the batch text - #cfg.ui.plainTextEdit_batch.textChanged.connect(cfg.batchT.textChanged) - # connect to calc button - cfg.ui.toolButton_run_batch.clicked.connect(cfg.batchT.runButton) - cfg.ui.check_batch.clicked.connect(cfg.batchT.textChanged) - cfg.ui.clear_batch_toolButton.clicked.connect(cfg.batchT.clearBatch) - cfg.ui.export_batch_toolButton.clicked.connect(cfg.batchT.exportBatch) - cfg.ui.import_batch_toolButton.clicked.connect(cfg.batchT.importBatch) - # connect to table double click - cfg.ui.batch_tableWidget.doubleClicked.connect(cfg.batchT.setFunction) - ''' Settings tab ''' - # connect the ID field name line - cfg.ui.ID_field_name_lineEdit.textChanged.connect(cfg.sets.IDFieldNameChange) - # connect the macroclass ID field name line - cfg.ui.MID_field_name_lineEdit.textChanged.connect(cfg.sets.MacroIDFieldNameChange) - # connect the macroclass Info field name line - cfg.ui.MCInfo_field_name_lineEdit.textChanged.connect(cfg.sets.MacroInfoFieldNameChange) - # connect the Info field name line - cfg.ui.Info_field_name_lineEdit.textChanged.connect(cfg.sets.InfoFieldNameChange) - # connect the variable name line - cfg.ui.variable_name_lineEdit.textChanged.connect(cfg.sets.VariableNameChange) - # connect the group name line - cfg.ui.group_name_lineEdit.textChanged.connect(cfg.sets.GroupNameChange) - # connect the SMTP line - cfg.ui.smtp_server_lineEdit.textChanged.connect(cfg.sets.SMTPServerChange) - # connect the SMTP to emails line - cfg.ui.to_email_lineEdit.textChanged.connect(cfg.sets.SMTPtoEmailsChange) - # connect the SMTP user - cfg.ui.smtp_user_lineEdit.editingFinished.connect(cfg.sets.rememberUser) - # connect the SMTP password - cfg.ui.smtp_password_lineEdit.editingFinished.connect(cfg.sets.rememberUser) - # connect the SMTP checkbox - cfg.ui.remeber_settings_checkBox.stateChanged.connect(cfg.sets.rememberUserCheckbox) - # connect the SMTP checkBox - cfg.ui.smtp_checkBox.stateChanged.connect(cfg.sets.SMTPCheckbox) - # connect to reset field names button - cfg.ui.reset_field_names_Button.clicked.connect(cfg.sets.resetFieldNames) - # connect to reset variable name button - cfg.ui.reset_variable_name_Button.clicked.connect(cfg.sets.resetVariableName) - # connect to reset group name button - cfg.ui.reset_group_name_Button.clicked.connect(cfg.sets.resetGroupName) - # connect the log file checkBox - cfg.ui.log_checkBox.stateChanged.connect(cfg.sets.logCheckbox) - # connect the download news checkBox - cfg.ui.download_news_checkBox.stateChanged.connect(cfg.sets.downloadNewsCheckbox) - # connect the virtual raster checkBox - cfg.ui.virtual_raster_load_checkBox.stateChanged.connect(cfg.sets.virtualRasterCheckbox) - # connect the sound checkBox - cfg.ui.sound_checkBox.stateChanged.connect(cfg.sets.soundCheckbox) - # connect the virtual raster format checkBox - cfg.ui.virtual_raster_checkBox.stateChanged.connect(cfg.sets.virtualRasterFormatCheckbox) - # connect the raster compression checkBox - cfg.ui.raster_compression_checkBox.stateChanged.connect(cfg.sets.rasterCompressionCheckbox) - # connect the parallel writing checkBox - cfg.ui.parallel_writing_checkBox.stateChanged.connect(cfg.sets.parallelWritingCheckbox) - # connect to change temporary directory button - cfg.ui.temp_directory_Button.clicked.connect(cfg.sets.changeTempDir) - # connect to reset temporary directory button - cfg.ui.reset_temp_directory_Button.clicked.connect(cfg.sets.resetTempDir) - # connect to clear log button - cfg.ui.clearLog_Button.clicked.connect(cfg.utls.clearLogFile) - # connect to export log button - cfg.ui.exportLog_Button.clicked.connect(cfg.sets.copyLogFile) - # connect to test dependencies button - cfg.ui.test_dependencies_Button.clicked.connect(cfg.sets.testDependencies) - # connect to RAM spinbox - cfg.ui.RAM_spinBox.valueChanged.connect(cfg.sets.RAMSettingChange) - # connect to thread spinbox - cfg.ui.CPU_spinBox.valueChanged.connect(cfg.sets.threadSettingChange) - # connect the Python path line - cfg.ui.python_path_lineEdit.textChanged.connect(cfg.sets.PythonPathSettingChange) - # connect the Python modules path line - cfg.ui.python_path_lineEdit_2.textChanged.connect(cfg.sets.PythonModulePathSettingChange) - # connect the GDAL path line - cfg.ui.gdal_path_lineEdit.textChanged.connect(cfg.sets.GDALPathSettingChange) - # connect to change color button - cfg.ui.change_color_Button.clicked.connect(cfg.sets.changeROIColor) - # connect to change color button - cfg.ui.reset_color_Button.clicked.connect(cfg.sets.resetROIStyle) - # connect to transparency slider - cfg.ui.transparency_Slider.valueChanged.connect(cfg.sets.changeROITransparency) - # first install - if cfg.firstInstallVal == 'Yes': - cfg.utls.welcomeTab() - cfg.utls.setQGISRegSetting(cfg.regFirstInstall, 'No') - cfg.utls.findAvailableRAM() - cfg.utls.findAvailableProcessors() - # welcome message - lWelcome = cfg.plgnDir + '/ui/welcome.html' - htmlTextF = open(lWelcome, 'r') - htmlText = htmlTextF.read() - cfg.uidc.main_textBrowser.clear() - cfg.uidc.main_textBrowser.setHtml(htmlText) - htmlTextF.close() - if cfg.osSCP.path.isfile(cfg.plgnDir + '/firstrun'): - cfg.ipt.welcomeText('https://semiautomaticgit.github.io/SemiAutomaticClassificationPluginWelcome/changelog.html') - cfg.osSCP.remove(cfg.plgnDir + '/firstrun') - else: - dateV = cfg.datetimeSCP.datetime.now() - dStr = dateV.strftime('%Y_%m_%d') - cfg.ipt.welcomeText('https://semiautomaticgit.github.io/SemiAutomaticClassificationPluginWelcome/welcome' + '_' + dStr + '.html', 'https://semiautomaticgit.github.io/SemiAutomaticClassificationPluginWelcome/welcome.html') - cfg.utls.cleanOldTempDirectory() - cfg.skipRegistry = False - else: - dockclassdlg = DockClassDialog(qgisUtils.iface.mainWindow(), qgisUtils.iface) - qgisUtils.iface.removeDockWidget(dockclassdlg) - - # save signature list when saving project - def projectSaved(self): - if cfg.skipProjectSaved == 'No': - if len(cfg.signIDs) > 0: - cfg.SCPD.saveSignatureListToFile() - if cfg.scpFlPath is not None: - cfg.SCPD.saveMemToSHP(cfg.shpLay) - cfg.utls.zipDirectoryInFile(cfg.scpFlPath, cfg.inptDir) - cfg.downProd.saveDownloadTable() - try: - scpPath = cfg.utls.readProjectVariable('trainingLayer', '') - name = cfg.utls.fileNameNoExt(scpPath) - duplicateID = cfg.utls.layerID(name, cfg.shpLay.id()) - cfg.qgisCoreSCP.QgsProject.instance().removeMapLayer(duplicateID) - except: - pass - - # reset all variables and interface - def resetSCP(self): - # logger - cfg.utls.logToFile(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'LOG ACTIVE' + cfg.sysSCPInfo) - cfg.scpFlPath = None - cfg.ui.image_raster_name_combo.blockSignals(True) - cfg.ui.Band_set_tabWidget.blockSignals(True) - cfg.rasterComboEdited = 'No' - cfg.projPath = cfg.qgisCoreSCP.QgsProject.instance().fileName() - cfg.lastSaveDir = cfg.osSCP.path.dirname(cfg.projPath) - cfg.projPath = cfg.qgisCoreSCP.QgsProject.instance().fileName() - cfg.lastSaveDir = cfg.osSCP.path.dirname(cfg.projPath) - cfg.signList = {} - cfg.signIDs = {} - cfg.spectrPlotList = {} - cfg.signPlotIDs = {} - cfg.scatterPlotIDs = {} - cfg.scatterPlotList = {} - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - cfg.lstROI = None - cfg.lstROI2 = None - cfg.rpdROICheck = '2' - cfg.vegIndexCheck = 2 - cfg.sigClcCheck = 2 - cfg.utls.clearTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.utls.clearTable(cfg.uiscp.scatter_list_plot_tableWidget) - cfg.utls.clearTable(cfg.ui.signature_threshold_tableWidget) - cfg.utls.clearTable(cfg.ui.download_images_tableWidget) - cfg.utls.clearTable(cfg.ui.LCS_tableWidget) - cfg.treeDockItm = {} - cfg.treeDockMCItm = {} - cfg.SCPD.clearTree() - cfg.scaPlT.scatterPlotListTable(cfg.uiscp.scatter_list_plot_tableWidget) - cfg.spSigPlot.refreshPlot() - cfg.LCSignT.LCSignatureThresholdListTable() - # reload layers in combos - cfg.ipt.refreshRasterLayer() - cfg.utls.refreshVectorLayer() - cfg.utls.refreshClassificationLayer() - cfg.utls.refreshRasterExtent() - cfg.acc.refreshReferenceLayer() - cfg.crossC.refreshReferenceLayer() - cfg.znlSttRstT.refreshReferenceLayer() - cfg.znlSttRstT.loadStatisticCombo() - cfg.clssNghbr.loadStatisticCombo() - cfg.landCC.refreshClassificationReferenceLayer() - cfg.landCC.refreshNewClassificationLayer() - # read variables - cfg.utls.readVariables() - # set ROI color - cfg.ui.change_color_Button.setStyleSheet('background-color :' + cfg.ROIClrVal) - # set ROI transparency - cfg.ui.transparency_Slider.setValue(cfg.ROITrnspVal) - # set RAM value - cfg.ui.RAM_spinBox.setValue(cfg.RAMValue) - # set CPU value - cfg.ui.CPU_spinBox.setValue(cfg.threads) - # rapid ROI band - cfg.uidc.rapidROI_band_spinBox.setValue(int(cfg.ROIband)) - # min ROI size - cfg.Min_region_size_spin.setValue(int(cfg.minROISz)) - # max ROI width - cfg.Max_ROI_width_spin.setValue(int(cfg.maxROIWdth)) - # range radius - cfg.Range_radius_spin.setValue(float(cfg.rngRad)) - # ROI ID field - cfg.uidc.ROI_ID_spin.setValue(int(cfg.ROIID)) - # ROI macro ID field - cfg.uidc.ROI_Macroclass_ID_spin.setValue(int(cfg.ROIMacroID)) - # preview size - cfg.preview_size_spinBox.setValue(float(cfg.prvwSz)) - # set ID field name line - cfg.ui.ID_field_name_lineEdit.setText(cfg.fldID_class) - cfg.ui.MID_field_name_lineEdit.setText(cfg.fldMacroID_class) - # set Info field name line - cfg.ui.Info_field_name_lineEdit.setText(cfg.fldROI_info) - cfg.ui.MCInfo_field_name_lineEdit.setText(cfg.fldROIMC_info) - cfg.ui.variable_name_lineEdit.setText(cfg.variableName) - cfg.ui.group_name_lineEdit.setText(cfg.grpNm) - # gdal path - cfg.ui.gdal_path_lineEdit.setText(cfg.gdalPath) - cfg.ui.python_path_lineEdit.setText(cfg.PythonPathSettings) - cfg.ui.python_path_lineEdit_2.setText(cfg.PythonModulesPathSettings) - # set signature calculation checkbox state - try: - cfg.uidc.rapid_ROI_checkBox.setCheckState(int(cfg.rpdROICheck)) - except: - pass - # set vegetation index calculation checkbox state - try: - cfg.uidc.display_cursor_checkBox.setCheckState(int(cfg.vegIndexCheck)) - except: - pass - # set signature calculation checkbox state - try: - cfg.uidc.signature_checkBox.setCheckState(int(cfg.sigClcCheck)) - cfg.ui.signature_checkBox2.setCheckState(int(cfg.sigClcCheck)) - except: - pass - # set save input checkbox state - try: - cfg.uidc.save_input_checkBox.setCheckState(int(cfg.saveInputCheck)) - except: - pass - # load classification algorithm - idAlg = cfg.ui.algorithm_combo.findText(cfg.algName) - if idAlg >= 0: - cfg.ui.algorithm_combo.setCurrentIndex(idAlg) - else: - cfg.ui.algorithm_combo.setCurrentIndex(0) - cfg.algName = cfg.algMinDist - # ROI info - cfg.uidc.ROI_Class_line.setText(cfg.ROIInfo) - cfg.uidc.ROI_Macroclass_line.setText(cfg.ROIMacroClassInfo) - cfg.uidc.custom_index_lineEdit.setText(cfg.customExpression) - # RGB list - cfg.RGBLT.RGBListTable(cfg.RGBList) - # reload raster bands in checklist - cfg.bst.rasterBandName() - cfg.rasterComboEdited = 'Yes' - cfg.ui.image_raster_name_combo.blockSignals(False) - cfg.ui.Band_set_tabWidget.blockSignals(False) - # new project - def newProjectLoaded(self): - # clear band set - t = cfg.ui.Band_set_tabWidget.count() - for index in reversed(list(range(0, t))): - cfg.bst.deleteBandSetTab(index) - self.resetSCP() - cfg.bCalc.rasterBandName() - cfg.SCPD.openInput() - cfg.bstLT.BandSetListTable() - # allow automatic batch - batchPath = cfg.plgnDir + '/batch.txt' - if cfg.osSCP.path.isfile(batchPath): - try: - text = open(batchPath, 'r').read() - cfg.ui.plainTextEdit_batch.setPlainText(text) - cfg.batchT.runButton() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - - # read project variables - def projectLoaded(self): - self.resetSCP() - # load product download table - cfg.downProd.openDownloadTable() - cfg.bCalc.rasterBandName() - cfg.SCPD.openInput() - cfg.bstLT.BandSetListTable() - - # run - def run(self): - # show the dialog - cfg.dlg.show() - # Run the dialog event loop - pointer_result = cfg.dlg.exec_() - - # remove plugin menu and icon - def unload(self): - cfg.utls.createBackupFile(cfg.scpFlPath) - # save window size - try: - cfg.utls.setQGISRegSetting(cfg.regWindowSizeW, cfg.dlg.size().width()) - cfg.utls.setQGISRegSetting(cfg.regWindowSizeH, cfg.dlg.size().height()) - except: - pass - try: - qgisUtils.iface.removeDockWidget(cfg.dockclassdlg) - del cfg.toolBar2 - del cfg.toolBar3 - cfg.menu.deleteLater() - # remove temp files - if cfg.tmpDir is not None and cfg.QDirSCP(cfg.tmpDir).exists(): - cfg.shutilSCP.rmtree(cfg.tmpDir, True) - oDir = cfg.utls.makeDirectory(str(cfg.QDirSCP.tempPath() + '/' + cfg.tempDirName)) - except: - if PluginCheck == 'Yes': - qgisUtils.iface.messageBar().pushMessage('Semi-Automatic Classification Plugin', QApplication.translate('semiautomaticclassificationplugin', 'Please, restart QGIS for executing the Semi-Automatic Classification Plugin'), level=qgisCore.Qgis.Info) +# reset all variables and interface +def reset_scp(): + cfg.logger.log.debug('reset_scp') + cfg.ui_utils.set_interface(False) + # clear band set + t = cfg.dialog.ui.Band_set_tabWidget.count() + for index in reversed(list(range(0, t))): + cfg.bst.delete_bandset_tab(index) + cfg.bandset_catalog = cfg.rs.bandset_catalog() + cfg.dock_class_dlg.ui.label_48.setText( + cfg.translate(' ROI & Signature list') + ) + cfg.utils.refresh_vector_layer() + # reset tabs + count = cfg.dialog.ui.Band_set_tabWidget.count() + for i in list(reversed(range(0, count))): + cfg.bst.delete_bandset_tab(i) + cfg.bst.add_band_set_tab() + cfg.dialog.ui.Band_set_tabWidget.blockSignals(True) + cfg.project_path = QgsProject.instance().fileName() + cfg.last_saved_dir = path.dirname(cfg.project_path) + cfg.util_qt.clear_table( + cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + ) + cfg.util_qt.clear_table( + cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + ) + cfg.util_qt.clear_table(cfg.dialog.ui.signature_threshold_tableWidget) + cfg.util_qt.clear_table(cfg.dialog.ui.download_images_tableWidget) + cfg.scp_dock.TrainingVectorLayer(signature_catalog=False, output_path=None) + # read variables + cfg.project_registry = cfg.project_registry_default.copy() + cfg.utils.read_project_variables() + cfg.ui_utils.set_interface(True) diff --git a/maininterface/__init__.py b/spectral_signature/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from maininterface/__init__.py rename to spectral_signature/__init__.py diff --git a/spectral_signature/scatter_plot.py b/spectral_signature/scatter_plot.py new file mode 100755 index 0000000..4945a90 --- /dev/null +++ b/spectral_signature/scatter_plot.py @@ -0,0 +1,678 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 self.scatter_band_y Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published self.scatter_band_y the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +import matplotlib.colors as mpl_colors +import matplotlib.pyplot as mpl_plot +from PyQt5.QtCore import QPointF +from PyQt5.QtGui import QColor, QPolygonF +from PyQt5.QtWidgets import QApplication +from matplotlib.ticker import MaxNLocator +from qgis.core import QgsVectorLayer, QgsGeometry, QgsFeature + +try: + from remotior_sensus.core.processor_functions import ( + get_values_for_scatter_plot + ) + from remotior_sensus.core.spectral_signatures import SpectralSignaturePlot +except Exception as error: + str(error) + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +class ScatterPlot: + + def __init__(self): + try: + canvas = cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas + self.mouseScroll = canvas.mpl_connect( + 'scroll_event', + self.scroll_event + ) + self.mousePress = canvas.mpl_connect( + 'button_press_event', + self.press_event + ) + self.mouseRelease = canvas.mpl_connect( + 'button_release_event', + self.release_event + ) + self.mouseMove = canvas.mpl_connect( + 'motion_notify_event', + self.motion_event + ) + self.ax = canvas.ax + except Exception as err: + str(err) + return + self.x_min = None + self.x_max = None + self.y_min = None + self.y_max = None + self.last_x_min = None + self.last_x_max = None + self.last_y_min = None + self.last_y_max = None + self.color = '#ffaa00' + self.temp_scatter_name = 'temp_scatter' + self.scatter_band_x = 1 + self.scatter_band_y = 2 + self.order_column = 1 + self.plot_catalog = cfg.rs.spectral_signatures_plot_catalog() + self.press = None + self.release = None + self.select_all = False + + @staticmethod + def motion_event(event): + if event.inaxes is not None: + cfg.scatter_plot_dlg.ui.value_label_2.setText( + 'x=%s y=%s' % (str(event.xdata)[:8].ljust(8), + str(event.ydata)[:8].ljust(8)) + ) + + def press_event(self, event): + if event.inaxes is None: + self.press = None + return 0 + self.press = [event.xdata, event.ydata] + + def release_event(self, event): + if event.inaxes is None: + self.release = None + return 0 + self.release = [event.xdata, event.ydata] + if event.button == 3: + self.resize() + else: + self.move() + + def scroll_event(self, event): + x_min, x_max = self.ax.get_xlim() + y_min, y_max = self.ax.get_ylim() + zoom_x = (x_max - x_min) * 0.2 + zoom_y = (y_max - y_min) * 0.2 + if event.button == 'down': + x_lim_min = x_min - zoom_x + x_lim_max = x_max + zoom_x + y_lim_min = y_min - zoom_y + y_lim_max = y_max + zoom_y + else: + x_lim_min = x_min + zoom_x + x_lim_max = x_max - zoom_x + y_lim_min = y_min + zoom_y + y_lim_max = y_max - zoom_y + self.ax.set_xlim(x_lim_min, x_lim_max) + self.ax.set_ylim(y_lim_min, y_lim_max) + cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas.draw() + self.last_x_min = x_lim_min + self.last_x_max = x_lim_max + self.last_y_min = y_lim_min + self.last_y_max = y_lim_max + + # edited cell + def edited_cell(self, row, column): + table = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + signature_id = table.item(row, 6).text() + if column == 0: + if table.item(row, column).checkState() == 2: + self.plot_catalog.catalog[signature_id].selected = 1 + else: + self.plot_catalog.catalog[signature_id].selected = 0 + elif column == 1: + self.plot_catalog.catalog[signature_id].macroclass_id = int( + table.item(row, column).text() + ) + elif column == 2: + self.plot_catalog.catalog[signature_id].macroclass_name = str( + table.item(row, column).text() + ) + elif column == 3: + self.plot_catalog.catalog[signature_id].class_id = int( + table.item(row, column).text() + ) + elif column == 4: + self.plot_catalog.catalog[signature_id].class_name = str( + table.item(row, column).text() + ) + self.create_scatter_plot() + + # scatter plot double click + def scatter_plot_double_click(self, index): + table = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + if index.column() == 5: + color = cfg.util_qt.select_color() + if color is not None: + cfg.scatter_plot_dlg.ui.colormap_comboBox.setCurrentIndex(0) + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected = list(set(selected)) + for row in selected: + signature_id = table.item(row, 6).text() + self.plot_catalog.catalog[signature_id].color = ( + color.toRgb().name() + ) + table.item(row, 5).setBackground(color) + del self.plot_catalog.catalog[signature_id].attributes[ + 'color_map'] + elif index.column() == 0: + self.select_all_rois() + self.create_scatter_plot() + + # select all signatures + def select_all_rois(self): + # select all + if self.select_all is True: + cfg.util_qt.all_items_set_state( + cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget, 2 + ) + for signature in self.plot_catalog.catalog: + self.plot_catalog.catalog[signature].selected = 1 + # set check all plot + self.select_all = False + # unselect all if previously selected all + else: + cfg.util_qt.all_items_set_state( + cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget, 0 + ) + # set check all plot + self.select_all = True + for signature in self.plot_catalog.catalog: + self.plot_catalog.catalog[signature].selected = 0 + + # add temp ROI to scatter plot + def add_temp_roi_to_scatter_plot(self): + if cfg.temporary_roi is not None: + self.calculate_vector_scatter_plot() + + # calculate polygon scatter plot + def calculate_polygon_scatter_plot(self, polygon): + crs = cfg.bandset_catalog.get_crs( + cfg.project_registry[cfg.reg_active_bandset_number] + ) + if crs is None: + crs = cfg.util_qgis.get_qgis_crs() + # date time for temp name + date = cfg.utils.get_time() + memory_layer = QgsVectorLayer( + 'MultiPolygon?crs=' + str(crs.toWkt()), 'm' + str(date), 'memory' + ) + point_f = QPointF() + polygon_f = QPolygonF() + for v in polygon: + point_f.setX(v.x()) + point_f.setY(v.y()) + polygon_f.append(point_f) + point_f.setX(polygon[0].x()) + point_f.setY(polygon[0].y()) + polygon_f.append(point_f) + g = QgsGeometry().fromQPolygonF(polygon_f) + f = QgsFeature() + f.setGeometry(g) + memory_layer.startEditing() + memory_layer.addFeatures([f]) + memory_layer.commitChanges() + memory_layer.dataProvider().createSpatialIndex() + memory_layer.updateExtents() + vector = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + cfg.util_qgis.save_qgis_memory_layer_to_file(memory_layer, vector) + self.calculate_vector_scatter_plot(vector=vector) + + # add vector to scatter plot + def calculate_vector_scatter_plot(self, vector=None): + # temporary ROI + if vector is None: + # get vector from ROI + vector = cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.gpkg' + ) + cfg.util_qgis.save_qgis_memory_layer_to_file( + cfg.temporary_roi, vector + ) + signature_id = self.temp_scatter_name + color_string = cfg.rs.shared_tools.random_color() + vector_plot = SpectralSignaturePlot( + value=None, wavelength=None, signature_id=signature_id, + macroclass_name=self.temp_scatter_name, + class_name=self.temp_scatter_name, color_string=color_string, + selected=1 + ) + self.plot_catalog.catalog[signature_id] = vector_plot + self.plot_catalog.catalog[signature_id].attributes[ + 'geometry_path'] = vector + self.scatter_plot_list_table() + + # calculate scatter plot + def calculate_scatter_plot(self): + self.create_scatter_plot(calculate=True) + + # plot colormap + def color_plot(self): + table = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected = list(set(selected)) + if len(selected) == 0: + count = table.rowCount() + selected = list(range(0, count)) + for x in selected: + signature_id = table.item(x, 6).text() + color_name = ( + cfg.scatter_plot_dlg.ui.colormap_comboBox.currentText() + ) + signature = self.plot_catalog.catalog[signature_id] + color = signature.color + if (len(color_name) > 0 + and color_name in cfg.scatter_color_map): + pal = mpl_plot.get_cmap(color_name) + pal.set_under('w', 0.0) + signature.attributes['color_map'] = pal + else: + q_color = QColor(color) + hue = q_color.hue() + saturation = q_color.saturation() + value = q_color.value() + # light color + light_color = QColor() + higher_value = value + 60 + if higher_value > 255: + higher_value = 255 + light_color.setHsv(hue, saturation, higher_value) + # dark color + dark_color = QColor() + lower_value = value - 60 + if lower_value < 0: + lower_value = 0 + dark_color.setHsv(hue, saturation, lower_value) + pal = mpl_colors.LinearSegmentedColormap.from_list( + 'color', [dark_color.toRgb().name(), color, + light_color.toRgb().name()] + ) + pal.set_under('w', 0.0) + signature.attributes['color_map'] = pal + self.create_scatter_plot(skip_color=True) + + # Create scatter plot + # noinspection PyTypeChecker,PyUnresolvedReferences + def create_scatter_plot(self, calculate=False, skip_color=False): + # Clear plot + try: + self.ax.clear() + cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas.draw() + except Exception as err: + str(err) + return None + # Set labels + self.ax.set_xlabel( + '%s %s' % ( + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Band' + ), str(self.scatter_band_x) + ) + ) + self.ax.set_ylabel( + '%s %s' % ( + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Band' + ), str(self.scatter_band_y)) + ) + x_min_list = [] + x_max_list = [] + y_min_list = [] + y_max_list = [] + for signature_id in self.plot_catalog.catalog: + signature = self.plot_catalog.catalog[signature_id] + if signature.selected == 1: + color = signature.color + geometry_path = signature.attributes['geometry_path'] + color_name = ( + cfg.scatter_plot_dlg.ui.colormap_comboBox.currentText() + ) + if skip_color is False: + if (len(color_name) > 0 + and color_name in cfg.scatter_color_map): + pal = mpl_plot.get_cmap(color_name) + pal.set_under('w', 0.0) + signature.attributes['color_map'] = pal + else: + q_color = QColor(color) + hue = q_color.hue() + saturation = q_color.saturation() + value = q_color.value() + # light color + light_color = QColor() + higher_value = value + 70 + if higher_value > 255: + higher_value = 255 + light_color.setHsv(hue, saturation, higher_value) + # dark color + dark_color = QColor() + lower_value = value - 70 + if lower_value < 0: + lower_value = 0 + dark_color.setHsv(hue, saturation, lower_value) + pal = mpl_colors.LinearSegmentedColormap.from_list( + 'color', [dark_color.toRgb().name(), color, + light_color.toRgb().name()] + ) + pal.set_under('w', 0.0) + signature.attributes['color_map'] = pal + # load scatter + if 'histogram_%s_%s' % ( + self.scatter_band_x, self.scatter_band_y + ) in signature.attributes and calculate is False: + try: + h = signature.attributes[ + 'histogram_%s_%s' % ( + self.scatter_band_x, self.scatter_band_y + ) + ] + if h is not False: + self.ax.imshow( + h[0].T, origin='lower', interpolation='none', + extent=[h[1][0], h[1][-1], h[2][0], h[2][-1]], + cmap=signature.attributes['color_map'], + vmin=0.001 + ) + else: + return False + except Exception as err: + cfg.logger.log.error(str(err)) + return False + else: + cfg.ui_utils.add_progress_bar() + # calculate scatter + value_list = ( + cfg.bandset_catalog.calculate_scatter_plot_histogram( + bandset_number=cfg.project_registry[ + cfg.reg_active_bandset_number + ], band_x=self.scatter_band_x, + band_y=self.scatter_band_y, + vector_path=geometry_path + ) + ) + if cfg.scatter_plot_dlg.ui.precision_checkBox.isChecked(): + ui = cfg.scatter_plot_dlg.ui + decimal_round = int( + ui.precision_comboBox.currentText() + ) + else: + decimal_round = -1 + if value_list is not False: + # calculate histogram + h = cfg.rs.shared_tools.calculate_2d_histogram( + x_values=value_list[0], y_values=value_list[1], + decimal_round=decimal_round + ) + if h is not False: + self.ax.imshow( + h[0].T, origin='lower', interpolation='none', + extent=[h[1][0], h[1][-1], h[2][0], h[2][-1]], + cmap=signature.attributes['color_map'], + vmin=0.001 + ) + # preserve histogram_ + signature.attributes[ + 'histogram_%s_%s' % ( + self.scatter_band_x, self.scatter_band_y) + ] = h + cfg.ui_utils.remove_progress_bar() + else: + cfg.ui_utils.remove_progress_bar() + return False + else: + cfg.ui_utils.remove_progress_bar() + return False + x_min_list.append(h[1][0]) + x_max_list.append(h[1][-1]) + y_min_list.append(h[2][0]) + y_max_list.append(h[2][-1]) + # Grid for X and Y axes + try: + self.ax.xaxis.set_major_locator(MaxNLocator(5)) + self.ax.yaxis.set_major_locator(MaxNLocator(5)) + except Exception as err: + str(err) + try: + self.x_min = min(x_min_list) + self.x_max = max(x_max_list) + self.y_min = min(y_min_list) + self.y_max = max(y_max_list) + if (self.last_x_min is None or self.last_x_max is None + or self.last_y_min is None or self.last_y_max is None): + self.last_x_min = self.x_min + self.last_x_max = self.x_max + self.last_y_min = self.y_min + self.last_y_max = self.y_max + except Exception as err: + str(err) + # Draw the plot + self.fit_plot_to_axes() + + # remove scatter plot from list + # noinspection PyTypeChecker + def remove_scatter(self): + answer = cfg.util_qt.question_box( + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Delete scatter plot' + ), + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Are you sure you want to delete highlighted scatter plots?' + ) + ) + if answer is True: + table = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + r = [] + for i in table.selectedIndexes(): + r.append(i.row()) + v = list(set(r)) + for x in v: + try: + signature_id = table.item(x, 6).text() + except Exception as err: + str(err) + return False + del self.plot_catalog.catalog[signature_id] + self.scatter_plot_list_table() + + # Create signature list for plot + def scatter_plot_list_table(self, skip_plot=False): + table = cfg.scatter_plot_dlg.ui.scatter_list_plot_tableWidget + table.setSortingEnabled(False) + table.blockSignals(True) + cfg.util_qt.clear_table(table) + # add signature_id items + x = 0 + for signature_id in self.plot_catalog.catalog: + selected = self.plot_catalog.catalog[signature_id].selected + if selected == 1: + checkbox_state = 2 + else: + checkbox_state = 0 + color = self.plot_catalog.catalog[signature_id].color + cfg.util_qt.insert_table_row(table, x, 20) + cfg.util_qt.add_table_item( + table, '', x, 0, True, None, checkbox_state + ) + cfg.util_qt.add_table_item( + table, + int(self.plot_catalog.catalog[signature_id].macroclass_id), + x, 1 + ) + cfg.util_qt.add_table_item( + table, + str(self.plot_catalog.catalog[signature_id].macroclass_name), + x, 2 + ) + cfg.util_qt.add_table_item( + table, int(self.plot_catalog.catalog[signature_id].class_id), + x, 3 + ) + cfg.util_qt.add_table_item( + table, str(self.plot_catalog.catalog[signature_id].class_name), + x, 4 + ) + cfg.util_qt.add_table_item(table, '', x, 5, True, QColor(color)) + cfg.util_qt.add_table_item(table, str(signature_id), x, 6, False) + x += 1 + table.show() + cfg.util_qt.sort_table_column( + table, self.order_column, + table.horizontalHeader().sortIndicatorOrder() + ) + table.setSortingEnabled(True) + table.blockSignals(False) + # Create plot + if skip_plot is False: + self.create_scatter_plot() + + # set band X + def band_x_plot(self): + # band set + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + cfg.project_registry[cfg.reg_active_bandset_number] + ) + count = bandset_x.get_band_count() + if cfg.scatter_plot_dlg.ui.bandX_spinBox.value() > count: + cfg.scatter_plot_dlg.ui.bandX_spinBox.blockSignals(True) + cfg.scatter_plot_dlg.ui.bandX_spinBox.setValue(count) + cfg.scatter_plot_dlg.ui.bandX_spinBox.blockSignals(False) + self.scatter_band_x = cfg.scatter_plot_dlg.ui.bandX_spinBox.value() + self.create_scatter_plot() + + # set band Y + def band_y_plot(self): + # band set + bandset_x = cfg.bandset_catalog.get_bandset_by_number( + cfg.project_registry[cfg.reg_active_bandset_number] + ) + count = bandset_x.get_band_count() + if cfg.scatter_plot_dlg.ui.bandY_spinBox.value() > count: + cfg.scatter_plot_dlg.ui.bandY_spinBox.blockSignals(True) + cfg.scatter_plot_dlg.ui.bandY_spinBox.setValue(count) + cfg.scatter_plot_dlg.ui.bandY_spinBox.blockSignals(False) + self.scatter_band_y = cfg.scatter_plot_dlg.ui.bandY_spinBox.value() + self.create_scatter_plot() + + # resize plot + def resize(self): + try: + x_lim_min = min([float(self.press[0]), float(self.release[0])]) + x_lim_max = max([float(self.press[0]), float(self.release[0])]) + y_lim_min = min([float(self.press[1]), float(self.release[1])]) + y_lim_max = max([float(self.press[1]), float(self.release[1])]) + if (((x_lim_max - x_lim_min) * (x_lim_max - x_lim_min)) < 0.000001 + or ((y_lim_max - y_lim_min) + * (y_lim_max - y_lim_min)) < 0.000001): + return + self.ax.set_xlim(x_lim_min, x_lim_max) + self.ax.set_ylim(y_lim_min, y_lim_max) + cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas.draw() + self.last_x_min = x_lim_min + self.last_x_max = x_lim_max + self.last_y_min = y_lim_min + self.last_y_max = y_lim_max + except Exception as err: + str(err) + + # move plot + def move(self): + try: + delta_x = (float(self.press[0]) - float(self.release[0])) + delta_y = (float(self.press[1]) - float(self.release[1])) + x_min, x_max = self.ax.get_xlim() + y_min, y_max = self.ax.get_ylim() + self.ax.set_xlim(x_min + delta_x, x_max + delta_x) + self.ax.set_ylim(y_min + delta_y, y_max + delta_y) + cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas.draw() + self.last_x_min = x_min + delta_x + self.last_x_max = x_max + delta_x + self.last_y_min = y_min + delta_y + self.last_y_max = y_max + delta_y + except Exception as err: + str(err) + + # save plot to file + @staticmethod + def save_plot(): + # noinspection PyTypeChecker + image_output = cfg.util_qt.get_save_file_name( + None, QApplication.translate( + 'semiautomaticclassificationplugin', 'Save plot to file' + ), '', 'JPG file (*.jpg);;PNG file (*.png);;PDF file (*.pdf)', + None + ) + if len(image_output) > 0: + scatter = cfg.scatter_plot_dlg.ui.Scatter_Widget_2 + if str(image_output).endswith('.png'): + scatter.sigCanvas.figure.savefig( + image_output, format='png', dpi=300 + ) + elif str(image_output).endswith('.pdf'): + scatter.sigCanvas.figure.savefig( + image_output, format='pdf', dpi=300 + ) + else: + image_output = image_output + '.jpg' + scatter.sigCanvas.figure.savefig( + image_output, format='jpg', dpi=300, quality=90 + ) + + # fit plot to axes + def fit_plot_to_axes(self, preserve_last=False): + if preserve_last is True: + x_min = self.last_x_min + x_max = self.last_x_max + y_min = self.last_y_min + y_max = self.last_y_max + else: + x_min = self.x_min + x_max = self.x_max + y_min = self.y_min + y_max = self.y_max + self.ax.set_xlim(x_min, x_max) + self.ax.set_ylim(y_min, y_max) + self.last_x_min = x_min + self.last_x_max = x_max + self.last_y_min = y_min + self.last_y_max = y_max + try: + # Draw the plot + cfg.scatter_plot_dlg.ui.Scatter_Widget_2.sigCanvas.draw() + except Exception as err: + str(err) + return False + + +# add colormap list to combo +def add_colormap_to_combo(color_list): + for i in color_list: + cfg.scatter_plot_dlg.ui.colormap_comboBox.addItem(i) diff --git a/spectral_signature/signature_importer.py b/spectral_signature/signature_importer.py new file mode 100755 index 0000000..94c42ea --- /dev/null +++ b/spectral_signature/signature_importer.py @@ -0,0 +1,311 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +import shutil +import zipfile + +from PyQt5.QtCore import QFileInfo +from qgis.core import QgsApplication + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +class USGSSpectralLib: + + def __init__(self): + self.library = None + self.usgs_lib_name = [] + self.usgs_lib = [] + self.usgs_c1 = cfg.translate('Chapter 1: Minerals') + self.usgs_c2 = cfg.translate('Chapter 2: Soils and Mixtures') + self.usgs_c3 = cfg.translate('Chapter 3: Coatings') + self.usgs_c4 = cfg.translate('Chapter 4: Liquids') + self.usgs_c5 = cfg.translate('Chapter 5: Organics') + self.usgs_c6 = cfg.translate('Chapter 6: Artificial') + self.usgs_c7 = cfg.translate('Chapter 7: Vegetation and Mixtures') + self.usgs_lib_list = [ + '', self.usgs_c1, self.usgs_c2, self.usgs_c3, self.usgs_c4, + self.usgs_c5, self.usgs_c6, self.usgs_c7 + ] + base_dir = ( + QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path() + + '/python/plugins/SemiAutomaticClassificationPlugin/' + 'spectral_signature/usgs_spectral_library/' + ) + self.usgs_c1p = base_dir + 'minerals.csv' + self.usgs_c2p = base_dir + 'soils.csv' + self.usgs_c3p = base_dir + 'coatings.csv' + self.usgs_c4p = base_dir + 'liquids.csv' + self.usgs_c5p = base_dir + 'organics.csv' + self.usgs_c6p = base_dir + 'artificial.csv' + self.usgs_c7p = base_dir + 'vegetation.csv' + + # add library list to combo + def add_libraries_to_combo(self): + cfg.dialog.ui.usgs_library_comboBox.blockSignals(True) + cfg.dialog.ui.usgs_library_comboBox.clear() + cfg.dialog.ui.usgs_library_comboBox.addItem('') + for i in self.usgs_lib_name: + cfg.dialog.ui.usgs_library_comboBox.addItem(i) + cfg.dialog.ui.usgs_library_comboBox.blockSignals(False) + + # selection of chapter + def chapter_changed(self): + self.usgs_lib_name = [] + self.usgs_lib = [] + chapter = cfg.dialog.ui.usgs_chapter_comboBox.currentText() + if chapter == self.usgs_c1: + usgs_list = self.usgs_c1p + elif chapter == self.usgs_c2: + usgs_list = self.usgs_c2p + elif chapter == self.usgs_c3: + usgs_list = self.usgs_c3p + elif chapter == self.usgs_c4: + usgs_list = self.usgs_c4p + elif chapter == self.usgs_c5: + usgs_list = self.usgs_c5p + elif chapter == self.usgs_c6: + usgs_list = self.usgs_c6p + elif chapter == self.usgs_c7: + usgs_list = self.usgs_c7p + else: + cfg.dialog.ui.usgs_library_comboBox.clear() + return 1 + library = open(usgs_list, 'r') + for i in library.readlines(): + row = eval(i) + self.usgs_lib_name.append(row[0]) + self.usgs_lib.append([row[1], row[2]]) + self.add_libraries_to_combo() + cfg.dialog.ui.USGS_library_textBrowser.setHtml('') + + # selection of library + def library_changed(self): + self.library = None + library_name = cfg.dialog.ui.usgs_library_comboBox.currentText() + if len(library_name) > 0: + try: + library_index = self.usgs_lib_name.index(library_name) + link, library = self.usgs_lib[library_index] + temp_path = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.html' + ) + ) + cfg.ui_utils.add_progress_bar() + check, output = cfg.rs.download_tools.download_file( + link, temp_path, timeout=2 + ) + cfg.ui_utils.remove_progress_bar() + if check is True: + description = open(temp_path, 'r', errors='ignore') + description_html = description.read() + cfg.dialog.ui.USGS_library_textBrowser.setHtml( + description_html + ) + self.library = library + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_5() + else: + cfg.dialog.ui.USGS_library_textBrowser.setHtml('') + + # download signature file + @staticmethod + def download_library(link): + temp_path = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.zip' + ) + ) + cfg.ui_utils.add_progress_bar() + try: + check, output = cfg.rs.download_tools.download_file( + link, temp_path, timeout=2 + ) + except Exception as err: + str(err) + check = False + cfg.ui_utils.remove_progress_bar() + if check is False: + cfg.mx.msg_err_5() + return None, None, None + else: + (reflectance, wavelength_list, + standard_deviation_list) = unzip_library(temp_path) + return reflectance, wavelength_list, standard_deviation_list + + # add signature to catalog + def add_signature_to_catalog(self): + library_name = cfg.dialog.ui.usgs_library_comboBox.currentText() + if self.library is not None: + cfg.logger.log.debug('self.library: %s' % self.library) + if len(str(self.library)) > 0: + cfg.ui_utils.add_progress_bar() + reflectance, wavelength, std = self.download_library( + self.library + ) + # add to training + if reflectance is not None: + cfg.scp_training.save_temporary_signature_catalog() + signature_catalog = ( + cfg.scp_training.signature_catalog_copy() + ) + cfg.scp_training.set_signature_catalog( + signature_catalog=signature_catalog + ) + cfg.scp_training.add_spectral_signature_to_catalog( + values=reflectance, wavelengths=wavelength, + standard_deviations=std, class_name=library_name + ) + cfg.dock_class_dlg.ui.undo_save_Button.setEnabled(True) + cfg.dock_class_dlg.ui.redo_save_Button.setEnabled(False) + cfg.ui_utils.remove_progress_bar() + cfg.logger.log.debug( + 'add_signature_to_catalog: %s' % library_name + ) + + # add chapter list to combo + def add_spectral_library_to_combo(self): + for i in self.usgs_lib_list: + cfg.dialog.ui.usgs_chapter_comboBox.addItem(i) + + +def import_usgs_library(file_path): + cfg.logger.log.debug('import_usgs_library: %s' % file_path) + cfg.ui_utils.add_progress_bar() + reflectance, wavelength, std = unzip_library(file_path) + # add to training + if reflectance is not None: + cfg.scp_training.add_spectral_signature_to_catalog( + values=reflectance, wavelengths=wavelength, + standard_deviations=std, class_name='imported' + ) + cfg.ui_utils.remove_progress_bar() + + +def unzip_library(file_path): + reflectance = [] + wavelength_list = [] + standard_deviation_list = [] + zero_standard_deviation = [] + with zipfile.ZipFile(file_path) as open_file: + for file_name in open_file.namelist(): + if file_name.endswith('.txt'): + # noinspection SpellCheckingInspection + if 'REF' in file_name and 'errorbars' not in file_name: + unzip_file = open_file.open(file_name) + temp_text = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.txt' + ) + ) + try: + unzip_temp_text = open(temp_text, 'wb') + with unzip_file, unzip_temp_text: + shutil.copyfileobj( + unzip_file, unzip_temp_text + ) + unzip_temp_text.close() + open_text = open(temp_text) + file = open_text.readlines() + for b in range(1, len(file)): + value = float(file[b]) + if value < 0: + value = 0 + reflectance.append(value) + zero_standard_deviation.append(0) + except Exception as err: + str(err) + elif 'Wavelengths' in file_name: + unzip_file = open_file.open(file_name) + temp_text = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.txt' + ) + ) + try: + unzip_temp_text = open(temp_text, 'wb') + with unzip_file, unzip_temp_text: + shutil.copyfileobj( + unzip_file, unzip_temp_text + ) + unzip_temp_text.close() + open_text = open(temp_text) + file = open_text.readlines() + for b in range(1, len(file)): + wavelength_list.append(float(file[b])) + except Exception as err: + str(err) + elif 'errorbars' in file_name: + unzip_file = open_file.open(file_name) + temp_text = ( + cfg.rs.configurations.temp.temporary_file_path( + name_suffix='.txt' + ) + ) + try: + unzip_temp_text = open(temp_text, 'wb') + with unzip_file, unzip_temp_text: + shutil.copyfileobj( + unzip_file, unzip_temp_text + ) + unzip_temp_text.close() + open_text = open(temp_text) + file = open_text.readlines() + for b in range(1, len(file)): + value = float(file[b]) + standard_deviation_list.append(value) + except Exception as err: + str(err) + if len(standard_deviation_list) == 0: + standard_deviation_list = zero_standard_deviation + return reflectance, wavelength_list, standard_deviation_list + + +# import ASTER spectral library (http://speclib.jpl.nasa.gov/search-1) +def aster_library(file_path): + if cfg.utils.check_file(file_path): + cfg.logger.log.debug('aster_library: %s' % file_path) + library = open(file_path) + lines = library.readlines() + if 'Name' in lines[0]: + wavelength = [] + reflectance = [] + standard_deviation = [] + for line in range(26, len(lines)): + value = lines[line].split() + wavelength.append(float(value[0])) + reflectance.append(float(value[1]) / 100) + standard_deviation.append(float(0)) + # add to training + if len(reflectance) > 0: + cfg.scp_training.add_spectral_signature_to_catalog( + values=reflectance, wavelengths=wavelength, + standard_deviations=standard_deviation, + class_name='imported' + ) + cfg.logger.log.debug('values: %s' % len(reflectance)) + else: + # try to open as csv + cfg.scp_training.import_csv_file(file_path) diff --git a/spectral_signature/spectral_signature_plot.py b/spectral_signature/spectral_signature_plot.py new file mode 100755 index 0000000..1270d8d --- /dev/null +++ b/spectral_signature/spectral_signature_plot.py @@ -0,0 +1,725 @@ +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from itertools import combinations as iter_combinations + +from PyQt5.QtGui import QColor +from PyQt5.QtWidgets import QApplication +from matplotlib.ticker import MaxNLocator + +cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) + + +class SpectralSignaturePlot: + + def __init__(self): + try: + canvas = cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas + self.mouseScroll = canvas.mpl_connect( + 'scroll_event', + self.scroll_event + ) + self.mousePress = canvas.mpl_connect( + 'button_press_event', + self.press_event + ) + self.mouseRelease = canvas.mpl_connect( + 'button_release_event', + self.release_event + ) + self.mouseMove = canvas.mpl_connect( + 'motion_notify_event', + self.motion_event + ) + self.check_limits = False + self.press = None + self.release = None + self.first_plot = True + self.select_all = False + self.sigma_check = True + self.legend_max_chars = 15 + self.order_column = 1 + self.filled_plots = [] + self.y_minimum_value = 10000000000 + self.y_maximum_value = -10000000000 + self.x_minimum_value = 10000000000 + self.x_maximum_value = -10000000000 + self.plot_catalog = cfg.rs.spectral_signatures_plot_catalog() + self.ax = cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.ax + self.ax.grid(True) + except Exception as err: + str(err) + + def press_event(self, event): + if event.inaxes is None: + self.press = None + return 0 + self.press = [event.xdata, event.ydata] + + def release_event(self, event): + if event.inaxes is None: + self.release = None + return 0 + self.release = [event.xdata, event.ydata] + if event.button == 3: + self.resize() + else: + self.move() + + @staticmethod + def motion_event(event): + if event.inaxes is not None: + cfg.spectral_plot_dlg.ui.value_label.setText( + 'x=%s y=%s' % (str(event.xdata)[:8].ljust(8), + str(event.ydata)[:8].ljust(8)) + ) + + # scroll + def scroll_event(self, event): + x_min, x_max = (self.ax.get_xlim()) + y_min, y_max = (self.ax.get_ylim()) + zoom_x = (x_max - x_min) * 0.2 + zoom_y = (y_max - y_min) * 0.2 + if event.button == 'down': + x_lim_min = x_min - zoom_x + x_lim_max = x_max + zoom_x + y_lim_min = y_min - zoom_y + y_lim_max = y_max + zoom_y + else: + x_lim_min = x_min + zoom_x + x_lim_max = x_max - zoom_x + y_lim_min = y_min + zoom_y + y_lim_max = y_max - zoom_y + self.ax.set_xlim(x_lim_min, x_lim_max) + self.ax.set_ylim(y_lim_min, y_lim_max) + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + + # resize plot + def resize(self): + try: + x_lim_min = min([float(self.press[0]), float(self.release[0])]) + x_lim_max = max([float(self.press[0]), float(self.release[0])]) + y_lim_min = min([float(self.press[1]), float(self.release[1])]) + y_lim_max = max([float(self.press[1]), float(self.release[1])]) + if ((x_lim_max - x_lim_min) * (x_lim_max - x_lim_min) < 0.0001 + or (y_lim_max - y_lim_min) + * (y_lim_max - y_lim_min) < 0.0001): + return + self.ax.set_xlim(x_lim_min, x_lim_max) + self.ax.set_ylim(y_lim_min, y_lim_max) + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + except Exception as err: + str(err) + + # move plot + def move(self): + try: + delta_x = (float(self.press[0]) - float(self.release[0])) + delta_y = (float(self.press[1]) - float(self.release[1])) + x_min, x_max = self.ax.get_xlim() + y_min, y_max = self.ax.get_ylim() + self.ax.set_xlim(x_min + delta_x, x_max + delta_x) + self.ax.set_ylim(y_min + delta_y, y_max + delta_y) + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + except Exception as err: + str(err) + + # save plot to file + @staticmethod + def save_plot(): + # noinspection PyTypeChecker + image_output = cfg.util_qt.get_save_file_name( + None, QApplication.translate( + 'semiautomaticclassificationplugin', 'Save plot to file' + ), '', 'JPG file (*.jpg);;PNG file (*.png);;PDF file (*.pdf)', + None + ) + if len(image_output) > 0: + if str(image_output).endswith('.png'): + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.figure.savefig( + image_output, format='png', dpi=300 + ) + elif str(image_output).endswith('.pdf'): + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.figure.savefig( + image_output, format='pdf', dpi=300 + ) + else: + image_output = image_output + '.jpg' + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.figure.savefig( + image_output, format='jpg', dpi=300, quality=90 + ) + + # fit plot to axes + def fit_plot_to_axes(self): + self.ax.relim() + self.ax.autoscale(True) + self.ax.autoscale_view(True) + try: + self.ax.set_xlim(self.x_minimum_value, self.x_maximum_value) + self.ax.set_ylim(self.y_minimum_value, self.y_maximum_value) + except Exception as err: + str(err) + # Draw the plot + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + + # Add to signature list + def add_to_signature_list(self): + # noinspection PyTypeChecker + answer = cfg.util_qt.question_box( + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Add to Signature list' + ), + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Are you sure you want to add highlighted signatures ' + 'to the list?' + ) + ) + if answer is True: + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected_rows = list(set(selected)) + if len(selected_rows) == 0: + count = table.rowCount() + selected_rows = list(range(0, count)) + for x in selected_rows: + signature_id = table.item(x, 6).text() + values = self.plot_catalog.catalog[signature_id].value + wavelengths = self.plot_catalog.catalog[ + signature_id].wavelength + standard_deviations = self.plot_catalog.catalog[ + signature_id].standard_deviation + macroclass_id = self.plot_catalog.catalog[ + signature_id].macroclass_id + macroclass_name = self.plot_catalog.catalog[ + signature_id].macroclass_name + class_name = self.plot_catalog.catalog[signature_id].class_name + class_id = self.plot_catalog.catalog[signature_id].class_id + color_string = self.plot_catalog.catalog[signature_id].color + cfg.scp_training.signature_catalog.add_spectral_signature( + value_list=values, + wavelength_list=wavelengths, + standard_deviation_list=standard_deviations, + macroclass_id=macroclass_id, class_id=class_id, + macroclass_name=macroclass_name, class_name=class_name, + geometry=0, signature=1, color_string=color_string + ) + cfg.scp_training.roi_signature_table_tree() + + # Create signature list for plot + def signature_list_plot_table(self, skip_plot=False): + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + table.setSortingEnabled(False) + table.blockSignals(True) + cfg.util_qt.clear_table(table) + # add signature items + x = 0 + for signature in self.plot_catalog.catalog: + selected = self.plot_catalog.catalog[signature].selected + if selected == 1: + checkbox_state = 2 + else: + checkbox_state = 0 + color = self.plot_catalog.catalog[signature].color + cfg.util_qt.insert_table_row(table, x, 20) + cfg.util_qt.add_table_item( + table, '', x, 0, True, None, checkbox_state + ) + cfg.util_qt.add_table_item( + table, + int(self.plot_catalog.catalog[signature].macroclass_id), x, 1 + ) + cfg.util_qt.add_table_item( + table, + str(self.plot_catalog.catalog[signature].macroclass_name), x, 2 + ) + cfg.util_qt.add_table_item( + table, int(self.plot_catalog.catalog[signature].class_id), x, 3 + ) + cfg.util_qt.add_table_item( + table, str(self.plot_catalog.catalog[signature].class_name), + x, 4 + ) + cfg.util_qt.add_table_item(table, '', x, 5, True, QColor(color)) + cfg.util_qt.add_table_item(table, str(signature), x, 6, False) + x += 1 + table.show() + cfg.util_qt.sort_table_column( + table, self.order_column, + table.horizontalHeader().sortIndicatorOrder() + ) + table.setSortingEnabled(True) + table.blockSignals(False) + # Create plot + if skip_plot is False: + self.signature_plot() + self.check_limits = True + + # Create signature plot + # noinspection PyTypeChecker + def signature_plot(self): + self.y_minimum_value = 10000000000 + self.y_maximum_value = -10000000000 + self.x_minimum_value = 10000000000 + self.x_maximum_value = -10000000000 + if self.first_plot is False: + x_min, x_max = self.ax.get_xlim() + y_min, y_max = self.ax.get_ylim() + else: + x_min = x_max = y_min = y_max = None + try: + for i in self.filled_plots: + i.remove() + self.filled_plots = [] + except Exception as err: + str(err) + try: + lines = len(self.ax.lines) + except Exception as err: + str(err) + return None + if lines > 0: + for i in reversed(list(range(0, lines))): + self.ax.lines.pop(i) + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + # Set labels + self.ax.set_xlabel( + QApplication.translate( + 'semiautomaticclassificationplugin', 'Wavelength' + ) + ) + self.ax.set_ylabel( + QApplication.translate( + 'semiautomaticclassificationplugin', 'Values' + ) + ) + # Add plots and legend + plot_legend = [] + plot_legend_name = [] + wavelengths_list = [] + # clear signature values + cfg.spectral_plot_dlg.ui.value_textBrowser.clear() + for signature_id in self.plot_catalog.catalog: + signature = self.plot_catalog.get_signature( + signature_id=signature_id + ) + if signature.selected == 1: + name = '%s#%s; %s#%s' % ( + signature.macroclass_id, signature.macroclass_name, + signature.class_id, signature.class_name + ) + values = signature.value + standard_deviations = signature.standard_deviation + wavelengths = signature.wavelength + wavelengths_list.extend(wavelengths) + color = signature.color + pixel_count = signature.pixel_count + try: + values = eval(str(values).replace('nan', '0')) + except Exception as err: + str(err) + try: + standard_deviations = eval( + str(standard_deviations).replace('nan', '0') + ) + except Exception as err: + str(err) + if sum(standard_deviations) != 0: + mean_plus = [ + v + s for v, s in zip(values, standard_deviations) + ] + mean_minus = [ + v - s for v, s in zip(values, standard_deviations) + ] + minimum_value = min(mean_minus) + maximum_value = max(mean_plus) + sigma_check = True + else: + minimum_value = min(values) + maximum_value = max(values) + mean_minus = mean_plus = None + sigma_check = False + if minimum_value < self.y_minimum_value: + self.y_minimum_value = minimum_value + if maximum_value > self.y_maximum_value: + self.y_maximum_value = maximum_value + # plot + plot, = self.ax.plot(wavelengths, values, color) + if self.sigma_check is True and sigma_check is True: + # fill plot + self.filled_plots.append( + self.ax.fill_between( + wavelengths, mean_minus, mean_plus, color=color, + alpha=0.2 + ) + ) + # add plot to legend + plot_legend.append(plot) + plot_legend_name.append(name[:self.legend_max_chars]) + # signature values + self.signature_details( + name, values, standard_deviations, wavelengths, color, + pixel_count + ) + wavelengths_list = set(wavelengths_list) + if len(wavelengths_list) > 0: + x_minimum_value = min(wavelengths_list) + x_maximum_value = max(wavelengths_list) + else: + x_minimum_value = self.x_minimum_value + x_maximum_value = self.x_maximum_value + if x_minimum_value < self.x_minimum_value: + self.x_minimum_value = x_minimum_value + if x_maximum_value > self.x_maximum_value: + self.x_maximum_value = x_maximum_value + if cfg.spectral_plot_dlg.ui.band_lines_checkBox.isChecked(): + for wave in wavelengths_list: + self.ax.axvline(wave, color='black', linestyle='dashed') + # place legend + # matplotlib API Changes for 3.1.1 + try: + self.ax.legend( + plot_legend, plot_legend_name, + bbox_to_anchor=(0.1, 0.0, 1.1, 1.0), loc=1, borderaxespad=0. + ).set_draggable(True) + except Exception as err: + str(err) + self.ax.legend( + plot_legend, plot_legend_name, + bbox_to_anchor=(0.1, 0.0, 1.1, 1.0), loc=1, borderaxespad=0. + ).draggable() + self.ax.set_xticks(wavelengths_list) + self.ax.xaxis.set_major_locator(MaxNLocator(7)) + self.ax.yaxis.set_major_locator(MaxNLocator(5)) + try: + if self.first_plot is True: + self.first_plot = False + self.ax.set_xlim(self.x_minimum_value, self.x_maximum_value) + self.ax.set_ylim(self.y_minimum_value, self.y_maximum_value) + else: + self.ax.set_xlim(x_min, x_max) + self.ax.set_ylim(y_min, y_max) + except Exception as err: + str(err) + # Draw the plot + cfg.spectral_plot_dlg.ui.Sig_Widget.sigCanvas.draw() + if self.check_limits is False: + self.fit_plot_to_axes() + + # remove signature from table + # noinspection PyTypeChecker + def remove_signature(self): + answer = cfg.util_qt.question_box( + QApplication.translate( + 'semiautomaticclassificationplugin', 'Delete signatures' + ), + QApplication.translate( + 'semiautomaticclassificationplugin', + 'Are you sure you want to delete highlighted signatures?' + ) + ) + if answer is True: + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected = list(set(selected)) + for x in selected: + try: + signature_id = table.item(x, 6).text() + except Exception as err: + str(err) + return False + del self.plot_catalog.catalog[signature_id] + self.signature_list_plot_table() + + # signature details + # noinspection PyTypeChecker + @staticmethod + def signature_details( + name, values, standard_deviations, wavelengths, color, + pixel_count + ): + text = ( + ''.format(color) + ) + text += ( + '' + ''.format( + len(values), name, QApplication.translate( + 'semiautomaticclassificationplugin', 'Pixel count' + ), pixel_count, QApplication.translate( + 'semiautomaticclassificationplugin', 'Wavelength' + ) + ) + ) + for w in wavelengths: + text += ''.format( + int(100 / len(wavelengths)), str(w) + ) + text += '' % QApplication.translate( + 'semiautomaticclassificationplugin', 'Values' + ) + for v in values: + text += ''.format( + int(100 / len(wavelengths)), str(round(v, 5)) + ) + text += '' % QApplication.translate( + 'semiautomaticclassificationplugin', 'Standard deviation' + ) + for s in standard_deviations: + text += ''.format( + int(100 / len(wavelengths)), str(round(s, 5)) + ) + text += '
' + '{}; {}={}
{}{}
%s{}
%s{}

' + cfg.spectral_plot_dlg.ui.value_textBrowser.append(text) + + # calculate spectral distances + def calculate_spectral_distances(self): + cfg.logger.log.debug('calculate_spectral_distances') + try: + # clear distance values + cfg.spectral_plot_dlg.ui.distance_textBrowser.clear() + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected = list(set(selected)) + if len(selected) == 0: + count = table.rowCount() + selected = list(range(0, count)) + signature_id_list = [] + for row in selected: + signature_id = table.item(row, 6).text() + signature = self.plot_catalog.get_signature( + signature_id=signature_id + ) + if signature.selected == 1: + signature_id_list.append(signature_id) + # calculate distances + combinations = list(iter_combinations(signature_id_list, 2)) + for combination in combinations: + signature_x = self.plot_catalog.get_signature( + signature_id=combination[0] + ) + signature_y = self.plot_catalog.get_signature( + signature_id=combination[1] + ) + values_x = signature_x.value + values_y = signature_y.value + spectral_angle = cfg.rs.shared_tools.calculate_spectral_angle( + values_x=values_x, values_y=values_y + ) + euclidean = cfg.rs.shared_tools.calculate_euclidean_distance( + values_x=values_x, values_y=values_y + ) + ( + bray_curtis + ) = cfg.rs.shared_tools.calculate_bray_curtis_similarity( + values_x=values_x, values_y=values_y + ) + self.output_signature_distances( + signature_x.macroclass_id, signature_x.macroclass_name, + signature_x.class_id, signature_x.class_name, + signature_x.color, signature_y.macroclass_id, + signature_y.macroclass_name, signature_y.class_id, + signature_y.class_name, signature_y.color, spectral_angle, + euclidean, bray_curtis + ) + cfg.input_interface.select_spectral_plot_settings_tab(2) + except Exception as err: + cfg.logger.log.error(str(err)) + cfg.mx.msg_err_6() + + # output signature distances + # noinspection PyTypeChecker + @staticmethod + def output_signature_distances( + macroclass_x, macroclass_name_x, class_x, class_name_x, color_x, + macroclass_y, macroclass_name_y, class_y, class_name_y, color_y, + spectral_angle, euclidean_distance, bray_curtis_similarity + ): + # distance names + euclidean_distance_name = QApplication.translate( + 'semiautomaticclassificationplugin', 'Euclidean distance' + ) + bray_curtis_similarity_name = QApplication.translate( + 'semiautomaticclassificationplugin', 'Bray-Curtis similarity [%]' + ) + spectral_angle_name = QApplication.translate( + 'semiautomaticclassificationplugin', 'Spectral angle' + ) + highlight_color = 'red' + default_color = 'black' + if float(spectral_angle) < 10: + spectra_angle_color = highlight_color + else: + spectra_angle_color = default_color + if float(bray_curtis_similarity) > 90: + bray_curtis_color = highlight_color + else: + bray_curtis_color = default_color + if float(euclidean_distance) < 0.1: + euclidean_distance_color = highlight_color + else: + euclidean_distance_color = default_color + tbl = ( + ''.format( + color_x, macroclass_x, macroclass_name_x, class_x, class_name_x + ) + ) + tbl += ( + '' + ''.format( + color_y, macroclass_y, macroclass_name_y, class_y, class_name_y + ) + ) + tbl += ( + '' + ''.format( + spectral_angle_name, spectra_angle_color, spectral_angle + ) + ) + tbl += ( + '' + ''.format( + euclidean_distance_name, euclidean_distance_color, + euclidean_distance + ) + ) + tbl += ( + '' + ''.format( + bray_curtis_similarity_name, bray_curtis_color, + bray_curtis_similarity + ) + ) + tbl += '
' + '{}#{}; {}#{}
{}#{}; {}#{}
{}{}
{}{}
{}{}

' + cfg.spectral_plot_dlg.ui.distance_textBrowser.append(tbl) + + # signature list double click + def signature_list_double_click(self, index): + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + if index.column() == 5: + color = cfg.util_qt.select_color() + if color is not None: + selected = [] + for i in table.selectedIndexes(): + selected.append(i.row()) + selected = list(set(selected)) + for row in selected: + signature_id = table.item(row, 6).text() + self.plot_catalog.catalog[signature_id].color = ( + color.toRgb().name() + ) + table.item(row, 5).setBackground(color) + elif index.column() == 0: + self.select_all_signatures() + self.signature_plot() + + # edited cell + def edited_cell(self, row, column): + table = cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget + signature_id = table.item(row, 6).text() + if column == 0: + if table.item(row, column).checkState() == 2: + self.plot_catalog.catalog[signature_id].selected = 1 + else: + self.plot_catalog.catalog[signature_id].selected = 0 + elif column == 1: + self.plot_catalog.catalog[signature_id].macroclass_id = int( + table.item(row, column).text() + ) + elif column == 2: + self.plot_catalog.catalog[signature_id].macroclass_name = str( + table.item(row, column).text() + ) + elif column == 3: + self.plot_catalog.catalog[signature_id].class_id = int( + table.item(row, column).text() + ) + elif column == 4: + self.plot_catalog.catalog[signature_id].class_name = str( + table.item(row, column).text() + ) + self.signature_plot() + + # select all signatures + def select_all_signatures(self): + # select all + if self.select_all is True: + cfg.util_qt.all_items_set_state( + cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget, 2 + ) + for signature in self.plot_catalog.catalog: + self.plot_catalog.catalog[signature].selected = 1 + # set check all plot + self.select_all = False + # unselect all if previously selected all + else: + cfg.util_qt.all_items_set_state( + cfg.spectral_plot_dlg.ui.signature_list_plot_tableWidget, 0 + ) + # set check all plot + self.select_all = True + for signature in self.plot_catalog.catalog: + self.plot_catalog.catalog[signature].selected = 0 + + # show signature plot + def show_signature_plot_t(self): + self.signature_list_plot_table() + cfg.spectral_plot_dlg.close() + cfg.spectral_plot_dlg.show() + + # set plot legend max length + def set_plot_legend_length(self): + self.legend_max_chars = ( + cfg.spectral_plot_dlg.ui.plot_text_spinBox.value() + ) + + # sigma checkbox + def sigma_checkbox(self): + if cfg.spectral_plot_dlg.ui.sigma_checkBox.isChecked(): + self.sigma_check = True + else: + self.sigma_check = False + # Create plot + self.signature_plot() + + # grid checkbox + def grid_checkbox(self): + if cfg.spectral_plot_dlg.ui.grid_checkBox.isChecked(): + self.ax.grid(True) + else: + self.ax.grid(False) + # Create plot + self.signature_plot() + + # refresh plot + def refresh_plot(self): + self.signature_plot() diff --git a/spectralsignature/__init__.py b/spectral_signature/usgs_spectral_library/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/__init__.py rename to spectral_signature/usgs_spectral_library/__init__.py diff --git a/spectralsignature/usgs_spectral_library/artificial.csv b/spectral_signature/usgs_spectral_library/artificial.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/artificial.csv rename to spectral_signature/usgs_spectral_library/artificial.csv diff --git a/spectralsignature/usgs_spectral_library/coatings.csv b/spectral_signature/usgs_spectral_library/coatings.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/coatings.csv rename to spectral_signature/usgs_spectral_library/coatings.csv diff --git a/spectralsignature/usgs_spectral_library/liquids.csv b/spectral_signature/usgs_spectral_library/liquids.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/liquids.csv rename to spectral_signature/usgs_spectral_library/liquids.csv diff --git a/spectralsignature/usgs_spectral_library/minerals.csv b/spectral_signature/usgs_spectral_library/minerals.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/minerals.csv rename to spectral_signature/usgs_spectral_library/minerals.csv diff --git a/spectralsignature/usgs_spectral_library/organics.csv b/spectral_signature/usgs_spectral_library/organics.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/organics.csv rename to spectral_signature/usgs_spectral_library/organics.csv diff --git a/spectralsignature/usgs_spectral_library/soils.csv b/spectral_signature/usgs_spectral_library/soils.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/soils.csv rename to spectral_signature/usgs_spectral_library/soils.csv diff --git a/spectralsignature/usgs_spectral_library/vegetation.csv b/spectral_signature/usgs_spectral_library/vegetation.csv old mode 100644 new mode 100755 similarity index 100% rename from spectralsignature/usgs_spectral_library/vegetation.csv rename to spectral_signature/usgs_spectral_library/vegetation.csv diff --git a/spectralsignature/scatter_plot.py b/spectralsignature/scatter_plot.py deleted file mode 100644 index 045efe8..0000000 --- a/spectralsignature/scatter_plot.py +++ /dev/null @@ -1,996 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Scatter_Plot: - - def __init__(self): - try: - self.mouseScroll = cfg.uiscp.Scatter_Widget_2.sigCanvas.mpl_connect('scroll_event', self.scroll_event) - self.mousePress = cfg.uiscp.Scatter_Widget_2.sigCanvas.mpl_connect('button_press_event', self.press_event) - self.mouseRelease = cfg.uiscp.Scatter_Widget_2.sigCanvas.mpl_connect('button_release_event', self.release_event) - self.mouseLeaveFigure = cfg.uiscp.Scatter_Widget_2.sigCanvas.mpl_connect('figure_leave_event', self.leave_event) - self.mouseMove = cfg.uiscp.Scatter_Widget_2.sigCanvas.mpl_connect('motion_notify_event', self.motion_event) - except: - return None - self.editing = 0 - self.xMin = None - self.xMax = None - self.yMin = None - self.yMax = None - self.lastxMin = None - self.lastxMax = None - self.lastyMin = None - self.lastyMax = None - self.polX = [] - self.polY = [] - self.polygon = [] - self.polygons = [] - self.polP = [] - self.patches = [] - self.color = "#FFAA00" - - # add colormap list to combo - def addColormapToCombo(self, list): - for i in list: - cfg.uiscp.colormap_comboBox.addItem(i) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list added") - - def motion_event(self, event): - if event.inaxes is not None: - cfg.uiscp.value_label_2.setText("x=" + str(event.xdata)[:8].ljust(8) + " y=" + str(event.ydata)[:8].ljust(8) ) - - def press_event(self, event): - if event.inaxes is None: - self.press = None - return 0 - self.press = [event.xdata, event.ydata] - - def selectRange(self): - self.editing = 1 - - def release_event(self, event): - if event.inaxes is None: - self.release = None - return 0 - self.release = [event.xdata, event.ydata] - if self.editing == 1: - if event.button == 3: - self.drawPolygon(self.color, float(cfg.ROITrnspVal)/100) - self.polygons.append([self.polygon, self.color]) - self.polygon = [] - self.polX = [] - self.polY = [] - else: - self.drawLine(self.color) - else: - if event.button == 3: - self.resize() - else: - self.move() - - def leave_event(self, event): - self.stop_edit() - - def stop_edit(self): - self.editing = 0 - self.skipQuestion = 0 - - def scroll_event(self, event): - xMin, xMax = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.get_xlim() - yMin, yMax = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.get_ylim() - zoomX = (xMax - xMin) * 0.2 - zoomY = (yMax - yMin) * 0.2 - if event.button == 'down': - xLimMin = xMin - zoomX - xLimMax = xMax + zoomX - yLimMin = yMin - zoomY - yLimMax = yMax + zoomY - else: - xLimMin = xMin + zoomX - xLimMax = xMax - zoomX - yLimMin = yMin + zoomY - yLimMax = yMax - zoomY - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_xlim(xLimMin, xLimMax) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_ylim(yLimMin, yLimMax) - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - self.lastxMin = xLimMin - self.lastxMax = xLimMax - self.lastyMin = yLimMin - self.lastyMax = yLimMax - - # edited cell - def editedCell(self, row, column): - if cfg.ScatterTabEdited == 'Yes': - tW = cfg.uiscp.scatter_list_plot_tableWidget - id = tW.item(row, 6).text() - if column == 0: - cfg.scatterPlotList["CHECKBOX_" + str(id)] = tW.item(row, 0).checkState() - cfg.scaPlT.scatterPlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "edited cell" + str(row) + ";" + str(column)) - - def scatterPlotDoubleClick(self, index): - if index.column() == 5: - c = cfg.utls.selectColor() - if c is not None: - tW = cfg.uiscp.scatter_list_plot_tableWidget - r = [] - for i in tW.selectedIndexes(): - r.append(i.row()) - v = list(set(r)) - for x in v: - i = tW.item(x, 6).text() - tW.item(x, 5).setBackground(c) - # color - c = str(tW.item(x, 5).background().color().toRgb().name()) - hue = tW.item(x, 5).background().color().hue() - saturation = tW.item(x, 5).background().color().saturation() - value = tW.item(x, 5).background().color().value() - # lighter color - cL = cfg.QtGuiSCP.QColor() - newVal = value + 60 - if newVal > 255: - newVal = 255 - cL.setHsv(hue, saturation, newVal) - # darker color - cD = cfg.QtGuiSCP.QColor() - newVal = value - 60 - if newVal < 0: - newVal = 0 - cD.setHsv(hue, saturation, newVal) - pal = cfg.mplcolorsSCP.LinearSegmentedColormap.from_list('color',[cD.toRgb().name(), c, cL.toRgb().name()]) - pal.set_under('w', 0.0) - cfg.scatterPlotList["COLORMAP_" + str(i)] = pal - cfg.scaPlT.scatterPlot() - elif index.column() == 0: - self.selectAllROIs() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " signatures index: " + str(index)) - - # select all signatures - def selectAllROIs(self): - try: - cfg.uiUtls.addProgressBar() - # select all - if cfg.allSignCheck3 == 'Yes': - cfg.utls.allItemsSetState(cfg.uiscp.scatter_list_plot_tableWidget, 2) - # set check all plot - cfg.allSignCheck3 = 'No' - # unselect all if previously selected all - elif cfg.allSignCheck3 == 'No': - cfg.utls.allItemsSetState(cfg.uiscp.scatter_list_plot_tableWidget, 0) - # set check all plot - cfg.allSignCheck3 = 'Yes' - tW = cfg.uiscp.scatter_list_plot_tableWidget - r = tW.rowCount() - for b in range(0, r): - id = tW.item(b, 6).text() - cfg.scatterPlotList["CHECKBOX_" + str(id)] = tW.item(b, 0).checkState() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " all signatures") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.uiUtls.removeProgressBar() - - # signature list to plot list - def sigListToScatterPlot(self, id, histogram, bandList): - cfg.scatterPlotIDs["ID_" + str(id)] = id - cfg.scatterPlotList["HISTOGRAM_" + str(id) + "_" + str(bandList)] = histogram - cfg.scatterPlotList["MACROCLASSID_" + str(id)] = cfg.signList["MACROCLASSID_" + str(id)] - cfg.scatterPlotList["MACROCLASSINFO_" + str(id)] = cfg.signList["MACROCLASSINFO_" + str(id)] - cfg.scatterPlotList["CLASSID_" + str(id)] = cfg.signList["CLASSID_" + str(id)] - cfg.scatterPlotList["CLASSINFO_" + str(id)] = cfg.signList["CLASSINFO_" + str(id)] - cfg.scatterPlotList["COLOR_" + str(id)] = cfg.signList["COLOR_" + str(id)] - cfg.scatterPlotList["CHECKBOX_" + str(id)] = 2 - try: - a = cfg.scatterPlotList["COLORMAP_" + str(id)] - except: - cfg.scatterPlotList["COLORMAP_" + str(id)] = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # temp ROI to plot list - def tempROIToScatterPlot(self, id, histogram, bandList): - cfg.scatterPlotIDs["ID_" + str(id)] = id - cfg.scatterPlotList["HISTOGRAM_" + str(id) + "_" + str(bandList)] = histogram - cfg.scatterPlotList["MACROCLASSID_" + str(id)] = 0 - cfg.scatterPlotList["MACROCLASSINFO_" + str(id)] = cfg. tempScatterNm - cfg.scatterPlotList["CLASSID_" + str(id)] = 0 - cfg.scatterPlotList["CLASSINFO_" + str(id)] = str(bandList) - cfg.scatterPlotList["COLOR_" + str(id)] = cfg.QtGuiSCP.QColor(cfg.ROIClrVal) - cfg.scatterPlotList["CHECKBOX_" + str(id)] = 2 - try: - a = cfg.scatterPlotList["COLORMAP_" + str(id)] - except: - cfg.scatterPlotList["COLORMAP_" + str(id)] = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # add temp ROI to scatter plot - def addTempROIToScatterPlot(self): - if cfg.lstROI is not None: - cfg.uiUtls.addProgressBar() - bX = cfg.scatterBandX - bY = cfg.scatterBandY - cfg.sctrROIID_h["HISTOGRAM_" + str(cfg.sctrROIID) + "_" + str([bX, bY])] = self.calculateTempROIToScatterPlot() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # add image extent to scatter plot - def addImageToScatterPlot(self): - cfg.uiUtls.addProgressBar() - rectangle = cfg.cnvs.extent() - imageName = cfg.bandSetsList[cfg.bndSetNumber][8] - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[cfg.bndSetNumber][3][0] - tLX, tLY, lRX, lRY, pSX, pSY = cfg.utls.imageInformationSize(imageName) - pol = [] - pol.append(cfg.qgisCoreSCP.QgsPointXY(tLX , tLY)) - pol.append(cfg.qgisCoreSCP.QgsPointXY(lRX , tLY)) - pol.append(cfg.qgisCoreSCP.QgsPointXY(lRX , lRY)) - pol.append(cfg.qgisCoreSCP.QgsPointXY(tLX , lRY)) - self.calculatePolygonScatterPlot(pol) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # add display extent to scatter plot - def addDisplayToScatterPlot(self): - cfg.uiUtls.addProgressBar() - rectangle = cfg.cnvs.extent() - imageName = cfg.bandSetsList[cfg.bndSetNumber][8] - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[cfg.bndSetNumber][3][0] - tLX, tLY, lRX, lRY, pSX, pSY = cfg.utls.imageInformationSize(imageName) - pol = [] - pol.append(cfg.qgisCoreSCP.QgsPointXY(min([rectangle.xMaximum(), tLX]) , min([rectangle.yMaximum(), tLY]))) - pol.append(cfg.qgisCoreSCP.QgsPointXY(max([rectangle.xMinimum(), lRX]) , min([rectangle.yMaximum(), tLY]))) - pol.append(cfg.qgisCoreSCP.QgsPointXY(max([rectangle.xMinimum(), lRX]) , max([rectangle.yMinimum(), lRY]))) - pol.append(cfg.qgisCoreSCP.QgsPointXY(min([rectangle.xMaximum(), tLX]) , max([rectangle.yMinimum(), lRY]))) - self.calculatePolygonScatterPlot(pol) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # calculate polygon scatter plot - def calculatePolygonScatterPlot(self, polygon): - bX = cfg.scatterBandX - bY = cfg.scatterBandY - imageName = cfg.bandSetsList[cfg.bndSetNumber][8] - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[cfg.bndSetNumber][3][0] - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - pCrs = cfg.utls.getCrs(bN0) - else: - # image CRS - bN0 = cfg.utls.selectLayerbyName(imageName, 'Yes') - pCrs = cfg.utls.getCrs(bN0) - if pCrs is None: - pCrs = cfg.utls.getQGISCrs() - # date time for temp name - dT = cfg.utls.getTime() - mL = cfg.qgisCoreSCP.QgsVectorLayer("MultiPolygon?crs=" + str(pCrs.toWkt()), "m"+ str(dT), "memory") - pointF = cfg.QtCoreSCP.QPointF() - polF = cfg.QtGuiSCP.QPolygonF() - for v in polygon: - pointF.setX(v.x()) - pointF.setY(v.y()) - polF.append(pointF) - pointF.setX(polygon[0].x()) - pointF.setY(polygon[0].y()) - polF.append(pointF) - g = cfg.qgisCoreSCP.QgsGeometry().fromQPolygonF(polF) - f = cfg.qgisCoreSCP.QgsFeature() - f.setGeometry(g) - mL.startEditing() - mL.addFeatures([f]) - mL.commitChanges() - mL.dataProvider().createSpatialIndex() - mL.updateExtents() - cfg.sctrROIID_h["HISTOGRAM_" + str(cfg.sctrROIID) + "_" + str([bX, bY])] = self.calculateTempROIToScatterPlot(mL) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # add temp ROI to scatter plot - def calculateTempROIToScatterPlot(self, vector = None): - if vector is None: - vector = cfg.lstROI - cfg.sctrROIID = cfg. tempScatterNm - h = cfg.utls.calculateScatterPlot(vector, "ID", str(cfg.sctrROIID), 'Yes') - # add ROI to scatter plot table - cfg.scaPlT.tempROIToScatterPlot(cfg.sctrROIID, h, [cfg.scatterBandX, cfg.scatterBandY]) - cfg.scaPlT.scatterPlotListTable(cfg.uiscp.scatter_list_plot_tableWidget) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - return h - - # calculate scatter plot - def scatterPlotCalc(self): - cfg.uiUtls.addProgressBar() - tW = cfg.uiscp.scatter_list_plot_tableWidget - bX = cfg.scatterBandX - bY = cfg.scatterBandY - r = tW.rowCount() - for b in range(0, r): - if tW.item(b, 0).checkState() == 2: - i = tW.item(b, 6).text() - if str(i) in list(cfg.ROI_SCP_UID.values()): - h = cfg.utls.calculateScatterPlot(cfg.shpLay, cfg.fldSCP_UID, str(i)) - # add ROI to scatter plot table - cfg.scaPlT.sigListToScatterPlot(i, h, [cfg.scatterBandX, cfg.scatterBandY]) - elif str(i) == cfg.sctrROIID: - cfg.sctrROIID_h["HISTOGRAM_" + str(i) + "_" + str([bX, bY])] = cfg.scaPlT.calculateTempROIToScatterPlot() - cfg.uiUtls.removeProgressBar() - cfg.scaPlT.scatterPlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # plot colormap - def colorPlot(self): - tW = cfg.uiscp.scatter_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - ids = [] - for x in v: - ids.append(tW.item(x, 6).text()) - cfg.scaPlT.scatterPlot(ids) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # Create scatter plot - def scatterPlot(self, colorMap = 'No'): - tW = cfg.uiscp.scatter_list_plot_tableWidget - # Clear plot - try: - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.clear() - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return None - cfg.uiUtls.addProgressBar() - bX = cfg.scatterBandX - bY = cfg.scatterBandY - # Set labels - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_xlabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band' + ' ' + str(bX))) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_ylabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Band' + ' ' + str(bY))) - r = tW.rowCount() - xMins = [] - xMaxs = [] - yMins = [] - yMaxs = [] - for b in range(0, r): - if tW.item(b, 0).checkState() == 2: - i = tW.item(b, 6).text() - if i in colorMap: - pal = cfg.mplpltSCP.get_cmap(cfg.uiscp.colormap_comboBox.currentText()) - pal.set_under('w', 0.0) - cfg.scatterPlotList['COLORMAP_' + str(i)] = pal - else: - if cfg.scatterPlotList['COLORMAP_' + str(i)] is None: - # color - c = str(tW.item(b, 5).background().color().toRgb().name()) - hue = tW.item(b, 5).background().color().hue() - saturation = tW.item(b, 5).background().color().saturation() - value = tW.item(b, 5).background().color().value() - # lighter color - cL = cfg.QtGuiSCP.QColor() - newVal = value + 60 - if newVal > 255: - newVal = 255 - cL.setHsv(hue, saturation, newVal) - # darker color - cD = cfg.QtGuiSCP.QColor() - newVal = value - 60 - if newVal < 0: - newVal = 0 - cD.setHsv(hue, saturation, newVal) - pal = cfg.mplcolorsSCP.LinearSegmentedColormap.from_list('color',[cD.toRgb().name(), c, cL.toRgb().name()]) - pal.set_under('w', 0.0) - cfg.scatterPlotList['COLORMAP_' + str(i)] = pal - else: - pal = cfg.scatterPlotList['COLORMAP_' + str(i)] - try: - h = cfg.scatterPlotList['HISTOGRAM_' + str(i) + '_' + str([bX, bY])] - if h != 'No': - p = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.imshow(h[0].T, origin='lower', interpolation='none', extent=[h[1][0], h[1][-1], h[2][0], h[2][-1]], cmap=pal, vmin = 0.001) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - except: - if str(i) == cfg.sctrROIID: - try: - h = cfg.sctrROIID_h['HISTOGRAM_' + str(i) + '_' + str([bX, bY])] - except: - cfg.uiUtls.removeProgressBar() - return 'No' - if h != 'No': - p = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.imshow(h[0].T, origin='lower', interpolation='none', extent=[h[1][0], h[1][-1], h[2][0], h[2][-1]], cmap=pal, vmin = 0.001) - else: - cfg.uiUtls.removeProgressBar() - return 'No' - else: - cfg.uiUtls.removeProgressBar() - return 'No' - xMins.append(h[1][0]) - xMaxs.append(h[1][-1]) - yMins.append(h[2][0]) - yMaxs.append(h[2][-1]) - # Grid for X and Y axes - try: - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.xaxis.set_major_locator(cfg.MaxNLocatorSCP(5)) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.yaxis.set_major_locator(cfg.MaxNLocatorSCP(5)) - except: - pass - try: - self.xMin = min(xMins) - self.xMax = max(xMaxs) - self.yMin = min(yMins) - self.yMax = max(yMaxs) - if self.lastxMin is None or self.lastxMax is None or self.lastyMin is None or self.lastyMax is None: - self.lastxMin = self.xMin - self.lastxMax = self.xMax - self.lastyMin = self.yMin - self.lastyMax = self.yMax - except: - pass - for pol in self.patches: - self.polP.append(cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.add_patch(pol)) - # Draw the plot - cfg.scaPlT.fitPlotToAxes('Yes') - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' scatter plot created') - cfg.uiUtls.removeProgressBar() - - # remove scatter plot from list - def removeScatter(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Delete scatter plot"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to delete highlighted scatter plots?")) - if a == 'Yes': - tW =cfg.uiscp.scatter_list_plot_tableWidget - r = [] - for i in tW.selectedIndexes(): - r.append(i.row()) - v = list(set(r)) - for x in v: - id = tW.item(x, 6).text() - self.removeScatterByID(id) - cfg.scaPlT.scatterPlotListTable(cfg.uiscp.scatter_list_plot_tableWidget, 'Yes') - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " removed plots: " + str(v)) - - # remove scatter plot by ID - def removeScatterByID(self, id): - cfg.scatterPlotIDs.pop("ID_" + str(id)) - cfg.scatterPlotList.pop("MACROCLASSID_" + str(id)) - cfg.scatterPlotList.pop("MACROCLASSINFO_" + str(id)) - cfg.scatterPlotList.pop("CLASSID_" + str(id)) - cfg.scatterPlotList.pop("CLASSINFO_" + str(id)) - cfg.scatterPlotList.pop("CHECKBOX_" + str(id)) - cfg.scatterPlotList.pop("COLOR_" + str(id)) - cfg.scatterPlotList.pop("COLORMAP_" + str(id)) - cfg.scatterPlotList.pop("ROW_" + str(id)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # Create signature list for plot - def scatterPlotListTable(self, table, skipPlot = 'No'): - # checklist - l = table - cfg.ScatterTabEdited = 'No' - l.setSortingEnabled(False) - l.blockSignals(True) - # column width - try: - wid0 = l.columnWidth(0) - wid1 = l.columnWidth(1) - wid2 = l.columnWidth(2) - wid3 = l.columnWidth(3) - wid4 = l.columnWidth(4) - wid5 = l.columnWidth(5) - except: - wid0 = 40 - wid1 = 40 - wid2 = 70 - wid3 = 40 - wid4 = 70 - wid5 = 70 - cfg.utls.clearTable(l) - l.setColumnCount(0) - cfg.utls.insertTableColumn(l, 0, "S", wid0) - cfg.utls.insertTableColumn(l, 1, cfg.tableMCID, wid1) - cfg.utls.insertTableColumn(l, 2, cfg.tableMCInfo, wid2) - cfg.utls.insertTableColumn(l, 3, cfg.tableCID, wid3) - cfg.utls.insertTableColumn(l, 4, cfg.tableCInfo, wid4) - cfg.utls.insertTableColumn(l, 5, cfg.tableColor2, wid5) - # signature ID column - cfg.utls.insertTableColumn(l, 6, cfg.tableColString, 60, 'Yes') - # add signature items - x = 0 - for k in list(cfg.scatterPlotIDs.values()): - cfg.utls.insertTableRow(l, x, 20) - cfg.utls.addTableItem(l, "checkbox", x, 0, 'Yes', None, cfg.scatterPlotList["CHECKBOX_" + str(k)]) - cfg.utls.addTableItem(l, int(cfg.scatterPlotList["MACROCLASSID_" + str(k)]), x, 1) - cfg.utls.addTableItem(l, str(cfg.scatterPlotList["MACROCLASSINFO_" + str(k)]), x, 2) - cfg.utls.addTableItem(l, int(cfg.scatterPlotList["CLASSID_" + str(k)]), x, 3) - cfg.utls.addTableItem(l, str(cfg.scatterPlotList["CLASSINFO_" + str(k)]), x, 4) - c = cfg.scatterPlotList["COLOR_" + str(k)] - cfg.utls.addTableItem(l, "", x, 5, 'Yes', c) - cfg.utls.addTableItem(l, str(cfg.scatterPlotIDs["ID_" + str(k)]), x, 6, 'No') - x = x + 1 - l.show() - l.setColumnWidth(0, wid0) - try: - vOrd = self.orderColumn - except: - vOrd = 6 - cfg.utls.sortTableColumn(l, vOrd,l.horizontalHeader().sortIndicatorOrder()) - l.setSortingEnabled(True) - l.blockSignals(False) - cfg.ScatterTabEdited = 'Yes' - self.orderedTable(vOrd) - # Create plot - if skipPlot == 'No': - self.scatterPlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list created") - - # ordered table - def orderedTable(self, column): - self.orderColumn = column - tW = cfg.uiscp.scatter_list_plot_tableWidget - count = tW.rowCount() - v = list(range(0, count)) - for x in v: - id = tW.item(x, 6).text() - cfg.scatterPlotList["ROW_" + str(id)] = x - - # set band X - def bandXPlot(self): - self.removePolygons() - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - b = len(cfg.bandSetsList[cfg.bndSetNumber][3]) - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - try: - b = i.bandCount() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - b = 1 - if cfg.uiscp.bandX_spinBox.value() > b: - cfg.uiscp.bandX_spinBox.setValue(b) - cfg.scatterBandX = cfg.uiscp.bandX_spinBox.value() - cfg.scaPlT.scatterPlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "scatter band X: " + str(cfg.scatterBandX)) - - # set band Y - def bandYPlot(self): - self.removePolygons() - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - b = len(cfg.bandSetsList[cfg.bndSetNumber][3]) - else: - i = cfg.utls.selectLayerbyName(cfg.bandSetsList[cfg.bndSetNumber][8], 'Yes') - try: - b = i.bandCount() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - b = 1 - if cfg.uiscp.bandY_spinBox.value() > b: - cfg.uiscp.bandY_spinBox.setValue(b) - cfg.scatterBandY = cfg.uiscp.bandY_spinBox.value() - cfg.scaPlT.scatterPlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "scatter band X: " + str(cfg.scatterBandY)) - - # resize plot - def resize(self): - try: - xLimMin = min([float(self.press[0]), float(self.release[0])]) - xLimMax = max([float(self.press[0]), float(self.release[0])]) - yLimMin = min([float(self.press[1]), float(self.release[1])]) - yLimMax = max([float(self.press[1]), float(self.release[1])]) - if ((xLimMax - xLimMin) * (xLimMax - xLimMin)) < 0.000001 or ((yLimMax - yLimMin) * (yLimMax - yLimMin)) < 0.000001: - return - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_xlim(xLimMin, xLimMax) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_ylim(yLimMin, yLimMax) - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - self.lastxMin = xLimMin - self.lastxMax = xLimMax - self.lastyMin = yLimMin - self.lastyMax = yLimMax - except: - pass - - # move plot - def move(self): - try: - dX = (float(self.press[0]) - float(self.release[0])) - dY = (float(self.press[1]) - float(self.release[1])) - xMin, xMax = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.get_xlim() - yMin, yMax = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.get_ylim() - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_xlim(xMin + dX, xMax + dX) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_ylim(yMin + dY, yMax + dY) - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - self.lastxMin = xMin + dX - self.lastxMax = xMax + dX - self.lastyMin = yMin + dY - self.lastyMax = yMax + dY - except: - pass - - # draw line - def drawLine(self, colorLine): - if self.press is not None: - self.polX.append(float(self.press[0])) - self.polY.append(float(self.press[1])) - try: - self.line.remove() - except: - pass - self.line, = cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.plot(self.polX , self.polY, colorLine) - point = [float(self.press[0]),float(self.press[1])] - self.polygon.append(point) - try: - # Draw the plot - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # draw polygon - def drawPolygon(self, fillColor, transparency, fillOption = True): - if self.press is not None: - try: - self.line.remove() - except: - pass - point = [float(self.press[0]),float(self.press[1])] - self.polygon.append(point) - pol = cfg.mplpltSCP.Polygon(self.polygon, True, facecolor=fillColor, alpha=transparency, fill=fillOption) - self.patches.append(pol) - self.polP.append(cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.add_patch(pol)) - try: - # Draw the plot - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # calculate scatter raster and add to signature list - def addToSignatureList(self): - cfg.uiUtls.addProgressBar() - r = self.calculatePolygonIntersection('Yes') - # temporary layer - tLP = cfg.utls.createTempRasterPath('gpkg') - cfg.utls.multiProcessRasterToVector(rasterPath = r, outputVectorPath = tLP, dissolveOutput = 'Yes') - vl = cfg.utls.addVectorLayer(tLP) - f = cfg.qgisCoreSCP.QgsFeature() - ids = [] - for f in vl.getFeatures(): - id = f.id() - ids.append(id) - if len(ids) > 0: - vl2 = cfg.utls.mergePolygonsToNewLayer(vl, ids, [0]) - roi = cfg.lstROI - cfg.lstROI = vl2 - cfg.SCPD.saveROItoShapefile('No') - cfg.lstROI = roi - vl = None - vl2 = None - cfg.uiUtls.removeProgressBar() - - # show area of scatter polygons - def showScatterPolygonArea(self): - cfg.uiUtls.addProgressBar() - self.calculatePolygonIntersection() - cfg.uiUtls.removeProgressBar() - - # conver polygon to raster - def polygonToRaster(self, polygon, xMin, xMax, yMin, yMax, dX, dY): - # temporary layer - tLP = cfg.utls.createTempRasterPath('shp') - # get layer crs - #crs = cfg.qgisCoreSCP.QgsCoordinateReferenceSystem('EPSG:4326') - srs = cfg.osrSCP.SpatialReference() - srs.ImportFromEPSG(4326) - crs = srs.ExportToWkt() - # create a temp shapefile with a field - cfg.utls.createEmptyShapefile(crs, tLP, format = 'ESRI Shapefile') - tSS = cfg.utls.addVectorLayer(tLP) - pointF = cfg.QtCoreSCP.QPointF() - polF = cfg.QtGuiSCP.QPolygonF() - for v in polygon: - pointF.setX(v[0]) - pointF.setY(v[1]) - polF.append(pointF) - pointF.setX(polygon[0][0]) - pointF.setY(polygon[0][1]) - polF.append(pointF) - g = cfg.qgisCoreSCP.QgsGeometry().fromQPolygonF(polF) - oF = cfg.qgisCoreSCP.QgsFeature() - if g is not None: - oF.setGeometry(g) - tSS.startEditing() - attributeList = [1] - oF.setAttributes(attributeList) - tSS.addFeature(oF) - tSS.commitChanges() - tSS.dataProvider().createSpatialIndex() - tSS.updateExtents() - a = self.rasterizePolygon(tLP, xMin, xMax, yMin, yMax, dX, dY) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '') - return a - - # rasterize polygon - def rasterizePolygon(self, shapefile, xMin, xMax, yMin, yMax, dX, dY): - shp = cfg.ogrSCP.Open(shapefile) - gL = shp.GetLayer() - # temporary layer - tLP = cfg.utls.createTempRasterPath('tif') - rC = abs(int(round((xMax - xMin) / dX))) - rR = abs(int(round((yMax - yMin) / dY))) - tD = cfg.gdalSCP.GetDriverByName('GTiff') - oR = tD.Create(tLP, rC, rR, 1, cfg.gdalSCP.GDT_Int32) - try: - oRB = oR.GetRasterBand(1) - # in case of errors - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - oR.SetGeoTransform( [ xMin , dX, 0 , yMin , 0 , dY ] ) - oRB.SetNoDataValue(cfg.NoDataVal) - m = cfg.np.zeros((rR, rC), dtype='int32') - oRB.WriteArray(m, 0, 0) - oRB.FlushCache() - # convert reference layer to raster - oC = cfg.gdalSCP.RasterizeLayer(oR, [1], gL, options = ['ATTRIBUTE=' + str('DN'), 'ALL_TOUCHED=TRUE']) - try: - o = oRB.GetOffset() - s = oRB.GetScale() - if o is None: - o = 0 - if s is None: - s = 1 - except: - o = 0 - s = 1 - a = oRB.ReadAsArray()*s+o - # close bands - oRB = None - # close rasters - oR = None - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '') - return a - - # create grid - def createGrid(self, h, xMin, xMax, yMin, yMax, dX, dY, polygon): - a = self.polygonToRaster(polygon, xMin, xMax, yMin, yMax, dX, dY) - d = a.T * cfg.np.where(h>0,1,0) - return d.T - - # aggregate grid - def aggregateGrid(self, grid, h, xMin, xMax, yMin, yMax, dX, dY): - # structure - s = cfg.np.array([[0, 0, 0], [1, 1, 1], [0, 0, 0]]) - ranges = [] - l, ft = cfg.labelSCP(grid, structure=s) - for v in range(1, ft + 1): - r = cfg.np.where( l == v ) - rY = r[0][0] - rXmin = r[1][0] - rXmax = r[1][-1] - rangeY = [yMin + rY * dY, yMin + (1 + rY) * dY] - rangeX = [xMin + rXmin * dX, xMin + (1 + rXmax) * dX] - ranges.append([rangeX, rangeY]) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '') - return ranges - - # calculate polygon intersection - def calculatePolygonIntersection(self, saveSignature = None): - if len(self.polygons)>0: - tW = cfg.uiscp.scatter_list_plot_tableWidget - bX = cfg.scatterBandX - bY = cfg.scatterBandY - r = tW.rowCount() - rangeList = [] - # grid polygon - n = 0 - colorList = [] - for p in self.polygons: - n = n + 1 - colorList.append([n, p[1]]) - for b in range(0, r): - if tW.item(b, 0).checkState() == 2: - i = tW.item(b, 6).text() - if str(i) in list(cfg.ROI_SCP_UID.values()): - h = cfg.scatterPlotList['HISTOGRAM_' + str(i) + '_' + str([bX, bY])] - elif str(i) == cfg.sctrROIID: - h = cfg.sctrROIID_h['HISTOGRAM_' + str(i) + '_' + str([bX, bY])] - else: - h = None - if h is not None: - grid = self.createGrid(h[0], h[1][0], h[1][-1], h[2][0], h[2][-1], h[1][1]-h[1][0], h[2][1]-h[2][0], p[0]) - ranges = self.aggregateGrid(grid, h[0], h[1][0], h[1][-1], h[2][0], h[2][-1], h[1][1]-h[1][0], h[2][1]-h[2][0]) - rangeList.append([ranges, n]) - rasterSymbol = cfg.utls.rasterScatterSymbol(colorList) - condition = cfg.utls.createScatterPlotRasterCondition(rangeList, nodataValue = cfg.NoDataVal) - aX = cfg.scatterBandX - 1 - aY = cfg.scatterBandY - 1 - # virtual raster - tPMN = cfg.tmpVrtNm + '.vrt' - # date time for temp name - dT = cfg.utls.getTime() - tPMD = cfg.tmpDir + '/' + dT + tPMN - # calculation extent - if cfg.uiscp.extent_comboBox.currentText() == 'same as display': - rectangle = cfg.cnvs.extent() - else: - imageName = cfg.bandSetsList[cfg.bndSetNumber][8] - # band set - if cfg.bandSetsList[cfg.bndSetNumber][0] == 'Yes': - imageName = cfg.bandSetsList[cfg.bndSetNumber][3][0] - i = cfg.utls.selectLayerbyName(imageName, 'Yes') - rectangle = i.extent() - # output raster - tPMD2 = cfg.utls.createTempRasterPath('tif') - # clip by ROI - bList = cfg.utls.subsetImageByRectangle([rectangle.xMinimum(), rectangle.xMaximum(), rectangle.yMinimum(), rectangle.yMaximum()], cfg.bandSetsList[cfg.bndSetNumber][8], [aX, aY], cfg.bndSetNumber) - bandNumberList = [1, 1] - vrtCheck = cfg.utls.createTempVirtualRaster(bList, bandNumberList, 'Yes', 'Yes', 0, 'No', 'No') - variableList = [['bandX', 'a'], ['bandY', 'b']] - if condition == 0: - conditions = cfg.utls.singleScatterPlotRasterCondition(rangeList, nodataValue = cfg.NoDataVal) - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.scatterRasterMultipleWhere, outputRasterList = [tPMD2], nodataValue = cfg.NoDataVal, functionBandArgument = conditions, functionVariable = variableList, progressMessage = 'Threshold ', compress = cfg.rasterCompression, compressFormat = 'LZW') - else: - o = cfg.utls.multiProcessRaster(rasterPath = vrtCheck, functionBand = 'No', functionRaster = cfg.utls.scatterRasterBandCalculation, outputRasterList = [tPMD2], nodataValue = cfg.NoDataVal, functionBandArgument = condition, functionVariable = variableList, progressMessage = 'Threshold ', compress = cfg.rasterCompression, compressFormat = 'LZW') - if saveSignature is None: - # move previous preview to group - g = cfg.utls.groupIndex(cfg.grpNm) - if g is None: - g = cfg.utls.createGroup(cfg.grpNm) - preP = cfg.utls.selectLayerbyName(cfg.lastScattRaster) - if preP is not None: - cfg.utls.moveLayer(preP, cfg.grpNm) - cfg.lastScattRaster = cfg.osSCP.path.basename(tPMD2) - try: - r = cfg.utls.addRasterLayer(tPMD2) - cfg.utls.setRasterScatterSymbol(r, rasterSymbol) - cfg.utls.moveLayerTop(r) - cfg.utls.setGroupVisible(g, False) - cfg.utls.setGroupExpanded(g, False) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), '') - return tPMD2 - - # remove polygons - def removePolygons(self): - self.patches = [] - self.polygons = [] - try: - for i in self.polP: - i.remove() - self.polP = [] - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - self.line.remove() - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - # Draw the plot - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - - # save plot to file - def savePlot(self): - imgOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Save plot to file'), '', 'JPG file (*.jpg);;PNG file (*.png);;PDF file (*.pdf)', None) - if len(imgOut) > 0: - if str(imgOut).endswith('.png'): - cfg.uiscp.Scatter_Widget_2.sigCanvas.figure.savefig(imgOut, format='png', dpi=300) - elif str(imgOut).endswith('.pdf'): - cfg.uiscp.Scatter_Widget_2.sigCanvas.figure.savefig(imgOut, format='pdf', dpi=300) - elif str(imgOut).endswith('.jpg'): - cfg.uiscp.Scatter_Widget_2.sigCanvas.figure.savefig(imgOut, format='jpg', dpi=300, quality=90) - else: - imgOut = imgOut + '.jpg' - cfg.uiscp.Scatter_Widget_2.sigCanvas.figure.savefig(imgOut, format='jpg', dpi=300, quality=90) - - # fit plot to axes - def fitPlotToAxes(self, preserveLast = 'No'): - if preserveLast == 'Yes': - xMin = self.lastxMin - xMax = self.lastxMax - yMin = self.lastyMin - yMax = self.lastyMax - else: - xMin = self.xMin - xMax = self.xMax - yMin = self.yMin - yMax = self.yMax - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_xlim(xMin, xMax) - cfg.uiscp.Scatter_Widget_2.sigCanvas.ax.set_ylim(yMin, yMax) - self.lastxMin = xMin - self.lastxMax = xMax - self.lastyMin = yMin - self.lastyMax = yMax - try: - # Draw the plot - cfg.uiscp.Scatter_Widget_2.sigCanvas.draw() - except Exception as err: - cfg.mx.msgErr53(None) - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - return 'No' - - # Change ROI color - def changePolygonColor(self): - c = cfg.QtWidgetsSCP.QColorDialog.getColor() - if c.isValid(): - self.color = c.name() - cfg.uiscp.polygon_color_Button.setStyleSheet("background-color :" + self.color) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - \ No newline at end of file diff --git a/spectralsignature/spectralsignatureplot.py b/spectralsignature/spectralsignatureplot.py deleted file mode 100644 index acd321b..0000000 --- a/spectralsignature/spectralsignatureplot.py +++ /dev/null @@ -1,1259 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class SpectralSignaturePlot: - - def __init__(self): - try: - self.mouseScroll = cfg.uisp.Sig_Widget.sigCanvas.mpl_connect('scroll_event', self.scroll_event) - self.mousePress = cfg.uisp.Sig_Widget.sigCanvas.mpl_connect('button_press_event', self.press_event) - self.mouseRelease = cfg.uisp.Sig_Widget.sigCanvas.mpl_connect('button_release_event', self.release_event) - self.mouseLeaveFigure = cfg.uisp.Sig_Widget.sigCanvas.mpl_connect('figure_leave_event', self.leave_event) - self.mouseMove = cfg.uisp.Sig_Widget.sigCanvas.mpl_connect('motion_notify_event', self.motion_event) - except: - return None - self.editing = 0 - self.checkLimits = 'No' - - def editValueRange(self): - self.editing = 1 - - def press_event(self, event): - if event.inaxes is None: - self.press = None - return 0 - self.press = [event.xdata, event.ydata] - - def release_event(self, event): - if event.inaxes is None: - self.release = None - return 0 - self.release = [event.xdata, event.ydata] - if self.editing == 1: - if event.button == 3: - self.resize() - else: - self.move() - try: - dX = (float(self.press[0]) - float(self.release[0])) - dY = (float(self.press[1]) - float(self.release[1])) - except: - return 0 - if dX == 0 and dY == 0: - tW = cfg.uisp.signature_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - # ask for confirm - if len(v) > 1: - if self.skipQuestion == 0: - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Edit value range"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to edit the value range for several signatures?")) - if a == 'Yes': - self.editing = 1 - self.skipQuestion = 1 - self.editLCSThresholds(v) - else: - self.editing = 0 - return 0 - else: - self.editLCSThresholds(v) - else: - self.editLCSThresholds(v) - else: - if event.button == 3: - self.resize() - else: - self.move() - - def motion_event(self, event): - if event.inaxes is not None: - cfg.uisp.value_label.setText("x=" + str(event.xdata)[:8].ljust(8) + " y=" + str(event.ydata)[:8].ljust(8) ) - - def leave_event(self, event): - self.stop_edit() - - def stop_edit(self): - self.editing = 0 - self.skipQuestion = 0 - - # edoted LCS thresholds - def editLCSThresholds(self, rows): - if self.press is None or self.release is None: - return 0 - tW = cfg.uisp.signature_list_plot_tableWidget - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - for row in rows: - wlgPressList = [] - id = tW.item(row, vx).text() - # find wavelength - w = cfg.spectrPlotList['WAVELENGTH_' + str(id)] - wlg = eval(str(w)) - wlgA = cfg.np.array(wlg) - wlgB = wlgA - float(self.press[0]) - wlgIndex = cfg.np.argmin(cfg.np.absolute(wlgB)) - # values - v = cfg.spectrPlotList['VALUES_' + str(id)] - val = eval(str(v).replace('nan', '0')) - if float(self.press[1]) >= val[wlgIndex * 2]: - max = cfg.spectrPlotList['LCS_MAX_' + str(id)] - lcs_max = eval(str(max)) - if float(self.release[1]) < val[wlgIndex * 2]: - lcs_max[wlgIndex] = val[wlgIndex * 2] - else: - lcs_max[wlgIndex] = float(self.release[1]) - cfg.spectrPlotList['LCS_MAX_' + str(id)] = lcs_max - cfg.signList['LCS_MAX_' + str(id)] = lcs_max - else: - min = cfg.spectrPlotList['LCS_MIN_' + str(id)] - lcs_min = eval(str(min)) - if float(self.release[1]) > val[wlgIndex * 2]: - lcs_min[wlgIndex] = val[wlgIndex * 2] - else: - lcs_min[wlgIndex] = float(self.release[1]) - cfg.spectrPlotList['LCS_MIN_' + str(id)] = lcs_min - cfg.signList['LCS_MIN_' + str(id)] = lcs_min - self.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.utls.selectRowsInTable(tW, rows) - - # scroll - def scroll_event(self, event): - xMin, xMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_xlim() - yMin, yMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_ylim() - zoomX = (xMax - xMin) * 0.2 - zoomY = (yMax - yMin) * 0.2 - if event.button == 'down': - xLimMin = xMin - zoomX - xLimMax = xMax + zoomX - yLimMin = yMin - zoomY - yLimMax = yMax + zoomY - else: - xLimMin = xMin + zoomX - xLimMax = xMax - zoomX - yLimMin = yMin + zoomY - yLimMax = yMax - zoomY - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xlim(xLimMin, xLimMax) - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylim(yLimMin, yLimMax) - cfg.uisp.Sig_Widget.sigCanvas.draw() - - # resize plot - def resize(self): - try: - xLimMin = min([float(self.press[0]), float(self.release[0])]) - xLimMax = max([float(self.press[0]), float(self.release[0])]) - yLimMin = min([float(self.press[1]), float(self.release[1])]) - yLimMax = max([float(self.press[1]), float(self.release[1])]) - if ((xLimMax - xLimMin) * (xLimMax - xLimMin)) < 0.0001 or ((yLimMax - yLimMin) * (yLimMax - yLimMin)) < 0.0001: - return - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xlim(xLimMin, xLimMax) - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylim(yLimMin, yLimMax) - cfg.uisp.Sig_Widget.sigCanvas.draw() - except: - pass - - # move plot - def move(self): - try: - dX = (float(self.press[0]) - float(self.release[0])) - dY = (float(self.press[1]) - float(self.release[1])) - xMin, xMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_xlim() - yMin, yMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_ylim() - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xlim(xMin + dX, xMax + dX) - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylim(yMin + dY, yMax + dY) - cfg.uisp.Sig_Widget.sigCanvas.draw() - except: - pass - - # save plot to file - def savePlot(self): - imgOut = cfg.utls.getSaveFileName(None , cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Save plot to file"), "", "JPG file (*.jpg);;PNG file (*.png);;PDF file (*.pdf)", None) - if len(imgOut) > 0: - if str(imgOut).endswith(".png"): - cfg.uisp.Sig_Widget.sigCanvas.figure.savefig(imgOut, format="png", dpi=300) - elif str(imgOut).endswith(".pdf"): - cfg.uisp.Sig_Widget.sigCanvas.figure.savefig(imgOut, format="pdf", dpi=300) - elif str(imgOut).endswith(".jpg"): - cfg.uisp.Sig_Widget.sigCanvas.figure.savefig(imgOut, format="jpg", dpi=300, quality=90) - else: - imgOut = imgOut + ".jpg" - cfg.uisp.Sig_Widget.sigCanvas.figure.savefig(imgOut, format="jpg", dpi=300, quality=90) - - # fit plot to axes - def fitPlotToAxes(self): - cfg.uisp.Sig_Widget.sigCanvas.ax.relim() - cfg.uisp.Sig_Widget.sigCanvas.ax.autoscale(True) - cfg.uisp.Sig_Widget.sigCanvas.ax.autoscale_view(True) - try: - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylim(self.minVal, self.maxVal) - except: - pass - # Draw the plot - cfg.uisp.Sig_Widget.sigCanvas.draw() - - # Add to signature list - def addToSignatureList(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Add to Signature list"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to add highlighted signatures to the list?")) - if a == 'Yes': - tW = cfg.uisp.signature_list_plot_tableWidget - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - for x in v: - id = tW.item(x, vx).text() - cfg.signIDs["ID_" + str(id)] = id - cfg.signList["MACROCLASSID_" + str(id)] = cfg.spectrPlotList["MACROCLASSID_" + str(id)] - cfg.signList["MACROCLASSINFO_" + str(id)] = cfg.spectrPlotList["MACROCLASSINFO_" + str(id)] - cfg.signList["CLASSID_" + str(id)] = cfg.spectrPlotList["CLASSID_" + str(id)] - cfg.signList["CLASSINFO_" + str(id)] = cfg.spectrPlotList["CLASSINFO_" + str(id)] - cfg.signList["VALUES_" + str(id)] = cfg.spectrPlotList["VALUES_" + str(id)] - cfg.signList["LCS_MIN_" + str(id)] = cfg.spectrPlotList["LCS_MIN_" + str(id)] - cfg.signList["LCS_MAX_" + str(id)] = cfg.spectrPlotList["LCS_MAX_" + str(id)] - cfg.signList["MIN_VALUE_" + str(id)] = cfg.spectrPlotList["MIN_VALUE_" + str(id)] - cfg.signList["MAX_VALUE_" + str(id)] = cfg.spectrPlotList["MAX_VALUE_" + str(id)] - cfg.signList["WAVELENGTH_" + str(id)] = cfg.spectrPlotList["WAVELENGTH_" + str(id)] - cfg.signList["MEAN_VALUE_" + str(id)] = cfg.spectrPlotList["MEAN_VALUE_" + str(id)] - cfg.signList["SD_" + str(id)] = cfg.spectrPlotList["SD_" + str(id)] - cfg.signList["COLOR_" + str(id)] = cfg.spectrPlotList["COLOR_" + str(id)] - cfg.signList["CHECKBOX_" + str(id)] = 2 - cfg.signList["UNIT_" + str(id)] = cfg.spectrPlotList["UNIT_" + str(id)] - cfg.signList["COVMATRIX_" + str(id)] = cfg.spectrPlotList["COVMATRIX_" + str(id)] - cfg.signList["ROI_SIZE_" + str(id)] = cfg.spectrPlotList["ROI_SIZE_" + str(id)] - cfg.signList["MD_THRESHOLD_" + str(id)] = cfg.spectrPlotList["MD_THRESHOLD_" + str(id)] - cfg.signList["ML_THRESHOLD_" + str(id)] = cfg.spectrPlotList["ML_THRESHOLD_" + str(id)] - cfg.signList["SAM_THRESHOLD_" + str(id)] = cfg.spectrPlotList["SAM_THRESHOLD_" + str(id)] - cfg.SCPD.ROIListTableTree(cfg.shpLay, cfg.uidc.signature_list_treeWidget) - - # Create signature list for plot - def signatureListPlotTable(self, table, skipPlot = 'No'): - # checklist - l = table - cfg.SigTabEdited = 'No' - l.setSortingEnabled(False) - l.blockSignals(True) - # column width - try: - wid0 = l.columnWidth(0) - wid1 = l.columnWidth(1) - wid2 = l.columnWidth(2) - wid3 = l.columnWidth(3) - wid4 = l.columnWidth(4) - wid5 = l.columnWidth(5) - except: - wid0 = 40 - wid1 = 40 - wid2 = 70 - wid3 = 40 - wid4 = 70 - wid5 = 70 - v = 6 - wid = [] - for i in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - try: - if l.columnWidth(v) == 0: - wid.append(70) - else: - wid.append(l.columnWidth(v)) - except: - wid.append(70) - v = v +1 - try: - if l.columnWidth(v) == 0: - wid.append(70) - else: - wid.append(l.columnWidth(v)) - except: - wid.append(70) - v = v +1 - cfg.utls.clearTable(l) - l.setColumnCount(0) - cfg.utls.insertTableColumn(l, 0, "S", wid0) - cfg.utls.insertTableColumn(l, 1, cfg.tableMCID, wid1) - cfg.utls.insertTableColumn(l, 2, cfg.tableMCInfo, wid2) - cfg.utls.insertTableColumn(l, 3, cfg.tableCID, wid3) - cfg.utls.insertTableColumn(l, 4, cfg.tableCInfo, wid4) - cfg.utls.insertTableColumn(l, 5, cfg.tableColor, wid5) - v = 6 - for i in range(1, cfg.bandSetsList[cfg.bndSetNumber][2] + 1): - cfg.utls.insertTableColumn(l, v, cfg.tableMin + str(i), wid[v-6]) - v = v +1 - cfg.utls.insertTableColumn(l, v, cfg.tableMax + str(i), wid[v-6]) - v = v +1 - # signature ID column - cfg.utls.insertTableColumn(l, v, cfg.tableColString, 60, 'Yes') - # add signature items - x = 0 - try: - for k in list(cfg.signPlotIDs.values()): - cfg.utls.insertTableRow(l, x, 20) - cfg.utls.addTableItem(l, "checkbox", x, 0, 'Yes', None, cfg.spectrPlotList["CHECKBOX_" + str(k)]) - cfg.utls.addTableItem(l, int(cfg.spectrPlotList["MACROCLASSID_" + str(k)]), x, 1) - cfg.utls.addTableItem(l, str(cfg.spectrPlotList["MACROCLASSINFO_" + str(k)]), x, 2) - cfg.utls.addTableItem(l, int(cfg.spectrPlotList["CLASSID_" + str(k)]), x, 3) - cfg.utls.addTableItem(l, str(cfg.spectrPlotList["CLASSINFO_" + str(k)]), x, 4) - c = cfg.spectrPlotList["COLOR_" + str(k)] - cfg.utls.addTableItem(l, "", x, 5, 'Yes', c) - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - cfg.utls.addTableItem(l, str(cfg.spectrPlotList["LCS_MIN_" + str(k)][b]), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(l, str(cfg.spectrPlotList["LCS_MAX_" + str(k)][b]), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(l, str(cfg.signPlotIDs["ID_" + str(k)]), x, v, 'No') - x = x + 1 - except Exception as err: - cfg.utls.clearTable(l) - cfg.mx.msgErr57("MC" +str(cfg.signList["MACROCLASSID_" + str(k)]) + ";C" + str(cfg.signList["CLASSID_" + str(k)]) + ";" + str(cfg.signList["CLASSINFO_" + str(k)]) ) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return 'No' - l.show() - l.setColumnWidth(0, wid0) - try: - vOrd = self.orderColumn - except: - vOrd = v - cfg.utls.sortTableColumn(l, vOrd,l.horizontalHeader().sortIndicatorOrder()) - l.setSortingEnabled(True) - l.blockSignals(False) - cfg.SigTabEdited = 'Yes' - self.orderedTable(vOrd) - intersect = self.checkIntersections() - self.higlightRowsByID(intersect) - # Create plot - if skipPlot == 'No': - self.signaturePlot() - self.checkLimits = 'Yes' - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " list created") - - # highlight rows by ID - def higlightRowsByID(self, IDComb): - tW = cfg.uisp.signature_list_plot_tableWidget - c = tW.rowCount() - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - cfg.SigTabEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - for b in range(0, c): - tW.item(b, 5).setText("") - for x in range(0, 5): - tW.item(b, x).setBackground(cfg.QtGuiSCP.QColor(255,255,255)) - for ids in IDComb: - row0 = cfg.spectrPlotList["ROW_" + str(ids[0])] - row1 = cfg.spectrPlotList["ROW_" + str(ids[1])] - for x in range(0, 5): - tW.item(row0, x).setBackground(cfg.QtGuiSCP.QColor(255,203,69)) - tW.item(row1, x).setBackground(cfg.QtGuiSCP.QColor(255,203,69)) - text0 = tW.item(row1, 5).text() - text1 = tW.item(row0, 5).text() - mcId0 = str(cfg.spectrPlotList["MACROCLASSID_" + str(ids[0])]) - cId0 = str(cfg.spectrPlotList["CLASSID_" + str(ids[0])]) - mcId1 = str(cfg.spectrPlotList["MACROCLASSID_" + str(ids[1])]) - cId1 = str(cfg.spectrPlotList["CLASSID_" + str(ids[1])]) - text0 = text0 + mcId0 + "-" + cId0 + ";" - text1 = text1 + mcId1 + "-" + cId1 + ";" - tW.item(row0, 5).setText(text1) - tW.item(row1, 5).setText(text0) - tW.blockSignals(False) - tW.setSortingEnabled(True) - cfg.SigTabEdited = 'Yes' - - # check in thresholds are intersecting - def checkIntersections(self): - intersect = [] - cmb = list(cfg.itertoolsSCP.combinations(list(cfg.signPlotIDs.values()), 2)) - for a in cmb: - id0 = a[0] - minA = cfg.np.array(cfg.spectrPlotList["LCS_MIN_" + str(id0)]) - maxA = cfg.np.array(cfg.spectrPlotList["LCS_MAX_" + str(id0)]) - id1 = a[1] - minB = cfg.np.array(cfg.spectrPlotList["LCS_MIN_" + str(id1)]) - maxB= cfg.np.array(cfg.spectrPlotList["LCS_MAX_" + str(id1)]) - if cfg.macroclassCheck == 'Yes': - class0 = cfg.spectrPlotList["MACROCLASSID_" + str(id0)] - class1 = cfg.spectrPlotList["MACROCLASSID_" + str(id1)] - else: - class0 = cfg.spectrPlotList["CLASSID_" + str(id0)] - class1 = cfg.spectrPlotList["CLASSID_" + str(id1)] - if class0 != class1: - test = [] - try: - for i in range(0, len(cfg.spectrPlotList["LCS_MIN_" + str(id0)])): - if max(cfg.spectrPlotList["LCS_MIN_" + str(id0)][i], cfg.spectrPlotList["LCS_MIN_" + str(id1)][i]) <= min(cfg.spectrPlotList["LCS_MAX_" + str(id1)][i], cfg.spectrPlotList["LCS_MAX_" + str(id0)][i]): - test.append(1) - # in case of deleted signature - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - try: - self.removeSignatureByID(id0) - self.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.LCSignT.LCSignatureThresholdListTable() - except: - pass - try: - self.removeSignatureByID(id1) - self.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.LCSignT.LCSignatureThresholdListTable() - except: - pass - cfg.mx.msgWar20() - return intersect - sum = cfg.np.array(test).sum() - if sum == len(cfg.spectrPlotList["LCS_MIN_" + str(id0)]): - intersect.append(a) - return intersect - - # range checkbox - def sigmaCheckbox(self): - if cfg.uisp.sigma_checkBox.isChecked() is True: - cfg.sigmaCheck = 'Yes' - else: - cfg.sigmaCheck = 'No' - # Create plot - self.signaturePlot() - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " checkbox set: " + str(cfg.sigmaCheck)) - - # refresh plot - def refreshPlot(self): - # Create plot - self.signaturePlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "") - - # remove signature from list - def removeSignature(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Delete signatures"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to delete highlighted signatures?")) - if a == 'Yes': - tW = cfg.uisp.signature_list_plot_tableWidget - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - r = [] - for i in tW.selectedIndexes(): - r.append(i.row()) - v = list(set(r)) - for x in v: - try: - id = tW.item(x, vx).text() - except: - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - self.removeSignatureByID(id) - self.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " removed signatures: " + str(v)) - - # remove signature by ID - def removeSignatureByID(self, id): - cfg.signPlotIDs.pop("ID_" + str(id)) - cfg.spectrPlotList.pop("MACROCLASSID_" + str(id)) - cfg.spectrPlotList.pop("MACROCLASSINFO_" + str(id)) - cfg.spectrPlotList.pop("CLASSID_" + str(id)) - cfg.spectrPlotList.pop("CLASSINFO_" + str(id)) - cfg.spectrPlotList.pop("WAVELENGTH_" + str(id)) - cfg.spectrPlotList.pop("VALUES_" + str(id)) - cfg.spectrPlotList.pop("MEAN_VALUE_" + str(id)) - cfg.spectrPlotList.pop("SD_" + str(id)) - cfg.spectrPlotList.pop("LCS_MIN_" + str(id)) - cfg.spectrPlotList.pop("LCS_MAX_" + str(id)) - cfg.spectrPlotList.pop("MIN_VALUE_" + str(id)) - cfg.spectrPlotList.pop("MAX_VALUE_" + str(id)) - cfg.spectrPlotList.pop("ROI_SIZE_" + str(id)) - cfg.spectrPlotList.pop("COLOR_" + str(id)) - cfg.spectrPlotList.pop("UNIT_" + str(id)) - cfg.spectrPlotList.pop("CHECKBOX_" + str(id)) - cfg.spectrPlotList.pop("ROW_" + str(id)) - - # edited cell - def editedCell(self, row, column): - if cfg.SigTabEdited == 'Yes': - tW = cfg.uisp.signature_list_plot_tableWidget - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - try: - id = tW.item(row, v).text() - except: - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - try: - if int(tW.columnCount() - 7)/2 != len(cfg.spectrPlotList["LCS_MIN_" + str(id)]): - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - except: - cfg.mx.msgWar26(str(cfg.bndSetNumber)) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " Error bands") - return 'No' - if column == 0: - cfg.spectrPlotList["CHECKBOX_" + str(id)] = tW.item(row, 0).checkState() - elif column == 5: - cfg.utls.setTableItem(tW, row, column, "") - elif column in [1, 2, 3, 4]: - cfg.spectrPlotList["MACROCLASSID_" + str(id)] = tW.item(row, 1).text() - cfg.spectrPlotList["MACROCLASSINFO_" + str(id)] = tW.item(row, 2).text() - cfg.spectrPlotList["CLASSID_" + str(id)] = tW.item(row, 3).text() - cfg.spectrPlotList["CLASSINFO_" + str(id)] = tW.item(row, 4).text() - else: - t = tW.item(row, column).text() - try: - tr = float(t) - values = cfg.spectrPlotList["VALUES_" + str(id)] - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - if column == vb: - if tr >= values[b * 2]: - val = str(values[b * 2]) - cfg.SigTabEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - cfg.SigTabEdited = 'Yes' - break - vb = vb + 1 - if column == vb: - if tr <= values[b * 2]: - val = str(values[b * 2]) - cfg.SigTabEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - cfg.SigTabEdited = 'Yes' - break - vb = vb + 1 - except: - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - if column == vb: - val = str(cfg.spectrPlotList["LCS_MIN_" + str(id)][b]) - break - vb = vb + 1 - if column == vb: - val = str(cfg.spectrPlotList["LCS_MAX_" + str(id)][b]) - break - vb = vb + 1 - cfg.SigTabEdited = 'No' - tW.blockSignals(True) - cfg.utls.setTableItem(tW, row, column, val) - tW.blockSignals(False) - cfg.SigTabEdited = 'Yes' - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - return 0 - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - #cfg.spSigPlot.refreshPlot() - # Create plot - self.signaturePlot() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "edited cell" + str(row) + ";" + str(column)) - - # read threshold table - def readThresholdTable(self): - tW = cfg.uisp.signature_list_plot_tableWidget - c = tW.rowCount() - for b in range(0, c): - try: - v = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - id = tW.item(b, v).text() - vb = 6 - min = [] - max = [] - for n in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - min.append(float(tW.item(b, vb).text())) - vb = vb + 1 - max.append(float(tW.item(b, vb).text())) - vb = vb + 1 - cfg.signList["LCS_MIN_" + str(id)] = min - cfg.signList["LCS_MAX_" + str(id)] = max - cfg.spectrPlotList["LCS_MIN_" + str(id)] = min - cfg.spectrPlotList["LCS_MAX_" + str(id)] = max - except: - pass - intersect = self.checkIntersections() - self.higlightRowsByID(intersect) - - # Create signature plot - def signaturePlot(self): - check = 'Yes' - self.minVal = 10000000000 - self.maxVal = -10000000000 - try: - if self.firstPlot == 'No': - xMin, xMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_xlim() - yMin, yMax = cfg.uisp.Sig_Widget.sigCanvas.ax.get_ylim() - except: - self.firstPlot = 'No' - # Clear plot - try: - for i in cfg.pF: - i.remove() - cfg.pF = [] - except: - pass - try: - lines = len(cfg.uisp.Sig_Widget.sigCanvas.ax.lines) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - return None - if lines > 0: - for i in reversed(list(range(0, lines))): - cfg.uisp.Sig_Widget.sigCanvas.ax.lines.pop(i) - cfg.uisp.Sig_Widget.sigCanvas.ax.grid('on') - cfg.uisp.Sig_Widget.sigCanvas.draw() - # Set labels - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xlabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Wavelength [' + str(cfg.ui.unit_combo.currentText()) + ']')) - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylabel(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Values')) - # Add plots and legend - pL = [] - pLN = [] - mVal = [] - wlg = [] - # clear signature values - cfg.uisp.value_textBrowser.clear() - for b in sorted(cfg.signPlotIDs.values()): - if cfg.spectrPlotList['CHECKBOX_' + str(b)] == 2: - #IDList.append(b) - c = cfg.spectrPlotList['COLOR_' + str(b)].toRgb().name() - # name - nm = str(cfg.spectrPlotList['MACROCLASSID_' + str(b)]) + '#' + str(cfg.spectrPlotList['MACROCLASSINFO_' + str(b)]) + ' ' + str(cfg.spectrPlotList['CLASSID_' + str(b)]) + '#' + str(cfg.spectrPlotList['CLASSINFO_' + str(b)]) - # wavelength - w = cfg.spectrPlotList['WAVELENGTH_' + str(b)] - wlg = eval(str(w)) - # values - v = cfg.spectrPlotList['VALUES_' + str(b)] - try: - val = eval(str(v).replace('nan', '0')) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - try: - self.removeSignatureByID(b) - self.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.LCSignT.LCSignatureThresholdListTable() - except: - pass - check = 'No' - if check == 'Yes': - mVal.extend(val) - minA = cfg.spectrPlotList['LCS_MIN_' + str(b)] - mMS = eval(str(minA).replace('nan', '0')) - maxA = cfg.spectrPlotList['LCS_MAX_' + str(b)] - mPS = eval(str(maxA).replace('nan', '0')) - vMin = min(mMS) - vMax = max(mPS) - if vMin < self.minVal: - self.minVal = vMin - if vMax > self.maxVal: - self.maxVal = vMax - # unit - unit = cfg.spectrPlotList['UNIT_' + str(b)] - m = cfg.spectrPlotList['MEAN_VALUE_' + str(b)] - sdL = cfg.spectrPlotList['SD_' + str(b)] - # plot - p, = cfg.uisp.Sig_Widget.sigCanvas.ax.plot(wlg , m, c) - if cfg.sigmaCheck == 'Yes': - # fill plot - cfg.pF.append(cfg.uisp.Sig_Widget.sigCanvas.ax.fill_between(wlg, mPS, mMS, color=c, alpha=0.2)) - # add plot to legend - pL.append(p) - pLN.append(nm[:cfg.sigPLRoundCharList]) - # signature values - self.signatureDetails(str(cfg.spectrPlotList['MACROCLASSID_' + str(b)]), str(cfg.spectrPlotList['MACROCLASSINFO_' + str(b)]), str(cfg.spectrPlotList['CLASSID_' + str(b)]), str(cfg.spectrPlotList['CLASSINFO_' + str(b)]), wlg, unit, m, sdL, c, str(cfg.spectrPlotList['ROI_SIZE_' + str(b)])) - if cfg.uisp.band_lines_checkBox.isChecked(): - for wl in wlg: - wlD = cfg.uisp.Sig_Widget.sigCanvas.ax.axvline(wl, color='black', linestyle='dashed') - # place legend - # matplotlib API Changes for 3.1.1 - try: - cfg.uisp.Sig_Widget.sigCanvas.ax.legend(pL, pLN, bbox_to_anchor=(0.1, 0.0, 1.1, 1.0), loc=1, borderaxespad=0.).set_draggable(True) - except: - cfg.uisp.Sig_Widget.sigCanvas.ax.legend(pL, pLN, bbox_to_anchor=(0.1, 0.0, 1.1, 1.0), loc=1, borderaxespad=0.).draggable() - # Grid for X and Y axes - if cfg.uisp.grid_checkBox.isChecked(): - cfg.uisp.Sig_Widget.sigCanvas.ax.grid('on') - else: - cfg.uisp.Sig_Widget.sigCanvas.ax.grid('off') - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xticks(wlg) - cfg.uisp.Sig_Widget.sigCanvas.ax.xaxis.set_major_locator(cfg.MaxNLocatorSCP(7)) - cfg.uisp.Sig_Widget.sigCanvas.ax.yaxis.set_major_locator(cfg.MaxNLocatorSCP(5)) - try: - cfg.uisp.Sig_Widget.sigCanvas.ax.set_xlim(xMin, xMax) - cfg.uisp.Sig_Widget.sigCanvas.ax.set_ylim(yMin, yMax) - if (self.maxVal/max(wlg)) > 100: - cfg.uisp.Sig_Widget.sigCanvas.ax.set_aspect('auto') - except: - pass - # Draw the plot - cfg.uisp.Sig_Widget.sigCanvas.draw() - if self.checkLimits == 'No': - self.fitPlotToAxes() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " plot created") - - # calculate spectral distances - def calculateSpectralDistances(self): - try: - IDList = [] - meanDict = {} - covDict = {} - for b in sorted(cfg.signPlotIDs.values()): - if cfg.spectrPlotList["CHECKBOX_" + str(b)] == 2: - IDList.append(b) - #clear distance values - cfg.uisp.distance_textBrowser.clear() - for b in sorted(cfg.signPlotIDs.values()): - # wavelength - w = cfg.spectrPlotList["WAVELENGTH_" + str(b)] - wlg = eval(str(w)) - # values - v = cfg.spectrPlotList["VALUES_" + str(b)] - val = eval(str(v)) - # counter - n = 0 - m = [] - for i in wlg: - m.append(val[n * 2]) - n = n + 1 - meanDict["ID_" + str(b)] = m - covDict["ID_" + str(b)] = cfg.spectrPlotList["COVMATRIX_" + str(b)] - # calculate distances - cmb = list(cfg.itertoolsSCP.combinations(sorted(IDList), 2)) - for cB in cmb: - sim = cfg.utls.brayCurtisSimilarity(meanDict["ID_" + str(cB[0])], meanDict["ID_" + str(cB[1])]) - JM = cfg.utls.jeffriesMatusitaDistance(meanDict["ID_" + str(cB[0])], meanDict["ID_" + str(cB[1])], covDict["ID_" + str(cB[0])], covDict["ID_" + str(cB[1])], cfg.algBandWeigths) - #TD = cfg.utls.transformedDivergence(meanDict["ID_" + str(cB[0])], meanDict["ID_" + str(cB[1])], covDict["ID_" + str(cB[0])], covDict["ID_" + str(cB[1])]) - dist = cfg.utls.euclideanDistance(meanDict["ID_" + str(cB[0])], meanDict["ID_" + str(cB[1])], cfg.algBandWeigths) - angle = cfg.utls.spectralAngle(meanDict["ID_" + str(cB[0])], meanDict["ID_" + str(cB[1])], cfg.algBandWeigths) - self.signatureDistances(str(cfg.spectrPlotList["MACROCLASSID_" + str(cB[0])]), str(cfg.spectrPlotList["MACROCLASSINFO_" + str(cB[0])]), str(cfg.spectrPlotList["CLASSID_" + str(cB[0])]), str(cfg.spectrPlotList["CLASSINFO_" + str(cB[0])]), cfg.spectrPlotList["COLOR_" + str(cB[0])].toRgb().name(), cfg.spectrPlotList["MACROCLASSID_" + str(cB[1])], str(cfg.spectrPlotList["MACROCLASSINFO_" + str(cB[1])]), str(cfg.spectrPlotList["CLASSID_" + str(cB[1])]), str(cfg.spectrPlotList["CLASSINFO_" + str(cB[1])]), cfg.spectrPlotList["COLOR_" + str(cB[1])].toRgb().name(), JM, angle, dist, sim) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " distances calculated") - cfg.utls.selectSpectralPlotTabSettings(2) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - - # signature details - def signatureDetails(self, macroclassID, macroclassInfo, classID, classInfo, wavelengths, wavelength_unit, values, standardDeviation, color, ROISize = 0): - tbl = "" - for w in wavelengths: - tbl = tbl + "" - tbl = tbl + "" - for v in values: - tbl = tbl + "" - tbl = tbl + "" - for s in standardDeviation: - tbl = tbl + "" - tbl = tbl + "
" + str(cfg.fldMacroID_class) + " = " + str(macroclassID) + " " + str(cfg.fldROIMC_info) + " = " + str(macroclassInfo) + " " + str(cfg.fldID_class) + " = " + str(classID) + " " + str(cfg.fldROI_info) + " = " + str(classInfo) + " " + str(cfg.ROI_Size_info) + " = " + str(ROISize) + " pixels
" + cfg.wavelenNm + " [" + str(wavelength_unit) + "]" + str(w) + "
" + cfg.valNm + "" + str(round(v, 5)) + "
" + cfg.standDevNm + "" + str(round(s, 5)) + "
" - cfg.uisp.value_textBrowser.append(tbl) - cfg.uisp.value_textBrowser.append("
") - - # signature distances - def signatureDistances(self, macroclassID1, macroclassInfo1, classID1, classInfo1, color1, macroclassID2, macroclassInfo2, classID2, classInfo2, color2, jeffriesMatusitaDistance, spectralAngle, euclideanDistance, brayCurtisSimilarity, transformedDivergence = 'No'): - highlightColor = "red" - jMColor = "black" - try: - if float(jeffriesMatusitaDistance) < 1.5: - jMColor = highlightColor - except: - pass - tDColor = "black" - if transformedDivergence != 'No': - if float(transformedDivergence) < 1.5: - tDColor = highlightColor - sAColor = "black" - if float(spectralAngle) < 10: - sAColor = highlightColor - bCColor = "black" - if float(brayCurtisSimilarity) > 90: - bCColor = highlightColor - mDColor = "black" - if float(euclideanDistance) < 0.1: - mDColor = highlightColor - tbl = "" - tbl = tbl + "" - tbl = tbl + "" - tbl = tbl + "" - if transformedDivergence != 'No': - tbl = tbl + "" - tbl = tbl + "
" + str(cfg.fldMacroID_class) + " = " + str(macroclassID1) + " " + str(cfg.fldROIMC_info) + " = " + str(macroclassInfo1) + " " + str(cfg.fldID_class) + " = " + str(classID1) + " " + str(cfg.fldROI_info) + " = " + str(classInfo1) + "
" + str(cfg.fldMacroID_class) + " = " + str(macroclassID2) + " " + str(cfg.fldROIMC_info) + " = " + str(macroclassInfo2) + " " + str(cfg.fldID_class) + " = " + str(classID2) + " " + str(cfg.fldROI_info) + " = " + str(classInfo2) - tbl = tbl + "
" + cfg.jeffriesMatusitaDistNm + "" + str(jeffriesMatusitaDistance) + "
" + cfg.spectralAngleNm + "" + str(spectralAngle) + "
" + cfg.euclideanDistNm + "" + str(euclideanDistance) + "
" + cfg.brayCurtisSimNm + "" + str(brayCurtisSimilarity) + "
" + cfg.transformedDivergenceNm + "" + str(transformedDivergence) + "
" - cfg.uisp.distance_textBrowser.append(tbl) - cfg.uisp.distance_textBrowser.append("
") - - # signature list double click - def signatureListDoubleClick(self, index): - if index.column() == 5: - c = cfg.utls.selectColor() - if c is not None: - tW = cfg.uisp.signature_list_plot_tableWidget - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - r = [] - for i in tW.selectedIndexes(): - r.append(i.row()) - v = list(set(r)) - for x in v: - k = cfg.uisp.signature_list_plot_tableWidget.item(x, vx).text() - cfg.spectrPlotList["COLOR_" + str(k)] = c - cfg.uisp.signature_list_plot_tableWidget.item(x, 5).setBackground(c) - elif index.column() == 0: - for k in list(cfg.signPlotIDs.values()): - if cfg.allSignCheck2 == 'Yes': - v = 2 - else: - v = 0 - cfg.spectrPlotList["CHECKBOX_" + str(k)] = v - self.selectAllSignatures() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), " signatures index: " + str(index)) - - # select all signatures - def selectAllSignatures(self): - try: - cfg.uiUtls.addProgressBar() - # select all - if cfg.allSignCheck2 == 'Yes': - cfg.utls.allItemsSetState(cfg.uisp.signature_list_plot_tableWidget, 2) - # set check all plot - cfg.allSignCheck2 = 'No' - # unselect all if previously selected all - elif cfg.allSignCheck2 == 'No': - cfg.utls.allItemsSetState(cfg.uisp.signature_list_plot_tableWidget, 0) - # set check all plot - cfg.allSignCheck2 = 'Yes' - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " all signatures") - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), " ERROR exception: " + str(err)) - cfg.uiUtls.removeProgressBar() - - # show signature plot - def showSignaturePlotT(self): - cfg.spSigPlot.signatureListPlotTable(cfg.uisp.signature_list_plot_tableWidget) - cfg.spectralplotdlg.close() - cfg.spectralplotdlg.show() - - # include Checkbox - def includeCheckbox(self): - cfg.uisp.LCS_cut_checkBox_2.blockSignals(True) - cfg.ui.LCS_include_checkBox.blockSignals(True) - cfg.ui.LCS_cut_checkBox.blockSignals(True) - if cfg.uisp.LCS_include_checkBox_2.isChecked(): - cfg.ui.LCS_cut_checkBox.setCheckState(0) - cfg.ui.LCS_include_checkBox.setCheckState(2) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(0) - else: - cfg.ui.LCS_cut_checkBox.setCheckState(2) - cfg.ui.LCS_include_checkBox.setCheckState(0) - cfg.uisp.LCS_cut_checkBox_2.setCheckState(2) - cfg.ui.LCS_cut_checkBox.blockSignals(False) - cfg.ui.LCS_include_checkBox.blockSignals(False) - cfg.uisp.LCS_cut_checkBox_2.blockSignals(False) - - # cut Checkbox - def cutCheckbox(self): - cfg.uisp.LCS_include_checkBox_2.blockSignals(True) - cfg.ui.LCS_include_checkBox.blockSignals(True) - cfg.ui.LCS_cut_checkBox.blockSignals(True) - if cfg.uisp.LCS_cut_checkBox_2.isChecked(): - cfg.ui.LCS_include_checkBox.setCheckState(0) - cfg.uisp.LCS_include_checkBox_2.setCheckState(0) - cfg.ui.LCS_cut_checkBox.setCheckState(2) - else: - cfg.ui.LCS_include_checkBox.setCheckState(2) - cfg.uisp.LCS_include_checkBox_2.setCheckState(2) - cfg.ui.LCS_cut_checkBox.setCheckState(0) - cfg.ui.LCS_include_checkBox.blockSignals(False) - cfg.uisp.LCS_include_checkBox_2.blockSignals(False) - cfg.ui.LCS_cut_checkBox.blockSignals(False) - - # Activate pointer for pixel threshold - def pointerActive(self): - # connect to click - t = cfg.LCSPixel2 - cfg.cnvs.setMapTool(t) - px = cfg.QtGuiSCP.QPixmap(":/pointer/icons/pointer/LCS_pointer.svg") - c = cfg.QtGuiSCP.QCursor(px) - cfg.cnvs.setCursor(c) - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "pointer active: LCS pixel") - - # left click ROI pointer for pixel signature - def pointerLeftClick(self, point): - tW = cfg.uisp.signature_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - point = cfg.utls.checkPointImage(cfg.bandSetsList[cfg.bndSetNumber][8], point) - if cfg.pntCheck == 'Yes': - sig = cfg.utls.calculatePixelSignature(point, cfg.bandSetsList[cfg.bndSetNumber][8], cfg.bndSetNumber, "Pixel") - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - progrStep = 0 - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - id = tW.item(x, idCol).text() - # undo list - cfg.undoIDList["ID_" + str(id)] = str(id) - cfg.undoSpectrPlotList["LCS_MIN_" + str(id)] = cfg.spectrPlotList["LCS_MIN_" + str(id)] - cfg.undoSpectrPlotList["LCS_MAX_" + str(id)] = cfg.spectrPlotList["LCS_MAX_" + str(id)] - cfg.uisp.undo_threshold_Button.setEnabled(True) - # values - val = cfg.spectrPlotList["VALUES_" + str(id)] - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - sigVal = sig[b] - valMax = float(cfg.spectrPlotList["LCS_MAX_" + str(id)][b]) - valMin = float(cfg.spectrPlotList["LCS_MIN_" + str(id)][b]) - if sigVal >= val[b * 2]: - if cfg.uisp.LCS_include_checkBox_2.isChecked(): - if sigVal >= valMax: - max = sigVal + 1e-12 - else: - max = valMax - else: - if sigVal >= valMax: - max = valMax - else: - max = sigVal - 1e-12 - min = valMin - else: - if cfg.uisp.LCS_include_checkBox_2.isChecked(): - if sigVal <= valMin: - min = sigVal - 1e-12 - else: - min = valMin - else: - if sigVal <= valMin: - min = valMin - else: - min = sigVal + 1e-12 - max = valMax - cfg.utls.setTableItem(tW, x, vb, str(min)) - vb = vb + 1 - cfg.utls.setTableItem(tW, x, vb, str(max)) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - cfg.utls.selectRowsInTable(tW, v) - cfg.uiUtls.removeProgressBar() - - # ordered table - def orderedTable(self, column): - self.orderColumn = column - tW = cfg.uisp.signature_list_plot_tableWidget - count = tW.rowCount() - v = list(range(0, count)) - vx = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - for x in v: - id = tW.item(x, vx).text() - cfg.spectrPlotList["ROW_" + str(id)] = x - - # set minimum and maximum - def setMinimumMaximum(self): - tW = cfg.uisp.signature_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.setSortingEnabled(False) - tW.blockSignals(True) - progrStep = 0 - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - id = tW.item(x, idCol).text() - # undo list - cfg.undoIDList["ID_" + str(id)] = str(id) - cfg.undoSpectrPlotList["LCS_MIN_" + str(id)] = cfg.spectrPlotList["LCS_MIN_" + str(id)] - cfg.undoSpectrPlotList["LCS_MAX_" + str(id)] = cfg.spectrPlotList["LCS_MAX_" + str(id)] - cfg.uisp.undo_threshold_Button.setEnabled(True) - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - min = float(cfg.spectrPlotList["MIN_VALUE_" + str(id)][b]) - max = float(cfg.spectrPlotList["MAX_VALUE_" + str(id)][b]) - cfg.utls.addTableItem(tW, str(min), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(max), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - cfg.utls.selectRowsInTable(tW, v) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - # undo threshold - def undoThreshold(self): - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Undo thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to undo thresholds?")) - if a == 'Yes': - pass - else: - return 'No' - tW = cfg.uisp.signature_list_plot_tableWidget - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - progrStep = 20 - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - c = tW.rowCount() - for x in range(0, c): - idT = tW.item(x, idCol).text() - if idT in list(cfg.undoIDList.values()): - progrStep = progrStep +80/(len(list(cfg.undoIDList.values()))) - cfg.uiUtls.updateBar(int(progrStep)) - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - cfg.utls.addTableItem(tW, str(cfg.undoSpectrPlotList["LCS_MIN_" + str(idT)][b]), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(cfg.undoSpectrPlotList["LCS_MAX_" + str(idT)][b]), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - cfg.uisp.undo_threshold_Button.setEnabled(False) - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "undo") - - # set threshold from ROI - def ROIThreshold(self): - if cfg.lstROI is not None: - tW = cfg.uisp.signature_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - progrStep = 0 - # calculate ROI - fID = cfg.utls.getLastFeatureID(cfg.lstROI) - cfg.utls.calculateSignature(cfg.lstROI, cfg.bandSetsList[cfg.bndSetNumber][8], [fID], 0, cfg.tmpROINm, 0, 0, 0, 20, "MinMax", "MinMax", None) - progrStep = 20 - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - for x in reversed(v): - progrStep = progrStep +80/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - id = tW.item(x, idCol).text() - # undo list - cfg.undoIDList["ID_" + str(id)] = str(id) - cfg.undoSpectrPlotList["LCS_MIN_" + str(id)] = cfg.spectrPlotList["LCS_MIN_" + str(id)] - cfg.undoSpectrPlotList["LCS_MAX_" + str(id)] = cfg.spectrPlotList["LCS_MAX_" + str(id)] - cfg.uisp.undo_threshold_Button.setEnabled(True) - # values - val = cfg.spectrPlotList["VALUES_" + str(id)] - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - stats = cfg.tblOut["BAND_" + str(b + 1)] - min = stats[0] - max = stats[1] - if cfg.uisp.LCS_include_checkBox_2.isChecked(): - if cfg.np.around(float(tW.item(x, vb).text()), 11) > cfg.np.around(min, 11): - cfg.utls.addTableItem(tW, str(min - 1e-12), x, vb) - else: - if cfg.np.around(float(tW.item(x, vb).text()), 11) < cfg.np.around(min, 11): - if min >= val[b * 2]: - if min < cfg.np.around(float(tW.item(x, vb + 1).text()), 11): - cfg.utls.addTableItem(tW, str(min + 1e-12), x, vb + 1) - else: - cfg.utls.addTableItem(tW, str(min + 1e-12), x, vb) - vb = vb + 1 - if cfg.uisp.LCS_include_checkBox_2.isChecked(): - if cfg.np.around(float(tW.item(x, vb).text()), 11) < cfg.np.around(max, 11): - cfg.utls.addTableItem(tW, str(max + 1e-12), x, vb) - else: - if cfg.np.around(float(tW.item(x, vb).text()), 11) > cfg.np.around(max, 11): - if max <= val[b * 2]: - if max > cfg.np.around(float(tW.item(x, vb - 1).text()), 11): - cfg.utls.addTableItem(tW, str(max - 1e-12), x, vb - 1) - else: - cfg.utls.addTableItem(tW, str(max - 1e-12), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - cfg.utls.selectRowsInTable(tW, v) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - # set weights based on variance - def setAllWeightsVariance(self): - tW = cfg.uisp.signature_list_plot_tableWidget - iR = [] - for i in tW.selectedIndexes(): - iR.append(i.row()) - v = list(set(iR)) - if len(v) == 0: - count = tW.rowCount() - v = list(range(0, count)) - if len(v) > 1: - # ask for confirm - a = cfg.utls.questionBox(cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Set thresholds"), cfg.QtWidgetsSCP.QApplication.translate("semiautomaticclassificationplugin", "Are you sure you want to set thresholds for several signatures?")) - if a == 'Yes': - pass - else: - return 'No' - cfg.uiUtls.addProgressBar() - self.tableEdited = 'No' - tW.blockSignals(True) - tW.setSortingEnabled(False) - progrStep = 0 - cfg.undoIDList = {} - cfg.undoSpectrPlotList = {} - for x in reversed(v): - progrStep = progrStep + 100/(len(v)) - cfg.uiUtls.updateBar(int(progrStep)) - cfg.QtWidgetsSCP.qApp.processEvents() - idCol = cfg.bandSetsList[cfg.bndSetNumber][2] * 2 + 6 - id = tW.item(x, idCol).text() - # undo list - cfg.undoIDList["ID_" + str(id)] = str(id) - cfg.undoSpectrPlotList["LCS_MIN_" + str(id)] = cfg.spectrPlotList["LCS_MIN_" + str(id)] - cfg.undoSpectrPlotList["LCS_MAX_" + str(id)] = cfg.spectrPlotList["LCS_MAX_" + str(id)] - cfg.uisp.undo_threshold_Button.setEnabled(True) - # values - val = cfg.spectrPlotList["VALUES_" + str(id)] - vb = 6 - for b in range(0, cfg.bandSetsList[cfg.bndSetNumber][2]): - sd = val[b * 2 +1] - cfg.utls.addTableItem(tW, str(val[b * 2] - (sd * cfg.uisp.multiplicative_threshold_doubleSpinBox_2.value())), x, vb) - vb = vb + 1 - cfg.utls.addTableItem(tW, str(val[b * 2] + (sd * cfg.uisp.multiplicative_threshold_doubleSpinBox_2.value())), x, vb) - vb = vb + 1 - tW.blockSignals(False) - tW.setSortingEnabled(True) - self.tableEdited = 'Yes' - self.readThresholdTable() - cfg.LCSignT.LCSignatureThresholdListTable() - cfg.spSigPlot.refreshPlot() - cfg.utls.selectRowsInTable(tW, v) - cfg.uiUtls.removeProgressBar() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "set") - - # set plot legend max lenght - def setPlotLegendLenght(self): - cfg.sigPLRoundCharList = cfg.uisp.plot_text_spinBox.value() - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), "plot legend max length value changed to: " + str(cfg.sigPLRoundCharList)) - \ No newline at end of file diff --git a/spectralsignature/usgs_spectral_lib.py b/spectralsignature/usgs_spectral_lib.py deleted file mode 100644 index ae41c8c..0000000 --- a/spectralsignature/usgs_spectral_lib.py +++ /dev/null @@ -1,235 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - - - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class USGS_Spectral_Lib: - - def __init__(self): - self.library = None - - # add library list to combo - def addLibrariesToCombo(self): - cfg.ui.usgs_library_comboBox.blockSignals(True) - cfg.ui.usgs_library_comboBox.clear() - cfg.ui.usgs_library_comboBox.addItem('') - for i in self.usgsLibNm: - cfg.ui.usgs_library_comboBox.addItem(i) - cfg.ui.usgs_library_comboBox.blockSignals(False) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'add libraries') - - # add signature to list - def addSignatureToList(self): - if self.library is not None: - if len(self.library) > 0: - cfg.uiUtls.addProgressBar() - libraryR, libraryW, libraryS = cfg.usgsLib.downloadLibrary(self.library) - if libraryR is not None: - try: - oldROIInfo = cfg.ROIInfo - cfg.ROIInfo = str(cfg.ui.usgs_library_comboBox.currentText()) - except: - pass - cfg.sigImport.USGSLibrary(libraryR, libraryW, libraryS) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'signature added: ' + str(self.library)) - cfg.ROIInfo = oldROIInfo - cfg.mx.msg28() - cfg.uiUtls.removeProgressBar() - - # add chapter list to combo - def addSpectralLibraryToCombo(self, libraryDB): - for i in cfg.usgs_lib_list: - cfg.ui.usgs_chapter_comboBox.addItem(i) - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'chapters added') - - # selection of chapter - def chapterChanged(self): - self.usgsLibNm = [] - self.usgsLib = [] - ch = cfg.ui.usgs_chapter_comboBox.currentText() - if ch == cfg.usgs_C1: - usgsList = cfg.usgs_C1p - elif ch == cfg.usgs_C2: - usgsList = cfg.usgs_C2p - elif ch == cfg.usgs_C3: - usgsList = cfg.usgs_C3p - elif ch == cfg.usgs_C4: - usgsList = cfg.usgs_C4p - elif ch == cfg.usgs_C5: - usgsList = cfg.usgs_C5p - elif ch == cfg.usgs_C6: - usgsList = cfg.usgs_C6p - elif ch == cfg.usgs_C7: - usgsList = cfg.usgs_C7p - else: - cfg.ui.usgs_library_comboBox.clear() - return 1 - l = open(usgsList, 'r') - for i in l.readlines( ): - c = eval(i) - self.usgsLibNm.append(c[0]) - self.usgsLib.append([c[1], c[2]]) - self.addLibrariesToCombo() - cfg.ui.USGS_library_textBrowser.setHtml('') - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'chapter: ' + str(ch)) - - # download signature file - def downloadLibrary(self, link): - # date time for temp name - dT = cfg.utls.getTime() - try: - check = cfg.utls.downloadFile(link, cfg.tmpDir + '/' + dT + '.zip', 'query') - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'library downloaded: ' + str(link)) - if check == 'Yes': - libraryR, libraryW, libraryS = cfg.usgsLib.unzipLibrary(cfg.tmpDir + '/' + dT + '.zip') - return libraryR, libraryW, libraryS - else: - raise ValueError('No') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr21() - return None, None, None - - # unzip file - def unzipLibrary(self, path): - # unzip to temp dir - try: - ref = [] - wl = [] - sD = [] - with cfg.zipfileSCP.ZipFile(path) as zOpen: - for flName in zOpen.namelist(): - if flName.endswith('.txt'): - if 'REF' in flName and 'errorbars' not in flName: - zipF = zOpen.open(flName) - # temp files - tS = cfg.utls.createTempRasterPath('txt') - try: - zipO = open(tS, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - f = open(tS) - file = f.readlines() - sD1 = [] - for b in range(1, len(file)): - val = float(file[b]) - if val < 0: - val = 0 - ref.append(val) - sD1.append(0) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - elif 'Wavelengths' in flName: - zipF = zOpen.open(flName) - # temp files - tS = cfg.utls.createTempRasterPath('txt') - try: - zipO = open(tS, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - f = open(tS) - file = f.readlines() - for b in range(1, len(file)): - wl.append(float(file[b])) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - elif 'errorbars' in flName: - zipF = zOpen.open(flName) - # temp files - tS = cfg.utls.createTempRasterPath('txt') - try: - zipO = open(tS, 'wb') - with zipF, zipO: - cfg.shutilSCP.copyfileobj(zipF, zipO) - zipO.close() - f = open(tS) - file = f.readlines() - for b in range(1, len(file)): - sD.append(float(file[b])) - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + (cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - if len(sD) == 0: - sD = sD1 - return ref, wl, sD - except Exception as err: - return None, None, None - - # download signature description and display - def getSignatureDescription(self, link): - # date time for temp name - dT = cfg.utls.getTime() - try: - check = cfg.utls.downloadFile(link, cfg.tmpDir + '/' + dT + '.html', 'query') - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'library downloaded: ' + str(link)) - if check == 'Yes': - f = open(cfg.tmpDir + '/' + dT + '.html', 'r', errors='ignore') - dHtml = f.read() - cfg.ui.USGS_library_textBrowser.setHtml(dHtml) - else: - raise ValueError('No') - except Exception as err: - # logger - cfg.utls.logCondition(str(__name__) + '-' + str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), ' ERROR exception: ' + str(err)) - cfg.mx.msgErr21() - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ ' ' + cfg.utls.lineOfCode(), 'library description: ' + str(link)) - - # selection of library - def libraryChanged(self): - self.library = None - lNm = cfg.ui.usgs_library_comboBox.currentText() - if len(lNm) > 0: - i = self.usgsLibNm.index(lNm) - d, l = self.usgsLib[i] - self.getSignatureDescription(d) - self.library = l - # logger - cfg.utls.logCondition(str(cfg.inspectSCP.stack()[0][3])+ " " + cfg.utls.lineOfCode(), "library: " + str(l)) - else: - cfg.ui.USGS_library_textBrowser.setHtml("") diff --git a/spectralsignature/usgs_spectral_library/__init__.py b/spectralsignature/usgs_spectral_library/__init__.py deleted file mode 100644 index 56f3b36..0000000 --- a/spectralsignature/usgs_spectral_library/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ui/__init__.py b/ui/__init__.py old mode 100644 new mode 100755 diff --git a/ui/icons/fromGIStoRS.png b/ui/icons/fromGIStoRS.png old mode 100644 new mode 100755 diff --git a/ui/icons/guide.svg b/ui/icons/guide.svg old mode 100644 new mode 100755 diff --git a/ui/icons/help.svg b/ui/icons/help.svg old mode 100644 new mode 100755 index ab13657..ea3834e --- a/ui/icons/help.svg +++ b/ui/icons/help.svg @@ -1,6 +1,4 @@ - - @@ -27,7 +25,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.9590208" - inkscape:cx="-80.201448" + inkscape:cx="1.2192073" inkscape:cy="30.970215" inkscape:current-layer="layer1" showgrid="true" @@ -35,11 +33,12 @@ inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> + style="stroke:#49646b;stroke-opacity:1"> - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/ui/icons/pointer/ROI_pointer.svg b/ui/icons/pointer/ROI_pointer.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin.svg b/ui/icons/semiautomaticclassificationplugin.svg old mode 100644 new mode 100755 index 4432aaa..6f5e2c4 --- a/ui/icons/semiautomaticclassificationplugin.svg +++ b/ui/icons/semiautomaticclassificationplugin.svg @@ -1,19 +1,18 @@ - - @@ -32,18 +31,231 @@ stdDeviation="0.15999999" id="feGaussianBlur6583" /> + + + + + + + + + + + + + id="filter4263" + x="-0.21599999" + width="1.432" + y="-0.072000001" + height="1.144"> + stdDeviation="0.192" + id="feGaussianBlur4265" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> - - - - + + + + - - - - - - - - - - - - - - - + id="g10182-9" + transform="translate(32.000001,-22.434636)" + style="fill:#423216;fill-opacity:1;filter:url(#filter6581)"> + id="rect888-61-92-9-1" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-61-8-3-7" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-61-9-8-0" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-1-4-7-6" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-6-0-6-9-0" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-6-5-2-3-8" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-1-9-47-2-5" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-61-1-1-3" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="rect888-61-6-9-7-9" + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:3.9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + + + + + + + + + + + + height="4.2666664" + x="-8.9190678e-08" + y="28.799999" /> + style="fill:#5bedff;fill-opacity:1;stroke:none;stroke-width:0.194208;stroke-opacity:1" + id="rect1119-3" + width="2.1333337" + height="2.1333351" + x="2.1333332" + y="30.933332" /> + + + + + + + height="4.2666664" + x="2.1333334" + y="8.5333338" /> + style="fill:#423216;fill-opacity:1;stroke:none;stroke-width:0.194208;stroke-opacity:1" + id="rect1119-3-5-6" + width="2.1333337" + height="2.1333351" + x="4.2666664" + y="8.5333338" /> + + + + + + height="4.2666664" + x="1.0463256e-07" + y="5.333333" /> + + + + + + + height="4.2666678" + x="6.400001" + y="-34.133335" + transform="rotate(90)" /> - - - - - - - - - - - - - + y="-34.133335" + transform="rotate(90)" /> + + + + height="6.4000006" + x="5.3333335" + y="-29.866667" + transform="rotate(90)" /> + + + + + + + + + + + + + + + + height="6.4000006" + x="5.3333335" + y="-29.866667" + transform="rotate(90)" /> + + + + + + + + + + + height="4.2666669" + x="32" + y="12.8" /> + + + + + + + + + + height="4.2666664" + x="1.0463256e-07" + y="5.333333" /> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + y="5.3333335" /> - - - - - - - - - - - - - - + id="g1116" + transform="matrix(0.78099166,0,0,0.77272716,35.993388,24.775761)"> - + id="g1820-6-9-0" + clip-path="url(#clipPath1822-6-6-2)" + style="fill:#003380;fill-opacity:1;stroke:#fdfdfd;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + transform="translate(-42.666669,-30.933333)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg b/ui/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg deleted file mode 100644 index ad5d9e7..0000000 --- a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg +++ /dev/null @@ -1,326 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg b/ui/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg deleted file mode 100644 index 5fbe170..0000000 --- a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg b/ui/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg deleted file mode 100644 index 7c7b162..0000000 --- a/ui/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_accuracy_tool.svg b/ui/icons/semiautomaticclassificationplugin_accuracy_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_add.svg b/ui/icons/semiautomaticclassificationplugin_add.svg old mode 100644 new mode 100755 index 75b843d..2ef3f0c --- a/ui/icons/semiautomaticclassificationplugin_add.svg +++ b/ui/icons/semiautomaticclassificationplugin_add.svg @@ -1,6 +1,4 @@ - - @@ -26,20 +24,21 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.9180417" - inkscape:cx="-58.638168" - inkscape:cy="15.53879" + inkscape:zoom="11.197802" + inkscape:cx="8.0392834" + inkscape:cy="13.155674" inkscape:current-layer="layer1" - showgrid="true" + showgrid="false" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_add_bandset_tool.svg b/ui/icons/semiautomaticclassificationplugin_add_bandset_tool.svg old mode 100644 new mode 100755 index db84731..30bed9b --- a/ui/icons/semiautomaticclassificationplugin_add_bandset_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_add_bandset_tool.svg @@ -1,6 +1,4 @@ - - + inkscape:window-maximized="1" + inkscape:document-rotation="0"> + style="opacity:1;fill:#49646b;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - - + id="defs2987"> + + + + + + + + + + + + + + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - - - - - - - + style="fill:#f2f2f2;stroke:#2e2e2e;stroke-width:3.30225;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 10.666667,1.1999999 H 32.666669 V 33.200001 H 10.666667 Z" + id="path3028-2" + inkscape:connector-curvature="0" /> + + style="fill:none;stroke:#007602;stroke-width:2.74343;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 21.733336,26.400001 27.066669,18.4 l -5.333333,-8" + id="path2999" + inkscape:connector-curvature="0" /> diff --git a/ui/icons/semiautomaticclassificationplugin_aster_tool.svg b/ui/icons/semiautomaticclassificationplugin_aster_tool.svg deleted file mode 100644 index 3d49245..0000000 --- a/ui/icons/semiautomaticclassificationplugin_aster_tool.svg +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_band_combination_tool.svg b/ui/icons/semiautomaticclassificationplugin_band_combination_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_band_processing.svg b/ui/icons/semiautomaticclassificationplugin_band_processing.svg old mode 100644 new mode 100755 index e29f23a..e1d645a --- a/ui/icons/semiautomaticclassificationplugin_band_processing.svg +++ b/ui/icons/semiautomaticclassificationplugin_band_processing.svg @@ -1,6 +1,4 @@ - - + inkscape:lockguides="true" + inkscape:document-rotation="0"> - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - 1 - 2 - 3 - 4 - - diff --git a/ui/icons/semiautomaticclassificationplugin_bandcalc_tool.svg b/ui/icons/semiautomaticclassificationplugin_bandcalc_tool.svg old mode 100644 new mode 100755 index f8d7d50..118ee8f --- a/ui/icons/semiautomaticclassificationplugin_bandcalc_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_bandcalc_tool.svg @@ -1,6 +1,4 @@ - - @@ -26,9 +24,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1.3997253" - inkscape:cx="-277.18962" - inkscape:cy="53.501914" + inkscape:zoom="5.5989012" + inkscape:cx="30.682579" + inkscape:cy="21.702244" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" @@ -36,11 +34,12 @@ showguides="true" inkscape:snap-global="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:guide-bbox="true"> + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> + + ry="0" /> + 1*2 - 1*2 diff --git a/ui/icons/semiautomaticclassificationplugin_bandset_cumulative_stretch_tool.svg b/ui/icons/semiautomaticclassificationplugin_bandset_cumulative_stretch_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_bandset_std_dev_stretch_tool.svg b/ui/icons/semiautomaticclassificationplugin_bandset_std_dev_stretch_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_bandset_tool.svg b/ui/icons/semiautomaticclassificationplugin_bandset_tool.svg old mode 100644 new mode 100755 index 0023b35..62e9705 --- a/ui/icons/semiautomaticclassificationplugin_bandset_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_bandset_tool.svg @@ -1,6 +1,4 @@ - - + inkscape:window-maximized="1" + inkscape:document-rotation="0"> - - + id="defs2987"> + + + + + + + + + + + + + + + + + inkscape:snap-global="true" + inkscape:document-rotation="0"> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="g1143" + clip-path="url(#clipPath1145)" + transform="matrix(0.49350634,0,0,0.49350634,16.664938,16.138532)"> - - - - - - + inkscape:label="Clip" + id="g1141"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_batch_check.svg b/ui/icons/semiautomaticclassificationplugin_batch_check.svg deleted file mode 100644 index a89c1e0..0000000 --- a/ui/icons/semiautomaticclassificationplugin_batch_check.svg +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg b/ui/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_class_signature_tool.svg b/ui/icons/semiautomaticclassificationplugin_class_signature_tool.svg deleted file mode 100644 index b2a431d..0000000 --- a/ui/icons/semiautomaticclassificationplugin_class_signature_tool.svg +++ /dev/null @@ -1,553 +0,0 @@ - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg b/ui/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_class_tool.svg b/ui/icons/semiautomaticclassificationplugin_class_tool.svg old mode 100644 new mode 100755 index 90b729e..8fe6043 --- a/ui/icons/semiautomaticclassificationplugin_class_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_class_tool.svg @@ -1,6 +1,4 @@ - - + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_classification.svg b/ui/icons/semiautomaticclassificationplugin_classification.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_classification_dilation.svg b/ui/icons/semiautomaticclassificationplugin_classification_dilation.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_classification_erosion.svg b/ui/icons/semiautomaticclassificationplugin_classification_erosion.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_classification_sieve.svg b/ui/icons/semiautomaticclassificationplugin_classification_sieve.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_clip_tool.svg b/ui/icons/semiautomaticclassificationplugin_clip_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_cloud_masking_tool.svg b/ui/icons/semiautomaticclassificationplugin_cloud_masking_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_cross_classification.svg b/ui/icons/semiautomaticclassificationplugin_cross_classification.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_delete_signature.svg b/ui/icons/semiautomaticclassificationplugin_delete_signature.svg deleted file mode 100644 index d39d325..0000000 --- a/ui/icons/semiautomaticclassificationplugin_delete_signature.svg +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_docks.svg b/ui/icons/semiautomaticclassificationplugin_docks.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_download_arrow.svg b/ui/icons/semiautomaticclassificationplugin_download_arrow.svg old mode 100644 new mode 100755 index 425e021..13b353c --- a/ui/icons/semiautomaticclassificationplugin_download_arrow.svg +++ b/ui/icons/semiautomaticclassificationplugin_download_arrow.svg @@ -1,6 +1,4 @@ - - @@ -26,20 +24,21 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.9180417" - inkscape:cx="-18.867373" - inkscape:cy="10.498552" - inkscape:current-layer="layer3" + inkscape:zoom="11.197802" + inkscape:cx="7.6094086" + inkscape:cy="16.013151" + inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:document-rotation="0"> @@ -75,7 +74,7 @@ id="layer3" inkscape:label="Livello"> - - + inkscape:window-maximized="1" + inkscape:document-rotation="0"> - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_enter.svg b/ui/icons/semiautomaticclassificationplugin_enter.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_export.svg b/ui/icons/semiautomaticclassificationplugin_export.svg old mode 100644 new mode 100755 index 52b192a..6d0c6a4 --- a/ui/icons/semiautomaticclassificationplugin_export.svg +++ b/ui/icons/semiautomaticclassificationplugin_export.svg @@ -1,20 +1,17 @@ - - @@ -31,16 +28,6 @@ offset="1" id="stop5975" /> - + inkscape:snap-global="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_export_spectral_library.svg b/ui/icons/semiautomaticclassificationplugin_export_spectral_library.svg old mode 100644 new mode 100755 index 7c5ce63..beae017 --- a/ui/icons/semiautomaticclassificationplugin_export_spectral_library.svg +++ b/ui/icons/semiautomaticclassificationplugin_export_spectral_library.svg @@ -1,20 +1,17 @@ - - @@ -31,16 +28,6 @@ offset="1" id="stop5975" /> - + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - - - - + - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_fit_plot.svg b/ui/icons/semiautomaticclassificationplugin_fit_plot.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_goes_tool.svg b/ui/icons/semiautomaticclassificationplugin_goes_tool.svg deleted file mode 100644 index 4adb00f..0000000 --- a/ui/icons/semiautomaticclassificationplugin_goes_tool.svg +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_home.svg b/ui/icons/semiautomaticclassificationplugin_home.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_import.svg b/ui/icons/semiautomaticclassificationplugin_import.svg old mode 100644 new mode 100755 index ee7af22..2bb25cd --- a/ui/icons/semiautomaticclassificationplugin_import.svg +++ b/ui/icons/semiautomaticclassificationplugin_import.svg @@ -1,48 +1,22 @@ - - - - - - - - + id="defs2987" /> + inkscape:snap-global="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_import_spectral_library.svg b/ui/icons/semiautomaticclassificationplugin_import_spectral_library.svg old mode 100644 new mode 100755 index 2f15845..73cfac6 --- a/ui/icons/semiautomaticclassificationplugin_import_spectral_library.svg +++ b/ui/icons/semiautomaticclassificationplugin_import_spectral_library.svg @@ -1,48 +1,22 @@ - - - - - - - - + id="defs2987" /> + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - - - - - - - - - - - + - - - - + + + + + + + + + + + + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_kmeans_tool.svg b/ui/icons/semiautomaticclassificationplugin_kmeans_tool.svg deleted file mode 100644 index e0af17e..0000000 --- a/ui/icons/semiautomaticclassificationplugin_kmeans_tool.svg +++ /dev/null @@ -1,2220 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   - - diff --git a/ui/icons/semiautomaticclassificationplugin_kml_add.svg b/ui/icons/semiautomaticclassificationplugin_kml_add.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_land_cover_change.svg b/ui/icons/semiautomaticclassificationplugin_land_cover_change.svg deleted file mode 100644 index 7012a18..0000000 --- a/ui/icons/semiautomaticclassificationplugin_land_cover_change.svg +++ /dev/null @@ -1,676 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_landsat8_tool.svg b/ui/icons/semiautomaticclassificationplugin_landsat8_tool.svg old mode 100644 new mode 100755 index a1cd6bc..f4a1120 --- a/ui/icons/semiautomaticclassificationplugin_landsat8_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_landsat8_tool.svg @@ -1,6 +1,4 @@ - - @@ -27,7 +25,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="7.9180417" - inkscape:cx="-18.014156" + inkscape:cx="5.8849138" inkscape:cy="27.300273" inkscape:current-layer="layer1" showgrid="true" @@ -36,10 +34,11 @@ showguides="true" inkscape:snap-global="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:document-rotation="0"> + gradientTransform="matrix(1.0666667,0,0,1.0666667,-4.5838022,-11.163527)" /> + gradientTransform="matrix(0.70774435,0.79804493,-0.90927429,0.55767198,-8.533334,-8.5333341)" /> @@ -170,10 +169,10 @@ - - @@ -35,16 +32,6 @@ offset="1" id="stop3819" /> - + inkscape:snap-global="true" + inkscape:document-rotation="0"> - + + + diff --git a/ui/icons/semiautomaticclassificationplugin_minus.svg b/ui/icons/semiautomaticclassificationplugin_minus.svg deleted file mode 100644 index 13e00b8..0000000 --- a/ui/icons/semiautomaticclassificationplugin_minus.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_modis_tool.svg b/ui/icons/semiautomaticclassificationplugin_modis_tool.svg deleted file mode 100644 index 4c89b7e..0000000 --- a/ui/icons/semiautomaticclassificationplugin_modis_tool.svg +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_mosaic_tool.svg b/ui/icons/semiautomaticclassificationplugin_mosaic_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_move_down.svg b/ui/icons/semiautomaticclassificationplugin_move_down.svg old mode 100644 new mode 100755 index ebeaf7e..85073d2 --- a/ui/icons/semiautomaticclassificationplugin_move_down.svg +++ b/ui/icons/semiautomaticclassificationplugin_move_down.svg @@ -1,6 +1,4 @@ - - @@ -27,19 +25,20 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="11.197802" - inkscape:cx="-21.016685" - inkscape:cy="17.12608" + inkscape:cx="10.716062" + inkscape:cy="17.023" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_move_up.svg b/ui/icons/semiautomaticclassificationplugin_move_up.svg old mode 100644 new mode 100755 index c11ea08..5db4e0e --- a/ui/icons/semiautomaticclassificationplugin_move_up.svg +++ b/ui/icons/semiautomaticclassificationplugin_move_up.svg @@ -1,6 +1,4 @@ - - @@ -27,19 +25,20 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="11.197802" - inkscape:cx="-29.274826" - inkscape:cy="21.156953" + inkscape:cx="19.857624" + inkscape:cy="14.272526" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_neighbor_pixels.svg b/ui/icons/semiautomaticclassificationplugin_neighbor_pixels.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_new_file.svg b/ui/icons/semiautomaticclassificationplugin_new_file.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_open_dir.svg b/ui/icons/semiautomaticclassificationplugin_open_dir.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_open_file.svg b/ui/icons/semiautomaticclassificationplugin_open_file.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_download_options.svg b/ui/icons/semiautomaticclassificationplugin_options.svg old mode 100644 new mode 100755 similarity index 97% rename from ui/icons/semiautomaticclassificationplugin_download_options.svg rename to ui/icons/semiautomaticclassificationplugin_options.svg index 7d20f36..d9a07b0 --- a/ui/icons/semiautomaticclassificationplugin_download_options.svg +++ b/ui/icons/semiautomaticclassificationplugin_options.svg @@ -14,7 +14,7 @@ id="svg2985" version="1.1" inkscape:version="0.92.1 r15371" - sodipodi:docname="semiautomaticclassificationplugin_download_options.svg" + sodipodi:docname="semiautomaticclassificationplugin_options.svg" inkscape:export-xdpi="67" inkscape:export-ydpi="67" viewBox="0 0 32 32"> diff --git a/ui/icons/semiautomaticclassificationplugin_order_by_date.svg b/ui/icons/semiautomaticclassificationplugin_order_by_date.svg new file mode 100755 index 0000000..294671a --- /dev/null +++ b/ui/icons/semiautomaticclassificationplugin_order_by_date.svg @@ -0,0 +1,207 @@ + + + + + + + + + + image/svg+xml + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + 2 + + diff --git a/ui/icons/semiautomaticclassificationplugin_order_by_name.svg b/ui/icons/semiautomaticclassificationplugin_order_by_name.svg old mode 100644 new mode 100755 index 0dcf942..473e7f9 --- a/ui/icons/semiautomaticclassificationplugin_order_by_name.svg +++ b/ui/icons/semiautomaticclassificationplugin_order_by_name.svg @@ -1,6 +1,4 @@ - - @@ -26,20 +24,21 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="11.197802" - inkscape:cx="-19.400251" - inkscape:cy="18.927042" + inkscape:zoom="7.9180417" + inkscape:cx="21.820918" + inkscape:cy="7.7431326" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> a + x="15.398268" + y="13.213651" + style="font-size:18.5501px;line-height:1.25;font-family:sans-serif;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.067;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">a bb  -   + + + + + + + + + + + + + + + c - + y="21.333334" /> + + + diff --git a/ui/icons/semiautomaticclassificationplugin_osm_add.svg b/ui/icons/semiautomaticclassificationplugin_osm_add.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_pca_tool.svg b/ui/icons/semiautomaticclassificationplugin_pca_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_plus.svg b/ui/icons/semiautomaticclassificationplugin_plus.svg deleted file mode 100644 index 3fd6127..0000000 --- a/ui/icons/semiautomaticclassificationplugin_plus.svg +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_pointer_tool.svg b/ui/icons/semiautomaticclassificationplugin_pointer_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_post_process.svg b/ui/icons/semiautomaticclassificationplugin_post_process.svg old mode 100644 new mode 100755 index 9dde5f8..008c601 --- a/ui/icons/semiautomaticclassificationplugin_post_process.svg +++ b/ui/icons/semiautomaticclassificationplugin_post_process.svg @@ -1,6 +1,4 @@ - - @@ -27,7 +25,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.9590209" - inkscape:cx="-102.91295" + inkscape:cx="8.4033843" inkscape:cy="7.1656834" inkscape:current-layer="layer1" showgrid="true" @@ -36,11 +34,12 @@ showguides="true" inkscape:snap-global="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:guide-bbox="true"> + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_preview.svg b/ui/icons/semiautomaticclassificationplugin_preview.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_preview_redo.svg b/ui/icons/semiautomaticclassificationplugin_preview_redo.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_random_forest.svg b/ui/icons/semiautomaticclassificationplugin_random_forest.svg deleted file mode 100644 index 2feee06..0000000 --- a/ui/icons/semiautomaticclassificationplugin_random_forest.svg +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - RF - - diff --git a/ui/icons/semiautomaticclassificationplugin_reclassification_tool.svg b/ui/icons/semiautomaticclassificationplugin_reclassification_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_redo_save_roi.svg b/ui/icons/semiautomaticclassificationplugin_redo_save_roi.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_reload.svg b/ui/icons/semiautomaticclassificationplugin_reload.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_remove.svg b/ui/icons/semiautomaticclassificationplugin_remove.svg old mode 100644 new mode 100755 index e57bc6c..810b72d --- a/ui/icons/semiautomaticclassificationplugin_remove.svg +++ b/ui/icons/semiautomaticclassificationplugin_remove.svg @@ -1,6 +1,4 @@ - - @@ -26,20 +24,21 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.9180417" - inkscape:cx="-58.638168" - inkscape:cy="15.53879" + inkscape:zoom="11.197802" + inkscape:cx="8.4262872" + inkscape:cy="35.24385" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_report_tool.svg b/ui/icons/semiautomaticclassificationplugin_report_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_reproject_raster_bands.svg b/ui/icons/semiautomaticclassificationplugin_reproject_raster_bands.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_reset.svg b/ui/icons/semiautomaticclassificationplugin_reset.svg old mode 100644 new mode 100755 index 57a7093..3b1c761 --- a/ui/icons/semiautomaticclassificationplugin_reset.svg +++ b/ui/icons/semiautomaticclassificationplugin_reset.svg @@ -1,6 +1,4 @@ - - @@ -26,20 +24,21 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.9180417" - inkscape:cx="-65.175436" - inkscape:cy="6.1833882" + inkscape:zoom="5.598901" + inkscape:cx="3.6381492" + inkscape:cy="39.445738" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" showguides="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-global="true"> + inkscape:snap-global="true" + inkscape:document-rotation="0"> - - - - + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_rgb_tool.svg b/ui/icons/semiautomaticclassificationplugin_rgb_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_roi_multiple.svg b/ui/icons/semiautomaticclassificationplugin_roi_multiple.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_roi_options.svg b/ui/icons/semiautomaticclassificationplugin_roi_options.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_roi_redo.svg b/ui/icons/semiautomaticclassificationplugin_roi_redo.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_roi_single.svg b/ui/icons/semiautomaticclassificationplugin_roi_single.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_roi_tool.svg b/ui/icons/semiautomaticclassificationplugin_roi_tool.svg old mode 100644 new mode 100755 index fb17810..1fb0dce --- a/ui/icons/semiautomaticclassificationplugin_roi_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_roi_tool.svg @@ -1,6 +1,4 @@ - - + inkscape:window-maximized="1" + inkscape:document-rotation="0"> - - + id="defs2987"> + + + + + + + + + + + + + + + + + inkscape:snap-global="true" + inkscape:document-rotation="0"> + style="fill:#000000;fill-opacity:1;stroke:#000600;stroke-width:0.935414px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 2.1333334,3.2000004 V 33.066668 l 29.8666676,-16 z" + id="path841-3" /> - - - - + style="fill:#49646b;fill-opacity:1;stroke:#ffffff;stroke-width:0.635;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.9584209,2.1333321 V 32 L 31.825089,16.000001 Z" + id="path841" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/icons/semiautomaticclassificationplugin_save_plot_image.svg b/ui/icons/semiautomaticclassificationplugin_save_plot_image.svg old mode 100644 new mode 100755 index 92e7523..2067e21 --- a/ui/icons/semiautomaticclassificationplugin_save_plot_image.svg +++ b/ui/icons/semiautomaticclassificationplugin_save_plot_image.svg @@ -1,48 +1,22 @@ - - - - - - - - + id="defs2987" /> + inkscape:snap-global="true" + inkscape:document-rotation="0"> diff --git a/ui/icons/semiautomaticclassificationplugin_save_roi.svg b/ui/icons/semiautomaticclassificationplugin_save_roi.svg old mode 100644 new mode 100755 index a5492d8..5887580 --- a/ui/icons/semiautomaticclassificationplugin_save_roi.svg +++ b/ui/icons/semiautomaticclassificationplugin_save_roi.svg @@ -1,6 +1,4 @@ - - @@ -27,8 +25,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="7.9180417" - inkscape:cx="-12.363458" - inkscape:cy="11.852459" + inkscape:cx="13.059312" + inkscape:cy="22.659317" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" @@ -36,10 +34,11 @@ showguides="true" inkscape:snap-global="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:document-rotation="0"> - + + diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg b/ui/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg deleted file mode 100644 index 2960b95..0000000 --- a/ui/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_raster_display.svg b/ui/icons/semiautomaticclassificationplugin_scatter_raster_display.svg deleted file mode 100644 index baf260e..0000000 --- a/ui/icons/semiautomaticclassificationplugin_scatter_raster_display.svg +++ /dev/null @@ -1,1986 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_raster_image.svg b/ui/icons/semiautomaticclassificationplugin_scatter_raster_image.svg deleted file mode 100644 index 8848af3..0000000 --- a/ui/icons/semiautomaticclassificationplugin_scatter_raster_image.svg +++ /dev/null @@ -1,1991 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_raster_temp_ROI.svg b/ui/icons/semiautomaticclassificationplugin_scatter_raster_temp_ROI.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg b/ui/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg deleted file mode 100644 index ffe0460..0000000 --- a/ui/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_show_raster.svg b/ui/icons/semiautomaticclassificationplugin_scatter_show_raster.svg deleted file mode 100644 index 72178af..0000000 --- a/ui/icons/semiautomaticclassificationplugin_scatter_show_raster.svg +++ /dev/null @@ -1,599 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_scatter_tool.svg b/ui/icons/semiautomaticclassificationplugin_scatter_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_search_images.svg b/ui/icons/semiautomaticclassificationplugin_search_images.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_select_all.svg b/ui/icons/semiautomaticclassificationplugin_select_all.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_sentinel1_tool.svg b/ui/icons/semiautomaticclassificationplugin_sentinel1_tool.svg deleted file mode 100644 index d642a29..0000000 --- a/ui/icons/semiautomaticclassificationplugin_sentinel1_tool.svg +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_sentinel3_tool.svg b/ui/icons/semiautomaticclassificationplugin_sentinel3_tool.svg deleted file mode 100644 index 6490023..0000000 --- a/ui/icons/semiautomaticclassificationplugin_sentinel3_tool.svg +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_sentinel_tool.svg b/ui/icons/semiautomaticclassificationplugin_sentinel_tool.svg deleted file mode 100644 index 147aab0..0000000 --- a/ui/icons/semiautomaticclassificationplugin_sentinel_tool.svg +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_settings_tool.svg b/ui/icons/semiautomaticclassificationplugin_settings_tool.svg old mode 100644 new mode 100755 index 338c887..af1b227 --- a/ui/icons/semiautomaticclassificationplugin_settings_tool.svg +++ b/ui/icons/semiautomaticclassificationplugin_settings_tool.svg @@ -1,6 +1,4 @@ - - @@ -25,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.9180418" - inkscape:cx="-14.028318" - inkscape:cy="13.43578" + inkscape:zoom="11.197802" + inkscape:cx="10.891178" + inkscape:cy="17.327602" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" @@ -35,10 +33,11 @@ showguides="true" inkscape:snap-global="true" inkscape:window-width="1366" - inkscape:window-height="708" + inkscape:window-height="706" inkscape:window-x="0" inkscape:window-y="0" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:document-rotation="0"> - - diff --git a/ui/icons/semiautomaticclassificationplugin_sign_edit_range.svg b/ui/icons/semiautomaticclassificationplugin_sign_edit_range.svg deleted file mode 100644 index d97b665..0000000 --- a/ui/icons/semiautomaticclassificationplugin_sign_edit_range.svg +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_sign_tool.svg b/ui/icons/semiautomaticclassificationplugin_sign_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_spectral_distance.svg b/ui/icons/semiautomaticclassificationplugin_spectral_distance.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_split_raster.svg b/ui/icons/semiautomaticclassificationplugin_split_raster.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_stack_raster.svg b/ui/icons/semiautomaticclassificationplugin_stack_raster.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_threshold_tool.svg b/ui/icons/semiautomaticclassificationplugin_threshold_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_training_input.svg b/ui/icons/semiautomaticclassificationplugin_training_input.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_undo_edit_raster.svg b/ui/icons/semiautomaticclassificationplugin_undo_edit_raster.svg deleted file mode 100644 index 98fc8af..0000000 --- a/ui/icons/semiautomaticclassificationplugin_undo_edit_raster.svg +++ /dev/null @@ -1,739 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg b/ui/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg deleted file mode 100644 index a2a78c2..0000000 --- a/ui/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_undo_save_roi.svg b/ui/icons/semiautomaticclassificationplugin_undo_save_roi.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_vector_to_raster_tool.svg b/ui/icons/semiautomaticclassificationplugin_vector_to_raster_tool.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_weight_tool.svg b/ui/icons/semiautomaticclassificationplugin_weight_tool.svg deleted file mode 100644 index c429adf..0000000 --- a/ui/icons/semiautomaticclassificationplugin_weight_tool.svg +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - 1.0 - - diff --git a/ui/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg b/ui/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg deleted file mode 100644 index 5f63637..0000000 --- a/ui/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - σ - - - - - - diff --git a/ui/icons/semiautomaticclassificationplugin_zoom_to_Image.svg b/ui/icons/semiautomaticclassificationplugin_zoom_to_Image.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_zoom_to_ROI.svg b/ui/icons/semiautomaticclassificationplugin_zoom_to_ROI.svg old mode 100644 new mode 100755 diff --git a/ui/icons/semiautomaticclassificationplugin_zoom_to_preview.svg b/ui/icons/semiautomaticclassificationplugin_zoom_to_preview.svg old mode 100644 new mode 100755 diff --git a/ui/resources.qrc b/ui/resources.qrc old mode 100644 new mode 100755 index a0082bb..9f19814 --- a/ui/resources.qrc +++ b/ui/resources.qrc @@ -1,34 +1,26 @@ - icons/semiautomaticclassificationplugin_goes_tool.svg - icons/semiautomaticclassificationplugin_kmeans_tool.svg + icons/semiautomaticclassificationplugin_order_by_date.svg icons/semiautomaticclassificationplugin_cross_classification.svg - icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg icons/semiautomaticclassificationplugin_import_spectral_library.svg icons/semiautomaticclassificationplugin_select_all.svg icons/semiautomaticclassificationplugin_add_sign_tool.svg icons/semiautomaticclassificationplugin_download_image_preview.svg - icons/semiautomaticclassificationplugin_delete_signature.svg icons/semiautomaticclassificationplugin_clip_tool.svg icons/semiautomaticclassificationplugin_cloud_masking_tool.svg icons/semiautomaticclassificationplugin_classification_dilation.svg icons/semiautomaticclassificationplugin_class_tool.svg - icons/semiautomaticclassificationplugin_class_signature_tool.svg icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg icons/semiautomaticclassificationplugin_batch.svg - icons/semiautomaticclassificationplugin_batch_check.svg icons/semiautomaticclassificationplugin_bandset_tool.svg - icons/semiautomaticclassificationplugin_bandcalc_rules.svg icons/semiautomaticclassificationplugin_bandcalc_tool.svg icons/semiautomaticclassificationplugin_bandcalc_expression.svg icons/semiautomaticclassificationplugin_band_processing.svg icons/semiautomaticclassificationplugin_band_combination_tool.svg - icons/semiautomaticclassificationplugin_aster_tool.svg icons/semiautomaticclassificationplugin_add_bandset_tool.svg icons/semiautomaticclassificationplugin_add.svg icons/semiautomaticclassificationplugin_accuracy_tool.svg icons/guide.svg - icons/semiautomaticclassificationplugin_undo_edit_raster.svg icons/semiautomaticclassificationplugin_enter.svg icons/semiautomaticclassificationplugin_kml_add.svg icons/semiautomaticclassificationplugin.svg @@ -37,29 +29,24 @@ icons/semiautomaticclassificationplugin_zoom_to_Image.svg icons/semiautomaticclassificationplugin_roi_single.svg icons/semiautomaticclassificationplugin_roi_redo.svg - icons/semiautomaticclassificationplugin_remove_temp.svg icons/semiautomaticclassificationplugin_preview.svg icons/semiautomaticclassificationplugin_preview_redo.svg icons/semiautomaticclassificationplugin_manual_ROI.svg - icons/semiautomaticclassificationplugin_edit_raster.svg icons/semiautomaticclassificationplugin_classification.svg icons/semiautomaticclassificationplugin_bandset_std_dev_stretch_tool.svg icons/semiautomaticclassificationplugin_bandset_cumulative_stretch_tool.svg icons/semiautomaticclassificationplugin_post_process.svg icons/semiautomaticclassificationplugin_home.svg icons/semiautomaticclassificationplugin_download_login.svg - icons/semiautomaticclassificationplugin_download_options.svg icons/semiautomaticclassificationplugin_download_search.svg icons/semiautomaticclassificationplugin_classification_erosion.svg icons/semiautomaticclassificationplugin_classification_sieve.svg - icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg icons/semiautomaticclassificationplugin_fit_plot.svg icons/semiautomaticclassificationplugin_pointer_tool.svg icons/semiautomaticclassificationplugin_move_down.svg icons/semiautomaticclassificationplugin_order_by_name.svg icons/semiautomaticclassificationplugin_osm_add.svg icons/semiautomaticclassificationplugin_pca_tool.svg - icons/semiautomaticclassificationplugin_plus.svg icons/semiautomaticclassificationplugin_move_up.svg icons/semiautomaticclassificationplugin_reload.svg icons/semiautomaticclassificationplugin_import.svg @@ -74,58 +61,39 @@ icons/semiautomaticclassificationplugin_remove.svg icons/semiautomaticclassificationplugin_open_file.svg icons/semiautomaticclassificationplugin_export_spectral_library.svg - icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg - icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg icons/semiautomaticclassificationplugin_download_arrow.svg - icons/semiautomaticclassificationplugin_class_signature_tool.svg icons/semiautomaticclassificationplugin_spectral_distance.svg icons/semiautomaticclassificationplugin_split_raster.svg icons/semiautomaticclassificationplugin_stack_raster.svg icons/semiautomaticclassificationplugin_threshold_tool.svg icons/semiautomaticclassificationplugin_training_input.svg - icons/semiautomaticclassificationplugin_undo_edit_raster.svg - icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg icons/semiautomaticclassificationplugin_undo_save_roi.svg icons/semiautomaticclassificationplugin_vector_to_raster_tool.svg - icons/semiautomaticclassificationplugin_weight_tool.svg - icons/semiautomaticclassificationplugin_random_forest.svg icons/semiautomaticclassificationplugin_reclassification_tool.svg icons/semiautomaticclassificationplugin_docks.svg icons/semiautomaticclassificationplugin_neighbor_pixels.svg icons/semiautomaticclassificationplugin_class_to_vector_tool.svg icons/help.svg icons/semiautomaticclassificationplugin_report_tool.svg - icons/semiautomaticclassificationplugin_scatter_raster_display.svg - icons/semiautomaticclassificationplugin_scatter_raster_image.svg icons/semiautomaticclassificationplugin_scatter_raster_temp_ROI.svg - icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg - icons/semiautomaticclassificationplugin_scatter_show_raster.svg icons/semiautomaticclassificationplugin_scatter_tool.svg icons/semiautomaticclassificationplugin_search_images.svg - icons/semiautomaticclassificationplugin_land_cover_change.svg icons/semiautomaticclassificationplugin_landsat8_tool.svg - icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg icons/fromGIStoRS.png icons/semiautomaticclassificationplugin_roi_multiple.svg icons/semiautomaticclassificationplugin_roi_options.svg icons/semiautomaticclassificationplugin_roi_tool.svg - icons/semiautomaticclassificationplugin_sentinel_tool.svg - icons/semiautomaticclassificationplugin_sentinel1_tool.svg - icons/semiautomaticclassificationplugin_sentinel3_tool.svg + icons/semiautomaticclassificationplugin_options.svg icons/semiautomaticclassificationplugin_settings_tool.svg - icons/semiautomaticclassificationplugin_sign_edit_range.svg icons/semiautomaticclassificationplugin_sign_tool.svg icons/semiautomaticclassificationplugin_redo_save_roi.svg icons/semiautomaticclassificationplugin_threshold_tool.svg icons/semiautomaticclassificationplugin_save_plot_image.svg icons/semiautomaticclassificationplugin_save_roi.svg icons/semiautomaticclassificationplugin_merge_sign_tool.svg - icons/semiautomaticclassificationplugin_minus.svg - icons/semiautomaticclassificationplugin_modis_tool.svg icons/semiautomaticclassificationplugin_mosaic_tool.svg - icons/pointer/LCS_pointer.svg icons/pointer/ROI_pointer.svg diff --git a/ui/resources_rc.py b/ui/resources_rc.py old mode 100644 new mode 100755 index 3e0089b..286d1d5 --- a/ui/resources_rc.py +++ b/ui/resources_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created by: The Resource Compiler for PyQt5 (Qt v5.11.3) +# Created by: The Resource Compiler for PyQt5 (Qt v5.15.8) # # WARNING! All changes made in this file will be lost! @@ -140,22623 +140,7 @@ \x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ \x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\ \x76\x67\x3e\x0a\ -\x00\x00\x15\x22\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x30\ -\x33\x39\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ -\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\ -\x20\x72\x31\x35\x33\x37\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ -\x33\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x4c\x43\x53\x5f\x70\x6f\x69\ -\x6e\x74\x65\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x33\x30\x34\x35\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ -\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ -\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ -\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ -\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ -\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x64\x65\x66\x73\x33\x30\x34\x33\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ -\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ -\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ -\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ -\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ -\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ -\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x30\x34\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x32\ -\x31\x34\x39\x31\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x33\x2e\x39\x31\x35\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x79\x3d\x22\x31\x36\x2e\x38\x34\x32\x31\x38\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x30\x33\x39\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x67\x34\x35\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\ -\x38\x31\x34\x35\x30\x34\x30\x32\x2c\x30\x2c\x30\x2c\x30\x2e\x38\ -\x31\x34\x35\x30\x34\x30\x32\x2c\x33\x2e\x32\x31\x38\x32\x34\x30\ -\x38\x2c\x33\x2e\x31\x39\x36\x32\x31\x37\x32\x29\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\ -\x65\x28\x34\x35\x2e\x36\x33\x38\x32\x30\x34\x29\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\x2e\x31\x37\x33\x34\x35\ -\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x36\ -\x2e\x39\x35\x39\x31\x38\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x78\x3d\x22\x31\x37\x2e\x34\x37\x36\x39\x31\x35\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x33\ -\x2e\x32\x31\x33\x38\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x2e\x32\x31\x33\x38\x39\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\ -\x74\x33\x38\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\ -\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\ -\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\ -\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\x30\ -\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\ -\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x30\x2e\x33\x37\x37\x35\x33\x39\x38\x31\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\ -\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\ -\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\ -\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\ -\x79\x70\x65\x73\x3d\x22\x61\x61\x61\x61\x61\x73\x73\x61\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x33\x35\x2d\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x33\x2e\x30\x32\ -\x34\x34\x30\x35\x2c\x31\x39\x2e\x35\x38\x34\x38\x35\x35\x20\x63\ -\x20\x2d\x31\x2e\x39\x34\x39\x31\x38\x33\x2c\x30\x2e\x32\x31\x34\ -\x39\x34\x34\x20\x2d\x33\x2e\x32\x34\x38\x39\x38\x36\x2c\x2d\x32\ -\x2e\x34\x35\x31\x39\x39\x37\x20\x2d\x34\x2e\x31\x30\x30\x35\x30\ -\x38\x2c\x2d\x34\x2e\x32\x31\x38\x34\x37\x33\x20\x2d\x30\x2e\x34\ -\x34\x37\x31\x35\x2c\x2d\x30\x2e\x39\x32\x37\x36\x30\x38\x20\x30\ -\x2e\x32\x37\x30\x35\x33\x34\x2c\x2d\x32\x2e\x32\x37\x35\x37\x38\ -\x33\x20\x2d\x30\x2e\x33\x39\x31\x37\x32\x36\x2c\x2d\x33\x2e\x30\ -\x36\x34\x33\x33\x32\x20\x2d\x30\x2e\x38\x32\x39\x38\x30\x37\x2c\ -\x2d\x30\x2e\x39\x38\x38\x30\x34\x39\x20\x2d\x33\x2e\x33\x39\x36\ -\x37\x30\x32\x2c\x30\x2e\x31\x30\x37\x39\x35\x36\x20\x2d\x33\x2e\ -\x36\x39\x37\x30\x33\x37\x2c\x2d\x31\x2e\x31\x34\x36\x38\x38\x33\ -\x20\x2d\x30\x2e\x32\x38\x37\x36\x33\x33\x2c\x2d\x31\x2e\x32\x30\ -\x31\x37\x36\x35\x36\x20\x31\x2e\x34\x32\x34\x31\x34\x34\x2c\x2d\ -\x32\x2e\x36\x30\x30\x36\x30\x36\x35\x20\x32\x2e\x36\x35\x39\x37\ -\x31\x35\x2c\x2d\x32\x2e\x35\x38\x32\x33\x37\x37\x31\x20\x31\x2e\ -\x38\x30\x31\x38\x37\x37\x2c\x30\x2e\x30\x32\x36\x35\x38\x35\x20\ -\x32\x2e\x37\x36\x30\x37\x30\x31\x2c\x32\x2e\x33\x38\x33\x31\x31\ -\x39\x31\x20\x33\x2e\x37\x36\x35\x39\x36\x36\x2c\x33\x2e\x38\x37\ -\x38\x37\x35\x31\x31\x20\x32\x2e\x32\x36\x35\x31\x33\x31\x2c\x33\ -\x2e\x33\x37\x30\x30\x35\x36\x20\x33\x2e\x35\x36\x38\x39\x35\x35\ -\x2c\x32\x2e\x30\x38\x37\x34\x37\x39\x20\x33\x2e\x37\x36\x35\x39\ -\x36\x35\x2c\x33\x2e\x38\x37\x38\x37\x35\x20\x30\x2e\x31\x33\x39\ -\x32\x35\x32\x2c\x31\x2e\x32\x36\x36\x31\x30\x35\x20\x2d\x30\x2e\ -\x37\x33\x36\x33\x31\x2c\x33\x2e\x31\x31\x34\x39\x34\x38\x20\x2d\ -\x32\x2e\x30\x30\x32\x33\x37\x34\x2c\x33\x2e\x32\x35\x34\x35\x36\ -\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x31\x63\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x30\x38\ -\x39\x32\x36\x37\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ -\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ -\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x61\x61\x61\x61\ -\x61\x73\x73\x61\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\ -\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x33\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\ -\x31\x2e\x36\x38\x38\x38\x39\x38\x2c\x32\x30\x2e\x34\x35\x38\x37\ -\x38\x20\x63\x20\x2d\x31\x2e\x39\x34\x39\x31\x38\x33\x2c\x30\x2e\ -\x32\x31\x34\x39\x34\x36\x20\x2d\x33\x2e\x32\x34\x38\x39\x38\x34\ -\x2c\x2d\x32\x2e\x34\x35\x31\x39\x39\x37\x20\x2d\x34\x2e\x31\x30\ -\x30\x35\x30\x38\x2c\x2d\x34\x2e\x32\x31\x38\x34\x37\x34\x20\x2d\ -\x30\x2e\x34\x34\x37\x31\x35\x32\x2c\x2d\x30\x2e\x39\x32\x37\x36\ -\x30\x33\x20\x30\x2e\x32\x37\x30\x35\x32\x39\x2c\x2d\x32\x2e\x32\ -\x37\x35\x37\x37\x38\x20\x2d\x30\x2e\x33\x39\x31\x37\x32\x38\x2c\ -\x2d\x33\x2e\x30\x36\x34\x33\x32\x37\x20\x2d\x30\x2e\x38\x32\x39\ -\x38\x31\x2c\x2d\x30\x2e\x39\x38\x38\x30\x34\x39\x20\x2d\x33\x2e\ -\x33\x39\x36\x37\x30\x34\x2c\x30\x2e\x31\x30\x37\x39\x35\x36\x20\ -\x2d\x33\x2e\x36\x39\x37\x30\x33\x36\x2c\x2d\x31\x2e\x31\x34\x36\ -\x38\x38\x34\x20\x2d\x30\x2e\x32\x38\x37\x36\x33\x35\x2c\x2d\x31\ -\x2e\x32\x30\x31\x37\x36\x34\x20\x31\x2e\x34\x32\x34\x31\x34\x33\ -\x2c\x2d\x32\x2e\x36\x30\x30\x36\x30\x35\x39\x20\x32\x2e\x36\x35\ -\x39\x37\x31\x35\x2c\x2d\x32\x2e\x35\x38\x32\x33\x37\x36\x37\x20\ -\x31\x2e\x38\x30\x31\x38\x37\x36\x2c\x30\x2e\x30\x32\x36\x35\x38\ -\x35\x20\x32\x2e\x37\x36\x30\x37\x30\x32\x2c\x32\x2e\x33\x38\x33\ -\x31\x31\x39\x37\x20\x33\x2e\x37\x36\x35\x39\x36\x37\x2c\x33\x2e\ -\x38\x37\x38\x37\x34\x39\x37\x20\x32\x2e\x32\x36\x35\x31\x32\x38\ -\x2c\x33\x2e\x33\x37\x30\x30\x35\x37\x20\x33\x2e\x35\x36\x38\x39\ -\x35\x33\x2c\x32\x2e\x30\x38\x37\x34\x37\x38\x20\x33\x2e\x37\x36\ -\x35\x39\x36\x36\x2c\x33\x2e\x38\x37\x38\x37\x35\x31\x20\x30\x2e\ -\x31\x33\x39\x32\x35\x2c\x31\x2e\x32\x36\x36\x31\x30\x31\x20\x2d\ -\x30\x2e\x37\x33\x36\x33\x31\x32\x2c\x33\x2e\x31\x31\x34\x39\x34\ -\x36\x20\x2d\x32\x2e\x30\x30\x32\x33\x37\x36\x2c\x33\x2e\x32\x35\ -\x34\x35\x36\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x35\x35\x64\x34\ -\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x34\x33\x31\x63\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x33\x30\x38\x39\x32\x36\x37\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ -\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x61\ -\x61\x61\x61\x61\x73\x73\x61\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ -\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ -\x33\x38\x33\x33\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x6d\x20\x31\x32\x2e\x37\x39\x39\x33\x38\x38\x2c\x31\x33\ -\x2e\x36\x37\x35\x30\x32\x34\x20\x63\x20\x31\x2e\x30\x36\x35\x33\ -\x37\x33\x2c\x2d\x30\x2e\x31\x34\x34\x32\x36\x33\x20\x32\x2e\x31\ -\x36\x33\x30\x35\x35\x2c\x30\x2e\x37\x31\x31\x36\x30\x31\x20\x32\ -\x2e\x38\x32\x32\x35\x36\x37\x2c\x31\x2e\x35\x36\x30\x36\x34\x36\ -\x20\x31\x2e\x30\x31\x38\x35\x38\x33\x2c\x31\x2e\x33\x31\x31\x33\ -\x30\x37\x20\x2d\x30\x2e\x30\x35\x31\x32\x2c\x33\x2e\x37\x39\x37\ -\x35\x36\x36\x20\x31\x2e\x32\x35\x37\x30\x35\x35\x2c\x34\x2e\x38\ -\x32\x30\x30\x37\x34\x20\x31\x2e\x31\x34\x37\x34\x30\x38\x2c\x30\ -\x2e\x38\x39\x36\x37\x39\x37\x20\x33\x2e\x37\x39\x34\x33\x33\x35\ -\x2c\x2d\x31\x2e\x32\x38\x39\x36\x31\x39\x20\x34\x2e\x33\x36\x38\ -\x36\x31\x33\x2c\x30\x2e\x30\x34\x38\x36\x36\x20\x30\x2e\x38\x35\ -\x33\x37\x32\x37\x2c\x31\x2e\x39\x38\x39\x35\x20\x2d\x32\x2e\x32\ -\x35\x37\x33\x37\x38\x2c\x34\x2e\x37\x32\x39\x34\x32\x32\x20\x2d\ -\x34\x2e\x34\x32\x32\x31\x34\x32\x2c\x34\x2e\x37\x35\x36\x38\x31\ -\x35\x20\x2d\x31\x2e\x38\x30\x31\x39\x32\x39\x2c\x30\x2e\x30\x32\ -\x32\x38\x20\x2d\x33\x2e\x39\x31\x33\x38\x39\x36\x2c\x2d\x32\x2e\ -\x30\x36\x38\x30\x33\x31\x20\x2d\x33\x2e\x37\x37\x39\x39\x35\x38\ -\x2c\x2d\x33\x2e\x38\x36\x35\x31\x31\x38\x20\x30\x2e\x37\x34\x31\ -\x30\x32\x36\x2c\x2d\x39\x2e\x39\x34\x32\x36\x33\x37\x20\x2d\x33\ -\x2e\x38\x35\x39\x39\x38\x32\x34\x2c\x2d\x32\x2e\x30\x36\x34\x38\ -\x32\x33\x20\x2d\x33\x2e\x37\x37\x39\x39\x35\x37\x32\x2c\x2d\x33\ -\x2e\x38\x36\x35\x31\x31\x37\x20\x30\x2e\x30\x36\x38\x37\x34\x38\ -\x2c\x2d\x31\x2e\x35\x34\x36\x35\x33\x37\x20\x31\x2e\x39\x30\x31\ -\x31\x31\x32\x32\x2c\x2d\x33\x2e\x32\x33\x34\x38\x37\x39\x20\x33\ -\x2e\x35\x33\x33\x38\x32\x32\x32\x2c\x2d\x33\x2e\x34\x35\x35\x39\ -\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x30\x38\ -\x39\x32\x36\x37\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ -\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ -\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x61\x61\x61\x61\ -\x61\x73\x73\x61\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\ -\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x33\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\ -\x34\x2e\x39\x31\x38\x32\x30\x39\x2c\x31\x32\x2e\x31\x35\x34\x31\ -\x32\x35\x20\x63\x20\x31\x2e\x30\x36\x35\x33\x37\x34\x2c\x2d\x30\ -\x2e\x31\x34\x34\x32\x35\x39\x20\x32\x2e\x31\x36\x33\x30\x35\x33\ -\x2c\x30\x2e\x37\x31\x31\x36\x30\x32\x20\x32\x2e\x38\x32\x32\x35\ -\x36\x34\x2c\x31\x2e\x35\x36\x30\x36\x34\x36\x20\x31\x2e\x30\x31\ -\x38\x35\x38\x35\x2c\x31\x2e\x33\x31\x31\x33\x30\x36\x20\x2d\x30\ -\x2e\x30\x35\x31\x32\x2c\x33\x2e\x37\x39\x37\x35\x36\x37\x20\x31\ -\x2e\x32\x35\x37\x30\x35\x37\x2c\x34\x2e\x38\x32\x30\x30\x37\x34\ -\x20\x31\x2e\x31\x34\x37\x34\x30\x39\x2c\x30\x2e\x38\x39\x36\x37\ -\x39\x38\x20\x33\x2e\x37\x39\x34\x33\x33\x36\x2c\x2d\x31\x2e\x32\ -\x38\x39\x36\x31\x38\x20\x34\x2e\x33\x36\x38\x36\x31\x34\x2c\x30\ -\x2e\x30\x34\x38\x36\x36\x20\x30\x2e\x38\x35\x33\x37\x32\x37\x2c\ -\x31\x2e\x39\x38\x39\x34\x39\x39\x20\x2d\x32\x2e\x32\x35\x37\x33\ -\x37\x38\x2c\x34\x2e\x37\x32\x39\x34\x31\x39\x20\x2d\x34\x2e\x34\ -\x32\x32\x31\x34\x31\x2c\x34\x2e\x37\x35\x36\x38\x31\x31\x20\x2d\ -\x31\x2e\x38\x30\x31\x39\x33\x2c\x30\x2e\x30\x32\x32\x37\x39\x20\ -\x2d\x33\x2e\x39\x31\x33\x38\x39\x34\x2c\x2d\x32\x2e\x30\x36\x38\ -\x30\x32\x39\x20\x2d\x33\x2e\x37\x37\x39\x39\x36\x2c\x2d\x33\x2e\ -\x38\x36\x35\x31\x31\x38\x20\x30\x2e\x37\x34\x31\x30\x32\x37\x2c\ -\x2d\x39\x2e\x39\x34\x32\x36\x33\x35\x32\x20\x2d\x33\x2e\x38\x35\ -\x39\x39\x38\x32\x2c\x2d\x32\x2e\x30\x36\x34\x38\x32\x31\x20\x2d\ -\x33\x2e\x37\x37\x39\x39\x35\x36\x2c\x2d\x33\x2e\x38\x36\x35\x31\ -\x31\x37\x20\x30\x2e\x30\x36\x38\x37\x35\x2c\x2d\x31\x2e\x35\x34\ -\x36\x35\x33\x35\x20\x31\x2e\x39\x30\x31\x31\x31\x32\x2c\x2d\x33\ -\x2e\x32\x33\x34\x38\x37\x38\x20\x33\x2e\x35\x33\x33\x38\x32\x32\ -\x2c\x2d\x33\x2e\x34\x35\x35\x39\x36\x31\x20\x7a\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x32\x31\x34\x34\x37\x38\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x30\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x30\x2e\x33\x30\x38\x39\x32\x36\x37\x39\x70\x78\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ -\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x66\x33\x66\x33\x66\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\ -\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x31\x2e\x33\x36\x36\x30\x30\x30\x30\x36\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ -\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x70\x61\x69\x6e\x74\x2d\x6f\ -\x72\x64\x65\x72\x3a\x6e\x6f\x72\x6d\x61\x6c\x22\x0a\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x6d\x20\x31\x35\x2e\x32\x30\x34\x39\x37\x35\ -\x2c\x38\x2e\x37\x39\x36\x32\x31\x31\x20\x76\x20\x33\x2e\x33\x35\ -\x37\x34\x32\x32\x20\x33\x2e\x33\x35\x39\x33\x37\x35\x20\x48\x20\ -\x31\x31\x2e\x33\x32\x34\x31\x31\x36\x20\x37\x2e\x34\x34\x33\x32\ -\x35\x36\x39\x20\x76\x20\x33\x2e\x33\x35\x37\x34\x32\x32\x20\x68\ -\x20\x33\x2e\x38\x38\x30\x38\x35\x39\x31\x20\x33\x2e\x38\x38\x30\ -\x38\x35\x39\x20\x76\x20\x33\x2e\x33\x35\x37\x34\x32\x32\x20\x33\ -\x2e\x33\x35\x39\x33\x37\x35\x20\x68\x20\x33\x2e\x38\x38\x32\x38\ -\x31\x33\x20\x56\x20\x32\x32\x2e\x32\x32\x37\x38\x35\x32\x20\x31\ -\x38\x2e\x38\x37\x30\x34\x33\x20\x68\x20\x33\x2e\x38\x38\x30\x38\ -\x35\x39\x20\x33\x2e\x38\x38\x30\x38\x35\x39\x20\x56\x20\x31\x35\ -\x2e\x35\x31\x33\x30\x30\x38\x20\x48\x20\x32\x32\x2e\x39\x36\x38\ -\x36\x34\x37\x20\x31\x39\x2e\x30\x38\x37\x37\x38\x38\x20\x56\x20\ -\x31\x32\x2e\x31\x35\x33\x36\x33\x33\x20\x38\x2e\x37\x39\x36\x32\ -\x31\x31\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ -\x65\x63\x74\x38\x38\x38\x2d\x36\x31\x2d\x36\x2d\x39\x2d\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ -\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x05\xc8\ -\x00\ -\x00\x1d\xbe\x78\x9c\xdd\x58\xdd\x93\x9b\x36\x10\x7f\xbf\xbf\x42\ -\x25\x2f\xed\xd4\x7c\x08\xb0\xf9\x88\xed\x3c\x24\xd3\x49\x66\xda\ -\x97\x36\x6d\x1f\x33\x18\x64\x9b\x06\x10\x15\xe2\x6c\xe7\xaf\xef\ -\x0a\x90\x00\x1b\xcf\x38\xbd\x4b\x72\x17\x66\x6e\x4e\xda\x5d\x49\ -\xbb\x3f\xed\x97\xb5\x7c\x75\xcc\x33\x74\x4f\x58\x95\xd2\x62\xa5\ -\x61\xc3\xd2\x10\x29\x62\x9a\xa4\xc5\x6e\xa5\xfd\xf9\xfe\x17\xdd\ -\xd7\x50\xc5\xa3\x22\x89\x32\x5a\x90\x95\x56\x50\xed\xd5\xfa\x6e\ -\xf9\x83\xae\xa3\xd7\x8c\x44\x9c\x24\xe8\x90\xf2\x3d\x7a\x57\x7c\ -\xac\xe2\xa8\x24\xe8\xc7\x3d\xe7\x65\x68\x9a\x87\xc3\xc1\x48\x3b\ -\xa2\x41\xd9\xce\xfc\x09\xe9\xfa\xfa\xee\x6e\x59\xdd\xef\xee\x10\ -\x42\x70\x6e\x51\x85\x49\xbc\xd2\xba\x05\x65\xcd\xb2\x46\x30\x89\ -\x4d\x92\x91\x9c\x14\xbc\x32\xb1\x81\x4d\xad\x17\x8f\x7b\xf1\x58\ -\x9c\x9e\xde\x93\x98\xe6\x39\x2d\xaa\x66\x65\x51\xbd\x18\x08\xb3\ -\x64\xab\xa4\x85\x36\x07\xa7\x11\xc2\x41\x10\x98\x96\x6d\xda\xb6\ -\x0e\x12\x7a\x75\x2a\x78\x74\xd4\xc7\x4b\x41\xc7\xa9\xa5\xb6\x65\ -\x59\x26\xf0\x7a\xc9\xdb\xa4\xc2\x0a\x00\x2d\xe1\x4f\x89\x4b\x82\ -\x51\xd1\x9a\xc5\x64\x0b\xeb\x88\x51\x10\x6e\xbe\x79\xff\x46\x31\ -\x75\xcb\x48\x78\x32\xd8\x46\xe2\x39\x3a\x75\x04\x72\x11\xe5\xa4\ -\x2a\xa3\x98\x54\xa6\xa4\x37\xeb\x0f\x69\xc2\xf7\x2b\xcd\x71\x0d\ -\xec\xc0\x37\x6f\x88\x7b\x92\xee\xf6\xfc\x9c\x9a\x26\x2b\x0d\xb4\ -\xb7\x03\xbf\x9d\x0f\x9c\x03\xb7\x02\xdd\xc6\xa1\xe2\x58\x46\x60\ -\x1b\x18\x31\x3c\x77\xbc\x56\x46\x9a\x10\x26\x34\x16\x3a\xc1\x96\ -\x24\x4f\xa3\x9a\xd3\x1c\x6e\x2d\x8e\xb3\xa8\xaa\xd2\x6d\x1a\xc3\ -\x84\x16\x65\x56\xef\xd2\xe2\x43\x02\xb7\xce\xc9\x87\x2a\xdd\x15\ -\x11\xaf\x19\x31\x24\x86\xea\x40\x72\x2c\x29\xe3\xfa\x31\x29\x01\ -\xc9\x85\x37\xc9\x3c\x49\xe6\x1a\xb8\xcb\x84\x6c\x2b\x21\xd5\x9a\ -\x25\x66\x60\x97\xa7\x21\xb3\xe1\x2a\x2d\x85\x8a\xc9\x7d\x4a\x0e\ -\xbd\xec\x26\xaa\x5a\xe8\x10\x2a\xa3\x1d\xb8\x59\x46\xd9\x4a\x7b\ -\xb1\x6d\xbe\x8e\xb1\xa1\x2c\x21\x4c\xb2\x16\xcd\x37\x62\x51\xb8\ -\x8a\x94\x9f\xda\xc0\xea\xf6\x96\xfa\x8a\x5d\x15\xdf\x9a\xe6\x57\ -\xfb\x28\xa1\x87\x95\x66\x9f\x33\x3f\x51\x9a\xaf\x34\xcf\x08\xb0\ -\x6f\xb9\xd8\x3b\x67\xc7\x47\xb1\xa5\xeb\x5a\x9e\x6d\x63\x7c\xc1\ -\x85\x03\x6d\xdb\x58\xe0\x85\xe5\x5e\xf0\x6a\xc6\x20\xf2\xf4\x2c\ -\x3a\x11\x30\xaa\xf9\x27\x37\xa8\xf6\xf4\xb0\x63\x02\x1c\xce\x6a\ -\x72\xbe\x52\x70\xf4\xcd\x86\x1e\xa7\xd9\xe0\x08\xb5\x88\x69\xbd\ -\x2e\x52\x0e\x71\x53\x1e\x87\xbb\xd6\x69\x42\xaa\xe9\x85\x87\xb4\ -\x00\x0c\xf4\xce\x83\xb1\xa3\x20\x3e\x97\x90\xee\xec\x59\xfe\x15\ -\x09\x81\xca\x15\xd6\xe9\x3a\x2b\x8f\x8e\x69\x9e\x7e\x22\x60\xf7\ -\x05\x94\x55\x11\x95\xfa\x2e\xa3\x9b\x28\xeb\xb4\x5f\x37\x12\xcb\ -\x11\x2c\xed\x22\x84\xf8\x49\xc4\xee\xf1\x24\x68\x9a\x24\x0a\x3c\ -\x05\xc1\xf1\x16\x73\x45\xa4\x2c\x85\x90\x18\xe8\x2b\x49\xa7\x21\ -\x49\x44\x3a\x24\xea\x63\xe3\x5f\x8d\xf7\x79\xe7\xbc\xd3\x90\xd7\ -\xb9\xbd\x79\xe9\xf7\x0d\x3d\x27\x3c\x4a\x22\x1e\xf5\x41\x20\x29\ -\x76\x10\x58\xd2\x32\x48\x9a\xe1\xef\x6f\x7e\x59\x77\x07\x2d\xe3\ -\x38\xfc\x9b\xb2\x8f\xf2\x5c\x84\x84\x40\xb4\xa1\x35\x5c\x85\xb6\ -\x56\xe4\x65\x12\x87\x90\xe6\x20\xfc\xd7\x69\x0e\xae\x2d\x32\xe4\ -\xcf\x90\xd6\x96\x66\xcf\x18\x09\x0b\xb0\xfa\x4d\xdb\x6d\x19\x69\ -\xf3\xe5\x64\xd1\x48\xe2\x3c\x15\x8b\xcc\x3f\x78\x9a\x65\xef\xc4\ -\x21\x9d\xc5\x83\x4d\x53\x9e\x91\x9e\xb8\x34\x3b\xed\x3b\xdb\xcc\ -\x81\x71\x4b\x53\x5a\xdf\xcc\x76\x3d\x2a\xa3\xa0\x50\x17\x9d\x45\ -\x1b\x02\x4e\xf0\xab\x60\xa2\x0b\xee\x8e\xd1\xba\xcc\x69\x42\xba\ -\xe5\x0a\x4d\x12\x73\x75\x65\xfc\x94\x01\x7f\x0b\xda\x87\x5d\xa2\ -\x79\x29\x26\x7a\x97\x26\x42\xdc\x4e\x59\x9d\x41\xba\xbb\x27\x05\ -\x4d\x92\x97\x15\x67\xf4\x23\x09\x5f\x58\x96\xeb\x5b\x56\x37\x6d\ -\xa3\x25\x54\xd3\x2c\x2d\x08\xa8\x11\x56\xff\xd6\x11\x23\x43\xea\ -\x3f\x34\x2d\x42\xc0\x8d\x30\x49\x6d\x26\x19\x78\x3c\x0f\x5d\x49\ -\x4b\x22\xc8\x44\x8c\x45\xa7\xb0\x80\x2e\x60\x48\xa5\xdb\x6d\x45\ -\x78\x7f\x92\x54\xd5\x32\x9c\xee\x1b\x39\xba\x30\xd7\x09\x02\xac\ -\x88\x93\x85\x49\x7c\xd3\xc5\x49\x7c\xa3\xa8\x00\xff\x0e\x0c\xd7\ -\x73\x02\xcb\x59\x10\x1d\x2f\x14\x83\x8d\xc4\x18\xc8\x39\x86\x03\ -\x05\x6a\x11\xf8\xca\x2b\x96\x65\xc4\xf7\x53\xe8\x0f\xac\x14\xc8\ -\x8a\x6f\x8c\xac\xdd\x2a\xe5\xb8\xee\x39\xc4\x9b\x9a\xf3\xc7\x02\ -\x58\xdd\xbb\xb2\x03\x20\xfc\x0d\x59\x33\x0b\xfd\x85\x24\x30\x63\ -\x80\x85\x45\x10\xad\x3d\x0e\x7d\x66\xa7\x05\x68\xc8\x29\xd3\x21\ -\xc7\xdf\x37\x15\x76\x94\x4b\x54\x4e\x00\x27\x15\x61\x04\xe9\x38\ -\x8e\x9f\x3b\x54\x0a\xa4\x99\x1a\xa1\xb7\xc8\x9a\x82\xcc\x7f\x3a\ -\x90\x61\x03\x6e\xd0\xb2\xe7\x7e\x79\xfc\x7c\xcc\xae\x20\xa1\xaa\ -\xc0\xcc\xf6\x0d\x1f\xbd\x46\x8e\x61\xb7\xc3\x8b\xc1\x05\x3a\x8e\ -\xe7\xd9\xba\x75\x33\x3e\x8f\xe2\x33\xd8\x9b\xbb\x78\x3e\x7f\x34\ -\x04\x72\x34\x97\x29\x69\xe6\xcc\x0d\x1b\xc5\x10\x47\xba\x6b\xd8\ -\x0d\x28\xd7\xc6\x97\x50\xf8\xee\x97\x03\xc2\x27\x97\x9e\xd0\xdd\ -\x9a\xfd\x45\x5c\x01\x3b\x86\xdf\xda\xdc\x19\x2c\x68\x36\xb8\x02\ -\xb6\x8c\x6e\xaa\x18\x08\x2f\x66\xe0\x21\x28\x53\x40\xce\x02\x63\ -\x21\x27\xee\x4c\xc6\x39\xf2\x0c\xb7\x59\x31\x53\x80\xfa\xc6\xbc\ -\x95\x81\xf5\x17\x88\xba\x96\xe3\x7d\x45\x44\xe1\xea\x1b\xad\x02\ -\xe7\x6b\xa4\xa3\x89\x32\xf8\x44\xaf\x40\x77\x3e\x3b\xff\x29\x39\ -\xce\xa2\xa2\x12\x3d\x9c\x1e\x43\x87\x4f\x98\xde\x74\xa4\x13\x35\ -\xe8\x42\x10\xca\xb2\x7e\xde\x9f\x3e\xb9\xc4\xd1\xdf\xc4\x03\x13\ -\x87\x7e\x7b\x8d\x79\xa2\x50\xd8\x58\x3a\xde\x43\xa1\x08\x9e\x3d\ -\x14\x8b\xc7\xf2\x8a\x67\x5f\x59\x1d\xfb\xc1\x18\xdc\x9e\x7d\x9e\ -\x28\x06\x22\x35\x3f\x10\x83\xdb\x9b\xf6\xa7\xd8\x62\xe6\xc3\x16\ -\xd3\x69\x0b\x90\x07\x70\xc8\xa2\xe4\xc0\xaf\x96\x2b\xe3\x2b\x0d\ -\xa7\x6e\x7f\x37\x80\x60\x5f\x96\xe6\x07\x01\x82\x9f\x35\x20\xa3\ -\xb6\xc7\x56\x3f\x42\x9a\xe1\xc5\xe0\x1a\x04\x5f\x33\x51\x7c\x59\ -\x9f\x90\x4d\xda\x03\x83\xc4\xfd\x6e\x00\x51\xc6\x3e\x0c\x90\xff\ -\xd1\x59\x4c\xbc\xc2\x8d\xdf\xdc\xc4\x7b\x5c\x03\xc7\xcd\xef\x71\ -\xdd\xfb\xdd\x19\x7c\x8b\x16\x55\xfb\xdb\x3d\xcc\xe1\x11\x6c\xcd\ -\x7b\x9c\x85\x7b\x2c\xbb\xf7\x38\xd9\xe7\xf5\xce\x25\xdf\xe3\x2e\ -\x39\xa2\xd9\x97\x1d\xf2\xf0\x5d\x6e\x14\xc5\xe2\x01\xce\x85\x9b\ -\x76\xdc\xc0\x76\x3e\xd3\x13\xa7\xa0\x74\x8d\x39\x5e\x78\xf3\xe0\ -\x5b\x3c\x2a\x09\xc3\x06\x25\xee\x2d\xb2\x83\xee\x37\xdc\x84\x4b\ -\xfa\xb7\x17\xb1\x9b\xde\x95\x96\xe6\x6e\x7d\xb7\x14\xaf\xe7\xeb\ -\xbb\xff\x00\x73\x77\xb5\x26\ -\x00\x00\x0a\x5a\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6e\x65\x77\x5f\x66\ -\x69\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ -\x3d\x22\x2d\x34\x36\x2e\x36\x38\x35\x31\x38\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ -\x36\x2e\x31\x38\x33\x33\x38\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ -\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ -\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ -\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x66\x32\x66\x32\x66\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x31\x2e\x33\x30\x36\x33\x39\x34\x35\x38\x70\ -\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ -\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x33\x33\x33\x33\ -\x33\x33\x33\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\x48\x20\ -\x33\x32\x20\x56\x20\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x48\ -\x20\x35\x2e\x33\x33\x33\x33\x33\x33\x33\x20\x5a\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\ -\x38\x2d\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ -\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\ -\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\ -\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\ -\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\ -\x3a\x23\x66\x66\x66\x66\x31\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x63\x36\x62\x36\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x30\x39\x30\x39\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\ -\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\ -\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\ -\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x32\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x36\x2e\x36\x36\ -\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\ -\x22\x31\x31\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x39\x38\x31\x38\x31\x38\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x34\ -\x30\x30\x30\x30\x30\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ -\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0e\x79\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x73\x6d\x5f\x61\ -\x64\x64\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ -\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ -\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\ -\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ -\x22\x2d\x37\x32\x2e\x39\x38\x31\x36\x37\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x34\ -\x37\x2e\x30\x36\x32\x39\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ -\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ -\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ -\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ -\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ -\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ -\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ -\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ -\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ -\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ -\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x36\x30\x30\ -\x38\x39\x32\x34\x31\x2c\x30\x2e\x37\x39\x39\x33\x32\x39\x39\x31\ -\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x39\x2e\x38\x39\x33\x32\x36\x35\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x36\x31\x36\x38\x33\x38\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x31\x34\ -\x2e\x36\x37\x38\x39\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x31\x2e\x38\x34\x36\x31\x39\x30\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x35\x2e\ -\x33\x38\x38\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x35\x35\x2e\x35\x31\x36\x38\x34\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x36\x65\x36\x65\x36\ -\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ -\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\ -\x34\x30\x33\x30\x37\x30\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x63\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x36\ -\x39\x35\x32\x36\x35\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x32\x37\x2e\x31\x37\x34\x30\x34\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x33\x35\x2e\x34\x31\x31\x33\x37\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x31\x33\x2e\x36\x37\x32\x34\x38\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x35\x34\x30\x36\ -\x39\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\ -\x33\x2e\x32\x33\x38\x37\x36\x39\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x79\x3d\x22\x35\x2e\x33\x35\x37\x37\x36\x34\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ -\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\ -\x2e\x35\x34\x33\x31\x30\x33\x31\x33\x2c\x30\x2e\x38\x33\x39\x36\ -\x36\x36\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\ -\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ -\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\ -\x32\x2e\x38\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\ -\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\ -\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\ -\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\ -\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\ -\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\x64\x27\x3b\x6c\x65\x74\x74\ -\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\ -\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\ -\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\ -\x31\x2e\x34\x33\x30\x32\x31\x38\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x32\x33\x2e\x34\x38\x31\x39\x39\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\ -\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\ -\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\x39\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\ -\x2e\x34\x33\x30\x32\x31\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x32\x33\x2e\x34\x38\x31\x39\x39\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\ -\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\ -\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x73\x69\x7a\x65\x3a\x31\x34\x2e\x36\x36\x36\x36\x36\x36\x39\ -\x38\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\ -\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ -\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\ -\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x27\x73\x61\x6e\x73\x2d\x73\ -\x65\x72\x69\x66\x2c\x20\x42\x6f\x6c\x64\x27\x3b\x66\x6f\x6e\x74\ -\x2d\x76\x61\x72\x69\x61\x6e\x74\x2d\x6c\x69\x67\x61\x74\x75\x72\ -\x65\x73\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\ -\x61\x72\x69\x61\x6e\x74\x2d\x63\x61\x70\x73\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x2d\ -\x6e\x75\x6d\x65\x72\x69\x63\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ -\x6f\x6e\x74\x2d\x66\x65\x61\x74\x75\x72\x65\x2d\x73\x65\x74\x74\ -\x69\x6e\x67\x73\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\ -\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x77\x72\x69\ -\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\ -\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ -\x74\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x32\x22\x3e\x4f\x53\x4d\x3c\x2f\x74\x73\x70\x61\ -\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ -\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x07\xf6\ -\x00\ -\x00\x1f\x0c\x78\x9c\xdd\x59\x59\x6f\xe3\x46\x12\x7e\xf7\xaf\xe0\ -\xd2\x0f\x49\xb0\x26\xd9\xf7\xc1\x91\x14\x20\x3b\x18\x20\xc0\xe6\ -\x25\x9b\xc5\x3e\x06\x14\xd9\x92\xb9\x43\x91\x02\xd9\xb2\xa4\xf9\ -\xf5\xa9\xe6\xa9\xcb\xce\x6c\xe2\x9d\x99\x8c\x60\xc3\x66\x1d\xdd\ -\x55\x5f\x7d\x5d\xdd\x6c\xcd\xbe\x3f\x6c\x0a\xef\xc9\xd4\x4d\x5e\ -\x95\x73\x1f\x87\xc8\xf7\x4c\x99\x56\x59\x5e\xae\xe7\xfe\xbf\x7f\ -\x79\x17\x28\xdf\x6b\x6c\x52\x66\x49\x51\x95\x66\xee\x97\x95\xff\ -\xfd\xe2\x6e\xf6\xb7\x20\xf0\xfe\x51\x9b\xc4\x9a\xcc\xdb\xe7\xf6\ -\xd1\xfb\xb1\x7c\xdf\xa4\xc9\xd6\x78\xdf\x3e\x5a\xbb\x8d\xa3\x68\ -\xbf\xdf\x87\x79\x2f\x0c\xab\x7a\x1d\x7d\xe7\x05\xc1\xe2\xee\x6e\ -\xd6\x3c\xad\xef\x3c\xcf\x83\x79\xcb\x26\xce\xd2\xb9\xdf\x3b\x6c\ -\x77\x75\xd1\x1a\x66\x69\x64\x0a\xb3\x31\xa5\x6d\x22\x1c\xe2\xc8\ -\x9f\xcc\xd3\xc9\x3c\x75\xb3\xe7\x4f\x26\xad\x36\x9b\xaa\x6c\x5a\ -\xcf\xb2\xb9\x3f\x31\xae\xb3\xd5\x68\xed\xa2\xd9\xd3\xd6\x08\x6b\ -\xad\x23\x44\x22\x42\x02\xb0\x08\x9a\x63\x69\x93\x43\x70\xee\x0a\ -\x31\xde\x72\x25\x08\xa1\x08\x74\x93\xe5\xc7\x59\xc5\x0d\x00\xba\ -\x85\xdf\xd1\x7c\x10\x84\x4d\xb5\xab\x53\xb3\x02\x3f\x13\x96\xc6\ -\x46\x6f\x7f\x79\x3b\x2a\x03\x14\x66\x36\x3b\x19\x66\xc0\xf3\x6c\ -\xd6\x33\x90\xcb\x64\x63\x9a\x6d\x92\x9a\x26\x1a\xe4\xad\xff\x3e\ -\xcf\xec\xe3\xdc\xa7\x2c\xc4\x14\x3e\xbc\x15\x3e\x9a\x7c\xfd\x68\ -\x2f\xa5\x79\x36\xf7\x21\x7a\xa2\x55\xf7\x7c\x42\x0e\xdc\x19\xf4\ -\x03\xc7\xa3\x06\x85\x9a\x84\xd8\xab\x31\xa7\xb2\xb3\x19\x52\x88\ -\xb3\x2a\x75\x31\xc1\x90\x66\x93\x27\x3b\x5b\x6d\xa0\x6a\x69\x5a\ -\x24\x4d\x93\xaf\xf2\x14\x1e\xaa\x72\x5b\xec\xd6\x79\xf9\x6b\x0d\ -\x2c\xab\x36\xbf\x02\x16\xa6\xb1\xe1\x00\xe0\x38\x9b\x39\x6c\xab\ -\xda\x06\x87\x6c\x0b\x30\x0a\x79\x53\x79\x3c\x55\x3e\xe5\x66\xff\ -\x43\x75\x80\xf0\x3c\xe4\x51\x02\x3f\xfe\x02\xe4\xb3\xcc\xac\x1a\ -\xa7\xef\x52\x75\x4f\x90\xab\xf4\xbd\xa8\xd5\x8e\x91\xbb\xb0\x33\ -\x37\xc6\x64\xbb\x4c\x9a\x0e\x4e\xcf\xdb\x26\x6b\xa0\x5e\x51\xd5\ -\x73\xff\x7e\xd5\x7e\x7a\xc5\xb2\xaa\x33\x53\x0f\x2a\xd1\x7e\xce\ -\x54\x15\x94\x27\xb7\xc7\x6e\xb1\xf5\x63\x0f\x69\xb8\x51\x47\x3d\ -\xba\xad\x6f\x1e\x93\xac\xda\xcf\x7d\x72\xa9\xfc\x50\x55\x9b\xb9\ -\x2f\x43\x8d\x15\x62\x58\x5e\xaa\x53\x40\x22\x20\x24\x54\x18\x51\ -\xc6\xae\xb4\x2e\x20\x1e\x12\x2a\xa5\xbc\x1a\x39\xdd\xd5\x35\x2c\ -\xc7\xa0\x48\x8e\x06\xb2\x6a\xff\xe0\xde\xa8\x79\xac\xf6\xeb\xda\ -\xa1\xb3\x4a\x8a\x11\x9e\xd1\xd5\xa9\x82\xe5\xd2\x95\xc1\xd6\xbb\ -\x2b\x35\xd0\x63\xe7\x56\x7a\xb0\x2b\x73\x0b\xab\x69\x7b\x38\x1d\ -\x76\x97\x67\xa6\xb9\xed\xb8\xcf\x81\x2c\xfb\xa0\xe7\x35\xa6\x23\ -\xc8\x97\x16\x03\xc9\x25\x52\xcf\x58\x38\x86\x3c\xa3\x3a\x3e\xaf\ -\xda\x24\x87\x7c\x93\x7f\x30\x90\x38\xbe\x34\x69\xca\x64\x1b\xac\ -\x8b\x6a\x99\x14\x7d\xf4\x8b\xd6\x62\x76\x06\x4b\xe7\xe4\x79\xf6\ -\xe8\x56\xf4\xe1\xe8\x64\xfe\x20\x74\x80\x3a\x01\x95\x82\x8f\xc2\ -\xaa\xce\x61\xa1\x9c\xc4\x3b\x88\x8e\xa7\x22\xb7\xfe\xa1\x7d\x1f\ -\xa6\xc0\x46\x99\x2b\xf2\x40\xf4\xe8\x9a\xe9\xad\x7c\x63\x6c\x92\ -\x25\x36\x99\x68\x3f\x48\x88\xd6\x68\xc8\x04\x5a\x67\xfc\xf3\xdb\ -\x77\x8b\x7e\x82\x59\x9a\xc6\xff\xa9\xea\xf7\xc3\x7c\x9e\xe7\x0c\ -\x92\x65\xb5\x03\xe8\xfd\xc5\x28\x9e\x65\x69\x0c\x0b\x1c\x9a\xc0\ -\x22\xdf\x00\x99\x5d\x9f\xfc\x3b\x34\xb7\x59\x34\x29\xce\x8c\x1d\ -\x38\xd3\xa0\xdd\xb0\xd0\x1f\xda\xae\x79\x73\xeb\xc8\xd2\x4d\xee\ -\x9c\xa2\x7f\xd9\xbc\x28\x7e\x74\x93\xf4\x19\x9f\x0c\x9a\xdb\xc2\ -\x4c\xc2\x59\xd4\x47\xdf\xe7\x16\x9d\x24\x37\x8b\x86\xec\xdb\xa7\ -\xf5\x84\xca\xd9\x2a\x18\x0b\x5b\x24\x4b\x03\x45\xff\xa7\x53\x7a\ -\x57\xda\x75\x5d\xed\xb6\x9b\x2a\x33\xbd\xfb\x88\xa6\x49\xed\x58\ -\x2a\x7b\x2c\x40\xbf\x82\xe8\xe3\xfb\x8c\xb9\xd6\xf2\xc6\x3d\x04\ -\x7d\x63\x88\xf1\x9b\xc6\xd6\xd5\x7b\x13\x43\xe3\x91\x5a\x98\xfe\ -\xb1\x5b\x0b\x31\x0d\x05\x17\x84\x0f\x42\x00\xc3\xd4\x05\x30\xd5\ -\xc6\x6c\x90\x65\x09\xf4\x90\xba\x4e\x8e\x71\x09\x7b\xfa\x20\x1d\ -\x87\x3f\xe3\xa0\x8b\x8c\x71\x41\x47\x61\xbf\xe2\x38\x0a\x85\xe4\ -\x0c\xb1\x51\x31\x2c\x34\xac\x42\xae\x94\x92\x13\x6d\x5d\xe3\x51\ -\x21\x16\x5a\x50\xaa\x47\xe9\xd1\xf5\x2a\x84\x25\x73\x1b\xcd\x50\ -\x8c\xd9\x36\xb1\x8f\xe3\xfc\x63\xff\xa9\xca\x12\xe2\xa8\xea\x00\ -\x3a\xd1\x53\x62\x77\xb5\x39\x25\xbc\x8b\xd3\xf9\x41\x9c\x53\xf0\ -\x8e\xb7\x1e\x26\x21\x82\x28\xc9\x03\x0b\x09\x16\x9c\x62\xe9\x61\ -\x1c\x2a\xd8\xa5\x94\x7e\x80\xfe\xaa\x30\x99\x02\x3a\x03\x1e\xa1\ -\x16\xf8\x97\x90\x96\xa1\xc0\x18\x13\xc1\xc8\x20\x2f\x72\x08\x33\ -\xd9\xc6\xcb\x9d\xb5\xa7\xb2\xff\x56\x79\x19\xb7\x95\xf8\x33\x65\ -\xb9\x89\xd1\x4b\x41\x23\x94\xe0\x44\x7e\xde\xa0\xcf\xca\x41\x28\ -\x6c\x4e\x44\x20\xed\xea\xa1\xa5\x22\x2f\xd6\x63\x2a\x2b\xd1\x01\ -\xf1\x3f\x96\x15\xaf\x44\x25\xac\x02\x79\x1a\xfd\x4f\x1e\x82\xdd\ -\x51\x11\xa2\xa9\xa3\x13\xa6\x9c\x30\x17\xfe\x15\xc3\x6e\xf3\x69\ -\xb5\x5a\xca\x25\x7f\x76\x21\x8b\xd4\x88\xe4\x0b\xa4\xd7\x1f\xc1\ -\xed\x62\x09\xe2\x90\x13\x38\x17\xea\x07\xa2\x42\x89\xb4\x40\x74\ -\xa8\xb9\xc6\xbf\xbf\x06\x11\x1a\x41\x62\xe9\xc9\xe3\x97\x04\xd2\ -\x45\xa1\xe1\xf8\x3f\x05\xcd\x09\xac\x48\xf2\x65\xad\x41\x0a\xfb\ -\x83\x6c\xcb\xa1\x91\xd2\x6c\x2c\xc7\x8b\x2b\xf0\xcf\xad\xbf\x53\ -\x88\x4e\x82\x8c\xef\x0d\xfa\xfc\x45\x3d\xc3\x07\x5e\xba\x28\xc6\ -\xee\x90\xec\x10\x12\x44\xc1\xd3\xd4\xa4\xe8\xb3\x18\x01\xc3\x5f\ -\x11\xa3\x7b\x47\x22\x35\xd1\xc8\x3d\x2e\x2f\x68\x04\x3b\x30\x65\ -\x14\x5a\xce\x27\x47\xc9\xf5\x42\xa5\xa8\x56\x8c\x2b\x07\x08\x87\ -\xb6\xc8\x18\xf6\x28\x0f\x11\x44\xc4\x39\x08\x29\x55\x90\x01\xc5\ -\xd7\x40\x29\xfc\xc9\x81\xd2\x14\x8e\x19\x5a\xb3\xed\xe1\x7f\xc7\ -\xea\x19\x9e\x60\x19\x2a\x21\x28\xc7\x0f\x81\x0e\xa5\xa2\x80\x81\ -\x97\x02\x2e\x88\x48\xe9\xfa\x1a\x41\x50\x1d\xac\x9d\x44\x62\xc6\ -\x40\xc2\x80\xd4\x5c\x39\x01\xc0\x02\xcf\x02\x6b\x04\xef\x5b\x4e\ -\x80\x19\x72\xcc\x22\x1c\xc1\xdb\x17\x71\x1c\x44\x08\xf6\x14\x14\ -\x72\xb0\xc0\xbd\x40\x38\x81\xe4\x94\x49\x84\x3b\x49\x3b\x91\x12\ -\x1c\xba\x6a\x67\x83\x19\x8c\x8c\x43\x49\x11\x8c\xad\x5a\x11\xc1\ -\x8c\x3f\x90\x90\x6b\x4e\xc0\xb2\xb3\x82\xc2\x81\x88\x3a\x44\x3a\ -\x3f\xaa\x85\x82\x1d\x0c\x28\xac\x54\x67\x03\xf6\xf8\x41\x86\x18\ -\x24\x44\xf6\xf3\xbb\xe9\x09\xe7\x82\x75\xd3\x63\x50\xc2\x64\xd0\ -\xf2\x31\x51\xac\x13\x29\x18\x17\x4b\x21\x34\x16\x9d\x13\x76\x04\ -\x21\x84\x12\x98\xbe\x93\x50\xe9\xb0\x60\x10\x35\xe9\x9c\x50\xcb\ -\x17\xf0\x91\xad\x0d\x84\x61\x02\xd6\xd2\x8a\x03\x55\x3c\x80\x57\ -\x88\x4e\x02\x00\x8a\xc1\x09\xb7\x02\x21\x19\xd5\xa4\x75\xc2\x67\ -\x5e\x2e\x73\xd2\x22\x06\x87\x0c\x45\x18\xbd\xf4\x52\x5d\x12\x1c\ -\x43\x2b\x84\x7f\x30\x52\x10\x64\x17\x22\x17\x4a\x39\x19\x08\x80\ -\x38\x1d\x42\x8a\xc3\xb6\xef\x7a\x03\xd3\x0c\x9c\xae\x58\xad\xd8\ -\x5f\x9f\xd4\x3f\x79\xc0\x64\x06\xa8\x69\xf2\xc0\x43\xcc\xb4\x84\ -\x09\x3c\x22\x9d\x10\x61\x0e\x32\x77\x29\x24\x94\xb8\xce\x9e\xd3\ -\xbf\x7c\xf6\x1b\xc8\x5e\x28\x26\x05\x2c\x56\x38\xd5\x41\xfa\x9c\ -\x72\xc7\x23\x2e\x15\x50\x44\x84\x30\x9b\xbc\x95\xba\xfc\x0a\x52\ -\x87\x22\x43\xee\x18\xd6\x3c\xa4\x0e\x55\x06\xe6\xf7\xa9\x8b\x31\ -\x75\xc4\xaf\x93\x3f\x79\xe1\xfa\x44\xc9\xc3\x1e\xac\x24\xc6\xf4\ -\x15\x93\xe7\x2e\x77\x0d\xaf\xa2\x6d\xdd\xb1\x60\x12\x03\x17\x20\ -\x67\xc1\x55\xb7\xe1\x13\x71\xa3\xf0\xe2\x93\x73\xfe\xff\x90\x3b\ -\xc1\x2e\x79\xd8\xb3\xdb\xc2\x33\x25\x29\x19\x73\x7f\x21\x75\xfe\ -\x15\x70\xfe\x56\xd9\x83\x9e\xf4\xec\xe1\xd9\xf5\x2e\x3e\xd3\x7a\ -\x57\xea\x35\x4f\x2f\x6d\xf2\x5c\xb4\xa9\x6b\x8d\x29\x1d\x52\x97\ -\x43\xe6\xe4\x56\xea\xc1\x67\xea\xf3\xaf\x9a\xfc\x2d\xce\x0f\x85\ -\x7f\xa9\xee\x81\xf8\x0a\x92\xa7\x6d\xf2\x08\x53\x97\x3c\xa5\x98\ -\x6a\xfe\x71\xc9\xff\x01\xda\x5b\x73\x18\xaf\x35\x0f\x9b\x22\x6e\ -\xbf\x99\x82\x11\x6b\xd3\x98\xfa\xc9\xf8\x97\xc0\x54\xa5\x0d\xda\ -\xff\xe1\x15\xa4\xde\x24\xc5\x9b\x56\xb2\x6f\x2f\x16\xcf\x44\x4d\ -\xfe\xc1\xc4\x84\x84\x70\x48\xd5\x9a\xb6\x5d\xc1\x81\xd0\x5f\xf6\ -\xc7\x18\x4e\xd2\x9d\xe1\x2a\xd9\xe4\xc5\x31\x6e\x92\xb2\x09\x60\ -\xce\x7c\xf5\xa6\x30\x16\x40\x0a\xfa\x0b\xf1\x18\x81\xeb\xbe\xaa\ -\xb3\x33\xc1\x54\x21\x78\x35\xbd\x7d\x65\x73\xfa\x8e\x34\x54\x8b\ -\x4b\xf7\x12\xa8\x27\xc0\xdd\xc5\x27\x76\x6f\x42\x5c\xa9\xa9\x63\ -\x1e\xe7\x3e\x85\x03\xb9\x24\x9a\x9d\xef\xa8\x0e\x2e\x38\x4d\x4f\ -\xf0\xdb\x1a\xe2\x76\xb7\xe2\x73\x1f\x00\x2f\xcc\xb7\x18\x8e\xea\ -\x0a\x75\x2f\x0b\xee\x36\x95\x53\x49\xbf\xf3\x17\x33\x0b\xd1\x97\ -\xd3\x35\xf9\x78\xb3\x5f\x57\x0e\x57\x07\x8d\x3f\x69\xdb\xa9\x9c\ -\x03\xcc\xc5\x4e\xe4\xb7\xa3\x7d\x26\xde\xdf\x2b\xda\x53\x52\xe7\ -\x49\x69\x6f\x15\x72\x59\x15\x59\x5f\x46\x5b\x1b\x9b\x3e\x9e\x19\ -\x5d\x57\x2c\x18\xf8\x16\x74\x4e\x5b\x93\x8e\x5f\x1d\xc6\xdf\x4c\ -\x86\xde\x0f\x30\xf0\x37\xcf\x16\x65\xf1\xf3\xbb\x59\xd4\xe6\xbd\ -\x80\xbf\x00\x75\x77\xbd\xbf\x5e\xdc\xcd\xdc\xb7\x10\x8b\xbb\xdf\ -\x00\x0b\x26\x09\xc9\ -\x00\x00\x09\xf8\ -\x00\ -\x00\xa0\xff\x78\x9c\xed\x5d\x5d\x8f\xa3\x38\x16\x7d\xef\x5f\xc1\ -\xa6\x5f\xa6\x35\xc5\x87\xbf\x30\xce\xa4\x6a\xa4\xdd\xd6\x48\x23\ -\xed\xd3\xce\xac\xf6\xb1\x45\x80\xa4\x50\x27\x10\x01\xa9\x24\xf3\ -\xeb\xc7\x26\x21\x21\xa9\xd8\xd3\xbb\x31\xab\xca\xad\x8e\xba\x55\ -\x85\x6d\xc0\x1c\xdf\x6b\x1f\xdf\x5c\x4e\x4d\x7e\xde\x2e\x17\xce\ -\x4b\x56\xd5\x79\x59\x3c\x8e\x90\x17\x8c\x9c\xac\x48\xca\x34\x2f\ -\xe6\x8f\xa3\x7f\xff\xfe\x8b\x1b\x8d\x9c\xba\x89\x8b\x34\x5e\x94\ -\x45\xf6\x38\x2a\xca\xd1\xcf\x4f\x1f\x26\x7f\x73\x5d\xe7\x1f\x55\ -\x16\x37\x59\xea\x6c\xf2\xe6\xd9\xf9\xb5\xf8\x5a\x27\xf1\x2a\x73\ -\x7e\x78\x6e\x9a\xd5\xd8\xf7\x37\x9b\x8d\x97\x1f\x0a\xbd\xb2\x9a\ -\xfb\x9f\x1c\xd7\x7d\xfa\xf0\x61\x52\xbf\xcc\x3f\x38\x8e\x23\xef\ -\x5b\xd4\xe3\x34\x79\x1c\x1d\x4e\x58\xad\xab\x45\xdb\x30\x4d\xfc\ -\x6c\x91\x2d\xb3\xa2\xa9\x7d\xe4\x21\x7f\x74\x6a\x9e\x9c\x9a\x27\ -\xea\xee\xf9\x4b\x96\x94\xcb\x65\x59\xd4\xed\x99\x45\xfd\xb1\xd7\ -\xb8\x4a\x67\xc7\xd6\xaa\x37\x1b\xd2\x36\x42\x42\x08\x3f\xc0\x3e\ -\xc6\xae\x6c\xe1\xd6\xbb\xa2\x89\xb7\xee\xf9\xa9\xb2\x8f\xd7\x4e\ -\xc5\x41\x10\xf8\xb2\xee\xd4\xf2\xdb\x5a\x8d\x6b\x09\xe8\x4a\xfe\ -\x3f\x36\xef\x0a\xbc\xba\x5c\x57\x49\x36\x93\xe7\x65\x5e\x91\x35\ -\xfe\xe7\xdf\x3f\x1f\x2b\xdd\xc0\x4b\x9b\xb4\x77\x99\x0e\xcf\xb3\ -\xbb\x9e\x81\x5c\xc4\xcb\xac\x5e\xc5\x49\x56\xfb\x5d\x79\x7b\xfe\ -\x26\x4f\x9b\xe7\xc7\x11\xa1\x1e\x22\xf2\xc3\xda\xc2\xe7\x2c\x9f\ -\x3f\x37\x97\xa5\x79\xfa\x38\x92\xbd\xc7\x22\xda\x1f\xf7\x8c\x03\ -\xed\x1b\x1c\x2e\x3c\x3e\xd6\x04\x9e\xc0\x1e\x72\x2a\xc4\x08\xdf\ -\xb7\xe9\x1e\x61\x9c\x96\x89\xea\x93\xbc\x64\xb6\xcc\xe3\x75\x53\ -\x2e\xe5\xa8\x25\xc9\x22\xae\xeb\x7c\x96\x27\xf2\xa0\x2c\x56\x8b\ -\xf5\x3c\x2f\xbe\x4c\xa5\x95\x7d\x91\xc3\x39\xcd\x8b\xb6\xf8\x4b\ -\x53\x96\x0b\xaf\x03\xf2\x78\xd7\x6c\xbb\x2a\xab\xc6\xdd\xa6\x2b\ -\x09\x67\xc8\xaf\x56\xee\xfa\x95\x2f\x79\xb6\xf9\x7b\xb9\x95\xdd\ -\x74\x02\x87\x60\xf9\x6f\xf4\x24\xcb\x27\x69\x36\xab\x55\xfd\xfe\ -\x91\xd5\x91\x7c\x66\x3e\x72\xfc\xb6\xf6\xf8\x04\xaa\xfb\xa9\xba\ -\xc6\xa9\xed\x34\xae\xf7\xb0\x3a\xce\x2a\x9e\x4b\x13\x5c\x94\xd5\ -\xe3\xe8\xe3\xac\xfd\x1c\x2a\xa6\x65\x95\x66\x55\x57\x15\xb6\x9f\ -\xb3\xaa\x52\x0e\x53\xde\xec\xf6\x4e\x77\xb8\x76\xf7\x18\xea\xaa\ -\xc7\xfa\xe0\x7a\x7d\xfd\x1c\xa7\xe5\xe6\x71\x84\x2f\x2b\xff\x28\ -\xcb\xa5\x1c\x54\x4f\x30\x11\xe0\x40\x5c\x56\x27\x12\x09\x17\x05\ -\xd4\x13\x04\x0b\xf6\xaa\x76\xd7\xda\x83\x3c\x33\x7a\x75\xe1\x64\ -\x5d\x55\xd2\x2b\xdd\x45\xbc\xcb\xe4\x43\xb5\x3f\xd0\xa1\x51\xfd\ -\x5c\x6e\xe6\x95\x02\xa7\xa9\xd6\xd9\xe5\x99\xaa\xc6\x9d\x4e\xd5\ -\x20\x5c\xab\x96\x46\xb2\x56\xfe\xee\xae\x8b\xbc\x91\x3e\xb5\xda\ -\xf6\xaf\xba\xce\xd3\xac\xbe\x7e\x62\x5d\xc4\x2b\x77\xbe\x28\xa7\ -\xf1\xe2\x7a\x83\x4d\x5e\x48\x90\xdc\x83\xf9\x23\x72\x1c\x83\xcb\ -\x16\x9d\x2f\xf0\x20\xd2\xb4\x50\x06\xa4\xa9\xda\xe9\xab\x96\xf1\ -\x36\x5f\xe6\x7f\x64\x12\x18\xd4\x9a\x9d\x34\xad\x33\x58\xf6\xa7\ -\x39\x4e\xb3\x53\x7e\xbd\xdd\xa9\xb2\x51\x57\xa8\xf0\x54\x05\x58\ -\x08\x7e\x2c\x2c\xab\x5c\xba\x4b\xaf\x3b\x5d\xd1\xae\x5f\xa4\x66\ -\x01\x39\x89\x6f\xd5\x7d\x2f\xca\x94\xcd\x75\x66\xee\xbf\xb6\xf3\ -\xb6\x7c\x99\x35\x71\x1a\x37\xf1\xc9\xe8\xbb\x12\xd9\x97\xa0\x7b\ -\x12\x39\x81\x8e\xff\xf5\xf9\x97\xa7\xc3\x0d\x26\x49\x32\xfe\x4f\ -\x59\x7d\xed\xee\xe7\x38\xaa\x41\x3c\x2d\xd7\x12\xd9\xd1\xd3\xb1\ -\x78\x92\x26\x63\x39\xe5\xc9\xa9\xe0\x29\x5f\x4a\x53\x56\xb3\xe5\ -\x8f\x72\x8a\x9b\xf8\xa7\x8a\xb3\xc6\x0a\x9c\xd3\x45\xf7\x97\xad\ -\xb2\xfd\xdc\x79\x75\x01\x49\x93\x65\xae\x4e\xf2\x7f\x6b\xf2\xc5\ -\xe2\x57\x75\x93\xc3\x13\xf7\x2e\x9a\x37\x8b\xec\x54\x38\xf1\x0f\ -\xbd\x3f\x3c\x9b\xdf\x7b\xb8\x89\xdf\x3d\x7d\x7b\x34\x3f\xa1\x72\ -\xe6\x04\xc7\x81\x5d\xc4\xd3\x4c\x5a\xe4\x3f\x55\xa5\xf3\xaa\x76\ -\x5e\x95\xeb\xd5\xb2\x4c\xb3\xc3\xe9\x1d\x9a\xf3\xb3\x61\x47\x04\ -\x45\xc7\x91\x6b\xaa\xb8\xa8\x15\x32\x72\x1c\xe2\xa6\xca\xb7\x3f\ -\x20\x8f\x0a\x2c\xdd\x94\x3e\x04\x1e\x62\x54\x4d\x5d\xd1\x83\x5c\ -\x31\x42\x26\x30\x67\x44\xc8\xe2\x90\x87\x01\x93\xc3\xf5\xe0\x0a\ -\xe6\xd1\x30\x24\x88\x3f\xb8\xc4\x8b\x08\x13\x22\xa2\x9f\x8e\x03\ -\x32\xa9\xb2\xa4\xe9\x8d\x59\x3b\x27\x91\xfd\x67\xd4\x2b\x3f\x33\ -\x39\xc7\x91\xcd\x5c\x8c\x7a\x05\xb2\x9e\xb1\xde\x71\xe7\x53\xb4\ -\x57\x76\xf0\xc4\x7e\x91\x7a\x5a\xd5\x03\x16\x11\xd1\x2b\xae\x9b\ -\xdd\x42\x22\x34\x93\xe3\x37\xfe\x18\x04\x49\x32\x9b\xfd\xa4\x0e\ -\xdc\xc3\xc4\x38\x46\xfb\xc3\x6a\xbd\x90\xf3\xfe\x4b\x56\x94\x69\ -\xfa\x53\xdd\x54\xe5\xd7\x6c\x7c\x98\x8a\x0f\x87\x7b\xf7\x1f\x07\ -\xdd\xa1\x34\x8d\xac\x5a\x48\xb7\x6c\xc6\xb4\x2b\x4b\x63\x39\x9f\ -\x56\x55\xbc\x1b\x17\x92\xe7\x74\xa5\xc7\x5b\xf5\x8c\xc7\x26\x5a\ -\xe2\x36\xb4\x5c\xa4\xc7\x2b\x8e\x53\x0a\x0d\xaf\x90\xdc\x8a\x97\ -\x1b\xe9\x11\x0b\xc3\x28\x00\x87\x18\xbf\x19\xb1\x40\x8f\x18\xa5\ -\x8c\x41\x43\x8c\xa3\x5b\x11\x23\x2e\xd6\x5a\xd9\x6c\x86\x63\x1c\ -\x83\xc3\xec\xc6\x59\x5f\x5a\x19\x77\xb5\x73\x3f\x50\xcc\x6e\x9e\ -\xfb\xdd\xc8\x65\x2e\x7f\x5f\xa8\x45\xb7\xaf\x00\x81\x4b\x5c\x02\ -\x1c\x35\x76\x8e\xda\xed\x3c\xc3\xa5\x3a\xc4\x80\x30\x8d\x0b\xc4\ -\x6c\x30\x0d\x13\x3b\x03\xc1\x35\x2e\x31\xb3\xc0\x35\xf4\xf3\x19\ -\x10\xb6\x71\x81\x99\x0d\xb6\x11\xba\xa1\x7e\x3a\x13\x02\x20\x68\ -\x36\xe8\x06\xd6\xbb\x27\x50\xd4\xec\x10\x0e\xe1\x62\xd8\xb8\x21\ -\xe2\x05\xea\x63\x39\xb2\x61\xda\x79\x42\x88\x6d\xe8\x60\xb3\x60\ -\x75\x06\xe4\x20\x70\x0f\x0d\x72\x56\x28\x88\x21\xa0\x06\x81\x82\ -\xe8\xa0\xb3\xc1\x44\xb4\x8b\x2a\x0c\x26\xa2\x81\xce\x4a\xf8\x43\ -\x6f\x76\x51\x7b\x4f\xa8\xd8\xd9\xe0\x25\x86\xcd\x29\x6c\xf0\xec\ -\xd0\x13\xc3\xae\x0b\x34\x7c\x96\x02\x23\xdc\x15\xda\x9d\x3e\x10\ -\xfc\xf8\x39\x70\x37\xf3\xba\xc0\x14\x1b\x01\xc1\xec\x2e\x11\xb3\ -\x10\x4d\xd2\x6f\x22\x80\x70\xba\x0b\xcc\xec\xc4\x93\x5c\xa6\x47\ -\x0d\x04\x9d\xbb\x44\xcd\x4a\x44\xc9\x44\x82\x41\x30\xb9\x0b\xd4\ -\xec\xc4\x94\xb0\x3e\x14\x97\x52\x88\x0b\x81\xa5\xa8\x12\xd7\x6f\ -\xf4\x81\xe2\x66\x2b\xae\x64\x58\x48\x61\x22\x67\x89\xb3\x61\xd3\ -\xc2\x00\x03\x39\x36\x4c\x48\x2e\x20\xfa\xec\x06\xb5\x9e\x82\x05\ -\xee\x76\x97\x0d\xf5\xdb\x54\xc8\xc8\x59\xe1\x71\x5c\x1f\x5b\x02\ -\x8d\x9d\x0d\x36\x67\xd8\xdf\x43\xc6\xce\x4a\x58\xce\xf0\xdd\x2a\ -\x21\xf7\xbf\x7b\xd0\x20\x67\x83\xd6\x19\xf6\x5d\x94\xc6\x77\x9f\ -\x2f\xa2\x41\xce\x0e\xb1\xd3\xae\x13\x38\xe6\xb3\xfb\x8f\x8e\x5c\ -\xc7\xce\x56\x38\x4e\x1f\x0b\xe6\x71\x9c\x66\xf7\x0e\x9e\x18\x88\ -\xd7\x49\x97\xd5\x12\x3b\xb5\xe5\xbf\xff\x65\x42\x83\x9c\x8d\xd0\ -\x9c\x21\x9f\x04\x32\x76\xb6\x42\x74\x72\xc6\xd3\x06\x37\x41\xe3\ -\x67\x27\x58\xa7\x8d\x01\x40\xc6\xce\x4e\xc8\xce\xc0\x52\x20\xf0\ -\x3b\x0d\x74\x76\xc2\x76\xc6\x6f\xfb\xef\x9f\xe1\x69\xb0\xb3\x15\ -\xba\x03\xce\xf1\xae\xa3\x67\x2d\x7c\xa7\xa5\x2a\x20\x48\x1e\xf6\ -\x44\xfb\x21\xe7\xe8\x59\x49\x0c\x33\xbd\x9e\x34\x4d\x52\xc2\xee\ -\xdd\xf4\x34\xe0\xd9\xc9\x0d\x53\x81\x28\x6d\x34\x05\x34\x7c\x56\ -\xf2\xc3\x4c\x2b\x2e\x64\xf4\xec\xa4\x88\xc1\x26\x2b\x3a\xe8\xec\ -\x64\x88\x19\x12\x4e\x00\x90\x15\x1d\x76\xb6\x12\xc4\xb4\x96\x07\ -\x83\xac\xa0\x3d\x59\x09\xa2\x73\xf8\x6c\xe4\x39\x99\xbe\x68\x8c\ -\xa2\x38\xbe\xff\xed\x99\x0e\x3c\x2b\x29\x4f\xa6\xdd\x2d\x68\xf8\ -\x6c\x85\x56\x4c\xef\x87\xc1\x06\xd0\x52\x22\x94\x5c\x3b\xc2\xf7\ -\xe9\xc1\xb6\x92\xa2\x0c\x6a\x08\x00\x68\x8b\x16\x3d\x5b\xb9\x51\ -\xc6\xd7\x3b\xef\x9e\xb9\x68\xe1\xb3\x97\x22\xa5\xb5\x3f\xd0\xe4\ -\xc5\x62\xa6\x94\xfe\xf5\x80\xb7\x12\x6c\x99\xf8\x73\xad\x20\x54\ -\x8f\x40\x5c\x93\x84\x22\x02\x73\x11\x0a\xa5\x03\x85\xc3\x88\x50\ -\x46\x78\xab\x09\x85\x58\x10\x46\x4a\xfd\x09\x79\x88\x33\x4e\xb1\ -\xfc\x35\x0a\x3d\xca\x31\x8a\xa2\x07\x12\x79\xb2\x9e\x84\xfc\x4d\ -\x4a\x42\xe9\x83\x8b\x30\xd2\xeb\xed\x8b\x42\x99\x10\x83\x90\x5c\ -\x3f\x84\x2c\x94\x09\x33\x08\xa9\xf5\x43\x08\x43\x99\x5e\x69\x86\ -\x90\x58\x3f\x8c\x34\x94\x49\xad\x01\x84\xf8\xcc\x20\xe2\x50\x7a\ -\xe2\x03\x14\x35\x4b\xf2\x50\xfa\x88\x03\x4c\xdc\x6c\x09\x44\xe9\ -\xe7\x36\x20\xb8\x0d\x20\x11\x65\x5a\x0f\x40\xf0\x8e\x41\x44\xa2\ -\xc0\x4b\x52\x0e\x22\x13\xe5\x8a\xef\x4a\x51\xff\x8b\x52\x94\x49\ -\x30\x10\x82\x7a\xcf\x50\x5a\x51\xef\x4e\x63\xcb\x9a\x5a\x94\x89\ -\x81\x40\x40\x6e\x30\xbd\x28\xe8\x81\x8f\x21\x15\xa3\x4c\x71\x7a\ -\x08\x54\x64\x50\xcd\x28\xe8\xb1\x90\x41\x55\xa3\xa0\xeb\x65\x0f\ -\xab\x1b\xf5\x5d\x39\xea\x26\xe5\x28\xbd\xac\x0a\x6c\xf8\xac\x69\ -\x47\x19\xf2\x5b\x20\x03\x68\x51\x3d\xca\x90\xe2\x02\x03\xc1\x01\ -\xf4\xa3\x4c\x6b\x06\x08\xa6\x37\x88\x82\x94\x29\x85\x14\x04\xc7\ -\x1b\x48\x43\x0a\xbc\x28\xe8\x40\x2a\x52\xe6\xb4\x5b\x00\xcc\x6e\ -\x28\x1d\x29\x7d\xec\x04\x86\x3a\xcd\x70\x4a\x52\x7a\x57\x05\x8a\ -\x9c\x45\x2d\x29\x3d\x17\x86\x89\x9d\x4d\x35\x29\xe8\xd8\x0d\xa8\ -\x27\xa5\x5f\x25\x20\xeb\xd3\xd8\x51\x94\xd2\x7f\x39\x01\x19\x3b\ -\x5b\x9a\x52\xef\x14\x3d\x4b\xaa\x52\xfa\xdd\x04\x64\xf4\xec\xe8\ -\x4a\x99\x98\x31\x84\xac\xf8\x21\x95\xa5\xcc\x49\x74\xf7\x9f\x12\ -\x3f\xac\xb6\x94\x3e\x9d\x1b\x46\x3e\xfc\xc0\xea\x52\x86\x78\xf1\ -\x5b\xc9\x86\x7f\xb3\xfa\x52\x7a\xc7\x85\xac\x54\x63\x4b\x61\x4a\ -\xbf\xb3\x85\x8c\x9e\x4d\x8d\x29\xfd\xb7\xb4\xa0\x11\xb4\xa4\x32\ -\xf5\x3e\x35\xce\x2c\xe9\x4c\x99\x38\x0b\x04\xbe\x37\xac\xd2\x94\ -\x39\x43\xe0\xfe\x19\xdf\xd0\x5a\x53\x7a\xd2\x02\x83\xf3\x0d\xad\ -\x36\x75\x07\xaf\x40\xbe\x65\xbd\xa9\xef\x8a\x53\x37\x2a\x4e\xbd\ -\x4f\xd5\x24\x7b\x9a\x53\x7a\xff\x85\x8c\x9f\x25\xd5\x29\xd3\x1f\ -\xe5\x06\x40\x5d\x06\xd6\x9d\x02\x4e\x5d\x06\x57\x9e\xd2\x13\x67\ -\x18\xd4\x65\x60\xed\xa9\xef\xea\x53\x37\xaa\x4f\x19\xa4\x46\x21\ -\x03\x68\x53\x7f\x4a\x1f\x38\x80\x0d\xa1\x4d\x05\xaa\x77\x2a\x83\ -\x66\x4d\x83\xca\xa4\x56\x0d\x80\xc4\x0c\xaf\x42\x65\xfa\xf3\xa3\ -\x00\x78\xcc\xff\x43\x87\xea\x9d\xca\x68\xda\x54\xa2\xd2\xb3\xc1\ -\x37\x13\x88\x39\x69\x51\xf5\x91\xbc\xf0\x18\xc6\x6e\x4d\xb6\x46\ -\x1e\xa6\x08\xe3\x80\xa3\x5b\x3a\xfd\xe1\x02\x6f\xdc\x67\xf2\x87\ -\x71\x41\xd8\xc3\x21\xc5\xe4\x34\x83\x76\x83\x88\x02\x2f\xa0\x28\ -\x3a\x55\xa8\x55\x8f\x79\x81\x88\x18\x3d\xf9\x8d\x34\x0d\x86\xbc\ -\x28\xe0\xac\xe7\x4c\xca\x7e\x90\x47\x43\xc4\x71\xd8\x2b\x6d\xad\ -\x8d\x21\x41\x68\x70\xea\xc7\x15\xd9\xae\x87\x40\x89\x74\x45\x21\ -\x25\x21\x8d\xf8\x43\xe0\xb1\x00\x47\x21\x43\xf2\xd7\x87\xe0\xd3\ -\xe9\xb1\x8a\xaf\x75\x12\xaf\x24\xa2\xdb\x55\x59\x35\xee\x36\x5d\ -\xe5\x67\x0b\xf3\x65\x83\x5d\xd7\xe0\x38\x9a\xfd\x41\xd4\x77\x04\ -\x51\xc1\x99\xa0\xaa\x23\x5c\x50\x41\xa3\xf3\x7e\xec\x9f\x2b\x44\ -\x88\x22\xfa\x57\x18\xc8\xa6\x24\xf2\xb0\xda\x53\xa1\x3e\xb0\x12\ -\xc3\x10\x0b\x84\xf0\xb5\x61\x08\x99\x1c\x88\x6f\x18\xb9\x6e\x9c\ -\x09\xef\x81\xf0\xea\x45\x80\x5b\xe9\x04\xf2\x10\x0b\x31\x65\x94\ -\x5b\x71\x28\xad\x1f\xcd\x66\xb7\x67\x56\xca\x49\x4b\x70\x12\x0a\ -\x4a\x6c\xfa\x91\xc4\x57\xfc\x17\x7e\xa4\x66\x58\x1e\xd2\xb3\xf1\ -\xa6\xd2\x34\x22\x16\xf6\xfc\x40\x6d\xb7\xb9\xc7\x30\xe2\xec\xdb\ -\x1c\x89\x23\x46\x04\x16\x7f\xed\x48\x3c\x64\x4c\xdd\x5f\xda\xaf\ -\x74\x29\x42\xa5\x35\xef\x0d\x78\x3f\x06\xed\x94\x36\xf1\xeb\x17\ -\xf9\xe3\x4f\x98\x39\xa9\x7a\ -\x00\x00\x06\xf7\ -\x00\ -\x00\x18\xf1\x78\x9c\xed\x58\x5b\x8f\xeb\x36\x0e\x7e\x9f\x5f\xa1\ -\xcd\x79\xe9\x62\x23\x5b\x92\xaf\x72\x2e\x7d\xd8\x83\x02\x05\xce\ -\xbe\x6c\xbb\x2d\xb0\x2f\x85\x62\x2b\x89\x3a\xb6\x95\x95\x95\x49\ -\xd2\x5f\x5f\xca\xb7\xc4\x99\x4c\x31\xc5\xb6\x40\x1f\x46\xc0\x4c\ -\x22\x92\xa2\x28\x92\x9f\x48\x65\xf9\xf5\xb9\x2a\xd1\x8b\x34\x8d\ -\xd2\xf5\x6a\x46\x3d\x32\x43\xb2\xce\x75\xa1\xea\xdd\x6a\xf6\x9f\ -\xef\xbf\xc1\xe9\x0c\x35\x56\xd4\x85\x28\x75\x2d\x57\xb3\x5a\xcf\ -\xbe\x5e\x3f\x2d\xff\x86\x31\xfa\xa7\x91\xc2\xca\x02\x9d\x94\xdd\ -\xa3\x6f\xeb\xe7\x26\x17\x07\x89\xbe\xda\x5b\x7b\xc8\x7c\xff\x74\ -\x3a\x79\xaa\x27\x7a\xda\xec\xfc\xbf\x23\x8c\xd7\x4f\x4f\xcb\xe6\ -\x65\xf7\x84\x10\x82\x7d\xeb\x26\x2b\xf2\xd5\xac\x5f\x70\x38\x9a\ -\xb2\x15\x2c\x72\x5f\x96\xb2\x92\xb5\x6d\x7c\xea\x51\x7f\x76\x15\ -\xcf\xaf\xe2\xb9\xdb\x5d\xbd\xc8\x5c\x57\x95\xae\x9b\x76\x65\xdd\ -\x7c\xba\x11\x36\xc5\x76\x94\x76\xd6\x9c\x82\x56\x88\x72\xce\x7d\ -\xc2\x7c\xc6\x30\x48\xe0\xe6\x52\x5b\x71\xc6\xd3\xa5\x60\xe3\xa3\ -\xa5\x8c\x10\xe2\x03\xef\x2a\xf9\x3e\xa9\xac\x01\x87\x1e\xe0\x6f\ -\x14\x1f\x08\x5e\xa3\x8f\x26\x97\x5b\x58\x27\xbd\x5a\x5a\xff\xf3\ -\xf7\x9f\x47\x26\x26\x5e\x61\x8b\x1b\x35\x83\x3f\x27\xbb\x4e\x9c\ -\x5c\x8b\x4a\x36\x07\x91\xcb\xc6\x1f\xe8\xed\xfa\x93\x2a\xec\x7e\ -\x35\x0b\x42\x8f\x06\x30\xa2\x96\xb8\x97\x6a\xb7\xb7\xf7\x54\x55\ -\xac\x66\x60\x3d\xe3\x69\x37\xbf\x49\x0e\xda\x09\xf4\x8a\xb3\x91\ -\x43\x3c\xce\x3c\x8a\x0c\x8d\x82\xa4\x93\x19\x8e\x90\x15\x3a\x77\ -\x36\x81\x4a\x59\x29\x71\xb4\xba\x82\xa8\xe5\x79\x29\x9a\x46\x6d\ -\x55\x0e\x13\x5d\x1f\xca\xe3\x4e\xd5\x3f\x6d\x95\xfd\xe9\x50\x6a\ -\xeb\x0d\xbe\x1b\x37\x92\xe7\x83\x36\x16\x9f\x8b\x03\x78\x30\x4e\ -\x1e\x32\x2f\x03\x73\x0d\xdc\x65\x21\xb7\x8d\x93\xea\x8e\xe3\x66\ -\x70\x9e\x64\x86\xfc\x96\x3b\x5a\xe7\x4c\x2b\x5e\x94\x3c\x5d\x65\ -\x37\xa2\xe9\x5c\x86\xd0\x41\xec\x20\xbd\x4a\x6d\x56\xb3\x4f\xdb\ -\x76\xf4\x8c\x8d\x36\x85\x34\x03\x2b\x6e\xc7\x84\xa5\x21\x04\xca\ -\x5e\x3a\x40\xf5\xba\x07\x7b\x9d\xd6\x91\x4f\x1e\xf3\x9b\xbd\x28\ -\xf4\x69\x35\x63\xf7\xcc\x5f\xb4\xae\x56\xb3\xc4\xe3\x34\x25\x21\ -\x4d\xee\xd9\xf9\x79\x35\xc3\x34\xf1\xa2\x30\x0c\x5e\x33\x61\x3f\ -\x96\x7a\x94\x90\x90\x44\xaf\x98\x47\x63\x00\x71\xb8\x14\x17\x09\ -\x87\x6a\x3f\x68\x2f\xd4\xec\xf5\x69\x67\x9c\x73\xac\x39\xca\xfb\ -\x95\x8e\x83\x37\x1b\x7d\x7e\xcc\x86\x04\x38\x3a\x2c\xe3\x63\xad\ -\x2c\xe0\xe5\x70\xbe\xd5\x7a\x54\x85\x6c\x1e\x2f\x3c\xa9\x1a\x7c\ -\x80\xfb\xcc\xa5\xc1\xe8\xe2\x7b\x89\x21\x8d\x13\x92\xbe\x21\x01\ -\xa6\xbd\x72\x73\xcf\xba\xbc\xcd\xaa\xc4\x59\x55\xea\x17\x09\xe7\ -\xa6\xf7\x22\x4d\x2d\x0e\x78\x57\xea\x8d\x28\x7b\xeb\xd7\xad\xc4\ -\x72\xe2\x96\x6e\x11\x42\xf6\xe2\x30\x7b\xbe\x38\xda\x6c\x20\x3a\ -\x7f\x3a\x42\x90\xc4\xd1\x48\xd4\x46\x01\x14\x6e\xec\x1d\x48\x97\ -\x5b\x92\x43\x38\x5c\xd0\xe7\x36\xbf\xda\xec\x4b\xee\x79\x97\x5b\ -\x5e\x9f\xf6\xfe\xeb\xbc\x6f\xe9\x95\xb4\xa2\x10\x56\x5c\x41\x30\ -\x50\x18\xe7\x64\x38\x19\x5c\x96\xd9\xbf\x3f\x7f\xb3\xee\x37\x5a\ -\xe6\x79\xf6\xa3\x36\xcf\xc3\xbe\x08\x39\x01\xb1\xd1\x47\x08\xc5\ -\x6c\x3d\x92\x97\x45\x9e\xc1\xf5\x06\xb0\x5f\xab\x0a\x52\xdb\xdd\ -\x8c\xff\x80\xeb\x6c\xe9\x5f\x19\x13\x61\xe7\xac\xab\xd2\x4e\xad\ -\x91\xdd\x3d\xf9\xb0\x58\x14\x79\xa5\xdc\x22\xff\x3b\xab\xca\xf2\ -\x5b\xb7\x49\x7f\xe2\x1b\xa5\xca\x96\xf2\x4a\x5c\xfa\xbd\xf5\xfd\ -\xd9\xfc\x9b\xc3\x2d\xfd\xe1\xf4\xed\x6c\x77\xf5\xca\x04\x14\x63\ -\xa0\x4b\xb1\x91\x90\x04\x5f\x1c\x13\xbd\xe2\xee\x8c\x3e\x1e\x2a\ -\x5d\xc8\x7e\xf9\xe8\x4d\x99\xdb\x31\x64\xf6\x52\x02\x7f\x0b\xd6\ -\x67\xfd\x45\xb3\x70\x13\xdc\x5f\x13\x19\xed\xa6\xe6\x58\xc2\x75\ -\xf7\x22\x6b\x5d\x14\x8b\xc6\x1a\xfd\x2c\xb3\x4f\x80\xe6\x94\x90\ -\x7e\xda\xa1\x25\x1b\xa7\xa5\xaa\x25\x98\x91\x35\xff\x3b\x0a\x23\ -\x6f\xa9\x3f\x6b\x55\x67\xe0\x37\x69\x06\x6a\x3b\x29\x21\xe3\x6d\ -\x16\x0e\xb4\x42\xc0\x4d\x64\x8c\xb8\x64\x35\x54\xff\x5b\xaa\xde\ -\x6e\x1b\x69\xaf\x3b\x0d\xa6\x12\x2f\xe8\xc7\x24\xd1\xdd\x71\x03\ -\xce\xe9\x48\x7c\x58\x90\xdc\x78\x5c\x94\xdc\x98\xa0\x02\xf2\x9b\ -\x7b\x61\x12\x70\x12\xc4\x12\xd3\x78\x64\x98\x89\x98\x01\xb9\xc0\ -\x0b\xa0\x30\xc5\x3c\x1d\xb3\x62\x79\x10\x76\xff\xc8\xfb\x37\xa7\ -\x74\x9e\x4d\xe5\xbd\x67\x47\x4c\xb1\xc3\xf9\xde\xc9\x9b\xa3\xb5\ -\xbf\xed\xe2\x31\x9e\xa3\x7d\x0e\x6b\x08\x8f\x5a\xe7\x8c\x79\x21\ -\x0a\x3c\x36\x1f\x68\x09\x8a\xbd\x70\x8e\x53\x2f\x6a\x9d\x8a\xa2\ -\xde\xbf\xc9\x8d\xc4\x40\x9b\x73\x2f\xbe\x4e\x58\xe7\xbf\x10\x7d\ -\x41\x01\x9b\xb3\xc4\x4b\x3a\x0d\x25\x1a\x94\xcd\x61\xa3\x49\x94\ -\x9c\x5b\x42\x12\x5c\x2f\x93\x6b\x79\xd0\x35\x1c\xd2\x6a\x83\xa1\ -\x50\xbc\x08\x7b\x34\xd2\xb9\xf9\xff\x77\x68\xe4\x31\xe6\x4e\xc1\ -\x83\xdf\xef\xce\xf7\x67\xec\x6f\x64\xe7\xab\x08\xd0\x5e\x66\x12\ -\x86\x78\x12\x86\xf0\x41\x18\xe2\x69\x18\xbe\x20\x16\x0e\x6e\xee\ -\x82\x0a\x31\x88\xbd\x6e\x93\xf7\xc4\x00\x07\xef\x8e\xc2\x2b\x39\ -\x6b\x44\xdd\xb8\xbb\x15\xe7\x50\x79\xa5\xc1\x6d\xa5\x88\xdf\x21\ -\x78\x71\xfd\xc3\x5d\xdd\x78\x1c\xde\xb6\xfb\x71\x31\x75\x63\xb1\ -\xd5\x50\xe1\x5b\x0e\xf8\x1d\xee\xf4\xb2\xa3\xbc\x08\xa3\x44\x6d\ -\x27\xb4\x53\x0b\xf0\x09\x09\xa2\x24\x6d\xbe\x9f\xd2\xa0\xf2\x66\ -\x50\xa5\xd4\xb1\x5a\xb8\xf0\xf7\x65\x7e\x22\xb3\x15\x95\x2a\x2f\ -\xd9\x77\x70\x88\x05\x1e\x0e\x85\xbb\xe5\x07\x99\x8f\x0d\x66\x27\ -\x61\xe5\xd9\x82\x54\x01\x27\x85\x7b\xab\x9d\x89\x52\xed\xea\x0c\ -\xde\x37\xc6\x76\x84\x02\x1a\x3e\xd3\xad\x69\xf3\xe7\x8e\xd8\x26\ -\x62\xc7\x29\xa5\x75\x0e\xeb\xcb\xed\x60\xd6\x09\xda\xbf\x7b\x5a\ -\xab\x63\xf4\x74\xb7\xfa\x64\x94\x05\x11\xec\x2a\x43\x56\x1a\x6c\ -\x37\x8b\x42\xb9\x4b\xd2\xed\x5c\x5a\xb3\x70\x6d\x68\x7b\xec\x66\ -\xaf\xb6\x36\x1b\xa6\xbd\xd9\x75\xbe\x07\xe7\x77\x76\x17\xaa\x39\ -\x40\x69\x81\xc7\x41\x2b\xa0\xa1\x2b\xdf\x96\xfa\x94\xbd\xa8\x46\ -\x6d\x4a\xb9\x68\x3f\x55\xe9\xd2\x7f\x20\x75\x95\x86\xe6\x74\xcb\ -\xc2\xfb\x4a\xd3\x83\xf5\x16\x3d\x1d\x52\x03\x8f\x87\x90\x15\x51\ -\x14\x2c\x2a\x61\x9e\xa5\xe9\x64\x64\x2d\x40\x25\xde\x88\xfc\xd9\ -\xd5\xba\xba\xc8\x44\x0e\x1d\xdf\xb1\x84\xb7\xe1\x14\x64\x00\x88\ -\xb4\x4d\xfa\x39\xc0\x90\x01\xbc\x48\x38\x77\xff\x1c\x56\x18\x74\ -\xb4\x51\x12\xcd\xdd\x2d\x15\xb3\x38\x48\x11\x80\x85\xb3\x30\x0a\ -\xd9\x9c\x12\x2f\x24\x69\xc2\x29\x0a\xe0\xa1\xd1\xa1\x06\xd0\x08\ -\x20\xba\xaa\xf8\x01\xb5\x3a\xff\xfb\x0a\x4a\x01\x21\xfc\x77\x03\ -\xe9\xda\x27\x41\x78\x5c\x6b\x01\x2d\x6a\xde\x8f\x0f\x50\x7c\x80\ -\xe2\x0f\x03\xc5\xbf\xa0\x0e\x30\x92\xa6\x1c\x0a\x49\x10\x79\x94\ -\x47\x3c\xe5\x63\x21\x81\xe2\xc0\x10\x64\x7f\x14\x84\x80\x08\x57\ -\xc2\x53\xce\x68\xe8\x5a\x02\x68\x40\x58\x1c\x42\xb5\x8a\x3c\x42\ -\x19\x89\x19\x82\x1a\x13\x25\x49\xc2\xe2\x39\xbc\xf1\xe0\x71\x48\ -\x28\xc2\x00\x1c\x9a\x24\x69\x4a\x63\x27\x18\x93\x94\x30\x47\x4c\ -\x79\x1a\x06\x34\x4e\xe7\xd0\x63\x25\xd4\x69\x7f\x03\x38\x98\x7e\ -\x40\xe7\x03\x3a\x7f\x55\xe8\xb8\x46\x25\x60\x00\x13\x0e\x1d\x17\ -\xa5\x9c\x07\x51\x84\xa8\xc7\x79\xec\x7e\xe2\x83\x12\x41\xe2\x34\ -\xa2\x8c\x03\x5c\x02\x4e\x69\x42\xe9\x9c\xc2\x12\xc6\xa3\x34\x45\ -\x1c\xaa\x46\x0a\x5f\x38\x94\x1c\x42\x49\x02\x08\x02\x28\x31\x78\ -\x51\x84\xa9\x2b\x29\x34\x21\x1c\xd0\x92\x7a\x24\x0a\x18\x74\x79\ -\x04\xf6\x0a\x03\xd8\xee\xb6\x57\x24\x6f\xe2\x06\xb3\x0f\xe4\x7c\ -\x20\xe7\xaf\x89\x9c\x0a\xc1\xbd\x0f\xa9\xce\x79\xea\x9e\x24\x50\ -\x15\xe2\x10\xd2\x1a\x92\x1e\xde\xd2\x89\x7b\x91\x90\x24\x82\x1a\ -\x81\x70\xe8\x85\x41\x44\xd2\x60\x0e\xdf\x38\x8b\x00\x1d\x08\x33\ -\x2f\x86\x4f\x36\x07\x15\x21\x61\x80\x38\xf8\x12\xc5\x00\x33\x58\ -\xc7\xa1\xc4\x00\xb6\x1e\xa8\xfa\x82\x86\xf7\x7c\xe0\x0a\xdd\x5b\ -\x9d\x1a\x0e\xff\x0c\xd8\x2c\xfd\xdd\xfa\x69\xe9\x7e\x78\x5a\x3f\ -\xfd\x0a\x4c\x29\xd2\x0a\ -\x00\x00\x0f\x7e\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x35\x33\x32\x30\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\ -\x6f\x61\x64\x5f\x61\x72\x72\x6f\x77\x2e\x73\x76\x67\x22\x0a\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x2e\x35\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x2e\x35\x22\x3e\x0a\x20\x20\ -\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ -\x65\x66\x73\x35\x33\x32\x32\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ -\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\ -\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\ -\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\ -\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ -\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ -\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ -\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x37\ -\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x38\x2e\ -\x38\x36\x37\x33\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\x2e\x34\x39\x38\ -\x35\x35\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ -\x3d\x22\x6c\x61\x79\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ -\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\ -\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ -\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x35\x33\x34\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ -\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x35\x33\x32\x35\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ -\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ -\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ -\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ -\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ -\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ -\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ -\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\ -\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\ -\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\ -\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x66\ -\x32\x32\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\ -\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x31\x2e\x32\x39\x32\x39\x39\x35\x33\x33\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ -\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\ -\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\ -\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x33\x2e\x37\x2c\ -\x30\x2e\x31\x36\x36\x36\x36\x36\x36\x37\x20\x63\x20\x2d\x31\x2e\ -\x30\x39\x32\x36\x31\x35\x2c\x30\x20\x2d\x31\x2e\x39\x36\x36\x36\ -\x36\x37\x2c\x30\x2e\x38\x37\x34\x30\x35\x31\x38\x33\x20\x2d\x31\ -\x2e\x39\x36\x36\x36\x36\x37\x2c\x31\x2e\x39\x36\x36\x36\x36\x36\ -\x36\x33\x20\x56\x20\x31\x36\x2e\x34\x33\x33\x33\x33\x33\x20\x48\ -\x20\x34\x2e\x32\x36\x36\x36\x36\x36\x37\x20\x63\x20\x2d\x32\x2e\ -\x31\x33\x33\x33\x33\x33\x37\x2c\x30\x20\x31\x31\x2e\x37\x33\x33\ -\x33\x33\x33\x33\x2c\x31\x36\x20\x31\x31\x2e\x37\x33\x33\x33\x33\ -\x33\x33\x2c\x31\x36\x20\x4c\x20\x31\x37\x2e\x30\x36\x36\x36\x36\ -\x37\x2c\x33\x33\x2e\x35\x20\x31\x38\x2e\x31\x33\x33\x33\x33\x33\ -\x2c\x33\x32\x2e\x34\x33\x33\x33\x33\x33\x20\x63\x20\x30\x2c\x30\ -\x20\x31\x33\x2e\x38\x36\x36\x36\x36\x38\x2c\x2d\x31\x36\x20\x31\ -\x31\x2e\x37\x33\x33\x33\x33\x34\x2c\x2d\x31\x36\x20\x48\x20\x32\ -\x32\x2e\x34\x20\x56\x20\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\ -\x63\x20\x30\x2c\x2d\x31\x2e\x30\x39\x32\x36\x31\x34\x38\x20\x2d\ -\x30\x2e\x38\x37\x34\x30\x35\x31\x2c\x2d\x31\x2e\x39\x36\x36\x36\ -\x36\x36\x36\x33\x20\x2d\x31\x2e\x39\x36\x36\x36\x36\x37\x2c\x2d\ -\x31\x2e\x39\x36\x36\x36\x36\x36\x36\x33\x20\x7a\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ -\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ -\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6c\x61\x79\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ -\x4c\x69\x76\x65\x6c\x6c\x6f\x22\x3e\x0a\x20\x20\x20\x20\x3c\x65\ -\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\ -\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\ -\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\ -\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x32\x33\ -\x34\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\ -\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\x35\ -\x65\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x31\x2e\x33\x33\x35\x37\x31\x32\x34\x33\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\ -\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\ -\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\ -\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x35\x39\x38\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x35\ -\x2e\x35\x39\x39\x39\x39\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x37\x2e\x34\x36\x36\x36\ -\x36\x35\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x36\x2e\x36\x36\x36\x36\x36\x36\x35\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\x35\x65\ -\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ -\x2e\x32\x30\x32\x30\x31\x38\x37\x38\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x63\x78\x3d\x22\x32\x35\x2e\x32\x38\x38\x38\x38\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x32\x37\x2e\x37\ -\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\ -\x3d\x22\x32\x2e\x37\x39\x39\x39\x39\x39\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x33\x37\x36\x38\x31\x31\ -\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\ -\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\x35\x65\x35\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x30\ -\x31\x31\x35\x31\x38\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x35\ -\x2e\x35\x39\x39\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x32\x32\x32\x32\ -\x32\x31\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x36\x2e\x33\x37\x36\x38\x31\x31\x35\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ -\x72\x69\x78\x28\x30\x2e\x30\x30\x36\x33\x37\x35\x38\x37\x2c\x30\ -\x2e\x39\x39\x39\x39\x37\x39\x36\x37\x2c\x2d\x31\x2c\x30\x2c\x30\ -\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x36\x30\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\x35\x65\x35\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x32\x30\x38\x37\x39\x35\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\ -\x37\x2e\x37\x33\x33\x38\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x63\x79\x3d\x22\x2d\x32\x35\x2e\x35\x37\x38\x37\x38\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x36\x30\ -\x38\x37\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x37\x2e\x33\x31\x31\x30\x35\x36\x31\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x09\x9e\ -\x00\ -\x00\x24\x4e\x78\x9c\xe5\x59\x5b\x6f\xdb\xd8\x11\x7e\xf7\xaf\x60\ -\xe5\x97\x04\x15\xa9\x73\xbf\x28\xb6\xf7\xa1\x8b\x2d\x16\x68\x51\ -\xa0\x9b\xa0\x8f\x0b\x8a\xa4\x6c\x36\x14\x29\x90\x94\x25\xe5\xd7\ -\xf7\x3b\x94\x48\x91\x92\x6c\xcb\xb1\x5b\x6c\x50\x05\x41\xc8\x33\ -\x73\x6e\x33\xdf\xcc\x7c\xc3\xdc\xfc\xb4\x59\x64\xde\x63\x52\x56\ -\x69\x91\xdf\x8e\x68\x40\x46\x5e\x92\x47\x45\x9c\xe6\xf7\xb7\xa3\ -\x2f\x9f\x7f\xf1\xcd\xc8\xab\xea\x30\x8f\xc3\xac\xc8\x93\xdb\x51\ -\x5e\x8c\x7e\xba\xbb\xba\xf9\x93\xef\x7b\x7f\x29\x93\xb0\x4e\x62\ -\x6f\x9d\xd6\x0f\xde\xaf\xf9\xd7\x2a\x0a\x97\x89\xf7\xe1\xa1\xae\ -\x97\xd3\xc9\x64\xbd\x5e\x07\xe9\x7e\x30\x28\xca\xfb\xc9\x47\xcf\ -\xf7\xef\xae\xae\x6e\xaa\xc7\xfb\x2b\xcf\xf3\xb0\x6f\x5e\x4d\x8b\ -\x6a\x76\x3b\xea\xcd\x28\x96\x49\x5e\xad\xc3\x3a\x7a\x98\x15\xc5\ -\xd7\x66\xde\xaa\x4c\x27\x8c\x10\x3b\x81\xee\xe8\x30\x33\x8e\xba\ -\x89\xcb\x55\x99\x35\xaa\x71\x34\x49\xb2\x64\x91\xe4\x75\x35\xa1\ -\x01\x9d\xf4\xd4\xa3\x83\x7a\xe4\xce\x9d\x3e\x26\x51\xb1\x58\x14\ -\x79\xd5\xcc\xcc\xab\xeb\x9e\x72\x19\xcf\x07\xa7\x5a\xf3\x46\x89\ -\x5a\x6b\x27\x84\x4d\x18\xf3\xa1\xe1\x57\xdb\xbc\x0e\x37\xfe\x70\ -\x2a\x6e\x77\x6e\x2a\x2e\x40\x26\x90\x1d\x34\x2f\xd3\x9a\x6e\x32\ -\x18\xf1\xc9\xc3\x34\xd2\xfe\xee\x70\xdc\x12\x7f\xbb\x09\xed\x40\ -\x50\x15\xab\x32\x4a\xe6\x98\x99\x04\x79\x52\x4f\x7e\xfe\xfc\x73\ -\x27\xf4\x49\x10\xd7\x71\x6f\x99\xd6\x6f\x83\x7d\x07\xce\xcc\xc3\ -\x45\x52\x2d\xc3\x28\xa9\x26\xed\x78\x33\x7f\x9d\xc6\xf5\xc3\xed\ -\x88\x8b\x80\x72\xfc\x64\x33\xf8\x90\xa4\xf7\x0f\xf5\xf1\x68\x1a\ -\xdf\x8e\x70\x57\x66\xad\x6e\xde\x7b\x20\xa4\x3b\x85\xfd\xc2\xd3\ -\x4e\x42\x02\xcb\x02\xea\x95\x54\x72\xbd\xd3\x69\xaf\x30\x8d\x8b\ -\xc8\x9d\x09\x4b\x26\x8b\x34\x5c\xd5\xc5\x02\x3e\x8e\xa2\x2c\xac\ -\xaa\x74\x9e\x46\x78\x29\xf2\x65\xb6\xba\x4f\xf3\xdf\x17\xd0\xaf\ -\x7e\xaf\x8b\x22\x0b\x5a\x5b\x77\x5b\x25\x9b\x65\x51\xd6\xfe\x26\ -\x5e\xc2\x86\x4a\x9f\x15\x6e\x5b\xe1\x1d\xa4\x37\xdd\x09\xdc\xf6\ -\xf1\x63\x9a\xac\xdd\x9c\xdd\xf5\x66\x61\xb5\x33\x8b\xe7\x2d\xc3\ -\x7b\x00\x2e\x2b\xca\xdb\xd1\xf5\xbc\xf9\xed\x05\xb3\xa2\x8c\x93\ -\xb2\x15\xa9\xe6\x37\x10\x15\x30\x73\x5a\x6f\x77\xc1\xb9\x5f\xbb\ -\x3d\x91\x5b\xb5\x93\x93\xf3\xf2\xea\x21\x8c\x8b\xf5\xed\x88\x1d\ -\x0b\xbf\x15\xc5\xe2\x76\x64\x8e\x87\xa3\xcd\xed\xc8\x17\x32\xa0\ -\x52\x68\x23\x4e\xa4\xee\x20\x2a\x10\x84\x13\xab\x4e\x84\xab\xb2\ -\x44\xf0\xf9\x59\xb8\x4d\x70\x9b\xe6\x1f\xba\x57\xaa\x1e\x8a\xf5\ -\x7d\xe9\xac\x52\x97\xab\xe4\x78\xa6\x93\xf8\xb3\x59\xb1\x39\x2f\ -\x86\x77\x57\x2e\xac\xfd\x55\x9e\xd6\x08\x9d\xe5\xa6\xbf\xea\x2a\ -\x8d\x93\xea\xfc\xc4\x2a\x0f\x97\xfe\x7d\x56\xcc\xc2\xec\xbc\xc2\ -\x3a\xcd\x61\x1d\x7f\x8f\x5b\xca\xd5\xc9\xa5\xf6\x1a\x2d\x88\x35\ -\x39\xb1\xd8\x5e\x03\x67\x3f\x71\xc0\x5e\xb4\x7d\x5a\xb4\x08\x37\ -\xe9\x22\xfd\x96\xc0\x30\xb4\x41\x14\x30\x35\x30\xcb\x6e\xda\x0e\ -\x50\xee\x9d\x13\x22\x47\xed\x60\xbd\x75\x51\xba\xd9\x3a\x41\x37\ -\x58\x94\x29\x70\xde\x3b\x4e\x3b\xb4\xed\x0f\xb9\xf0\x45\x96\xdf\ -\x34\xc0\x6a\x60\xa7\x8f\x65\xdb\xbe\xcc\x9b\x34\x78\x9f\x9c\x02\ -\xbe\x19\x8f\x93\x79\x75\x40\xbe\x7b\x43\x64\xdb\xf6\x46\xc8\x53\ -\x49\x58\xfe\xb5\x0c\xe3\x14\x6e\xec\x5f\x69\x28\x91\x46\xb6\x73\ -\x5c\x6c\xd5\xc5\xb2\xd5\xc5\xa1\xea\x6d\xe6\x02\x1c\x83\x7e\x13\ -\x2f\xd3\x6b\x1b\x85\x21\x21\x9f\x9a\xa1\x7d\x1c\x4c\xe9\xa7\xd1\ -\x61\x4e\x31\x9f\x57\x49\xdd\xbf\xf6\x3e\xf1\x60\x86\x34\x8a\xee\ -\x6f\x75\xe1\x6e\x94\xc7\x74\x76\xc1\x6e\xf4\xfc\x6e\xbc\xdb\xed\ -\x66\x32\xbc\xf6\xab\xad\xc4\x0e\x5b\xa0\x2c\x22\xce\xd3\x1c\xfb\ -\x56\x45\x06\x18\x5c\x7e\xa1\xb9\x42\xc1\x39\x32\x1f\x09\xb4\x31\ -\x8c\x4b\xfe\x0a\x3b\xb2\x77\xbc\x19\x95\xef\x72\xb3\xf9\x4c\xcf\ -\xf4\x77\x03\x83\xea\xef\xbc\x50\x97\x09\x8b\x2c\x4b\x22\xac\x1f\ -\x66\xeb\x70\x5b\x75\x9b\x34\x05\x7b\xfa\x50\x26\x20\x18\xd7\x67\ -\xa0\xff\x9c\x65\xd4\xc1\x32\x1b\x0a\x90\xd1\x40\x53\xa1\x7a\xc9\ -\x60\x4b\x9b\x22\x40\x25\x25\x44\x74\xd9\x19\xda\x0c\xb5\x97\x06\ -\x86\x10\x46\xf8\x41\x9b\x9d\xd7\xbe\xdf\x6f\xf8\x65\x97\x6a\x57\ -\x55\x52\xfe\xe6\x2a\xfd\x3f\xf2\x2f\x5d\x35\x3b\x68\x7d\x2e\xc3\ -\xbc\x02\xad\x40\x25\x41\xc5\x2d\xd3\xcd\x07\x12\x18\x21\x19\xa5\ -\xd2\x8e\x41\x2c\x94\x24\x0a\x78\xa2\x63\x12\x08\xcb\x99\x62\x42\ -\xe1\xd1\x0a\xa9\x95\xa0\xd0\x90\x01\xd3\x52\x50\xae\xc7\x38\x21\ -\x93\x12\x73\x3f\x1e\x6c\xff\x8a\x80\xd0\x3e\xf1\x9f\x4c\x1d\x3d\ -\xa8\x5a\x5f\xfb\xf4\x05\x20\x9c\x01\x14\x21\xf3\x30\x0e\x4f\x00\ -\xf5\x64\xfa\x38\xec\xc8\x29\x4e\x66\x5e\xc8\x12\x67\x83\x73\x3e\ -\x3f\x09\xce\x4f\x2f\xe1\xd2\xbd\x85\xd9\xfb\xe2\x72\x6f\xdb\xbe\ -\xf9\x87\xdb\x70\x23\xf5\xbb\xe1\xc7\xe7\x01\xe3\xcd\x9f\x31\x0b\ -\x80\x0c\xa1\x8c\x03\x92\xa1\x44\x59\xc6\xdc\x23\xd0\x63\x88\x06\ -\xbe\xb4\x08\x14\x02\x80\xa9\xb1\x6f\x80\x3a\x61\x34\x17\x1f\xbb\ -\x2d\x1c\x91\xa1\x32\x38\xc4\x47\xc3\x5d\x74\xa0\xad\x30\xf6\x70\ -\xde\xf9\xb1\xda\xfc\xac\x1a\xf8\x0c\x35\x81\x54\x4c\x76\x95\xd0\ -\x15\xb9\xe6\x69\x91\xd4\x00\x47\x1d\x1e\xea\x5f\x3b\x82\x62\xcd\ -\xda\x1a\x88\x9e\x61\xfa\xcf\x9f\x7f\xe9\x00\x13\x45\xd3\x7f\x15\ -\xe5\xd7\x03\x08\x9c\x42\x38\x2b\x56\x70\x4f\x07\x64\x57\x59\xa3\ -\xa9\x33\x50\x58\xdf\xa5\x0b\xf0\x39\xd7\x20\xfc\x19\x3c\x1d\xfb\ -\x77\x82\x81\xb2\xe3\x04\x87\x45\x77\xcb\x96\xc9\xae\x01\x38\xdb\ -\x33\xc5\xd1\x22\x75\x93\x26\xbf\xd5\x69\x96\xfd\xea\x36\xe9\x01\ -\x7b\xbf\x68\x5a\x67\x49\x0f\xed\x93\xfd\xe9\x5b\x30\xf6\x2e\x77\ -\x33\x69\x6f\xdf\xbc\xdd\x9f\x50\xbd\x62\xb5\x04\x07\x4f\xf6\x04\ -\xf1\x98\x17\x65\xe1\x2c\x01\x59\xfb\x9b\x93\x79\x6d\x8c\x34\x21\ -\xbf\xa3\x93\xfb\x1d\x93\x2c\x4b\x97\x55\x77\xd1\x7d\x00\xcd\x71\ -\x81\x29\xae\xf6\xe1\xfa\x14\xa1\x1f\x3f\x39\x69\x2f\x7a\x9b\xd7\ -\x72\x95\x81\xd9\x3f\x26\x79\x11\xc7\x08\xb6\xb2\xf8\x9a\xb8\x68\ -\xdf\x17\x46\xf7\xba\x23\x87\xd3\xee\x15\xc6\x4a\xca\x0c\xa4\xad\ -\x9e\x8a\x76\x2c\x0e\x41\xb3\xcb\x32\xdc\x4e\x73\xb4\xc9\xed\x68\ -\xb7\xd5\x20\x76\x96\x61\xfd\xa0\x14\x67\x43\xa0\x92\x5d\x6f\xc4\ -\x87\x68\x45\x8e\x77\x83\xe2\x00\x43\xe8\xb2\xde\x2b\x94\x18\xc2\ -\xe4\x90\x16\x4a\x84\xf7\x39\xa3\x5c\x73\xcd\x75\x64\xde\x68\x83\ -\x80\x52\x63\x95\xe0\xea\xbd\x8c\xe1\x8e\x2b\x98\x24\xfe\xa1\x00\ -\xb5\x5c\x1c\x5d\x86\x65\x42\x1c\xf4\x5b\x0a\x6e\x03\x45\x49\xbf\ -\xbe\xa1\x61\xe1\x26\x20\x1a\xf1\xdf\xab\x86\x18\x85\x55\x8d\xb2\ -\xaa\x37\xea\x0c\x26\x9a\x5b\x18\x66\x06\x56\x05\xd3\xe5\x44\x6b\ -\x7d\x58\xb7\x3e\xcd\x4d\x6e\x3d\xa9\x2d\xb4\x5c\x22\x92\x84\x70\ -\x2b\x88\x41\x45\x63\x42\xa3\x9e\x59\xda\xe4\x27\x65\x2c\x31\x5c\ -\x8e\xc9\x98\x1c\xd2\x51\x07\xf0\x6e\x59\x3f\x02\x32\x93\xd2\x35\ -\x0e\x8c\x06\x92\x19\xc2\xf8\x05\xea\xcd\xc5\x68\xc0\x51\x59\x65\ -\x8f\x78\x39\x58\x3d\x19\x0d\xa7\x5c\xe2\xad\xd1\x10\x10\x58\x96\ -\x0a\xaa\x9f\x43\xc2\xa9\xcf\xe1\xf2\xbf\x7b\x2a\x90\x70\xad\x95\ -\x72\x4c\x45\x60\x35\xa1\x94\x7a\xc8\xb8\x46\x2a\x8a\x0c\xaf\x5c\ -\x24\x10\x3c\x7a\x91\x07\x63\x1a\x45\x84\xb3\xaa\xd6\xee\xbe\xc6\ -\x63\xe0\x14\x5c\x52\x3a\x76\x75\xc2\x82\xaa\x29\x8f\x07\x9c\x31\ -\x61\xe5\x58\x04\xcc\x6a\x61\x88\xf1\x32\x0f\x16\x95\x82\x58\xe1\ -\xaa\x88\xd4\x30\x6d\xb3\x9c\x82\x6f\x0c\x1f\xc3\xd9\x60\x20\x8a\ -\xbb\x11\x4b\x80\x26\xac\x26\x90\x23\x38\xf7\xb0\x15\x8e\x66\x39\ -\x75\xab\x49\xc5\x2d\xd6\x6a\xec\x0d\x22\xc3\xf4\x18\x85\x86\x6b\ -\x22\xb1\x98\x4f\x1b\x39\xc5\xf1\xdc\x31\xa9\xf5\x5c\xe9\x52\x8a\ -\x81\xda\x8c\x1d\x0b\x62\x54\x60\x6c\xbf\x0a\x69\xe8\x50\xb3\x32\ -\xf3\x00\x0c\xcf\x67\x01\x65\x98\x25\xdd\x38\x15\xda\x2a\xed\xc6\ -\x10\x5e\x5c\x11\x3e\xc6\x3c\xf4\xdf\x5c\xb8\xf3\x68\x65\xa8\xc2\ -\xa2\x18\x83\x65\x38\x6e\x4c\x03\x04\x86\xa0\x84\x3a\x06\xc5\x25\ -\xb3\x54\xc1\x30\x52\x33\x62\x41\xa5\x7c\x05\xd3\xe0\x20\xcc\xfb\ -\x76\x26\xd8\x84\x3c\x05\x59\x54\xe4\x39\x84\x45\xe9\xa3\x87\x7f\ -\x0c\xeb\x55\x99\x0c\x7a\xc5\xae\xe7\x43\xde\x76\xa5\x02\x85\xbd\ -\x6a\x7e\xd1\xb7\xea\x65\x08\xf6\xd2\xc0\x53\x68\xe2\xac\x19\x66\ -\xed\xb8\x03\x2c\x4e\x36\x9d\xad\xea\xba\x3f\xf6\xef\x22\xcd\xa7\ -\x0d\xd4\xde\x23\x03\xed\xd1\xe8\xf2\x86\x02\x47\x65\x32\x50\x46\ -\x12\xcd\x3d\x94\x7a\x6a\x08\x37\x66\x8c\x34\x64\xc4\x30\x32\xf7\ -\x39\x5c\x9a\x5e\x0e\x7a\xc9\x92\x3f\xb8\x8d\x00\x62\xcd\x11\x96\ -\xd2\xd9\xc3\x4a\xc2\x05\x22\x16\xa4\x49\x5b\x00\x1a\x31\x41\x29\ -\x67\x96\xa8\xb3\x36\xf2\xcf\x24\xb5\x97\xac\xf4\x64\x15\x4b\x94\ -\xfb\xf3\xe6\xdc\x85\x04\xae\x91\xc6\xdf\xb3\x8a\x49\xc4\xa0\x2f\ -\x8e\xab\x98\x0c\xac\x45\x9b\x46\xc4\x49\x15\x43\xae\x40\xf0\x5b\ -\xcd\x07\x75\xcc\x01\x4f\x2b\xab\x69\xbf\x8e\x21\xfb\x48\xae\xe8\ -\x90\x05\x20\x2d\xa0\x6d\x43\xed\x1c\x16\x37\xc7\x99\x85\x42\x3a\ -\x7a\xa6\x8c\x11\xf7\xfd\x4e\x12\x21\x9b\xc4\x8a\x2c\xee\x0a\x5a\ -\x93\xc5\x28\xa7\x9a\x59\xf7\x28\xc0\xb0\x35\x43\x16\xbc\xbc\x88\ -\x21\xfd\x09\x8e\x73\xea\x0b\x8b\x18\x72\x24\x11\x42\xd1\x7e\x15\ -\xfb\x61\x1d\xdf\x6b\x90\xbe\xd7\xf5\xe8\x66\xc0\x77\xf4\x80\xc2\ -\x60\x50\x48\xe7\xab\x77\xf4\x3d\xa5\x0c\x81\xcb\x77\xbe\x47\xff\ -\x8f\x02\xe8\x7c\x0f\x4a\xa5\xad\x69\x7c\x0f\x97\x50\xa4\xbc\x57\ -\xfa\x1e\xa0\x62\xfc\x72\xe7\x6b\x0d\xca\xc3\xc9\x25\xdc\x55\x45\ -\xb0\x01\x7f\xb3\xf3\x71\x3f\x06\xee\xf3\x9e\xce\x57\x84\x9c\x38\ -\x9e\x07\x14\xe4\x88\xf6\x04\xad\xe3\x59\xc0\x18\xd8\xa8\x15\x03\ -\xc7\x83\xc0\x1b\x89\x9f\xea\x3b\x9e\x83\x14\x80\x0a\x50\x73\xe4\ -\x78\x34\x03\x00\x1c\x65\x03\xc7\xbb\x48\x32\xdc\x72\x29\x9e\xf5\ -\xbc\x01\x94\x14\xb3\x4d\x3f\x2d\x91\xc2\xad\x6b\xb2\x9d\xe7\x15\ -\xd7\x42\x73\xe7\x79\xe6\x88\x2c\x3a\xee\xcb\x3d\x0f\x06\x25\xe0\ -\x46\x45\x2e\xe4\xae\xd8\x8f\x23\xe3\x10\x2b\x7f\x78\xc7\xfb\xec\ -\xad\xae\xa7\x16\x24\x50\xe0\x68\x47\xae\x17\x84\x22\x42\x7f\x10\ -\xd7\x4b\x72\x86\x51\x3e\xe7\x7a\x4e\xff\x67\x09\x9f\x0a\x81\x04\ -\xa7\xd9\x7f\x21\xe1\xf3\x63\xe7\xa3\x4c\x13\x42\xb9\x3e\xed\x58\ -\x15\x0a\x8f\xa4\xb2\xf7\x95\x6c\xf7\xd1\x09\xad\x08\xd7\xac\xef\ -\x7b\xd7\xb2\x52\x10\x4f\x45\x07\xce\x47\xfb\x81\x05\x34\x1d\x76\ -\xfe\x02\x2d\x0e\xba\x05\xf5\xbc\xeb\x35\x55\x28\x14\xd2\xf9\x18\ -\xc4\xc2\x70\xd3\x34\xa9\x02\x5e\x83\x23\x9a\x4e\xc5\x32\x8d\xae\ -\x49\xbc\x26\xdd\x3b\x88\xa2\x85\x23\x97\xba\x5e\xa3\x9b\xd1\x48\ -\x67\x97\x04\xfd\x1f\xbf\xd4\x9f\x7e\xad\x78\x75\xb1\xa7\xe0\x79\ -\x5c\x4a\xd3\x77\x3e\xc8\x1f\x1a\x45\x34\x73\xff\xd7\xc5\xde\x39\ -\xd3\x90\x3f\x6c\xce\xa7\x6f\xce\xf9\x70\x3d\x4e\x46\x79\xdf\xf5\ -\x0c\x6d\x95\x72\xec\xfb\x1d\x73\xbe\x54\x9a\x51\xc1\x9b\x70\x77\ -\xff\xa5\xa7\x1b\x2f\x03\xa8\x56\x18\x25\x34\x1e\xe1\x43\x22\xd0\ -\xfb\x5e\xea\x7b\x57\x9c\x02\x1c\xd3\x7d\x8c\xef\x3e\x83\xdf\xdf\ -\x5d\xdd\xb8\x8f\xd2\x77\x57\xff\x01\x40\xf9\x03\x4b\ -\x00\x00\x06\x77\ -\x00\ -\x00\x24\x04\x78\x9c\xe5\x99\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ -\x58\xe5\xd2\xa2\x2b\x4a\x24\xf5\x8e\xed\x1c\x12\x04\x09\x90\x5e\ -\xda\xb4\x3d\x06\xb2\x44\xdb\x6a\x24\xd1\x95\xa8\xb5\x9d\x5f\xdf\ -\xa1\xde\xb6\x6c\x64\x83\x7d\x65\x53\x01\x41\xa4\x99\xe1\xeb\xe3\ -\xcc\x70\xe8\x9d\xbd\xda\x67\x29\xba\xe1\x45\x99\x88\x7c\xae\x11\ -\x6c\x6a\x88\xe7\x91\x88\x93\x7c\x3d\xd7\xfe\xfc\xf8\x56\xf7\x34\ -\x54\xca\x30\x8f\xc3\x54\xe4\x7c\xae\xe5\x42\x7b\xb5\xb8\x9a\xfd\ -\xa4\xeb\xe8\x75\xc1\x43\xc9\x63\xb4\x4b\xe4\x06\xbd\xcf\x3f\x97\ -\x51\xb8\xe5\xe8\xe7\x8d\x94\xdb\xc0\x30\x76\xbb\x1d\x4e\x5a\x21\ -\x16\xc5\xda\xf8\x05\xe9\xfa\xe2\xea\x6a\x56\xde\xac\xaf\x10\x42\ -\x30\x6e\x5e\x06\x71\x34\xd7\xda\x06\xdb\xaa\x48\x6b\xc3\x38\x32\ -\x78\xca\x33\x9e\xcb\xd2\x20\x98\x18\xda\x60\x1e\x0d\xe6\x91\x1a\ -\x3d\xb9\xe1\x91\xc8\x32\x91\x97\x75\xcb\xbc\x7c\x31\x32\x2e\xe2\ -\x55\x6f\xad\x66\xb3\x63\xb5\x11\xf1\x7d\xdf\x30\xa9\x41\xa9\x0e\ -\x16\x7a\x79\xc8\x65\xb8\xd7\x8f\x9b\xc2\x1c\xcf\x35\xa5\xa6\x69\ -\x1a\xa0\x1b\x2c\x6f\x67\x15\x94\x00\x74\x0b\xff\x7a\xf3\x4e\x80\ -\x4b\x51\x15\x11\x5f\x41\x3b\x8e\x73\x2e\x8d\x37\x1f\xdf\xf4\x4a\ -\xdd\xc4\xb1\x8c\x47\xdd\x74\x3c\x8f\x46\x3d\x82\x9c\x87\x19\x2f\ -\xb7\x61\xc4\x4b\xa3\x93\xd7\xed\x77\x49\x2c\x37\x73\x8d\x59\x98\ -\x30\x78\xec\x5a\xb8\xe1\xc9\x7a\x23\x4f\xa5\x49\x3c\xd7\x60\xf6\ -\xd4\xf7\x9a\xef\x91\x73\x90\xc6\xa0\xed\x38\xe8\x35\x26\xf6\x29\ -\x26\xa8\x20\x36\x73\x1b\x9b\x6e\x09\x41\x2c\x22\x35\x27\xe8\x92\ -\x67\x49\x58\x49\x91\xc1\xae\x45\x51\x1a\x96\x65\xb2\x4a\x22\xf8\ -\x10\xf9\x36\xad\xd6\x49\xfe\x29\x0a\xd3\xa8\x4a\xc1\xa5\x3e\x95\ -\x5b\x1e\xc9\x22\x4c\x3f\xc5\x89\xf2\x3d\x58\x0d\xee\x78\xf6\x83\ -\xf3\xfd\x56\x14\x52\xdf\xc7\x5b\xa0\xea\xb8\x67\x95\x87\x4e\xb9\ -\x00\xed\x2c\xe6\xab\x52\x59\x35\x4b\x54\x5f\xb0\x46\x57\x43\x46\ -\xad\xed\x67\xac\xa6\x1b\xdf\x24\x7c\x37\xd8\x2e\xc3\xb2\xc1\x88\ -\xd0\x36\x5c\x83\xcb\xa5\xa2\x98\x6b\x2f\x56\xf5\xd3\x2a\x96\xa2\ -\x88\x79\xd1\xa9\x9c\xfa\x39\x52\x09\xd8\x96\x44\x1e\x9a\x20\x6b\ -\xfb\xee\xe6\xab\x7a\xed\xf5\xe6\x79\x7d\xb9\x09\x63\xb1\x9b\x6b\ -\xf4\x54\xf9\x45\x88\x6c\xae\xd9\xd8\xf6\x3d\xdf\x24\xa7\xda\x68\ -\x3f\xd7\x74\xd7\xc7\x0e\xf1\x5c\x6a\x4d\xb4\x30\x9e\x83\x89\x69\ -\x53\x66\xb9\x13\x65\x55\x14\x10\x85\x7a\x1a\x1e\x38\x2c\xaa\xfe\ -\xaf\xeb\xbf\xdc\x88\xdd\xba\x50\x70\x64\x51\xf1\xd3\x96\x4a\xa3\ -\x2f\x97\x62\x7f\x5e\x0d\x4e\x51\xa9\xf8\xd6\xab\x3c\x91\x10\x43\ -\xdb\xfd\xb8\xd7\x2a\x89\x79\x79\xbe\xe1\x2e\xc9\x81\x81\xde\x7a\ -\x33\x61\x3d\xe2\x53\x8b\xce\xb5\x5d\xd3\xbb\x60\x01\x53\x9b\x60\ -\x6e\x55\x87\xcb\xaa\x2c\xdc\x27\x59\xf2\x85\xc3\xba\x27\xa4\xcb\ -\x3c\xdc\xea\xeb\x54\x2c\xc3\xb4\x9d\xfd\xa2\xb6\x98\x1d\x61\x69\ -\x1a\x21\x24\x0f\x2a\x8e\xf7\x07\x25\xd3\x3a\xa1\xe2\xa9\x04\xcc\ -\x75\xec\x5e\x28\x8a\x04\xc2\x63\x34\xdf\x4e\x74\x18\x8b\x54\xd4\ -\x43\xd2\xde\xd7\xfe\x55\x7b\x9f\x7b\xaa\x3b\x8c\x75\xad\xdb\x1b\ -\x53\xbf\xaf\xe5\x19\x97\x61\x1c\xca\x70\x08\x82\x4e\x42\x7d\xdf\ -\xec\x56\x06\x09\x34\xf8\xfd\xcd\xdb\x45\x3b\xd0\x2c\x8a\x82\xbf\ -\x45\xf1\xb9\x1b\x17\x21\x65\x10\x2e\x45\x05\x5b\xa1\x2d\x7a\xf1\ -\x2c\x8e\x02\x48\x79\x90\x0a\x16\x49\x06\xae\xad\xb2\xe5\xaf\x90\ -\xe2\x66\xc6\xa0\x38\x32\x56\xb0\x86\x4e\x9b\x6e\x0b\xde\xe4\xce\ -\xb3\x07\x48\x1c\x65\x89\x6a\x64\xfc\x21\x93\x34\x7d\xaf\x06\x69\ -\x57\x3c\xea\x34\x91\x29\x1f\x84\x33\xa3\x9d\x7d\xbb\x36\x63\xb4\ -\xb8\x99\xd1\xad\xbe\xfe\x5a\x0f\x54\x8e\x82\xa2\xdf\xe8\x34\x5c\ -\x72\x70\x82\x0f\x4a\x89\x26\xda\x75\x21\xaa\x6d\x26\x62\xde\x36\ -\xef\x69\x42\xd6\xeb\xb7\x4c\x1e\x52\xd0\xaf\x60\xf6\x41\x9b\x68\ -\x5e\xaa\x0f\xbd\x4d\x13\x01\x69\x3e\x8b\x2a\x85\x74\x77\xc3\x73\ -\x11\xc7\x2f\x4b\x59\x88\xcf\x3c\x78\x61\x9a\x96\x67\x9a\xed\x67\ -\x13\x2d\x41\xff\x99\x26\x39\x87\x69\x04\xe5\xbf\x55\x58\xf0\xb1\ -\xf4\x1f\x91\xe4\x01\x70\xe3\x45\x27\xad\x3f\x52\xf0\x78\x19\x58\ -\x9d\x2c\x0e\x21\x13\x15\x45\x78\x08\x72\xa8\x08\xc6\x52\xb1\x5a\ -\x95\x5c\x0e\x23\x75\x53\x35\x31\x6b\x9f\x23\x47\x57\xcb\x65\xbe\ -\x4f\x7a\xe1\xd9\x43\x4a\x3d\xe7\x0f\x2a\xf5\x1c\x45\x05\xf8\xb7\ -\x8f\x2d\x97\xf9\x26\x73\xb8\x4e\x9c\x5e\x51\x1c\x99\x15\x60\xc7\ -\x30\x83\xc3\xca\xf1\xbd\xde\x2b\x66\xdb\x50\x6e\xce\xd1\x1f\xad\ -\x52\x91\x55\xcf\x31\x59\xda\x4c\x8a\x59\xd6\x29\xe2\x65\x25\xe5\ -\x7d\x01\xee\xf7\xbd\x5f\x07\x20\xfc\x0d\x99\xd7\x26\xfa\x0b\x75\ -\x60\x8e\x01\xab\x15\x41\xb4\x0e\x1c\x86\xcc\x2e\x72\x98\xa1\x14\ -\x85\x0e\x39\xfe\x26\x94\x55\xc1\x8f\x72\x49\x9f\x13\xc0\x49\x55\ -\x18\x41\x3a\x8e\xa2\xe7\x8e\xaa\x87\x74\xdd\xbf\xa1\x77\xc8\x3c\ -\x87\xcc\xfb\x7e\x90\x11\x0c\x3b\x68\x52\xdb\xdb\xee\xbf\x9d\xd9\ -\x05\x12\xfd\x29\x70\x4d\x3d\xec\xa1\xd7\x88\x61\xda\xbc\x4e\x5e\ -\x26\x74\x98\xeb\x52\xdd\xbc\x35\x9f\x7b\xf1\x19\xe2\xda\x16\xb1\ -\xed\x7b\x23\x90\x21\xbb\x4b\x49\xd7\xcc\xc6\x14\x45\x10\x47\xba\ -\x85\x69\x0d\xe5\xd2\xfb\x14\x85\x67\x3d\x7b\x10\xc4\xc4\xad\x2b\ -\xdc\x11\x84\x7e\xfb\x98\xf9\x4e\x51\x50\x82\xef\xc7\x27\x74\xff\ -\xd9\xa3\x70\xee\xcb\x2b\x9e\x7d\x80\x30\x7a\x67\x06\xec\xb9\x33\ -\x20\xce\x9d\x19\xdc\xbe\x08\xf9\x1e\x8f\xcc\x6c\x7c\x64\x32\x6c\ -\x35\x8b\x8e\x50\x57\xcf\x30\xa8\xc2\x2e\xbc\x5f\x38\x40\x75\xfa\ -\xc3\x00\x21\x5e\x57\x4d\xdd\x09\x08\x79\xd6\x40\xc6\x45\x15\xa1\ -\x7d\x51\x55\xbf\x4e\x5e\x2e\x21\x78\xcc\x44\xf1\xb0\x3e\xe1\x36\ -\x31\x72\xd7\x20\xb1\x7e\x18\x20\xfd\x62\xef\x06\xe4\xa1\x2a\x0b\ -\x6e\xae\x56\x13\x20\x0c\xdb\x8c\x7a\x8e\x63\x79\x4f\x72\xb1\x1d\ -\x6e\x69\x50\x8e\x78\x0d\x46\x1f\xdb\xc4\xf5\x2d\xef\xcc\x29\xe3\ -\xfa\x8f\x59\x76\x41\xd9\xec\x02\x19\xc6\xc8\x13\xb0\xd1\xad\xde\ -\x53\xa8\x8f\x29\x01\xaf\x75\x10\xa5\xd8\x6d\x64\x16\xb6\x15\x22\ -\x72\x26\xcf\x78\xe4\x71\x6b\x53\x13\x2e\xd3\xd4\xf7\x9e\xc2\x81\ -\x68\x7f\xb3\x71\xb1\x69\x3b\x16\x50\x42\xd4\xc2\xde\x35\x81\x48\ -\xbf\xe0\x43\x1e\x7d\xcc\x53\xe8\x49\xf1\x10\xab\x2d\x63\x06\x1e\ -\x08\x4e\x72\xe7\x9a\x38\xd8\x57\x0e\x65\x9d\xc5\xa3\xbb\xff\x0f\ -\x40\xf5\xcd\xb8\x8d\xb1\x9e\x08\x6a\xe3\xce\x82\x10\xf3\x29\x33\ -\xdd\xf3\x2e\xf4\xc8\xf7\xbf\x27\x64\x34\xca\x43\x04\x7b\x0a\x11\ -\xe9\x65\x5f\x83\xf4\x98\x67\xfb\x93\x42\xd2\xe9\x50\x05\x38\xd8\ -\xad\x33\xf3\xad\x29\xd9\xb7\xa6\x34\xb1\x93\x45\x98\x97\xea\xaf\ -\x29\x7a\xc4\x73\x58\x83\xfa\x93\x97\xee\x35\xb7\x34\xe7\x4c\x18\ -\x4f\xec\x0f\x73\x8d\x42\x92\x20\x36\xf3\x9c\xaf\x6f\x42\x0d\xde\ -\x33\x47\xfb\xe0\x44\x7e\x7c\xbc\x0f\x16\x64\x62\xdf\xb3\x7d\xd7\ -\x7e\x8a\x03\x81\x75\x07\x24\xc5\x3e\xac\xc9\x82\x80\x66\x97\x0a\ -\x72\xc5\xfe\xa1\xae\x68\xaa\xd4\x32\xc3\xd3\xea\xb3\xf5\x11\xfa\ -\x30\xe5\xa7\x8d\x9d\xfa\xfa\xa1\xb7\x32\x17\x7d\x18\xfd\xf6\x47\ -\x1c\x75\xc7\x87\x23\xc1\x6f\x0a\xae\xb4\xff\x81\x14\x2a\x2e\xa7\ -\xfb\xb0\xba\x2a\xd6\x42\x5d\x7d\x7f\xdd\xde\xfa\x1d\xe4\x41\xb1\ -\x58\xdb\xc0\x28\x13\x9c\x96\xc9\x5c\x9d\x3d\xdc\xd9\xea\xf1\x69\ -\x35\xff\xa0\x3c\x07\x54\x63\xa8\xce\x11\xd4\xfe\x37\x66\xc5\xb6\ -\xe3\xe4\x8e\x7e\x66\x84\x02\xdb\x6b\x65\xce\x68\x27\xd2\x09\x5d\ -\xf7\xeb\x74\xbf\x11\xed\xcc\x58\x2f\xae\x66\xea\xef\xae\x8b\xab\ -\xff\x00\x21\x49\x9d\x0d\ -\x00\x00\x0a\x59\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x70\x6f\x73\x74\x5f\ -\x70\x72\x6f\x63\x65\x73\x73\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\ -\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x78\x3d\x22\x2d\x31\x30\x32\x2e\x39\x31\x32\x39\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x79\x3d\x22\x37\x2e\x31\x36\x35\x36\x38\x33\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ -\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ -\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ -\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\ -\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\ -\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ -\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ -\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ -\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ -\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ -\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ -\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ -\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ -\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\ -\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x66\x32\x32\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x32\x39\ -\x32\x39\x39\x35\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ -\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x33\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x31\x37\x2e\x30\x36\x36\x36\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ -\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x31\ -\x2e\x33\x33\x33\x33\x33\x34\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x32\x64\x30\x66\x36\ -\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ -\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x36\x35\x34\x39\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\ -\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ -\x20\x31\x32\x2e\x39\x34\x39\x31\x37\x35\x2c\x31\x36\x20\x68\x20\ -\x38\x2e\x33\x38\x34\x31\x35\x38\x20\x76\x20\x2d\x33\x2e\x31\x39\ -\x37\x32\x30\x35\x20\x6c\x20\x37\x2e\x33\x33\x36\x31\x33\x39\x2c\ -\x35\x2e\x31\x31\x35\x35\x33\x20\x2d\x37\x2e\x33\x33\x36\x31\x33\ -\x39\x2c\x35\x2e\x31\x31\x35\x35\x33\x20\x76\x20\x2d\x33\x2e\x31\ -\x39\x37\x32\x30\x36\x20\x68\x20\x2d\x38\x2e\x33\x38\x34\x31\x35\ -\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x72\x65\x63\x74\x33\x38\x31\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ -\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\ -\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ -\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x06\xaf\ -\x00\ -\x00\x20\x4b\x78\x9c\xe5\x58\x6d\x6f\xdb\x36\x10\xfe\x9e\x5f\xa1\ -\xa9\x5f\x5a\xcc\x92\x28\x52\xef\xb5\xd3\x0f\x2b\xba\x16\xe8\x30\ -\x60\x6d\xb7\x8f\x05\x2d\xd1\xb6\x56\x59\xf4\x28\x29\xb6\xfb\xeb\ -\x77\x94\x44\x4a\xb2\x1d\x20\x6d\xb2\x75\x5d\x14\x04\x11\xef\x8e\ -\x6f\xcf\xdd\x3d\x77\xca\xfc\xc5\x61\x5b\x18\x37\x4c\x54\x39\x2f\ -\x17\xa6\x6b\x23\xd3\x60\x65\xca\xb3\xbc\x5c\x2f\xcc\x0f\xef\x5f\ -\x59\x91\x69\x54\x35\x2d\x33\x5a\xf0\x92\x2d\xcc\x92\x9b\x2f\xae\ -\xaf\xe6\x3f\x58\x96\xf1\x93\x60\xb4\x66\x99\xb1\xcf\xeb\x8d\xf1\ -\xa6\xfc\x54\xa5\x74\xc7\x8c\xa7\x9b\xba\xde\x25\x8e\xb3\xdf\xef\ -\xed\xbc\x17\xda\x5c\xac\x9d\x67\x86\x65\x5d\x5f\x5d\xcd\xab\x9b\ -\xf5\x95\x61\x18\xb0\x6f\x59\x25\x59\xba\x30\xfb\x09\xbb\x46\x14\ -\xad\x61\x96\x3a\xac\x60\x5b\x56\xd6\x95\xe3\xda\xae\x63\x0e\xe6\ -\xe9\x60\x9e\xca\xdd\xf3\x1b\x96\xf2\xed\x96\x97\x55\x3b\xb3\xac\ -\x9e\x8c\x8c\x45\xb6\xd2\xd6\xf2\x34\x7b\xd2\x1a\xb9\x71\x1c\x3b\ -\x08\x3b\x18\x5b\x60\x61\x55\xc7\xb2\xa6\x07\x6b\x3a\x15\xce\x78\ -\x69\x2a\x46\x08\x39\xa0\x1b\x2c\xef\x66\x95\x1c\x0a\x80\xe2\xd6\ -\xc3\xb4\xda\xf1\xee\x00\xff\x0e\x7e\xf5\x04\x25\xb0\x2b\xde\x88\ -\x94\xad\x60\x26\xb3\x4b\x56\x3b\x2f\xdf\xbf\xd4\x4a\x0b\xd9\x59\ -\x9d\x8d\x96\x51\xe8\x4f\xf6\x9d\xb8\xa4\xa4\x5b\x56\xed\x68\xca\ -\x2a\x47\xc9\xdb\xf9\xfb\x3c\xab\x37\x0b\x93\x78\xb6\x4b\xe0\xf1\ -\x5b\xe1\x86\xe5\xeb\x4d\x7d\x2a\xcd\xb3\x85\x09\x77\xc5\x71\xd4\ -\x8d\x47\xa1\xe4\x76\x06\xfd\xc2\x89\xd6\x20\x3b\xc6\xb6\x6b\x08\ -\xd7\x27\x61\x67\xa3\xae\x90\x64\x3c\x95\x67\x82\x25\xd9\x36\xa7\ -\x4d\xcd\xb7\xe0\xe3\x34\x2d\x68\x55\xe5\xab\x3c\x85\x01\x2f\x77\ -\x45\xb3\xce\xcb\x8f\x15\xbd\x61\x1f\x77\x05\xaf\x3f\xe6\x5b\x0a\ -\x70\x28\xc0\xf5\x7e\xec\xb0\xe3\xa2\xb6\x0e\xd9\x0e\x80\x0c\xc2\ -\x8b\xca\xa3\x52\x5e\x83\x76\x9e\xb1\x55\x25\xad\xba\x5b\xc9\x11\ -\x5c\xab\xd3\x81\x16\x9c\xc4\xa8\xf8\x59\xd0\x2c\x87\xd0\xec\xec\ -\x46\x2b\xa6\xbc\x28\x58\x0a\xf8\xd0\x62\x4f\x8f\x95\xa9\x0d\x60\ -\xa9\xe9\x54\x3f\x86\x6b\x5f\xf7\xfa\x79\x55\xf3\x9d\xb2\x05\x24\ -\xea\x63\x21\xaf\x0f\x42\x0b\x56\xe4\x22\x79\x02\xd1\x84\x22\xf4\ -\xbc\x15\x71\x70\x56\x5e\x1f\x13\xf7\xb9\x39\xcc\xe1\xab\x55\xc5\ -\x60\x63\x34\x92\xb5\x6e\x81\x19\xb0\x17\x31\x0d\xe7\x7e\xbb\xa1\ -\x4b\xbb\xb9\x97\x77\xf3\xf5\x6e\x73\x67\x7a\xed\xfb\xc1\xd8\xe6\ -\x48\xb2\x11\x0c\x72\xfa\xc9\x05\x3c\x6f\x87\x9b\x20\x1c\x6a\xf5\ -\xba\x17\x7e\x28\xf3\x1a\x92\xb7\xa9\x98\x78\x27\x13\xe0\xd7\xf2\ -\x43\xc5\xce\xac\xde\x0b\x5a\x56\x90\x6d\xdb\x85\x09\x81\x28\xf2\ -\xc3\x53\x88\xdd\x88\x44\xbe\x8b\xe3\x19\x92\x3f\xa3\xa1\x1d\x84\ -\xd8\xf3\x03\x9f\xcc\xb0\x4d\x50\x14\xc5\x7e\xfc\x6c\x38\xbe\x0b\ -\x88\xf9\x7a\x78\x84\x21\xc6\x83\x16\x2f\x4c\x6f\x50\xc2\x88\xa0\ -\x1e\xc7\xb9\x23\xe3\xb0\x7d\xd3\x59\x22\x53\x24\xbb\xc9\xd9\x7e\ -\x08\xd6\x25\xd5\xc7\xdf\x41\x36\xb4\xce\x04\xa0\x56\xed\xd3\x2b\ -\x96\x5c\x64\x4c\x28\x55\xd0\x3e\x13\x55\xef\xef\xae\x0c\x5c\x4d\ -\xfd\x22\x57\xd5\x7a\x74\x59\x5f\x6d\x68\xc6\xf7\x70\xb3\x53\xe5\ -\x67\xce\x01\x42\x17\x28\x21\x0e\x23\x74\xa6\x4e\x0f\x0b\xd3\x72\ -\x03\x3b\x8a\xdc\xc8\x8b\xcf\xb4\xf2\x40\xbe\xed\x85\x3e\x46\xd1\ -\x99\xb2\x11\x02\x1c\x65\x15\xf4\xc8\xe0\x56\xed\x1f\x15\x0c\xd5\ -\x86\xef\xd7\x42\xa2\x53\x8b\x86\x9d\xce\x94\x1a\x6b\xb9\xe4\x87\ -\xcb\x6a\x60\xa2\x46\x96\x20\xab\xe9\x22\x65\x77\x18\xaf\xda\xe4\ -\x19\xab\x2e\x4f\xdc\xe7\x25\x80\x60\xf5\x14\xea\x12\x8d\xf1\xa9\ -\x85\xe2\xd3\xf0\xfc\x56\xbd\xc5\x61\xc8\xe9\x53\xd5\xf1\x76\xd5\ -\x96\x1e\xf2\x6d\xfe\x99\x65\x43\x8e\x6a\x93\xaa\xa4\x3b\x6b\x5d\ -\xf0\x25\x2d\xfa\xd3\xf7\x59\x39\x81\x45\x05\x62\x7d\x94\xc5\xe3\ -\x70\x94\xb2\x49\x82\x49\x01\x09\x83\x21\x9e\xb9\xc8\x81\x93\x0f\ -\x63\x0e\xea\x44\xc7\xb1\x48\x96\x1a\xe8\x2b\x0e\x6d\x80\xb5\xe1\ -\x17\x9e\xea\x8e\x63\x9d\xca\x80\xf3\xc0\x6f\xe5\x5b\x56\xd3\x8c\ -\xd6\x74\xc8\x02\x25\xc1\x71\x8c\xd4\xcd\xa0\xc6\x27\xbf\xbd\x7c\ -\xa5\x19\x30\x4d\x93\x3f\xb8\xf8\x34\x90\x97\x34\xa0\x4b\xde\x80\ -\x2b\x34\x2b\xcb\x62\x90\x26\x32\xf3\x69\x7d\xdd\xd6\x17\x59\xd0\ -\x7f\x84\xba\x0a\xf9\xa8\x15\x13\x63\x09\xd6\xb0\x68\xb7\xac\x60\ -\x5d\xc1\xbe\xd8\xe3\x64\xe9\x36\x97\x93\x9c\x77\x75\x5e\x14\x6f\ -\xe4\x26\x23\xa6\xee\x17\xcd\xeb\x82\x8d\xe8\xdb\xe9\x4f\xaf\x18\ -\x76\x74\xb9\xb9\xa3\x6e\xdf\x8e\xd6\x03\x2a\x93\xa4\xd0\x8e\x2e\ -\xe8\x92\x41\x10\xbc\x95\x4a\xe3\x4c\xbb\x16\xbc\xd9\x6d\x79\xc6\ -\xfa\xe9\x0a\xcd\x1d\xad\x37\xda\x65\x5d\xf5\x58\xc1\xe9\x13\xb8\ -\xd7\xd3\x27\xe7\xbc\xfb\xec\xb9\xd4\x8e\xca\x56\x3b\x14\x4d\x01\ -\x15\xf8\x86\x95\x3c\xcb\xa0\xd2\x08\xfe\x89\x75\xf9\x92\x68\xdf\ -\x0f\xdc\x28\xdd\x6a\xb8\x44\x52\x6a\x18\x87\xc0\xad\x28\xc0\x31\ -\x21\x91\x91\x1a\x16\x98\xa3\x30\x8c\x82\x19\x92\xef\x91\x4b\xe2\ -\x30\x04\x22\x8e\x50\xe0\xc6\xc8\x1d\xc9\xfa\x17\xdf\xf8\xdd\x70\ -\xc3\x6e\x8f\xd0\x78\x6d\x78\x76\x80\x60\xba\x4b\xba\xc5\xe2\x20\ -\x0c\x11\xf6\x60\x35\x17\x16\xc1\x98\x04\x1e\x4c\xf5\xec\xd0\x0f\ -\x43\xb0\xbf\x28\x2c\x8c\xbe\x06\x60\x55\x0c\xb0\x92\xb8\x33\x4b\ -\x8b\x52\x03\xc9\x65\xb1\x1d\xc6\x08\x05\xe1\xcc\x3a\x5f\x16\x8f\ -\x85\xaf\x0d\xec\xda\xa4\x7d\xe0\xcc\xc4\x8e\xc2\x20\x86\x9a\xd2\ -\xae\xa3\xae\xed\xc5\x86\xd5\x5f\xd6\x9d\x59\xfa\x8a\xfa\x6d\x24\ -\xfb\x3c\x49\x5f\x01\x05\xd6\x27\x5e\x34\x08\x87\xea\x5b\x96\xa0\ -\xe4\xc2\x02\x62\xbd\xa1\x75\x23\x98\x4c\x60\x5d\xd2\xe5\xcc\x4b\ -\xee\xef\x0b\xcd\x5d\xbd\x2d\xdb\x0c\x2f\x42\x68\xea\x7c\x3d\x94\ -\x71\x04\xc7\x49\xaa\xbf\x1a\x2a\xd8\x58\xfa\x27\xcf\xcb\x04\xd2\ -\x86\x09\x25\x6d\x07\x05\x10\x5e\x9d\x78\x4a\x96\x51\xa8\x44\x42\ -\xd0\x63\x52\xc2\x37\xcb\x58\xda\x35\x2f\xc3\x4e\xba\xc3\xe9\xb1\ -\x26\xe4\x0c\x28\x12\xc7\x43\x77\xa1\x58\x1d\x7c\x13\xc2\x33\x20\ -\xa8\xc8\xfc\x5c\x03\x6c\xa7\x5c\x39\x2a\xf1\x20\x24\xb6\x37\xa5\ -\x40\x31\xe1\x4f\xd1\x52\xa1\x8b\xa0\xb9\x20\x43\x0b\x77\x6b\x02\ -\x8e\x6e\xda\x35\x71\xa7\xe8\xba\xb6\x4f\x70\x24\xbb\xbb\x53\x98\ -\x97\x4d\x5d\x3f\x14\xc8\xda\xf7\xe3\xfc\xfd\x65\x08\xe6\x99\xbe\ -\xb6\x0c\x6b\xcf\x8e\x3c\x78\xfc\x09\xe8\xf2\x86\x40\xe0\xc1\x9d\ -\xa3\x53\xc3\xa1\xcb\x04\xf0\x96\x64\x56\xa8\xd0\x69\xfa\x00\xd0\ -\x01\xe7\x44\x44\x7e\xa9\x7d\x0b\xe8\x08\xb1\xc3\x36\xa2\x66\xea\ -\xc3\x8b\x48\x76\xc0\xb6\x77\x09\xb5\xbb\xe7\xf4\xff\x19\xb5\xad\ -\x0c\xb8\x20\x82\x27\x9e\x01\x7e\x3d\xdf\x03\x77\xda\xa1\x2b\x1f\ -\xa0\xe2\x8b\xaf\x67\x88\x42\x2e\x63\x0b\x7d\x39\x4f\x7e\xa7\xa0\ -\x41\x80\xe9\x50\xf3\x5a\xf8\x54\xc1\xf1\xb0\x7c\x6e\x7b\x3f\xc7\ -\x2d\xf2\xfe\x39\xd4\x22\x76\xce\x6d\x01\xf1\xe5\xbf\x5d\xf0\xb7\ -\x40\x0d\x7c\x26\x59\xcc\x9b\x11\x64\xe3\x0e\x1b\xd5\xc7\xc8\x0e\ -\x80\xf8\xf2\x31\x70\x97\xbc\xde\xcc\xc2\x3d\xeb\x81\x55\x9f\xd9\ -\x83\x95\x16\x11\x1b\xab\x81\x6c\x69\xba\x08\x35\xde\x1a\x3a\x9c\ -\x67\x04\x1b\xc4\xb7\xe3\x36\x72\xb5\xf4\xcc\x13\x1e\x22\xe1\xa3\ -\x89\x5f\x80\xa3\x85\xf1\x41\xe2\xd7\xfa\x8a\xfe\xe8\x3b\xc5\x2d\ -\xb6\xfd\x8e\x01\x1f\x04\xb7\xf8\xb1\xe0\x46\x5c\x1b\xf7\x45\xe6\ -\x21\x70\x7b\x34\x75\x66\xc4\x61\x0f\x81\x1b\x79\x2c\xb8\xe1\xd0\ -\x0e\xbb\x2e\xfa\x41\x70\xbb\x7b\x87\xfd\x5d\x7f\x7d\x4c\x9a\x41\ -\x95\xb1\x5f\xdf\x0c\x5a\xf8\xf1\xc1\xa6\x0b\xc4\x3d\x60\x73\x1f\ -\x21\x6c\x2a\x5f\xef\x01\xdb\xbf\x49\x6e\xff\x15\xd8\x54\x1b\x77\ -\x0f\xd8\xbc\x47\x08\x9b\xfa\x7a\xbb\x07\x6c\x5f\xda\xba\xcd\x9d\ -\xf5\xf5\xd5\x5c\xfe\x6f\xfc\xfa\xea\x6f\x89\xcc\x6b\x21\ -\x00\x00\x09\xbc\ -\x00\ -\x00\x22\x51\x78\x9c\xe5\x59\x5b\x6f\xdb\xd8\x11\x7e\xf7\xaf\x60\ -\xe5\x97\x04\x15\xa9\x73\xbf\x28\xb6\xf7\x61\x83\x5d\x2c\xb0\x45\ -\x81\x6e\x82\x02\x7d\x59\x50\x24\x65\xb3\xa1\x48\x81\xa4\x2c\x29\ -\xbf\xbe\xdf\xa1\xc4\x8b\x2e\xb6\xe5\xc4\xbb\x45\x51\x09\x41\xc4\ -\x73\xe6\x5c\x66\xe6\x9b\x99\x6f\xe8\x9b\x1f\x36\x8b\xcc\x7b\x4c\ -\xca\x2a\x2d\xf2\xdb\x11\x0d\xc8\xc8\x4b\xf2\xa8\x88\xd3\xfc\xfe\ -\x76\xf4\xf9\xd3\x4f\xbe\x19\x79\x55\x1d\xe6\x71\x98\x15\x79\x72\ -\x3b\xca\x8b\xd1\x0f\x77\x57\x37\x7f\xf1\x7d\xef\xc7\x32\x09\xeb\ -\x24\xf6\xd6\x69\xfd\xe0\xfd\x92\x7f\xa9\xa2\x70\x99\x78\xef\x1e\ -\xea\x7a\x39\x9d\x4c\xd6\xeb\x75\x90\xee\x07\x83\xa2\xbc\x9f\xbc\ -\xf7\x7c\xff\xee\xea\xea\xa6\x7a\xbc\xbf\xf2\x3c\x0f\xe7\xe6\xd5\ -\xb4\xa8\x66\xb7\xa3\xc1\x8a\x62\x99\xe4\xd5\x3a\xac\xa3\x87\x59\ -\x51\x7c\x69\xd6\xad\xca\x74\xc2\x08\xb1\x13\xc8\x8e\xfa\x95\x71\ -\xd4\x2d\x5c\xae\xca\xac\x11\x8d\xa3\x49\x92\x25\x8b\x24\xaf\xab\ -\x09\x0d\xe8\x64\x20\x1e\xf5\xe2\x91\xbb\x77\xfa\x98\x44\xc5\x62\ -\x51\xe4\x55\xb3\x32\xaf\xae\x07\xc2\x65\x3c\x3f\xb8\xd5\x9a\x37\ -\x42\xd4\x5a\x3b\x21\x6c\xc2\x98\x0f\x09\xbf\xda\xe6\x75\xb8\xf1\ -\x0f\x97\x42\xbb\x73\x4b\xa1\x00\x99\x60\xae\x97\xbc\x4c\x6a\xba\ -\xc9\x60\xc4\x27\x2f\xd3\xcc\x0e\x4f\x87\xe3\x96\xf8\xd7\x2d\x68\ -\x07\x82\xaa\x58\x95\x51\x32\xc7\xca\x24\xc8\x93\x7a\xf2\xf1\xd3\ -\xc7\x6e\xd2\x27\x41\x5c\xc7\x83\x6d\x5a\xbf\x1d\x9c\x7b\xe0\xcc\ -\x3c\x5c\x24\xd5\x32\x8c\x92\x6a\xd2\x8e\x37\xeb\xd7\x69\x5c\x3f\ -\xdc\x8e\xb8\x08\x28\xc7\x47\x36\x83\x0f\x49\x7a\xff\x50\x1f\x8f\ -\xa6\xf1\xed\x08\xba\x32\x6b\x75\xf3\x3c\x00\x21\xdd\x09\xec\x37\ -\x9e\x76\x33\x24\xb0\x2c\xa0\x5e\x49\x25\xd7\x3b\x99\x56\x85\x69\ -\x5c\x44\xee\x4e\xd8\x32\x59\xa4\xe1\xaa\x2e\x16\xf0\x71\x14\x65\ -\x61\x55\xa5\xf3\x34\xc2\x43\x91\x2f\xb3\xd5\x7d\x9a\xff\x7e\x5f\ -\x24\xd5\xef\x75\x51\x64\x41\x6b\xea\xee\xa4\x64\xb3\x2c\xca\xda\ -\xdf\xc4\x4b\x98\x50\xe9\xb3\x93\xdb\x76\xf2\x0e\xb3\x37\xdd\x05\ -\xdc\xe9\xf1\x63\x9a\xac\xdd\x9a\x9d\x76\xb3\xb0\xda\x59\xc5\xf3\ -\x96\xe1\x3d\xf0\x96\x15\xe5\xed\xe8\x7a\xde\x7c\xf6\x13\xb3\xa2\ -\x8c\x93\xb2\x9d\x52\xcd\xe7\x60\xaa\x80\x95\xd3\x7a\xbb\x8b\xcd\ -\xfd\xde\xed\x8d\xdc\xae\xdd\x3c\x39\x3f\x5f\x3d\x84\x71\xb1\xbe\ -\x1d\xb1\xe3\xc9\xaf\x45\xb1\xb8\x1d\x89\xe3\xe1\x68\x73\x3b\xf2\ -\x29\x0b\x04\x1c\xc3\xf5\xc9\xec\xb6\x71\xa3\x55\xc2\xf0\x93\x1d\ -\xa3\x55\x59\x22\xf6\xfc\x2c\xdc\x26\xd0\xa6\xf9\x8f\xee\x85\xaa\ -\x87\x62\x7d\x5f\x3a\xab\xd4\xe5\x2a\x39\x5e\xe9\x66\xfc\xd9\xac\ -\xd8\x9c\x9f\x86\x73\x57\x2e\xaa\xfd\x55\x9e\xd6\x88\x9c\xe5\x66\ -\xb8\xeb\x2a\x8d\x93\xea\xfc\xc2\x2a\x0f\x97\xfe\x7d\x56\xcc\xc2\ -\xec\xbc\xc0\x3a\xcd\x61\x1d\x7f\x0f\x5b\xca\x3b\xe3\x1f\x4b\xb4\ -\x18\xd6\xc4\x3c\x21\x81\xbb\x9f\x38\x60\x3f\xb5\x7d\x7a\x6a\x11\ -\x6e\xd2\x45\xfa\x35\x81\x61\x68\x83\x28\x60\xea\xc0\x2c\xbb\x65\ -\x3b\x40\xb9\x67\x4e\x88\x1c\xb5\x83\xf5\xd6\x05\xe9\x66\xeb\x26\ -\xba\xc1\xa2\x4c\x01\xf3\xc1\x75\xda\xa1\xed\x70\xc8\x45\x2f\x92\ -\xfc\xa6\x01\x56\x03\x3b\x7d\x3c\xb7\x1d\xce\x79\x93\x06\xef\x93\ -\x53\xc0\x37\xe3\x71\x32\xaf\x7a\xe4\xbb\x27\xe0\xc7\xb6\x1a\x21\ -\x4d\x25\x61\xf9\x73\x19\xc6\x29\xdc\x38\x54\xe9\x70\x46\x1a\xd9\ -\xae\x71\xb1\x55\x17\xcb\x56\x16\x97\xaa\xb7\x99\x8b\x6f\x0c\xfa\ -\x4d\xbc\x4c\xaf\x6d\x14\x86\x84\x7c\x68\x86\xf6\x71\x30\xa5\x1f\ -\x46\xfd\x9a\x62\x3e\xaf\x92\x7a\xa8\xf6\x3e\xef\x60\x85\x34\x8a\ -\xee\xb5\xba\xf0\x34\xca\x63\x3a\xbb\xe0\x34\x7a\xfe\x34\xde\x9d\ -\x76\x33\x39\x54\xfb\xd5\x56\x62\xfd\x11\xa8\x8a\x88\xf3\x34\xc7\ -\xb9\x55\x91\x01\x06\x97\x2b\x34\x57\xa8\x37\x47\xe6\x23\x81\x36\ -\x86\x71\xc9\x5f\x61\x47\xf6\x86\x9a\x51\xf9\x26\x9a\xcd\x67\x7a\ -\xa6\xbf\x19\x18\x54\x7f\xa3\x42\x5d\x26\x2c\xb2\x2c\x89\xb0\x7f\ -\x98\xad\xc3\x6d\xd5\x1d\xd2\xd4\xeb\xe9\x43\x99\x80\x5f\x5c\x9f\ -\x81\xfe\x73\x96\x51\xbd\x65\x36\x14\x20\xa3\x81\xa6\x42\x0d\x92\ -\xc1\x96\x36\x45\x80\x4a\x4a\x88\xb0\xaa\x97\x66\xc8\xd9\x34\x30\ -\x84\x30\xc2\x7b\x69\x76\x5e\xfa\x7e\x7f\xe0\xe7\x5d\xaa\x5d\x55\ -\x49\xf9\x9b\x2b\xf4\x7f\xcf\x3f\x77\xd5\xac\x97\xfa\x54\x86\x79\ -\x05\x56\x81\x4a\x82\x82\x5b\xa6\x9b\x77\x20\x13\xcc\x32\xab\xad\ -\x11\x63\x1f\xe9\x83\x49\x25\xa8\x1c\xbb\x44\x42\x09\x13\x76\x0c\ -\x01\x4a\xac\x54\x9c\x88\x31\xe3\x81\xd4\x42\x19\x36\xc6\x05\xa5\ -\xd5\x9a\xbe\xef\x2d\xff\x8a\x70\xd0\x3e\xf1\x9f\x4c\x1c\x03\xa0\ -\x5a\x5f\xfb\xf4\x05\x18\x9c\x81\x13\x21\xf3\x30\x0e\x4f\xe0\xf4\ -\x64\xf2\xe8\x4f\xe4\x14\x37\x33\x2f\xe4\x88\x33\x27\x9a\xd0\x7d\ -\x8f\x42\xf3\x25\x50\xba\xa7\x30\x7b\x5b\x50\xee\x4d\x3b\xb4\xfe\ -\xe1\x31\xdc\x48\xfd\x76\xe0\x01\x1e\xb8\x94\x5c\x51\x00\xc6\x0a\ -\xaa\xad\x65\x0e\x30\x4a\x11\xc3\x89\xe2\x0d\xa2\xb8\xc0\x57\x8d\ -\xb5\x0a\x94\x85\xb0\x18\x03\xc6\x82\x0a\x43\xed\xfb\xee\x08\xc7\ -\x62\xa8\x0c\xfa\xe0\x70\xc4\x85\xea\x40\x5b\x61\x6c\x7f\xdf\xf9\ -\xb1\xd8\xfc\xac\x18\xc8\x0c\x35\x81\x54\x4c\x76\x65\xd0\x55\xb8\ -\xe6\xd7\x22\xa9\x81\x8d\x3a\xec\x8b\x5f\x3b\x82\x4a\xcd\xda\x02\ -\x88\x7e\x61\xfa\x8f\x8f\x3f\x75\x78\x89\xa2\xe9\x3f\x8b\xf2\x4b\ -\x8f\x01\x27\x10\xce\x8a\x15\xdc\xd3\xe1\xd8\x95\xd5\x68\xea\x0c\ -\x14\xd6\x77\xe9\x02\x64\xce\x35\x07\x7f\x05\x47\xc7\xf9\xdd\xc4\ -\x81\xb0\x23\x04\xfd\xa6\xbb\x6d\xcb\x64\x47\xfe\xcf\xf6\x4b\x71\ -\xb4\x48\xdd\xa2\xc9\x6f\x75\x9a\x65\xbf\xb8\x43\x06\xb8\xde\x6f\ -\x9a\xd6\x59\x72\xd7\x9c\xb9\xfb\xd9\x6a\x31\xd9\xab\xd1\xa2\x72\ -\xa0\xe5\xcd\xa4\x35\x43\xf3\x74\x7f\x42\xf8\x8a\xd5\x72\x51\xc4\ -\xc9\x9e\x26\x1e\xb3\xa3\x2c\x9c\x25\xa0\x6c\xbf\xba\x39\xaf\x8d\ -\x95\x26\xf4\x77\xa4\xb2\x35\x2b\xf0\xdc\x91\x96\x5d\x14\xcd\xa1\ -\xc6\xf4\x3a\x51\xee\xfb\xc1\x3d\x0c\x22\xb6\x79\x2c\x57\x19\xb8\ -\xfc\x63\x92\x17\x71\x8c\x00\x2b\x8b\x2f\x89\x8b\xf0\x7d\x29\x74\ -\x8f\x3b\x3a\x88\x52\x48\x29\x97\x44\x4b\xd5\x8e\xc3\x54\x49\x99\ -\x81\xaf\xd5\x53\xd1\x8e\xc5\x21\x18\x76\x59\x86\xdb\x69\x8e\x06\ -\xb9\x1d\xed\xce\x3c\x8c\x1c\x5c\x57\x5a\xaa\x7c\x31\x08\xa9\x96\ -\x7b\xa2\xb9\x21\x72\x98\xa1\xbb\xb6\x09\x25\x99\x28\x21\x58\x1f\ -\xb1\xa0\xe8\x4c\x04\x46\x0b\x3d\xa8\x0a\x5b\x37\xca\x03\xd4\x6e\ -\x63\xfb\xed\xcb\x86\xe1\x71\xc5\xa9\x24\xa2\x1f\x85\x30\x0b\x0c\ -\x97\xe0\xf1\x7d\xee\xaf\xcf\x65\x73\x43\x8d\x14\x4a\x68\x17\x87\ -\x48\xd6\x42\x10\x4e\xdd\x6f\x21\x29\x63\x42\x34\xbf\x8d\x65\x82\ -\xe2\xf6\x63\x32\x26\x7d\x10\x76\xde\xec\xf6\xf5\x23\x84\x7d\x52\ -\x3a\xae\x2c\x10\xd4\x96\xa2\x20\x5c\x20\xee\x34\x93\x01\x35\x94\ -\x59\x31\x28\xcd\x49\x96\xa5\xcb\x2a\x39\x07\x00\x20\xfc\xdd\xf5\ -\x69\xa2\x7a\xff\x9d\x88\x78\x2b\x20\x2c\xc3\xfa\x41\x29\xce\x0e\ -\xf3\x15\xd9\xb5\xc7\xfc\x30\x69\xa1\xce\xbb\x41\x71\xe0\x51\x76\ -\xe4\x4a\xf4\x6b\xbd\x5d\xdc\xee\x4f\x1a\xe5\x94\x56\x7c\xaf\x51\ -\x02\x62\xe0\x49\x24\xeb\xe7\xac\x73\x6a\x07\x98\xe1\x6f\x1e\x1a\ -\x4d\x33\xa6\x02\xb5\xdf\x12\xee\x99\x40\x4b\x2d\x05\x05\x8e\x02\ -\x14\x6b\x18\x48\x7b\x3f\x62\x54\x10\x49\x28\x6d\x90\x86\xc6\x9f\ -\xa2\x18\x68\xb7\x12\xf0\xd7\xb2\xa9\x0f\x80\xa1\xb0\x90\xf0\x28\ -\x0f\xc0\x22\x20\xd0\x54\x0d\xcd\x41\x6e\xb8\xf5\x7e\xf5\xa8\x02\ -\xd8\x85\x92\xae\x80\x30\x08\x0a\xa2\xbd\xc8\xc3\x6f\x66\x8d\x94\ -\x4e\x98\x71\xb7\xaf\xf0\x78\x20\xac\x00\xb6\x71\x05\xc4\x9c\x24\ -\x60\x25\x18\x33\x42\x39\x42\x03\x16\x25\x24\xf2\xba\x16\xd8\x13\ -\x11\xa8\x99\x20\x96\x3b\x05\x10\x15\x52\x1a\xec\xe9\x2e\x83\x10\ -\xb7\x90\x95\xae\x85\xa6\x9e\xbb\x1f\x63\xd8\x7f\x8c\xe0\xc4\x1d\ -\x94\xf4\xfc\xfd\x46\x7c\xbc\xdf\x5a\x7a\x88\x1c\x27\x69\x19\x53\ -\xd0\x09\xd5\x8f\x71\x61\x99\x07\xdc\x33\x4e\xac\x72\x43\x50\x05\ -\x05\x0f\x16\x81\x96\x9c\x5b\xe9\x68\x95\x33\x8e\xb2\xac\xd1\x9c\ -\x11\xc1\x10\xa7\x28\x68\x56\xe3\xda\xf4\xc8\xba\xff\x3a\xc9\x45\ -\x10\x97\xa7\xe1\x17\x15\x79\x8e\xc9\xa2\xf4\xd1\xd0\x3f\x86\xf5\ -\xaa\x4c\x0e\x1a\xc7\xae\x01\x44\xfa\x76\xa5\x03\x85\xbe\x6a\x3e\ -\xd1\xd7\xea\x65\x10\x0e\x82\xe3\x29\x3c\x31\xae\x08\x67\x96\xb7\ -\xe3\x0e\xb2\xb8\xd9\x74\xb6\xaa\xeb\xe1\xd8\xbf\x8b\x34\x9f\x36\ -\x60\x7b\x8b\xb8\xdc\xe1\x91\x06\xc2\x91\x0d\xf0\x0f\xf8\x42\x13\ -\x6e\x94\xe7\x82\xcb\x5d\x93\x8e\xc1\x01\x9a\x50\xe4\x27\xc1\x2c\ -\xcd\x80\x42\xbf\x64\xc9\x37\xb1\x91\x26\x14\x38\x97\x7f\xba\x8d\ -\x16\x1e\xc3\xe9\xcd\x3b\x81\x31\x03\x05\x73\x1f\xe3\xd9\x40\xed\ -\x4c\xa4\x9d\xfd\x86\xef\x12\x86\x16\xf2\xf9\xeb\x6d\xf4\x07\x97\ -\x78\x82\x6c\xa1\xb5\x7d\x36\x77\x7d\x6b\x89\xf7\xd5\x71\x91\x47\ -\x64\x22\x2e\xc5\xa0\x10\xf7\x45\x9e\x51\x8b\xa0\xe5\xc3\x22\x6f\ -\x41\x44\x15\x57\x03\x82\xed\x72\xbd\x08\xa8\xd6\xa8\x84\x07\x05\ -\x01\x7d\x3b\xba\x38\xc1\xa4\x3c\xaa\xf1\xc8\x8c\xc8\x2f\xf4\x99\ -\x1a\x0f\xa0\x4b\x64\x54\xc1\x54\x93\x60\xd1\x9b\x69\xcd\xe5\xd8\ -\xfd\x94\x5c\x30\x6d\xc6\x4e\x02\xb5\x9e\xc9\x57\xd4\x77\x1f\xb9\ -\xc7\x58\x2c\x17\x97\x15\x78\x86\x56\x91\x5a\xa2\xfe\xe7\x33\x48\ -\x93\x73\x55\xd0\xdc\x8b\x7a\x20\x64\x28\xdf\xe8\x62\x90\x9f\xd1\ -\x40\x58\x61\xcf\x47\x06\xfb\x73\xb3\xc7\x7f\xcf\x3e\xfb\x4c\x81\ -\xd2\x27\x83\x86\xed\x08\xe6\x32\x8a\x6c\x8c\x04\xdb\xa1\xd4\x19\ -\xc6\xce\x1b\x49\xff\xdf\xa4\xd8\xae\xe4\x1c\xa4\xd8\x97\xb2\xeb\ -\x2b\x50\x74\x51\x0c\x1b\x24\x7a\x42\x89\xbe\x94\xa3\x83\xd5\x28\ -\xb4\x02\xc3\xf7\x81\x4f\xa6\x6f\x11\xbb\xef\x77\x77\x68\x8e\xaa\ -\x59\xcd\xfe\x80\xf4\xcd\x8f\x93\x37\xb8\x01\x3c\xd2\xfe\xe5\xc9\ -\x7d\xda\xe4\x8d\x68\xd7\x60\x63\x83\x3c\xbd\x71\x19\xdd\x72\xb4\ -\x4d\xe4\xa0\x41\x63\x12\xf4\xd2\x08\xcd\x0e\x92\x37\xfa\x33\xac\ -\x47\x61\x38\xc8\xdd\xe0\x6d\x12\xd9\x5f\x89\xe7\x73\xb7\x51\x9c\ -\x6b\xdb\x90\x63\x8a\xf3\x38\x18\xa0\x6b\xce\xb8\x6b\xf9\xb8\x23\ -\xd2\x96\x72\x06\x9d\x5e\x93\xbb\x15\xc0\x4f\x19\x68\xfd\x65\x8e\ -\x17\x01\x58\x30\xb1\x56\x5c\xe0\xf7\x26\xe6\xf9\x77\xfb\xdd\xbd\ -\x41\x44\xbd\x7c\x4b\xbf\x23\x2f\xd9\xc1\xdb\xc1\xbd\xd7\x41\xf2\ -\x91\x2a\xc9\xd9\xbe\xdc\x30\x63\x07\x8d\xd9\xa6\xf9\xdb\x98\x90\ -\x96\x0c\xfc\xdb\xc4\x85\x02\x9d\x37\xf0\xd4\x51\xc9\x96\x44\xa1\ -\x31\x50\xf4\xc0\xed\x00\x83\x25\xcc\x92\xe7\x4b\x36\xda\x6d\x85\ -\xfc\xe4\xda\x14\x34\x3e\xda\xbd\x6c\x05\x05\x40\x4b\x8e\x8e\xc7\ -\x15\x6c\x90\x58\x02\x00\xd8\x4b\xbd\xee\xae\xc9\x03\x2a\xd1\x95\ -\xd2\xcb\x40\x22\x03\x43\x01\x5a\x61\x2e\x70\xba\x8a\x24\x97\xdf\ -\xed\x74\x68\x6c\x19\x3a\xd6\x37\x77\x3a\x3b\x76\x3a\x2c\x81\xa6\ -\x16\x20\x3b\x71\x3a\x43\xcb\xa8\xb8\xb4\x07\x5e\xf7\xd1\x86\x51\ -\xc3\xa9\xb1\x43\xb7\x4b\xf7\xee\x84\x71\x69\x8f\xbc\x8e\x92\x87\ -\x70\xa4\xec\xc0\xeb\x90\x25\x86\xa3\xbd\x7b\x3e\xda\x8d\x01\x1d\ -\xa4\xee\x45\x28\x20\xa0\x0c\x45\x83\xaa\x5c\x8c\x6b\x2a\xd1\x1d\ -\xba\x70\x17\x68\xf5\x8c\x79\xd5\xab\x18\x00\x07\x7e\x44\xcb\x78\ -\x86\x9e\x9f\x03\x8a\x3b\x0f\x8d\xad\xe9\xff\x28\x78\x7f\x77\x75\ -\xe3\xde\x4d\xde\x5d\xfd\x07\x74\x60\xa1\xb7\ -\x00\x00\x0d\x2a\ -\x00\ -\x00\x49\x75\x78\x9c\xed\x5c\x59\x6f\xdb\x56\x1a\x7d\xcf\xaf\xe0\ -\x28\x2f\x2d\x46\xa4\xee\xbe\x28\xb6\xfb\xd0\x62\x80\x02\x1d\x0c\ -\xd0\x76\x3a\x8f\x01\x4d\x52\x36\x27\x14\x29\x50\xf4\x96\x5f\x3f\ -\xe7\x5e\x2e\xa2\x36\x8f\xe3\xc4\x69\x12\x55\x6e\x20\xf2\xbb\xfb\ -\xf9\xce\xb7\x5c\xf2\xaa\x67\x3f\xdc\x2f\x8b\xe0\x36\xab\xd7\x79\ -\x55\x9e\x4f\x68\x44\x26\x41\x56\x26\x55\x9a\x97\x57\xe7\x93\x7f\ -\xff\xfe\x8f\xd0\x4c\x82\x75\x13\x97\x69\x5c\x54\x65\x76\x3e\x29\ -\xab\xc9\x0f\x17\xaf\xce\xfe\x16\x86\xc1\x8f\x75\x16\x37\x59\x1a\ -\xdc\xe5\xcd\x75\xf0\x73\xf9\x6e\x9d\xc4\xab\x2c\xf8\xee\xba\x69\ -\x56\xf3\xd9\xec\xee\xee\x2e\xca\x3b\x61\x54\xd5\x57\xb3\xef\x83\ -\x30\xbc\x78\xf5\xea\x6c\x7d\x7b\xf5\x2a\x08\x02\x8c\x5b\xae\xe7\ -\x69\x72\x3e\xe9\x1a\xac\x6e\xea\xc2\x57\x4c\x93\x59\x56\x64\xcb\ -\xac\x6c\xd6\x33\x1a\xd1\xd9\x64\x53\x3d\xd9\x54\x4f\xdc\xe8\xf9\ -\x6d\x96\x54\xcb\x65\x55\xae\x7d\xcb\x72\xfd\x7a\x54\xb9\x4e\x17\ -\x43\x6d\x37\x9b\x3b\xee\x2b\x51\x6b\xed\x8c\xb0\x19\x63\x21\x6a\ -\x84\xeb\x87\xb2\x89\xef\xc3\xed\xa6\x98\xe3\xa1\xa6\x8c\x10\x32\ -\x43\xd9\xa6\xe6\xd3\x6a\xcd\xd7\x00\x74\x85\x7f\x43\xf5\x5e\x10\ -\xad\xab\x9b\x3a\xc9\x16\x68\x97\x45\x65\xd6\xcc\x7e\xfa\xfd\xa7\ -\xa1\x30\x24\x51\xda\xa4\xa3\x6e\x7a\x3c\xb7\x46\xdd\x02\xb9\x8c\ -\x97\xd9\x7a\x15\x27\xd9\x7a\xd6\xcb\x7d\xfb\xbb\x3c\x6d\xae\xcf\ -\x27\x5c\x44\x94\xe3\x23\xbd\xf0\x3a\xcb\xaf\xae\x9b\x5d\x69\x9e\ -\x9e\x4f\x30\x7b\x66\x4d\x7b\x3f\x22\x07\x6d\x2b\x74\x1d\xcf\x87\ -\x12\x12\x59\x16\xd1\xa0\xa6\x92\xeb\xb6\x4e\xbf\x84\x79\x5a\x25\ -\x6e\x4e\xe8\x32\x5b\xe6\xf1\x4d\x53\x2d\xa1\xb5\x24\x29\xe2\xf5\ -\x3a\x5f\xe4\x09\x6e\xaa\x72\x55\xdc\x5c\xe5\xe5\xdb\x5f\x7e\xfc\ -\xed\x6d\x73\x5d\x67\xeb\xeb\xaa\x48\xdf\xfe\xfa\xaf\x9f\xdf\x36\ -\x55\x55\x44\x3d\x92\xc3\xb0\xd9\xfd\xaa\xaa\x9b\xf0\x3e\x5d\x01\ -\x4f\xa5\x0f\x16\x3e\xf4\x85\x17\x28\x3d\x4b\xb3\xc5\xda\xd5\x6a\ -\x17\xe7\xee\xb0\x3a\x3d\x09\x66\xbe\x74\x98\xab\x9b\x68\x7a\x9b\ -\x67\x77\x9b\xba\x97\xf1\xba\x05\x30\x08\x56\xf1\x15\xc8\x56\x54\ -\xf5\xf9\xe4\xf5\xc2\x7f\xba\x82\xcb\xaa\x4e\xb3\xba\x2f\x52\xfe\ -\xb3\x55\x54\x41\x21\x79\xf3\xd0\x9a\x57\xd7\x77\x3f\x5f\xd7\xeb\ -\x50\x4e\x0e\x97\xaf\xaf\xe3\xb4\xba\x3b\x9f\xb0\xdd\xc2\xf7\x55\ -\xb5\x3c\x9f\xc8\x48\x5a\x63\x09\xdd\x2d\x4d\xee\xcf\x27\xa1\x95\ -\x11\x55\x96\x48\xbd\x57\x8a\xf1\x98\x8c\x84\x35\x8c\xee\x17\xde\ -\xd4\x35\xec\x2f\x2c\xe2\x87\x0c\x8b\xf2\x5f\x7d\xff\x50\xcf\xdd\ -\x55\xed\xc0\x69\xea\x9b\x6c\xb7\xa5\x2b\x09\x2f\x2f\xab\xfb\xc3\ -\xc5\xa0\xc3\x8d\xb3\xec\xf0\xa6\xcc\x1b\x58\xcf\xea\x7e\xdc\xeb\ -\x4d\x9e\x66\xeb\xc3\x0d\xd7\x65\xbc\x0a\xaf\x8a\xea\x32\x2e\x0e\ -\x57\xb8\xcb\x4b\x80\x14\x76\x44\xa7\x7c\xd0\xc1\x6e\x8d\x9e\xf5\ -\x9a\x98\x23\x35\x30\xf7\x3d\x3d\x74\x45\x0f\xc7\x8b\x96\xf1\x7d\ -\xbe\xcc\xdf\x67\x00\x66\x4f\x15\x7e\x65\x63\x58\x2e\x7c\x85\xb3\ -\x2d\xd8\xda\x36\x41\xd0\x3c\x38\x0b\xbf\x7f\x70\xb2\x49\x2f\x74\ -\x78\x3b\x01\xb3\x56\x0f\xc2\xaa\xce\x61\x38\xa3\xe9\xf6\xa2\x87\ -\xb1\xc8\xf9\x03\xb8\xf3\x7b\xcf\x3f\xcf\x4e\xbd\x5b\xf6\x30\x2e\ -\xeb\xcc\x62\xb6\x6f\x17\x5e\xbe\xcc\x9a\x38\x8d\x9b\x78\x63\x24\ -\xbd\x04\x73\x23\xfd\xca\xe0\x5a\xe7\xbf\xfe\xf4\x8f\x8b\x6e\xa0\ -\xb3\x24\x99\xff\xa7\xaa\xdf\xf5\xe3\x06\x81\xab\x10\x5f\x56\x37\ -\xd0\xc4\xe4\x62\x10\x9f\xa5\xc9\x1c\xce\x10\x4e\xe2\x22\x5f\x82\ -\xfa\xce\x8f\xfe\x1d\xce\xef\x6c\xb6\x29\xd8\xaa\xec\xc0\xda\x74\ -\xda\x76\x0b\x17\xe2\xbd\xea\xc1\xd0\x92\x26\xcb\xdc\x35\x9a\xfd\ -\xd6\xe4\x45\xf1\xb3\x1b\xa4\x5b\xf1\xa8\xd3\xbc\x29\xb2\x8d\xf0\ -\x6c\xd6\xcd\xbe\x5b\xdb\x6c\xb4\xb8\xb3\x59\xbf\x7a\x7f\x77\xb5\ -\x41\x65\xcb\x68\x06\x45\x17\xf1\x65\x06\x06\xff\xe2\x0a\x83\x7d\ -\x9e\xd4\xd5\xcd\x6a\x59\xa5\x59\xd7\x7c\x40\x33\x4b\x9a\x41\x65\ -\xcd\x43\x81\x72\xef\x6f\xe6\xaf\x89\xff\xbc\x49\xf3\xf5\x0a\x2d\ -\x10\x21\x8a\xbc\xcc\xde\x54\x70\xcd\x8b\xa2\xba\x9b\xdf\xe6\xeb\ -\xfc\xb2\xc8\xde\xf8\xef\xbc\xc0\xca\x07\xd1\x02\xcb\x9f\x77\x9e\ -\xcc\xdf\x84\x9d\x1f\x9a\xd3\xf6\xb6\xbe\x29\xb2\x79\x59\x95\xef\ -\xe1\xc1\xde\xac\x9b\xba\x7a\x97\xcd\x5f\xa7\x97\x8e\x24\xdd\x6d\ -\x6b\x6d\xf3\x81\x3a\xac\x97\xbb\x49\x60\x41\xf3\xcb\x9b\xa6\x19\ -\xcb\xfe\x5b\xe5\xe5\x1c\xf8\x67\x75\x2f\xf5\x37\x05\x0c\xa7\x99\ -\x8b\x5e\x96\xc6\xf0\x78\x75\x8d\xe5\x60\xf4\x6c\x2c\xad\x16\x8b\ -\x75\xd6\xcc\x49\x2f\xdb\xcc\x78\x19\xd7\xef\xb2\xba\x6d\x90\x95\ -\x31\x16\x18\x5e\xc6\xc9\x3b\x07\x68\x99\xce\xe3\x04\x6e\xe7\xa6\ -\x40\xba\xb2\x65\x50\x0e\x56\x6e\xa8\x1c\x84\x7d\x98\xd4\x91\x8b\ -\x87\x9c\x0d\x05\x43\xa8\xdc\x2b\xd9\xb2\x3e\xd8\x51\xc8\xa3\x4d\ -\x61\x0d\x01\x8f\x38\xe2\xa2\xb2\x66\xa0\xd9\xd9\x2a\x6e\xae\x77\ -\xd4\xd9\x6a\x83\xc5\x8b\x05\x8b\x77\xb5\xd1\x63\xef\x34\x4d\x93\ -\x6d\xec\xc9\x4b\x42\x3e\x4c\x61\x58\x10\x40\xfb\x67\x20\x68\xa4\ -\x84\xa2\x62\x4a\x45\x64\xad\x24\x46\x06\x3f\x06\x40\x46\x68\x4a\ -\xac\x9e\x32\x12\x71\x26\x95\x34\x01\xd3\x91\x16\x56\x69\x33\xa5\ -\x3a\x22\x56\x1a\x27\xa3\x2d\x82\xdc\xb7\xf6\x57\x01\x4a\xad\xe2\ -\xf0\x6c\x53\xca\x23\x6d\xb5\x96\x90\xa9\x88\x2b\x23\xa5\x9e\x9a\ -\x48\x6b\x2a\x88\x82\x8c\x45\x86\x71\x6a\x18\x64\x92\x30\x29\x68\ -\x60\x22\x6e\x88\xe1\x56\x42\x44\x15\x46\xe5\x26\x10\x91\x31\x56\ -\x20\x22\xba\x61\xa9\x30\xc4\x9a\xc0\x73\x54\x23\x4e\xba\x61\x8d\ -\x22\x94\xd0\x20\x64\x88\x9c\x82\x11\x8b\x8a\x2c\x52\xca\x18\xad\ -\x83\x90\x46\x16\x6d\x18\xe1\x53\xe9\xda\x30\xc9\x04\x5a\x53\xca\ -\x89\x24\x58\x1c\x64\x84\x1a\x21\x03\x84\x5d\x66\x94\x95\x72\x8a\ -\x7e\x38\x43\xc0\x41\x3d\x8e\x6e\x88\x32\x62\x8a\x94\xc8\x1a\x61\ -\xb4\xd0\x01\xb5\x58\x80\x95\x98\x22\x92\x24\xa6\x15\x97\x2c\xe0\ -\x3c\x92\x0a\xab\xa2\x53\x11\xe1\xdb\x12\xed\x45\xc2\x28\xad\xa6\ -\xa1\xc3\x97\x43\xd9\x32\xe0\x26\x12\x1e\x6a\x34\xf5\x48\xdb\x20\ -\x09\x78\x04\x11\xfe\x20\xd4\x94\x19\x66\x0c\x26\x63\x29\x35\x5c\ -\x4e\x2d\xd0\xd5\x98\x02\x45\x2d\xe6\x96\xa5\xad\xfb\xd0\xe0\xfd\ -\x16\xf3\x1d\x03\x39\xea\x87\x1b\xee\x6e\x82\x7f\x55\x82\x4a\x4d\ -\x55\x87\x48\x03\x6e\xe3\xe6\xa6\xce\xb6\xc2\xc9\x10\x16\xe0\xa7\ -\x9c\x27\x45\xc4\x8e\xdd\x67\xbd\x8e\x9f\x42\xf1\x24\x26\x2c\x39\ -\x4e\x71\xc1\xbf\x08\x8a\x93\x48\xb6\x2c\xb5\x91\x72\xec\x06\x1b\ -\xa5\x61\xb6\x25\x2d\xd2\x29\x1e\x30\x15\x29\x30\x54\x83\x3c\x34\ -\xd2\x84\x68\x27\x23\x11\x63\x44\x32\x8d\x66\x60\x22\x13\x5a\x3a\ -\x22\x1b\x49\xa9\x05\x41\x05\x61\x20\x21\x68\x22\x23\x06\x66\xcb\ -\x29\x7c\x03\xf8\xc0\x28\x0d\x5c\x1f\x94\x70\x2f\xa3\x44\x0b\x09\ -\x53\xd1\x11\x53\x86\x70\xe6\x15\xad\x89\x84\x39\x40\xab\x5a\x83\ -\xa9\xdc\xfa\x51\x25\x27\x94\x07\xd8\x27\x10\xa1\xdc\x0c\x30\xac\ -\x50\x92\xc0\x10\x02\xf8\x21\x4d\x34\xa1\xd2\x4c\xd1\x8f\xe6\xda\ -\x52\xe3\x84\x04\x0c\x64\x98\x74\xe8\xac\xd4\x18\xfc\x93\x01\x03\ -\xc9\x60\x11\x4a\x67\xa1\x98\xa2\x0e\xe7\xb0\x1e\x50\x52\x44\x02\ -\xed\x61\x33\x21\x0c\x99\x82\xcc\x96\x39\x1b\x94\x42\xc3\x52\xa6\ -\xa1\x88\xb8\x55\xd2\x6a\x58\x97\x89\x9c\xff\x37\xc6\xb5\x66\x58\ -\xa2\x24\x3c\xe0\xe8\x56\x0a\x6c\x2b\xdc\x58\x1a\x76\xab\x8d\x54\ -\x5e\x0a\x28\xb5\xeb\x93\x38\xdb\x75\x54\xd5\xbd\x4f\x70\xcd\x0f\ -\x31\x5c\xd9\x9e\xe2\x6a\xa0\xb8\xe9\x29\x6e\x8e\x90\xfb\xf3\x53\ -\xdb\xd8\x98\x3c\xe6\xbd\x09\xf9\xb3\xa9\xbd\x0c\x9c\xa7\xc3\x47\ -\xaa\x29\xb4\x46\x5b\x07\x9c\x40\xca\xa0\x6a\x4d\xac\xf3\x66\x50\ -\x29\x85\xcf\x54\xee\x42\x7a\x55\xc3\xaf\x31\xec\x23\xc0\x53\xd2\ -\x36\xd7\xa2\xd5\x95\x8c\x94\x55\x44\x58\x38\x3c\x25\xa1\x2a\x1a\ -\x58\x70\x9b\x38\xe7\x8b\x0b\x0b\x6b\x06\xdd\x3b\x47\x2f\x9c\xdb\ -\xf6\x17\xce\xa2\xb8\xab\x87\x86\xcc\xfb\x28\x26\x40\x18\x11\xe1\ -\x8b\xbb\xc0\x02\xf7\x69\xc0\x7d\xe5\x1c\xa0\xed\xc2\x85\x53\xb4\ -\x00\x0b\x88\x84\x9f\x9c\x52\xb7\x77\x91\x12\x55\x20\xc3\xd4\x05\ -\x66\xc4\xe0\x69\x41\x5c\x6e\x61\xbf\x53\x2e\x3d\x95\xc0\x52\x66\ -\xb9\x51\x0c\x9e\x16\xac\x74\xeb\x0a\x31\x21\x09\xf3\x84\x3b\x87\ -\xf7\xc5\xee\xc8\xc2\x86\x5a\x0a\x63\x61\x53\x82\xc0\x80\x39\x49\ -\x74\xcf\x18\xe0\x90\x11\xac\x84\x1b\x5f\xc9\x5b\x84\x16\xdc\xb5\ -\x04\xb7\x51\x69\xd4\x52\xb8\xa6\xdc\xe1\xa0\x39\x02\x91\x03\xc8\ -\xc2\x7c\x61\x34\xce\xa6\xac\x87\x17\x52\x67\x41\x08\x5e\x30\x7a\ -\x82\x1b\xdd\x26\x4f\xfa\x30\x87\x79\x68\x3e\x37\x8b\x09\xe6\x63\ -\x1e\x65\x31\xf2\xc5\x3f\x9d\xc5\x43\xce\x39\x65\xa2\x73\xd5\x1b\ -\x16\x53\x7a\x80\xc5\xfc\x00\x8b\x15\xff\x58\x16\x23\x54\xb7\x2c\ -\xb6\x08\xd0\x2d\x8b\x99\x8b\xde\x9e\xc5\x70\x6b\x1d\x8b\x07\x07\ -\x87\x64\x80\x05\x02\x9e\xb3\x65\x31\xb2\x21\xd3\xb1\x18\xe1\xbf\ -\x65\x31\x62\x0d\x6d\x59\xec\xa2\xff\xd4\x65\x5b\x1f\xcb\x63\xd4\ -\x18\x78\x6c\x46\x34\xa6\x07\x68\x0c\x4c\xc6\x34\x3e\xc0\x62\x2a\ -\x3f\x90\xc4\x9f\x9b\xc2\x34\x61\x82\xb1\x0d\x67\x53\xf7\xb7\xcd\ -\x59\x8e\x1c\x11\xc1\x18\x91\xf4\xe3\xc8\xeb\xb4\x8e\x8f\xa1\xcf\ -\x4a\x33\x46\x2c\x46\x58\x74\x7c\x42\x44\xf3\x97\x7b\x17\xfb\xc0\ -\x6a\xcd\x42\x12\xb2\x27\x83\xfb\xcd\xe0\x36\xb6\xfe\x0d\xf5\x9c\ -\xf5\xd3\xce\xca\xc8\xb1\xeb\x63\x28\xd2\x13\x47\x11\xb9\xe4\xc6\ -\x87\x3e\x1b\xc5\xa7\x1b\xfa\x37\x83\xe2\xd8\x86\xd5\x60\xc2\xaa\ -\x33\xdc\xd1\xf7\x31\xcc\xc4\xe9\x61\xb6\xc5\xbc\xfe\xea\xe3\x98\ -\x67\x5f\x10\xc5\x03\x79\xfb\x97\x81\xa2\xec\x92\x0a\x3e\xed\xdf\ -\xe0\x38\xfb\x25\x6e\x63\xc6\x3c\xa8\xc7\xae\x0f\x04\x69\xf1\xf4\ -\x07\x01\xdf\x10\x82\x6e\x4f\xf1\x49\xc0\x0b\xd5\x29\xc2\xc7\xcc\ -\xa7\x82\xef\x25\xb3\x98\x2f\x17\xbe\xe1\x51\xe8\x27\xc1\x50\x9f\ -\x76\x24\x71\x0f\x9b\x3f\x3e\x87\x39\x45\x1e\x86\x3b\xdb\x90\x0d\ -\x7e\x62\x84\xd9\xce\xf5\xd1\xfd\xc8\x8b\x66\x81\x5f\x03\x86\x87\ -\xb6\x24\xcf\x00\x92\x9e\x66\x52\x13\x3e\xbe\x2b\x79\x06\x90\xfc\ -\x45\x77\x77\x5f\x03\x90\xd8\x7e\xf8\x69\xd2\x8f\x03\x52\xbc\xe8\ -\x66\xe5\x6b\x00\xb2\xbf\x32\x1f\x07\xa4\x3d\x79\x46\x1e\x0a\xd6\ -\xcf\xf1\x91\x4f\x7f\xc7\x33\xe0\xf8\x72\x67\x29\xdc\x93\xf1\x0f\ -\x39\x4b\xf1\xd9\xdf\x08\xbd\xd8\x11\x0a\xc2\xc0\x69\x05\x07\xb1\ -\x49\x4d\xfb\x83\x58\xee\x1d\x20\xfe\x36\x8a\xea\x8f\x52\x20\xf9\ -\x25\x5c\xe3\xbf\xf1\x51\x0a\xf7\xb2\x54\x51\x63\x36\xcc\x71\xc7\ -\xd4\xdc\xcb\x54\x2a\x99\xfe\x4b\x89\x2f\xac\x44\x11\x1a\x28\xd2\ -\x22\x89\x53\xa3\x34\xee\x99\xaa\x94\x88\x3a\x30\x72\xb5\xa5\x4a\ -\x13\x31\xe6\xde\xcb\xfc\xa5\xca\xcf\xa0\x4a\xe9\x95\xf9\x32\x36\ -\xf9\x79\x14\xb9\xad\xb6\xf9\x6b\xa9\x94\xdc\x55\x29\x89\xa4\x55\ -\x44\x1b\xc1\x1f\xd1\xed\x62\x61\xe4\xae\x6e\x25\xc2\x19\x15\x88\ -\x8a\xf4\x33\x29\x99\xb9\x37\x70\xc6\x9d\xc9\xf8\x94\xda\x86\xc2\ -\x76\x35\xac\x6c\xfb\x64\x41\xed\x69\x58\x76\x6f\xf9\xcc\x58\xc3\ -\xa1\x3b\xcb\xb2\xfd\x64\xc1\x9d\x64\xeb\xde\x73\xf2\xd1\xc9\xb5\ -\xab\xf1\xe8\x57\x9c\xcb\xcd\xd0\x4d\x1d\x97\x6b\x77\x44\x13\xa1\ -\x3e\x6e\xea\xfc\xfe\x3b\x28\xc6\x68\x39\x25\xee\x2f\xd2\x42\x68\ -\x4b\x11\xfa\x25\xb2\x51\xaa\x90\x45\xf8\x37\xfa\x50\x9d\xa0\xdf\ -\x0f\x27\x40\xb7\x48\x74\xb8\x4f\x2d\x0d\x32\x10\xc5\xda\x77\xb5\ -\xc4\x32\xc6\xfd\x01\x13\xad\xc1\x5d\x4a\x9d\x98\x59\xca\x14\x33\ -\x6e\xdc\xef\x27\x9b\xde\xea\xf6\x98\x2b\x16\xa5\xb8\x1d\xcb\x01\ -\x81\x3b\x02\xa3\x14\xd5\x74\x24\x77\x87\xf7\xfc\xa1\x1d\x6b\xd9\ -\x48\xec\x01\x93\x91\x95\x54\x13\x31\x92\xf7\x10\x1b\xb7\x2a\x22\ -\xcd\xb8\xac\xb7\x3c\x11\x29\xa3\x8d\x92\xa3\xa2\x5e\x8f\x18\xc5\ -\xc2\x66\xf9\xa8\x68\x2b\xcd\xcb\x6c\x7c\x49\xd5\x71\x6f\x96\xdd\ -\x66\x65\x95\xa6\x03\xe3\xa9\x49\xd5\xd1\x37\xf5\xcf\x79\xff\x3e\ -\x3a\x10\xfb\xff\xb5\x64\x99\xa0\x52\x59\x0d\x75\x70\xc3\x08\x65\ -\xb6\x3d\x06\xe4\xf4\x05\x5f\xe2\x08\x41\x84\x35\xd2\x65\x77\x87\ -\xb4\xa4\x8d\x94\xcc\x98\x1d\x2d\x51\xf4\x4b\x20\xb7\xdb\x5a\xb2\ -\x91\x02\x15\xa9\x14\x3b\x5a\x12\xd2\x1d\xcc\x12\xcc\x1c\xd0\x12\ -\xc2\x13\x01\x1d\x25\x3f\xa0\x25\x1a\x49\xcc\xd7\xd0\xe3\x5a\xd2\ -\x5f\xa1\x9a\x6a\xff\x0b\x03\x89\x98\x0c\x9a\xef\xf2\x1f\xc4\xa4\ -\x56\x49\xce\xb6\x91\x1d\x8e\x08\xed\x20\xab\x64\x97\xca\x1f\x40\ -\xb6\x7f\x4a\x69\xf7\x91\xed\xd3\x7e\xf1\x08\xb2\xa1\x39\x0d\x68\ -\x43\xb0\xd6\xc7\xc5\x5d\xd6\xbe\x20\xb6\x5f\x27\xb2\xd8\xbd\x12\ -\x01\xb7\x29\x77\x80\x75\x27\x66\xb8\xd4\x56\x3d\x15\x58\xe3\xd1\ -\xd3\x07\x70\xdd\x52\x4e\x0f\x68\xf7\x78\xfe\x38\xa0\x5f\x03\x9c\ -\xe3\xc7\x06\x87\x0f\xd6\x24\x47\x3e\xe3\x65\x3f\xf1\xdc\xce\x36\ -\x40\x23\x71\xbb\xff\x77\x69\x49\xbb\xff\x0f\x29\x02\x40\x70\xeb\ -\x0e\x56\x07\x9c\xf9\xaf\xeb\xf1\xcd\x1f\x81\x7f\x12\xfd\x4b\x10\ -\xba\x63\x7c\xee\x48\x39\x6b\x1f\xa9\x3a\x9f\x6e\xda\x3e\xfa\xf4\ -\x84\xa3\x9f\x50\x8d\x6a\x87\x3a\x12\xdd\x4b\x65\x27\xa0\xdd\x90\ -\xee\x24\xef\xad\x7b\x08\xe1\xc6\xf2\x5f\x21\x46\x7b\x1f\xb8\x23\ -\x91\x18\x22\x62\x10\x63\xab\x69\x5c\x3f\xee\x80\xe1\xf0\x66\xfa\ -\x8f\xc0\x35\x2d\xfc\xa9\xb1\xf6\xed\x81\x7b\x32\xe9\x3a\xf1\xd5\ -\xdf\xef\xd3\x60\x3b\xef\x5d\x54\x65\x13\xfa\x12\xc0\x5e\x2f\xe3\ -\xa2\x95\xdc\xc6\x75\x1e\x97\xcd\x96\xec\xce\xf3\x71\x4b\x04\xe5\ -\x66\x4d\x72\xbd\x2d\xcb\xdf\x67\xf3\x65\x96\xe6\x37\xcb\x37\x2e\ -\x3f\xed\x7e\xd4\xb4\x55\x67\x11\x2f\xf3\xe2\x61\xfe\x1b\x62\xf3\ -\x9b\xb0\x57\x60\xd8\x36\x5f\x65\xc9\xf0\xeb\xbb\xb6\x46\x93\xdd\ -\x37\xa8\x95\x66\xa5\xdb\x8b\xf8\xbb\xb8\xc8\xaf\xca\xf9\xba\x89\ -\xeb\xa6\x15\xa4\x59\x52\xd5\x6d\x1b\x4f\xbb\x1d\xa1\xcf\x94\xdb\ -\x92\x22\x6b\x40\xda\xb0\xfb\x75\x51\x3f\xad\xbb\xaa\x4e\x77\x65\ -\xbe\x8f\x21\x81\x68\x5b\xdf\xd5\x79\x83\x2a\xa1\xfb\x21\xcc\xbc\ -\xa8\xc3\xe6\x12\x5b\x07\x47\x2a\x37\x72\xd1\xd4\x6f\xdc\xaf\xf2\ -\xfc\xb2\xd7\xd7\xf9\xa2\x99\xf7\xb7\xdd\xb4\xcb\xe4\x1a\xe0\xb7\ -\xf3\x7e\xf6\xde\xb1\x33\xc9\xa7\x9a\xf0\xd8\x0c\x5b\xfb\x65\x11\ -\xd5\x12\x79\x8f\xe1\x4f\x4f\xed\x8f\x9a\xed\x87\xd9\x9f\x7f\x40\ -\x66\xb7\xdc\x5f\x6b\x7f\xc2\x76\x6f\x26\xa6\x1b\x0b\x49\x02\x98\ -\xce\xf0\x84\x98\x3f\x76\x77\xcc\xdd\x19\x14\x1e\x3f\x31\xba\x38\ -\xb0\xab\xa6\x91\x11\x5a\x32\x62\xf8\xea\xfe\xc3\xf7\x5e\x4f\xf0\ -\x73\xcf\x02\x4c\xed\x03\xc6\xfa\xc3\x94\x63\xc0\xc2\x6d\x8c\x1e\ -\xbd\x3d\x86\x19\x21\x8a\xd3\x3d\x7e\x3d\x86\xd9\xf0\x38\x54\x7c\ -\x49\x98\x89\x90\x3d\x42\xb3\xee\x38\x7f\x87\xc8\xee\xf7\x37\xcf\ -\xa7\x90\x3e\xc2\xa8\x0e\x9b\x9e\x2e\xfb\x17\x27\x40\x9d\x03\x00\ -\x71\xdb\x5a\x9a\xcb\x11\x46\xef\xff\x5a\x4c\xb8\x7f\xfd\xa0\x1f\ -\xbb\x3b\x01\x52\x1d\x42\x8d\x0f\x26\x37\x46\x2d\xdc\x06\xea\xd1\ -\xdb\x53\xa0\x9b\xde\x03\x4e\xd3\x0d\xdd\xdc\x0f\x4c\x4e\xd9\x59\ -\x85\x07\x32\x76\xb9\xe1\x55\x0b\xcf\x69\xfb\xab\x7d\x84\x34\xc1\ -\xea\xfd\xaf\x3a\x4e\x9a\x3a\xfb\xc9\xa6\x1a\x60\x39\x6d\xca\xec\ -\xe7\x47\x9b\x10\x37\xfe\x05\xde\x09\x93\x67\x3f\xf1\xde\xc4\xb3\ -\x31\x44\x5f\x23\x91\xce\x66\x57\xed\xff\x27\x02\x5f\x67\xee\x7f\ -\x67\x71\xf1\xea\x7f\xea\x44\xfa\xd7\ -\x00\x00\x05\xc9\ -\x00\ -\x00\x25\xd3\x78\x9c\xed\x5a\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ -\xd4\x97\x0d\x0b\x29\x52\xb2\xae\xb5\xdd\x87\x15\xc3\x0a\x74\x2f\ -\x5b\xd7\x01\x7b\x29\x68\x89\xb6\xb5\xca\xa2\x47\x51\xb1\xdd\x5f\ -\xbf\x43\xdd\x6c\xd9\x4e\x17\x37\xf3\x06\x14\x56\x10\x24\x3a\x17\ -\xf2\xf0\xfb\xce\x25\x09\x33\x7e\xb5\x5d\xe5\xe8\x41\xa8\x32\x93\ -\xc5\xc4\x62\x84\x5a\x48\x14\x89\x4c\xb3\x62\x31\xb1\x7e\x7b\xf7\ -\x23\x0e\x2d\x54\x6a\x5e\xa4\x3c\x97\x85\x98\x58\x85\xb4\x5e\x4d\ -\xef\xc6\xdf\x60\x8c\x7e\x50\x82\x6b\x91\xa2\x4d\xa6\x97\xe8\x4d\ -\xf1\xb1\x4c\xf8\x5a\xa0\x6f\x97\x5a\xaf\x63\xdb\xde\x6c\x36\x24\ -\x6b\x85\x44\xaa\x85\xfd\x1d\xc2\x78\x7a\x77\x37\x2e\x1f\x16\x77\ -\x08\x21\xd8\xb7\x28\xe3\x34\x99\x58\xad\xc3\xba\x52\x79\x6d\x98\ -\x26\xb6\xc8\xc5\x4a\x14\xba\xb4\x19\x61\xb6\xb5\x37\x4f\xf6\xe6\ -\x89\xd9\x3d\x7b\x10\x89\x5c\xad\x64\x51\xd6\x9e\x45\xf9\xe2\xc0\ -\x58\xa5\xf3\xde\xda\x44\xb3\x71\x6b\x23\x16\x45\x91\x4d\x1d\xdb\ -\x71\x30\x58\xe0\x72\x57\x68\xbe\xc5\x43\x57\x88\xf1\x9c\xab\x43\ -\x29\xb5\x41\xb7\xb7\x7c\x9a\x55\x5c\x02\xa0\x6b\xf8\xec\xcd\x3b\ -\x01\x29\x65\xa5\x12\x31\x07\x3f\x41\x0a\xa1\xed\xd7\xef\x5e\xf7\ -\x4a\x4c\x49\xaa\xd3\x83\x65\x3a\x3c\x07\xbb\x0e\x40\x2e\xf8\x4a\ -\x94\x6b\x9e\x88\xd2\xee\xe4\xb5\xff\x26\x4b\xf5\x72\x62\xb9\x23\ -\xc2\x5c\x78\xbc\x5a\xb8\x14\xd9\x62\xa9\x8f\xa5\x59\x3a\xb1\x20\ -\x7a\x27\x0a\x9b\xf7\x83\xe4\x60\x8d\x41\xbb\x70\xdc\x6b\x28\x89\ -\x1c\xc2\x90\x62\x9e\x1b\x34\x36\xdd\x11\xe2\x54\x26\x26\x26\x58\ -\x52\xac\x32\x5e\x69\xb9\x02\xd6\x92\x24\xe7\x65\x99\xcd\xb3\x04\ -\x5e\x64\xb1\xce\xab\x45\x56\x7c\x00\x2e\xb5\x54\x1f\xb4\xfc\xa0\ -\x78\xa9\x85\xf9\x4e\xe6\xa4\x03\xb2\xdf\x55\x6c\xd7\x52\x69\xbc\ -\x4d\xd7\x00\xa7\x1f\x9c\x55\xee\x3a\xe5\x14\xb4\xe3\x54\xcc\x4b\ -\x63\xd5\x9c\xcd\xbc\xc1\xe1\x02\x0b\xd9\xb5\xb6\x0f\xd5\xc4\x99\ -\x3e\x64\x62\xb3\xb7\x9d\xf1\xb2\xc1\x0f\xa1\x35\x5f\x40\xae\xe5\ -\x52\x4d\xac\x17\xf3\xfa\x69\x15\x33\xa9\x52\xa1\x3a\x95\x5f\x3f\ -\x03\x95\x04\x3e\x32\xbd\x6b\xaa\xab\x5d\xbb\x8b\xd7\xac\xda\xeb\ -\xe9\x79\x7d\xb9\xe4\xa9\xdc\x4c\x2c\xe7\x58\xf9\x49\xca\x15\xb0\ -\x47\x22\x2f\xa2\x0e\x8d\x8e\xd5\xc9\x76\x62\x61\x46\x61\x55\xc6\ -\x58\x78\xa2\x85\x0d\x5d\xd0\xd1\xd0\x73\xdc\x13\x65\xa5\x14\xd4\ -\x1f\xce\xf9\x4e\xc0\xa9\xea\x2f\xac\x35\x2a\x97\x72\xb3\x50\x06\ -\x1d\xad\x2a\x71\xec\x69\x34\x78\x36\x93\xdb\xf3\x6a\x48\x87\xca\ -\x54\x36\xae\x8a\x4c\x43\xf5\xac\xb7\x87\xab\x56\x59\x2a\xca\xf3\ -\x8e\x65\xc1\xd7\x78\x91\xcb\x19\xcf\xcf\x1b\x6c\xb2\x02\x50\xc2\ -\x6d\xa2\x33\xb7\x27\xe1\xd8\xa2\xcb\xfa\x80\x9e\x60\xd2\x5a\x40\ -\xec\x27\x44\xb4\xaa\xdd\xe3\xaa\x15\xdf\x66\xab\xec\x93\x00\x60\ -\x58\x9d\x77\x90\x5b\x03\x58\x1a\x37\x84\xf4\xce\x54\xf0\x76\x67\ -\x64\x56\x27\x34\x78\x1a\x81\x13\x45\x41\x2f\x94\x2a\x83\xc2\x38\ -\x08\xa7\x13\xed\x0e\x45\xa6\xde\xa1\x5d\x6f\xeb\x04\xab\xd3\x2f\ -\x38\xd6\xed\x0e\x75\x6d\xde\xdb\xa7\x89\x5f\xcb\x57\x42\xf3\x94\ -\x6b\xbe\xaf\x82\x4e\x02\xb1\xd1\xee\x64\xd0\x3a\xe3\x5f\x5e\xff\ -\x38\x6d\x37\x1a\x27\x49\xfc\xbb\x54\x1f\xbb\x7d\x11\x32\x06\x7c\ -\x26\x2b\x40\xda\x9a\xf6\xe2\x71\x9a\xc4\xd0\xec\xa0\x09\x4c\xb3\ -\x15\xe4\xb6\xe9\x93\xdf\x43\x73\x1b\xdb\x7b\xc5\xc0\xd8\x80\xb5\ -\x5f\xb4\x59\x56\x89\xa6\x6b\x9e\x1d\x1d\x69\xb2\xca\x8c\x93\xfd\ -\xab\xce\xf2\xfc\x8d\xd9\xa4\x3d\xf1\xc1\xa2\x99\xce\xc5\x5e\x38\ -\xb6\xdb\xe8\xdb\xb3\xd9\x07\x87\x1b\xdb\xdd\xe9\xeb\xb7\xc5\x1e\ -\x95\x41\x51\xf4\x44\xe7\x7c\x26\x20\x43\xdf\x1a\x25\x3a\xd1\x2e\ -\x94\xac\xd6\x2b\x99\x8a\xd6\xbd\x47\x13\x5a\x5f\x4f\x99\xde\xe5\ -\xa0\x9f\x43\xf4\x31\x74\x1a\x21\x38\x7f\x69\x5e\x70\xdb\x27\x62\ -\xf6\xb2\xd4\x4a\x7e\x14\xf1\x0b\x4a\x45\x30\x9f\xb7\xaf\x4d\xea\ -\xc7\x94\x8c\x9c\x9a\xe8\xb0\x93\x03\x1e\x42\xe5\x90\x9b\x3a\x1e\ -\x75\xb2\x94\x43\x57\x51\x8a\xef\xe2\x02\xc6\x7a\x27\xed\x77\x18\ -\xa4\xa5\x09\xce\x0d\xdd\x51\x2f\x6c\x6b\xcc\x73\x89\x99\x1a\xae\ -\xd3\x2b\xba\xd2\x1a\x39\xa4\x09\xa1\xd7\x34\xad\x88\x1c\x65\x27\ -\xa4\x25\x76\xc9\xde\x5f\xd5\x79\xea\x8f\xcc\xe3\xf7\xac\x3d\x8e\ -\x4e\x3a\x82\x51\x4b\x8f\xd1\xa9\x5f\x55\x95\xc3\x34\x78\x10\x85\ -\x4c\xd3\x1e\x2f\x27\x9c\xcf\x53\x7a\x8c\x57\xe8\xd5\xc7\xf0\xfe\ -\x4d\xbc\xbc\xd0\x8d\x30\xc3\xa3\x53\xd0\x1a\xcc\xda\x59\x3b\x00\ -\x8d\x44\xb5\x66\x74\x08\x9a\x13\x92\x20\x32\xcf\x21\x66\x2e\x09\ -\x9a\x45\xf6\xc0\x0d\x7a\xc4\x10\xc6\x3e\xb4\xcf\x0d\xd0\x73\x06\ -\xfd\x10\xfd\x0a\x88\x08\x43\xec\x5f\x83\x0a\xe6\x12\xff\xc6\xc2\ -\x93\xcb\x01\x3b\xd8\xbd\x06\x0d\xe1\x71\x67\xb9\x51\xf1\x0f\x54\ -\xf8\xd7\xa9\x07\xc7\x25\xa3\x1b\x13\x17\x16\x85\x7f\x9d\xa2\x60\ -\x21\xf1\x6e\x63\xe2\xe2\x06\x15\xe0\xe0\x2a\x95\x11\x92\xd1\x8d\ -\x88\x27\xcf\x6b\x1c\x61\xe7\x99\x34\x0c\xff\xac\xd1\x15\xc5\x6d\ -\x60\x5f\x44\x03\xc3\xde\xb3\xeb\xe1\x2c\x11\xb7\x91\x7d\x39\x19\ -\x01\x7e\xee\xef\x13\x67\xa9\xb8\x0d\xed\x2f\x2b\x0c\x0f\xd3\xab\ -\xb4\xa8\xdb\xdc\xfe\xb2\x3e\x45\x71\x74\x95\xf2\xb8\x4d\xee\x27\ -\x53\x11\x3e\xbb\x43\x9d\x36\xa3\xdb\xd4\xbe\x88\x02\x0a\x3f\xc5\ -\xb2\xab\xb0\x70\x1b\xd9\x17\x32\xe1\xe2\xf0\x1a\x3c\xdc\xe6\xf5\ -\xc5\x25\x11\x3c\xfb\xb7\x89\xf3\x7d\xe9\x36\xaa\xbf\xa0\x39\x5d\ -\xa9\x2a\xfe\x87\x31\xbd\xe6\x7a\x79\x96\x06\x4a\x2f\xa3\xa1\xb9\ -\x51\x1e\xd2\xc0\x88\x13\xb9\x34\x08\xa2\x9e\x86\x3c\x2b\x04\x04\ -\x14\x97\x7f\x55\x5c\x89\x43\xe9\x9f\x32\x2b\xe2\x9a\xa5\xcb\x29\ -\x33\x52\x39\x9f\x97\x42\xc7\xf4\x71\x1a\x81\xc5\x9f\x11\x36\xb7\ -\x4b\x2c\x72\x20\x3d\xee\xcd\x4c\x8e\xfc\x28\x40\x3f\x21\xe6\xa3\ -\xf7\x28\x68\x6f\x83\x3c\xf4\x16\xb9\x94\xb8\x7e\xc4\x42\xef\x9e\ -\x05\xc4\x63\xe6\x03\x8c\xee\x9d\xa0\x75\x79\x8f\x1c\xd6\x52\x0e\ -\xee\x07\xab\xa2\x3f\x4e\xf2\xc6\x0d\x19\x3b\xa5\x24\x91\x45\x51\ -\xff\xbf\x00\x4e\x2a\xf5\xc0\x75\xa5\xc4\xe0\x4e\xb4\xbf\xdb\x94\ -\xa9\x30\xd7\x81\xe5\xc4\x4a\xda\xe7\x09\xf4\xb5\x55\xf4\xb9\x7b\ -\x36\x46\xe0\x78\x94\x32\x37\x58\x6f\x8f\xf9\x99\x55\x5a\x7f\x9e\ -\x9d\xc7\xf0\x0d\x49\xe0\xf9\x0e\x1d\x85\xf7\x2e\xc0\xeb\xf8\x2e\ -\x0b\x11\x86\xd4\xf5\xc3\x80\xfa\xec\xde\x03\x30\xc3\xc8\x0b\x23\ -\xe4\x91\x30\x70\x1c\x8f\x06\xf7\xa6\x76\x9c\x11\x0d\x5d\x04\x8c\ -\x84\x75\x59\x18\xe7\xfa\xb6\x37\x38\xbb\xe2\x00\x62\x83\x81\x4b\ -\x47\xf4\xc9\x10\x7f\x2d\x3d\xe8\xd9\x7f\xd6\x80\xe6\xcf\x86\xcd\ -\xbf\xe9\x42\x47\xc2\xff\xa2\x15\x8d\xed\xc5\xf4\x6e\x6c\x2e\xd3\ -\xa7\x77\x7f\x03\x12\x53\xa0\x4a\ -\x00\x00\x06\x33\ -\x00\ -\x00\x4e\xa2\x78\x9c\xe5\x5c\xdd\x8f\xa3\x36\x10\x7f\xdf\xbf\x82\ -\xb2\x2f\xad\x2a\x9b\xcf\x24\xc0\x25\xb9\x87\xae\x4e\x3a\xa9\x4f\ -\xed\x55\x7d\x3c\x11\x70\x12\x6b\x01\x47\x86\x6c\x92\xfb\xeb\x3b\ -\xe6\x2b\x21\x61\xa5\x56\x06\x89\xad\x59\x9d\x56\xcc\x8c\x8d\xfd\ -\xe3\x37\xb6\x67\x86\xbd\xe5\xe7\x73\x9a\x68\x6f\x84\xe7\x94\x65\ -\x2b\xdd\xc2\xa6\xae\x91\x2c\x62\x31\xcd\x76\x2b\xfd\xaf\x6f\x5f\ -\x90\xa7\x6b\x79\x11\x66\x71\x98\xb0\x8c\xac\xf4\x8c\xe9\x9f\xd7\ -\x4f\xcb\x9f\x10\xd2\x7e\xe3\x24\x2c\x48\xac\x9d\x68\xb1\xd7\xbe\ -\x66\xaf\x79\x14\x1e\x88\xf6\xf3\xbe\x28\x0e\x81\x61\x9c\x4e\x27\ -\x4c\x6b\x21\x66\x7c\x67\xfc\xa2\x21\xb4\x7e\x7a\x5a\xe6\x6f\xbb\ -\x27\x4d\xd3\xe0\xb9\x59\x1e\xc4\xd1\x4a\xaf\x1b\x1c\x8e\x3c\x29\ -\x0d\xe3\xc8\x20\x09\x49\x49\x56\xe4\x86\x85\x2d\x43\xbf\x9a\x47\ -\x57\xf3\x48\x3c\x9d\xbe\x91\x88\xa5\x29\xcb\xf2\xb2\x65\x96\x3f\ -\xdf\x18\xf3\x78\xdb\x5a\x8b\xd1\x9c\x9c\xd2\xc8\xf2\x7d\xdf\x30\ -\x6d\xc3\xb6\x11\x58\xa0\xfc\x92\x15\xe1\x19\x75\x9b\xc2\x18\xfb\ -\x9a\xda\xa6\x69\x1a\xa0\xbb\x5a\xfe\x3b\xab\x20\x07\x40\x0f\xf0\ -\xaf\x35\x6f\x04\x38\x67\x47\x1e\x91\x2d\xb4\x23\x38\x23\x85\xf1\ -\xf2\xed\xa5\x55\x22\x13\xc7\x45\x7c\xd3\x4d\x83\x67\xe7\xa9\x1d\ -\x90\xb3\x30\x25\xf9\x21\x8c\x48\x6e\x34\xf2\xb2\xfd\x89\xc6\xc5\ -\x7e\xa5\x3b\x2e\xb6\x1c\xb8\x66\xa5\x70\x4f\xe8\x6e\x5f\xdc\x4b\ -\x69\xbc\xd2\x61\xf4\xb6\xef\x55\xf7\x37\xe4\xb0\x2a\x83\xba\xe3\ -\xa0\xd5\x98\xd8\xb7\xb1\xa5\x71\x6b\xe6\x2c\x2a\x9b\x66\x0a\x41\ -\xcc\x22\x31\x26\xe8\x92\xa4\x34\x3c\x16\x2c\x85\xb7\x16\x45\x49\ -\x98\xe7\x74\x4b\x23\xb8\x61\xd9\x21\x39\xee\x68\xf6\xbd\x2b\xfc\ -\x9e\x53\xf2\x46\x70\x83\x63\xfb\x50\x72\x3e\x30\x5e\xa0\x73\x7c\ -\x00\x34\xe7\x8b\x5e\xe5\xa5\x51\xae\x41\xbb\x8c\xc9\x36\x17\x56\ -\xd5\xd4\xc4\x1d\xcc\x6d\xa1\x6b\x46\xa9\x6d\x47\x2a\x86\x19\xbf\ -\x51\x72\xba\xda\x6e\xc2\xbc\x82\x4f\xd3\x0e\xe1\x0e\xa8\x96\x30\ -\xbe\xd2\x9f\xb7\xe5\x55\x2b\x36\x8c\xc7\x84\x37\xaa\x79\x79\x75\ -\x54\x0c\x5e\x07\x2d\x2e\x95\x73\xd5\x7d\x37\xe3\x15\xbd\xb6\x7a\ -\xb3\x5f\x9f\xef\xc3\x98\x9d\x56\xba\x7d\xaf\xfc\xc1\x58\xba\xd2\ -\x67\x78\xe6\x7b\xbe\x69\xdd\x6b\xa3\xf3\x4a\x47\xb3\x05\xf6\x7c\ -\xd7\xf7\x1f\xb5\xf0\x3c\xd7\xc6\xee\xc2\xb4\xe7\x8f\xca\x23\xe7\ -\xe0\x7d\x28\x09\x2f\x04\x26\x55\xfe\x6a\x8c\xf2\x3d\x3b\xed\xb8\ -\x00\xa7\xe0\x47\x72\xdf\x52\x68\xd0\x66\xc3\xce\xfd\x6a\x20\xc3\ -\x51\xf8\x35\x3a\x66\xb4\x00\xdf\x39\x9c\x6f\x7b\x3d\xd2\x98\xe4\ -\xfd\x0d\xf3\x2c\x3c\xa0\x5d\xc2\x36\x61\xd2\x6f\x70\xa2\x19\x80\ -\x84\x6a\x9a\x5b\x4e\xfb\x0e\xee\x2d\x1a\xce\x2f\x4c\xef\x1d\x0b\ -\x18\xfb\xc3\x7b\xa8\x55\x97\xf7\x55\x69\x78\xa6\x29\xfd\x41\x00\ -\x18\xab\xa4\x1d\x50\xab\x03\x4b\xd5\x4c\xd3\x8a\x8b\xf0\xdf\xf3\ -\x45\xc8\xf4\x46\x28\xf0\x14\x02\xdb\xf7\x17\xad\x90\x71\x0a\x6e\ -\x71\x33\x9c\x46\x74\xb9\x15\x09\x6f\x87\xc5\xfa\x5c\xf2\xab\x64\ -\xdf\xe2\x5e\x77\xb9\xd5\xd5\xb4\x37\x1e\x79\x5f\xca\x53\x52\x84\ -\x71\x58\x84\x57\x27\x68\x24\x30\x36\xb3\x99\x19\x2c\x9c\xc1\x1f\ -\x2f\x5f\xd6\xf5\x83\x96\x51\x14\xfc\xcd\xf8\x6b\xf3\x5c\x4d\x13\ -\x06\xe1\x86\x1d\x01\x69\x7d\xdd\x8a\x97\x71\x14\xc0\x52\x07\x4b\ -\xc0\x9a\xa6\x40\x6d\xb1\x4a\xfe\x0a\x4b\xdb\xd2\xb8\x2a\x3a\xc6\ -\x02\xac\x6b\xa7\x55\xb7\x9c\x54\x6b\x66\xef\xc6\x11\x47\x29\x15\ -\x8d\x8c\x3f\x0b\x9a\x24\x5f\xc5\x43\xea\x19\xdf\x74\x4a\x8b\x84\ -\x5c\x85\x4b\xa3\x1e\x7d\x3d\x37\xe3\x66\x72\x4b\xa3\x99\x7d\x79\ -\xb7\xbb\xa2\xd2\x71\x8a\xf6\x45\x27\xe1\x86\x00\x43\x7f\x17\x4a\ -\xed\x41\xbb\xe3\xec\x78\x48\x59\x4c\xea\xe6\x2d\x9a\x24\x2a\xda\ -\x57\x56\x5c\x12\xd0\x6f\x61\xf4\xc1\xb3\x69\xba\xfe\xc6\xfe\x24\ -\x6e\x50\xbd\x4c\x04\x56\x75\xcb\x8f\x09\x2c\x77\x6f\x24\x63\x71\ -\xfc\x29\x2f\x38\x7b\x25\xc2\x5e\x5c\xf5\x6d\xe5\x0c\x81\x89\x5d\ -\xc7\x77\xc5\xbb\x6f\xe4\x80\x10\xe1\x09\xb0\xb5\x08\xdc\x46\x16\ -\x87\xb0\xcc\x70\x1e\x5e\x82\x0c\xb6\xf9\x46\xda\x3e\xb3\x43\x54\ -\x31\xdc\x99\xe7\xf8\xc8\x42\x5e\xab\xa8\x3d\x6f\x86\x1d\xe7\xba\ -\x95\x88\xab\x71\x38\x17\xfb\xa5\xc6\x6d\x35\x82\xb2\x26\xbe\xa3\ -\x2c\x70\xd5\xc1\x5e\x67\x19\x85\xd7\xde\x71\x02\x5e\xf2\x79\xee\ -\x8a\x6b\xde\xbe\xdd\xf7\x51\xdc\x38\xe2\x67\xca\x28\x22\x6b\x0c\ -\x1c\xd1\xe3\x82\x20\x07\xe4\xf4\xe9\x88\xfc\x31\x80\xb4\x1c\xbc\ -\xe8\x5a\xca\xe1\x28\x4e\x0f\x80\xcb\x94\x71\xb4\xd0\x6c\x0c\x24\ -\x3d\xec\x95\x73\xb1\xd5\x41\x72\x31\x06\x8e\xb6\x83\x87\x5a\x1d\ -\x3f\x80\x53\x03\x19\x47\x61\xa3\xe5\x61\xd5\x36\x1a\x7f\x1c\x3e\ -\x3a\x0e\x76\x15\xdb\x69\x80\x94\xc8\x1c\xc5\xb7\x3d\x3c\x2b\x4d\ -\x95\x60\xa5\x24\x82\x66\x87\x85\x03\x1f\x1c\xa7\xce\x42\x49\xec\ -\x1e\xcd\x55\x3c\x7c\xbb\x63\xa0\x38\xf8\xd1\x7b\xe2\x30\xca\xc6\ -\x81\x1d\x37\x1e\xfa\xb8\x3d\x75\x37\x46\x9e\x2c\x7c\xbd\x1c\x1c\ -\x1a\xc6\x89\x53\xd0\x94\xf6\xe4\x0e\x09\x87\x8e\x54\x26\x4f\x42\ -\x17\xd9\x63\xb0\x70\x68\x1c\xa7\xce\x42\x67\x48\x12\xaa\x14\xe6\ -\xcd\xc7\x60\xdf\x80\x00\x4e\x9d\x78\xd2\x81\x5d\x77\x0f\x1e\x38\ -\x34\x9e\x3c\xfd\xdc\x71\x08\xa8\x5e\x8a\x41\x3e\x99\xdd\x1f\x97\ -\x0c\x9c\x61\x98\x38\x90\x70\x9a\x91\xc6\xb1\xbb\x95\x0c\x9c\x55\ -\xf8\x00\x0e\x6d\x4b\x2f\x89\xfd\x7b\x8a\x52\xf9\x99\x8a\x89\xc3\ -\x9e\xad\x55\xf4\x65\xe9\xd3\x75\x07\x41\xd5\xf2\x0b\x22\xe1\xea\ -\xca\x72\xd0\x9e\xdf\xef\xc5\x65\xbe\x6b\xe1\x28\xe4\xcd\x55\xe6\ -\x5a\x76\x5d\xec\x45\x12\x38\xa9\x48\x90\x57\x15\x52\x64\x93\xff\ -\xbd\x20\x5a\xca\x04\x2c\x4d\x0d\x45\xb6\xb2\xd7\x0b\xa3\x77\x5f\ -\x57\xf9\x9f\x1f\x76\x3c\xb4\x90\xde\x60\x7a\x81\xb4\x95\x2c\xec\ -\xcd\x90\x29\x1b\x0d\xf6\x7b\xb7\x5a\x47\xc7\xba\xe0\x3c\x0e\x33\ -\xe1\x10\x59\x5a\x2a\x93\xa0\xad\x4b\xce\xd2\x47\xf1\x7e\x3f\xf7\ -\xb0\x22\xe5\x16\xe9\xef\x1f\xd4\x3e\x3e\x4a\xfb\xb2\x85\xef\x84\ -\x2a\xa2\xe8\x22\x5b\xb6\xe6\xd7\x0b\xe4\x80\x67\xf0\x89\xbb\xb1\ -\x87\x64\x2b\x2d\x96\xba\x07\x6f\x79\xf0\x7a\xd9\x37\x20\x86\x13\ -\x67\x5f\x99\xd2\x71\xa5\xbf\x7e\x1f\x33\x66\x99\x3c\x0b\x45\x82\ -\x76\x94\x45\x50\xad\xe0\xcf\x74\x06\x3e\xd2\x0c\x1d\xf2\x4d\xfe\ -\x1b\xed\xb9\x7c\x0e\xa2\x8f\x86\x8a\x85\xce\x26\x04\x7a\xc3\x2e\ -\x88\x43\x47\xcb\x13\x07\xb0\xac\x41\x23\x47\xb6\xea\xd7\xbf\x33\ -\x2b\x97\x78\x10\xd1\xb2\x2f\x9d\xa2\xed\x0d\x56\xd4\x4a\x3c\x54\ -\xd5\x2b\x6f\xd8\xd3\xb6\x3a\xe9\x86\xba\x10\x2d\x5d\xcc\xef\xdf\ -\x62\x86\x83\x71\xe2\x1e\x5d\x57\xa1\xe5\xff\x2a\x6d\xd4\x1c\xe2\ -\x87\x00\xd1\x46\xbe\x6c\x72\xdb\x52\xb8\xf0\xe7\xca\x7f\x28\x7b\ -\xc3\x37\x15\x93\x5f\x65\x05\x5a\xfa\x73\xbb\x2e\x88\x6a\x71\x50\ -\xb8\xb2\xec\x59\xbb\x8b\x9f\x52\xe9\xaf\xaa\xee\x2c\xbd\x25\x77\ -\x11\x54\x2d\x7d\x53\x96\x9c\xa5\x53\x0f\x5d\x0c\x87\x0e\x99\x3f\ -\x00\x88\x75\xb5\x79\xe0\x3d\x45\xbd\x78\xaf\x2a\x34\x4b\xe7\xb5\ -\xef\xb6\x66\xb5\xce\x87\x37\x35\x66\xe9\x2a\xf3\x9d\x63\xff\xb7\ -\x40\x65\x69\xec\xd6\x4f\x4b\xf1\xbf\x03\xad\x9f\xfe\x01\xed\x59\ -\x64\x2c\ -\x00\x00\x05\xfe\ -\x00\ -\x00\x1c\x9e\x78\x9c\xdd\x58\x49\x8f\xdb\x36\x14\xbe\xcf\xaf\x60\ -\x95\x4b\x8b\x9a\x5a\x28\x5b\xdb\xd8\xce\x21\x41\xd1\x00\xc9\xa5\ -\x4d\xdb\x63\x20\x4b\xb4\xcd\x8e\x24\x0a\x14\x35\xb6\xf3\xeb\xfb\ -\x28\x89\xb2\xe4\x05\x98\x20\x9e\x41\xa6\x02\x12\x4b\x6f\x21\xdf\ -\xfb\xde\x46\xce\xfc\xed\x3e\xcf\xd0\x23\x15\x15\xe3\xc5\xc2\x70\ -\x4c\xdb\x40\xb4\x48\x78\xca\x8a\xcd\xc2\xf8\xeb\xf3\x6f\x38\x30\ -\x50\x25\xe3\x22\x8d\x33\x5e\xd0\x85\x51\x70\xe3\xed\xf2\x6e\xfe\ -\x13\xc6\xe8\x9d\xa0\xb1\xa4\x29\xda\x31\xb9\x45\x1f\x8a\x87\x2a\ -\x89\x4b\x8a\x7e\xde\x4a\x59\x46\x96\xb5\xdb\xed\x4c\xd6\x11\x4d\ -\x2e\x36\xd6\x2f\x08\xe3\xe5\xdd\xdd\xbc\x7a\xdc\xdc\x21\x84\x60\ -\xdf\xa2\x8a\xd2\x64\x61\x74\x0a\x65\x2d\xb2\x46\x30\x4d\x2c\x9a\ -\xd1\x9c\x16\xb2\xb2\x1c\xd3\xb1\x8c\xa3\x78\x72\x14\x4f\xd4\xee\ -\xec\x91\x26\x3c\xcf\x79\x51\x35\x9a\x45\xf5\x66\x20\x2c\xd2\x75\ -\x2f\xad\xac\xd9\xb9\x8d\x90\x13\x86\xa1\x65\x13\x8b\x10\x0c\x12\ -\xb8\x3a\x14\x32\xde\xe3\xb1\x2a\xd8\x78\x49\x95\xd8\xb6\x6d\x01\ -\xef\x28\xf9\x34\xa9\xa8\x02\x40\x4b\xf8\xd7\x8b\x6b\x82\x59\xf1\ -\x5a\x24\x74\x0d\x7a\xd4\x2c\xa8\xb4\xde\x7f\x7e\xdf\x33\xb1\x6d\ -\xa6\x32\x1d\x2c\xa3\xf1\x1c\xed\x3a\x02\xb9\x88\x73\x5a\x95\x71\ -\x42\x2b\x4b\xd3\x1b\xfd\x1d\x4b\xe5\x76\x61\xb8\x53\xd3\x71\xe1\ -\x99\x35\xc4\x2d\x65\x9b\xad\x3c\xa5\xb2\x74\x61\x80\xf5\x24\x0c\ -\xda\xef\x41\x72\x38\xad\x40\xb7\x70\xd4\x73\x6c\x33\x24\xa6\x83\ -\x84\x33\x73\xfd\x56\x46\xbb\x10\xa5\x3c\x51\x36\xc1\x92\x34\x67\ -\x71\x2d\x79\x0e\x51\x4b\x92\x2c\xae\x2a\xb6\x66\x09\x7c\xf0\xa2\ -\xcc\xea\x0d\x2b\xbe\xc8\xad\xa0\xd5\x96\x67\xe9\x17\xc9\x79\x66\ -\x6a\x04\xfb\xed\xe8\xbe\xe4\x42\xe2\x7d\x5a\x02\x8e\x9e\x7f\x91\ -\x79\xd0\xcc\x25\x70\xe7\x29\x5d\x57\x4a\xaa\x75\x4a\x7d\x81\x57\ -\xbe\x81\xac\x86\xdb\xdb\xa8\x0c\x4c\x1f\x19\xdd\x1d\x65\x57\x71\ -\xd5\x02\x87\x50\x19\x6f\x20\xc9\x32\x2e\x16\xc6\x9b\x75\xf3\x74\ -\x8c\x15\x17\x29\x15\x9a\xe5\x35\xcf\x88\xc5\x21\x10\x4c\x1e\xda\ -\xb2\xea\xd6\xd6\xf6\xaa\x55\x7b\xbe\x7d\x99\x5f\x6d\xe3\x94\xef\ -\x16\x06\x39\x65\x7e\xe5\x3c\x87\x55\x67\x66\xe0\x7a\x76\xe0\x9e\ -\xb2\x93\xfd\xc2\xc0\x33\xd7\xf4\x66\xd3\x20\x38\x63\x36\xf6\x38\ -\x8e\xef\x10\x7f\x76\xc6\xac\x85\x80\xba\xc3\x59\x7c\xa0\xe0\x54\ -\xf3\xe3\x74\x42\x10\x9a\xdd\x46\x28\x70\xa4\xa8\xe9\xa9\xa6\xe2\ -\xe0\xd5\x8a\xef\x2f\xb3\x21\x0d\x6a\x55\xd1\xb8\x2e\x98\x84\xaa\ -\x29\xf7\xc3\x55\x6b\x96\xd2\xea\xb2\x62\x55\xc4\x25\xde\x64\x7c\ -\x15\x67\x97\x05\x76\xac\x00\x90\x70\x97\xe0\x8e\xdb\xc7\xe0\x54\ -\x42\x67\xbb\x6f\x9f\x61\xd2\x49\x80\xed\x67\x71\xe8\x58\x87\xeb\ -\xac\x3c\xde\xb3\x9c\x7d\xa5\x00\x8c\x73\x86\x8a\xf2\x6c\x08\xcb\ -\xb2\x11\x98\x8f\x60\x6b\x75\x10\x92\x07\x55\xd9\xfb\x83\xa2\x19\ -\x9a\xa8\xf0\x56\x04\x12\x86\x7e\x4f\xe4\x82\x41\xc1\x0c\xcc\xd5\ -\xa4\xc3\x90\xa4\xfa\x00\xb4\xf1\x7d\x93\x7f\x4d\x76\xfa\xa7\xbc\ -\xc3\x90\xd7\x95\x85\x75\x5e\x17\x0d\x3d\xa7\x32\x4e\x63\x19\x1f\ -\x8b\x44\x53\xc0\x36\x5b\x7b\x06\x2d\x35\xfa\xe3\xfd\x6f\xcb\x6e\ -\xa3\x79\x92\x44\xff\x70\xf1\xa0\xf7\x45\x48\x09\xc4\x2b\x5e\x43\ -\x24\x8c\x65\x4f\x9e\xa7\x49\x04\x4d\x10\x9a\xc3\x92\xe5\x90\xfa\ -\xaa\x7f\xfe\x0a\x4d\x6f\x6e\x1d\x19\x23\x61\x05\xd6\x71\xd1\x76\ -\x59\x68\x1f\x4d\x37\xbd\x38\x52\xd2\x24\x67\x4a\xc9\xfa\x53\xb2\ -\x2c\xfb\xa0\x36\xe9\x3c\x1e\x2c\xca\x64\x46\x8f\xc4\xb9\xd5\x59\ -\xdf\xf9\x66\x0d\x9c\x9b\x5b\xda\xfb\xe6\x6b\x73\x44\x65\x54\x34\ -\x7d\xa0\xb3\x78\x45\x21\x83\x3f\x2a\x26\x3a\xcf\x13\xc1\xeb\x32\ -\xe7\x29\xed\xd4\x35\x9a\x34\xcb\x58\x59\xf5\x8e\x56\xf2\x90\x81\ -\x48\xd3\x72\xa2\x37\x76\xf3\xdc\xa7\xac\x2a\x41\x09\x86\x43\xc6\ -\x0a\x7a\xcf\xa1\x2b\xaf\x33\xbe\x8b\x1e\x59\xc5\x56\x19\xbd\x6f\ -\x7e\x59\x06\xce\xf7\xa4\x35\x20\x10\x15\x30\xcf\xef\x2b\x29\xf8\ -\x03\x8d\xba\xc6\xd6\x7d\xb6\xc5\x14\x11\xe8\xe9\xbe\x4d\xa6\x61\ -\x38\xd5\x0c\xb5\x03\x18\x1c\xad\x6a\x29\x87\xb4\x7f\x39\x2b\x22\ -\xc0\x97\x0a\x4d\x6d\x3e\x32\x28\x0c\x19\xf5\xda\x69\x0c\x1d\x4d\ -\x08\xb0\x75\xb0\x77\x43\xe5\xeb\x75\x45\x65\x64\x6b\x5a\xd7\x19\ -\x23\xe7\x3e\x8f\xc5\x03\x15\xad\x02\x2d\x62\xb0\x1e\xaf\xe2\xe4\ -\x41\x01\x56\xa4\x51\x9c\x40\x5b\xa9\x33\x38\x86\x8c\x0a\xa6\x8c\ -\xe5\xd6\xb5\x9d\x00\x07\xf8\x98\xf2\xc9\xa8\x5e\x54\x1b\x74\x61\ -\x6e\xa9\xb9\x47\x7a\xaa\x00\x19\x12\x98\x7e\xa8\x9e\x23\x55\x95\ -\x89\xdf\xd6\x49\xd0\x27\xcd\x3c\x61\x22\xc9\x9e\x31\x36\xea\x6d\ -\x80\x44\xf3\x29\xea\x8c\x2a\xee\x57\x98\x2e\x7d\xf0\xba\xcd\x46\ -\xc1\x73\x4c\x37\x68\x47\xd2\x6b\x8d\x9d\x8f\xbd\x51\xec\x3c\xd3\ -\x0e\x3d\xd7\x0d\xc9\x38\x86\xa3\xb3\x4b\x13\x2d\x20\x92\x57\x13\ -\x25\xd2\xe6\x9a\xff\x5a\xa3\x14\x8c\x62\x34\x33\x5d\x77\x1c\x8d\ -\xab\x31\x72\x6c\x73\x34\x77\x20\x54\x6a\xd1\x93\x40\x9d\x77\xaa\ -\x4b\x30\x92\x76\x7d\x77\xfa\xac\x8d\xaa\x87\xac\x77\x03\x80\xf8\ -\x84\xb4\x77\xee\xc4\x75\xdb\x1e\xe1\xa3\xdf\x91\x7d\x06\x17\x4c\ -\xc9\x23\x58\xc7\x13\x17\x2f\xc0\x52\xc9\x05\x86\xb3\xd7\x63\x2c\ -\x6b\x41\x47\x33\xbc\x9f\xc5\x30\x1c\xd4\xf8\x82\x63\x52\x92\xdc\ -\x00\x32\xc7\x0c\x43\xcf\x26\xb3\xa0\xdc\x7f\x3b\x66\x17\x91\xc8\ -\x51\x7f\x94\x98\x10\xdf\xf4\x1b\x4c\x50\x82\x74\x70\xdc\x89\x7d\ -\xed\xfd\x3c\xb5\x7c\x9f\x60\xfb\xc9\x68\xdd\x24\x83\x1c\x7f\x36\ -\x75\x66\xb3\x1b\xe2\xa1\xab\x01\x32\x43\xe7\x08\xe0\x61\x4f\xf0\ -\xd4\x24\x0d\x50\xd7\xde\xcf\xf1\x08\xa6\xcf\x87\x46\x40\xcf\x93\ -\xa3\x0b\x24\xb9\x21\x1a\x78\x90\x1e\x76\xeb\xa8\x8f\x5c\x93\x4c\ -\x34\xc3\x47\x9e\x39\x9d\xe0\xc0\x9c\xb5\x50\x7d\x44\x8e\x6b\x06\ -\xad\x46\x68\x7a\xc8\x09\x41\x58\xfd\x87\xc8\xb4\x93\x99\x10\xa7\ -\xc3\x18\xb9\x64\x42\x66\x20\x95\x21\xbd\xc0\x04\x16\x3f\x43\x72\ -\x6a\xbb\xfe\x0b\x22\xa9\x53\x60\x1a\xbe\x44\x67\xb2\x75\xc2\xb9\ -\xd7\xa1\x3f\x02\x36\x80\xde\x1b\x41\x3f\xed\x33\xd7\x1f\x48\x68\ -\x5a\x13\x8b\x8f\xc3\x18\x10\x73\xda\xc0\xef\x75\x1d\xfd\x29\x31\ -\xc0\xee\x37\xf7\xc2\x5e\x4e\x8a\xb8\xa8\xd4\xa5\x00\x27\x70\xa5\ -\xa4\x02\x37\x57\x1c\xef\x09\x82\x30\x8c\xf0\xe9\x85\xe7\xc7\xea\ -\xa2\x9f\x86\x5d\x54\x01\xfb\xae\x09\x54\x8b\xf1\xe9\xcb\x95\xbe\ -\x89\xc9\x0b\x76\xce\xe7\x1d\x24\xfa\xd8\xed\x7f\xd7\x20\xc1\xce\ -\xff\x07\x10\xe7\x16\x93\xf5\x1b\xaa\xef\x47\x04\x64\x58\x24\x5e\ -\x5f\x23\x5e\x57\x19\x83\xdf\x6b\xee\x4f\x5f\xb5\xfb\xa3\x7c\xd0\ -\x6f\xdf\x97\x0f\xe1\x6b\x3f\x6b\x39\xc4\x0c\x6e\x72\xcc\xc2\x17\ -\xe6\xc8\xeb\x82\x82\x04\xb7\x82\xe2\x25\xe7\xc8\xf3\x40\xa1\x4f\ -\x3b\xb7\xc1\xe3\xf9\x4e\x8e\x3f\xd8\x9d\xd6\x3e\x9e\xfb\x7c\xf4\ -\x37\xea\x2f\xb6\x97\x2e\xb5\x4f\xaf\x97\x27\x5d\x6a\xe7\xd6\x66\ -\x79\x37\x57\x7f\xff\x5d\xde\xfd\x07\x5c\xd5\x81\xeb\ -\x00\x00\x05\xfe\ -\x00\ -\x00\x1c\x9e\x78\x9c\xdd\x58\x49\x8f\xdb\x36\x14\xbe\xcf\xaf\x60\ -\x95\x4b\x8b\x9a\x5a\x28\x5b\xdb\xd8\xce\x21\x41\xd1\x00\xc9\xa5\ -\x4d\xdb\x63\x20\x4b\xb4\xcd\x8e\x24\x0a\x14\x35\xb6\xf3\xeb\xfb\ -\x28\x89\xb2\xe4\x05\x98\x20\x9e\x41\xa6\x02\x12\x4b\x6f\x21\xdf\ -\xfb\xde\x46\xce\xfc\xed\x3e\xcf\xd0\x23\x15\x15\xe3\xc5\xc2\x70\ -\x4c\xdb\x40\xb4\x48\x78\xca\x8a\xcd\xc2\xf8\xeb\xf3\x6f\x38\x30\ -\x50\x25\xe3\x22\x8d\x33\x5e\xd0\x85\x51\x70\xe3\xed\xf2\x6e\xfe\ -\x13\xc6\xe8\x9d\xa0\xb1\xa4\x29\xda\x31\xb9\x45\x1f\x8a\x87\x2a\ -\x89\x4b\x8a\x7e\xde\x4a\x59\x46\x96\xb5\xdb\xed\x4c\xd6\x11\x4d\ -\x2e\x36\xd6\x2f\x08\xe3\xe5\xdd\xdd\xbc\x7a\xdc\xdc\x21\x84\x60\ -\xdf\xa2\x8a\xd2\x64\x61\x74\x0a\x65\x2d\xb2\x46\x30\x4d\x2c\x9a\ -\xd1\x9c\x16\xb2\xb2\x1c\xd3\xb1\x8c\xa3\x78\x72\x14\x4f\xd4\xee\ -\xec\x91\x26\x3c\xcf\x79\x51\x35\x9a\x45\xf5\x66\x20\x2c\xd2\x75\ -\x2f\xad\xac\xd9\xb9\x8d\x90\x13\x86\xa1\x65\x13\x8b\x10\x0c\x12\ -\xb8\x3a\x14\x32\xde\xe3\xb1\x2a\xd8\x78\x49\x95\xd8\xb6\x6d\x01\ -\xef\x28\xf9\x34\xa9\xa8\x02\x40\x4b\xf8\xd7\x8b\x6b\x82\x59\xf1\ -\x5a\x24\x74\x0d\x7a\xd4\x2c\xa8\xb4\xde\x7f\x7e\xdf\x33\xb1\x6d\ -\xa6\x32\x1d\x2c\xa3\xf1\x1c\xed\x3a\x02\xb9\x88\x73\x5a\x95\x71\ -\x42\x2b\x4b\xd3\x1b\xfd\x1d\x4b\xe5\x76\x61\xb8\x53\xd3\x71\xe1\ -\x99\x35\xc4\x2d\x65\x9b\xad\x3c\xa5\xb2\x74\x61\x80\xf5\x24\x0c\ -\xda\xef\x41\x72\x38\xad\x40\xb7\x70\xd4\x73\x6c\x33\x24\xa6\x83\ -\x84\x33\x73\xfd\x56\x46\xbb\x10\xa5\x3c\x51\x36\xc1\x92\x34\x67\ -\x71\x2d\x79\x0e\x51\x4b\x92\x2c\xae\x2a\xb6\x66\x09\x7c\xf0\xa2\ -\xcc\xea\x0d\x2b\xbe\xc8\xad\xa0\xd5\x96\x67\xe9\x17\xc9\x79\x66\ -\x6a\x04\xfb\xed\xe8\xbe\xe4\x42\xe2\x7d\x5a\x02\x8e\x9e\x7f\x91\ -\x79\xd0\xcc\x25\x70\xe7\x29\x5d\x57\x4a\xaa\x75\x4a\x7d\x81\x57\ -\xbe\x81\xac\x86\xdb\xdb\xa8\x0c\x4c\x1f\x19\xdd\x1d\x65\x57\x71\ -\xd5\x02\x87\x50\x19\x6f\x20\xc9\x32\x2e\x16\xc6\x9b\x75\xf3\x74\ -\x8c\x15\x17\x29\x15\x9a\xe5\x35\xcf\x88\xc5\x21\x10\x4c\x1e\xda\ -\xb2\xea\xd6\xd6\xf6\xaa\x55\x7b\xbe\x7d\x99\x5f\x6d\xe3\x94\xef\ -\x16\x06\x39\x65\x7e\xe5\x3c\x87\x55\x67\x66\xe0\x7a\x76\xe0\x9e\ -\xb2\x93\xfd\xc2\xc0\x33\xd7\xf4\x66\xd3\x20\x38\x63\x36\xf6\x38\ -\x8e\xef\x10\x7f\x76\xc6\xac\x85\x80\xba\xc3\x59\x7c\xa0\xe0\x54\ -\xf3\xe3\x74\x42\x10\x9a\xdd\x46\x28\x70\xa4\xa8\xe9\xa9\xa6\xe2\ -\xe0\xd5\x8a\xef\x2f\xb3\x21\x0d\x6a\x55\xd1\xb8\x2e\x98\x84\xaa\ -\x29\xf7\xc3\x55\x6b\x96\xd2\xea\xb2\x62\x55\xc4\x25\xde\x64\x7c\ -\x15\x67\x97\x05\x76\xac\x00\x90\x70\x97\xe0\x8e\xdb\xc7\xe0\x54\ -\x42\x67\xbb\x6f\x9f\x61\xd2\x49\x80\xed\x67\x71\xe8\x58\x87\xeb\ -\xac\x3c\xde\xb3\x9c\x7d\xa5\x00\x8c\x73\x86\x8a\xf2\x6c\x08\xcb\ -\xb2\x11\x98\x8f\x60\x6b\x75\x10\x92\x07\x55\xd9\xfb\x83\xa2\x19\ -\x9a\xa8\xf0\x56\x04\x12\x86\x7e\x4f\xe4\x82\x41\xc1\x0c\xcc\xd5\ -\xa4\xc3\x90\xa4\xfa\x00\xb4\xf1\x7d\x93\x7f\x4d\x76\xfa\xa7\xbc\ -\xc3\x90\xd7\x95\x85\x75\x5e\x17\x0d\x3d\xa7\x32\x4e\x63\x19\x1f\ -\x8b\x44\x53\xc0\x36\x5b\x7b\x06\x2d\x35\xfa\xe3\xfd\x6f\xcb\x6e\ -\xa3\x79\x92\x44\xff\x70\xf1\xa0\xf7\x45\x48\x09\xc4\x2b\x5e\x43\ -\x24\x8c\x65\x4f\x9e\xa7\x49\x04\x4d\x10\x9a\xc3\x92\xe5\x90\xfa\ -\xaa\x7f\xfe\x0a\x4d\x6f\x6e\x1d\x19\x23\x61\x05\xd6\x71\xd1\x76\ -\x59\x68\x1f\x4d\x37\xbd\x38\x52\xd2\x24\x67\x4a\xc9\xfa\x53\xb2\ -\x2c\xfb\xa0\x36\xe9\x3c\x1e\x2c\xca\x64\x46\x8f\xc4\xb9\xd5\x59\ -\xdf\xf9\x66\x0d\x9c\x9b\x5b\xda\xfb\xe6\x6b\x73\x44\x65\x54\x34\ -\x7d\xa0\xb3\x78\x45\x21\x83\x3f\x2a\x26\x3a\xcf\x13\xc1\xeb\x32\ -\xe7\x29\xed\xd4\x35\x9a\x34\xcb\x58\x59\xf5\x8e\x56\xf2\x90\x81\ -\x48\xd3\x72\xa2\x37\x76\xf3\xdc\xa7\xac\x2a\x41\x09\x86\x43\xc6\ -\x0a\x7a\xcf\xa1\x2b\xaf\x33\xbe\x8b\x1e\x59\xc5\x56\x19\xbd\x6f\ -\x7e\x59\x06\xce\xf7\xa4\x35\x20\x10\x15\x30\xcf\xef\x2b\x29\xf8\ -\x03\x8d\xba\xc6\xd6\x7d\xb6\xc5\x14\x11\xe8\xe9\xbe\x4d\xa6\x61\ -\x38\xd5\x0c\xb5\x03\x18\x1c\xad\x6a\x29\x87\xb4\x7f\x39\x2b\x22\ -\xc0\x97\x0a\x4d\x6d\x3e\x32\x28\x0c\x19\xf5\xda\x69\x0c\x1d\x4d\ -\x08\xb0\x75\xb0\x77\x43\xe5\xeb\x75\x45\x65\x64\x6b\x5a\xd7\x19\ -\x23\xe7\x3e\x8f\xc5\x03\x15\xad\x02\x2d\x62\xb0\x1e\xaf\xe2\xe4\ -\x41\x01\x56\xa4\x51\x9c\x40\x5b\xa9\x33\x38\x86\x8c\x0a\xa6\x8c\ -\xe5\xd6\xb5\x9d\x00\x07\xf8\x98\xf2\xc9\xa8\x5e\x54\x1b\x74\x61\ -\x6e\xa9\xb9\x47\x7a\xaa\x00\x19\x12\x98\x7e\xa8\x9e\x23\x55\x95\ -\x89\xdf\xd6\x49\xd0\x27\xcd\x3c\x61\x22\xc9\x9e\x31\x36\xea\x6d\ -\x80\x44\xf3\x29\xea\x8c\x2a\xee\x57\x98\x2e\x7d\xf0\xba\xcd\x46\ -\xc1\x73\x4c\x37\x68\x47\xd2\x6b\x8d\x9d\x8f\xbd\x51\xec\x3c\xd3\ -\x0e\x3d\xd7\x0d\xc9\x38\x86\xa3\xb3\x4b\x13\x2d\x20\x92\x57\x13\ -\x25\xd2\xe6\x9a\xff\x5a\xa3\x14\x8c\x62\x34\x33\x5d\x77\x1c\x8d\ -\xab\x31\x72\x6c\x73\x34\x77\x20\x54\x6a\xd1\x93\x40\x9d\x77\xaa\ -\x4b\x30\x92\x76\x7d\x77\xfa\xac\x8d\xaa\x87\xac\x77\x03\x80\xf8\ -\x84\xb4\x77\xee\xc4\x75\xdb\x1e\xe1\xa3\xdf\x91\x7d\x06\x17\x4c\ -\xc9\x23\x58\xc7\x13\x17\x2f\xc0\x52\xc9\x05\x86\xb3\xd7\x63\x2c\ -\x6b\x41\x47\x33\xbc\x9f\xc5\x30\x1c\xd4\xf8\x82\x63\x52\x92\xdc\ -\x00\x32\xc7\x0c\x43\xcf\x26\xb3\xa0\xdc\x7f\x3b\x66\x17\x91\xc8\ -\x51\x7f\x94\x98\x10\xdf\xf4\x1b\x4c\x50\x82\x74\x70\xdc\x89\x7d\ -\xed\xfd\x3c\xb5\x7c\x9f\x60\xfb\xc9\x68\xdd\x24\x83\x1c\x7f\x36\ -\x75\x66\xb3\x1b\xe2\xa1\xab\x01\x32\x43\xe7\x08\xe0\x61\x4f\xf0\ -\xd4\x24\x0d\x50\xd7\xde\xcf\xf1\x08\xa6\xcf\x87\x46\x40\xcf\x93\ -\xa3\x0b\x24\xb9\x21\x1a\x78\x90\x1e\x76\xeb\xa8\x8f\x5c\x93\x4c\ -\x34\xc3\x47\x9e\x39\x9d\xe0\xc0\x9c\xb5\x50\x7d\x44\x8e\x6b\x06\ -\xad\x46\x68\x7a\xc8\x09\x41\x58\xfd\x87\xc8\xb4\x93\x99\x10\xa7\ -\xc3\x18\xb9\x64\x42\x66\x20\x95\x21\xbd\xc0\x04\x16\x3f\x43\x72\ -\x6a\xbb\xfe\x0b\x22\xa9\x53\x60\x1a\xbe\x44\x67\xb2\x75\xc2\xb9\ -\xd7\xa1\x3f\x02\x36\x80\xde\x1b\x41\x3f\xed\x33\xd7\x1f\x48\x68\ -\x5a\x13\x8b\x8f\xc3\x18\x10\x73\xda\xc0\xef\x75\x1d\xfd\x29\x31\ -\xc0\xee\x37\xf7\xc2\x5e\x4e\x8a\xb8\xa8\xd4\xa5\x00\x27\x70\xa5\ -\xa4\x02\x37\x57\x1c\xef\x09\x82\x30\x8c\xf0\xe9\x85\xe7\xc7\xea\ -\xa2\x9f\x86\x5d\x54\x01\xfb\xae\x09\x54\x8b\xf1\xe9\xcb\x95\xbe\ -\x89\xc9\x0b\x76\xce\xe7\x1d\x24\xfa\xd8\xed\x7f\xd7\x20\xc1\xce\ -\xff\x07\x10\xe7\x16\x93\xf5\x1b\xaa\xef\x47\x04\x64\x58\x24\x5e\ -\x5f\x23\x5e\x57\x19\x83\xdf\x6b\xee\x4f\x5f\xb5\xfb\xa3\x7c\xd0\ -\x6f\xdf\x97\x0f\xe1\x6b\x3f\x6b\x39\xc4\x0c\x6e\x72\xcc\xc2\x17\ -\xe6\xc8\xeb\x82\x82\x04\xb7\x82\xe2\x25\xe7\xc8\xf3\x40\xa1\x4f\ -\x3b\xb7\xc1\xe3\xf9\x4e\x8e\x3f\xd8\x9d\xd6\x3e\x9e\xfb\x7c\xf4\ -\x37\xea\x2f\xb6\x97\x2e\xb5\x4f\xaf\x97\x27\x5d\x6a\xe7\xd6\x66\ -\x79\x37\x57\x7f\xff\x5d\xde\xfd\x07\x5c\xd5\x81\xeb\ -\x00\x00\x09\x06\ -\x00\ -\x00\x5f\x8b\x78\x9c\xe5\x5c\x5b\x8f\xa3\x38\x16\x7e\xaf\x5f\x91\ -\x4d\xbd\x74\x6b\x0b\x62\x8c\x09\x76\xba\x52\xf3\xb0\xad\x19\x8d\ -\xb4\xd2\x4a\x3b\xdd\xda\xc7\x96\x03\x26\xc5\x36\x81\x08\x48\x25\ -\x99\x5f\xbf\xc7\x04\x02\x04\x8c\x7a\xb5\xb1\xb4\xe5\x4e\xab\x55\ -\x85\x8f\xaf\x9f\xcf\xe5\xe3\xc4\xe5\xe7\x5f\x4e\xbb\x64\xf6\x26\ -\xf2\x22\xce\xd2\xf5\xdc\xb1\xd1\x7c\x26\xd2\x20\x0b\xe3\x74\xbb\ -\x9e\x7f\xfd\xf2\xab\x45\xe7\xb3\xa2\xe4\x69\xc8\x93\x2c\x15\xeb\ -\x79\x9a\xcd\x7f\x79\x79\x78\xfe\x8b\x65\xcd\xfe\x96\x0b\x5e\x8a\ -\x70\x76\x8c\xcb\xd7\xd9\xef\xe9\xf7\x22\xe0\x7b\x31\xfb\xf0\x5a\ -\x96\xfb\xd5\x62\x71\x3c\x1e\xed\xb8\x2e\xb4\xb3\x7c\xbb\xf8\x38\ -\xb3\xac\x97\x87\x87\xe7\xe2\x6d\xfb\x30\x9b\xcd\x60\xdc\xb4\x58\ -\x85\xc1\x7a\x5e\x37\xd8\x1f\xf2\xa4\xaa\x18\x06\x0b\x91\x88\x9d\ -\x48\xcb\x62\xe1\xd8\xce\x62\xde\x56\x0f\xda\xea\x81\x1c\x3d\x7e\ -\x13\x41\xb6\xdb\x65\x69\x51\xb5\x4c\x8b\xc7\x4e\xe5\x3c\x8c\xae\ -\xb5\xe5\x6c\x8e\x6e\x55\xc9\x61\x8c\x2d\x10\x5e\x60\x6c\x41\x0d\ -\xab\x38\xa7\x25\x3f\x59\xfd\xa6\x30\xc7\xb1\xa6\x18\x21\xb4\x00\ -\x59\x5b\xf3\xc7\x6a\xad\x4e\x09\x40\xa1\x9c\x4c\x25\xed\x8e\x0e\ -\xf0\xef\xe1\xff\xb5\x41\x53\x60\x17\xd9\x21\x0f\x44\x04\x2d\x85\ -\x9d\x8a\x72\xf1\xf9\xcb\xe7\xab\xd0\x42\x76\x58\x86\x9d\x6e\x1a\ -\xf4\x7b\xe3\xf6\xb6\x24\xe5\x3b\x51\xec\x79\x20\x8a\x45\x53\x5e\ -\xb5\x3f\xc6\x61\xf9\xba\x9e\xbb\xc4\x76\x5c\xf8\x78\x55\xe1\xab\ -\x88\xb7\xaf\xe5\x6d\x69\x1c\xae\xe7\xb0\x56\xcc\xe8\xe5\xb9\xa3\ -\x4a\xce\xa5\x42\xdd\xf1\xea\x2a\x41\x36\xc3\xb6\x33\xcb\x1d\xcf\ -\xf5\x2f\x75\x9a\x25\xac\xc2\x2c\x90\x73\x82\x2e\xc5\x2e\xe6\x87\ -\x32\xdb\xc1\x1e\x07\x41\xc2\x8b\x22\x8e\xe2\x00\x1e\xb2\x74\x9f\ -\x1c\xb6\x71\xfa\xed\xcf\x2c\xdb\x7d\x2b\xb3\x6f\xfb\x5c\xbc\xc5\ -\xe2\x68\x37\x80\x5f\xc7\x13\xa7\x7d\x96\x97\xd6\x29\xdc\x03\x90\ -\x4b\x7f\x54\x78\x6e\x84\x2f\x20\x7d\x0e\x45\x54\xc8\x5a\x97\x55\ -\xc9\x27\x58\xd6\x45\x06\x52\xd8\x24\xc1\xf3\xdf\x72\x1e\xc6\xa0\ -\x9a\x97\x7a\x97\x9a\x7d\x89\xeb\xfb\xac\x6e\x03\xad\x8a\x32\xdb\ -\x37\x75\x61\xa1\xe5\x39\x91\xab\x83\x42\x2b\xc8\x92\x2c\x5f\x3d\ -\x46\x28\x12\x51\xf4\xa9\x2a\xca\x60\x2f\xe2\xf2\xbc\x42\x9f\xe6\ -\x6d\x9b\x2c\x8a\x0a\x01\xb8\xa3\x4e\x59\x85\x3a\xb4\x70\x7d\xea\ -\xce\x67\x0b\xc5\x68\x9d\x5a\xfe\x58\x87\x36\x61\xae\xe3\xa1\x25\ -\x9d\x4f\xce\x70\xb3\x89\xf8\x60\x86\x36\xf1\x91\x47\x29\x26\x9f\ -\x7e\x68\x7c\x6f\x64\x7c\x67\x7a\x58\xea\x47\xcb\xe1\xb0\x8c\x22\ -\x97\x61\x67\xd9\x0e\xfb\xbc\xe8\xe3\x5f\x97\xca\x27\x9e\x0c\xb6\ -\xab\x51\x00\x18\x24\x11\x01\xcc\x82\x27\x47\x7e\x2e\xae\x53\xa9\ -\x6c\x71\xf5\x9a\x0b\xf0\x1d\x8f\x23\x1b\xdb\xdd\xf7\xfe\x10\x20\ -\x6e\x57\x19\x9c\xd6\x73\x62\xbb\xbe\x47\x01\xa4\xb6\xf4\xbc\x9e\ -\x7b\xf6\xd2\xf3\x3c\x42\xdc\x6b\x69\x34\x5a\x37\x1a\xad\x9b\x03\ -\x6c\xc4\x86\xf5\x77\x6a\x6e\xeb\x09\x7c\xc9\x79\x5a\x80\x6f\xd8\ -\xad\xe7\x60\x36\x79\x7c\xfa\x00\xee\x1c\x23\x4c\x08\x7b\x42\xf0\ -\x0f\x9e\x1c\x86\x29\x7d\x82\x1e\xd8\xd2\x67\x2e\x7d\xa2\xb6\x4f\ -\x3c\x8a\x96\xe4\xe3\xa0\xb7\xaf\x69\x5c\x82\x7b\x3b\x14\x22\xff\ -\x43\xba\x88\x7f\xa4\x5f\x0b\x51\x83\xfe\xbc\x90\xc6\x51\xfd\x76\ -\x35\x5d\x69\xb7\xa1\xb4\xc4\xd6\x82\x36\xbc\x10\x75\xbf\x7b\xbe\ -\x15\xd5\xbe\x02\xaa\x51\xf5\xa9\x05\x9b\x2c\x0f\x45\xde\x88\x96\ -\xd5\xa7\x27\xaa\xb7\xfe\x12\x9b\x1e\xfa\x9b\x28\x7b\xbd\xca\xd1\ -\xb8\xbc\x78\xe5\x61\x76\x5c\xcf\xf1\xad\x50\x3a\x10\xd9\x2b\xf3\ -\x99\xe7\x20\x72\x2b\x96\x3b\x68\x51\xd7\xc6\xd4\x63\xde\x72\x20\ -\x85\x01\x2d\x8c\x6c\x17\x13\x46\xfc\x81\xf4\x90\xe7\x00\xa1\x95\ -\xf0\xb3\x80\x65\x55\x3f\x1a\x6d\x2f\x5e\xb3\xe3\x36\x97\xf0\x94\ -\xf9\x41\xdc\xb6\x94\x12\x6b\xb3\xc9\x4e\xe3\x62\xf0\x8f\x07\x19\ -\x18\xad\xc3\x65\x77\xf6\xa7\x6e\xaf\x87\x38\x14\x50\x18\xf1\xa4\ -\x18\xb4\x2c\x52\xbe\xb7\xb6\x49\xb6\xe1\x89\xa2\xc6\x31\x4e\x01\ -\x28\xab\xf6\xfd\x8e\xbb\x1c\x2c\xba\xae\xd1\x04\x02\x1f\x51\x45\ -\x8d\x53\xeb\xad\x6e\x45\x67\xb5\x68\xc7\x4f\xf1\x2e\xfe\x53\x84\ -\xd2\x35\xd4\x56\xdc\x03\xa6\x51\xd1\xf2\x2c\x83\xda\xe9\x2c\xcb\ -\x7a\x06\x29\x0b\x30\x63\xad\xb3\xcb\xf2\x18\x62\xc5\xa9\xeb\x3c\ -\x2f\x45\xe7\x6e\x91\x0c\x81\xc0\x77\x4e\x95\x8e\x55\x1a\xe8\xdf\ -\xca\xce\x5d\x59\x63\x04\x43\xdd\xaf\xca\x77\xa2\xe4\x21\x2f\x79\ -\x6b\x08\x4d\x09\xcc\x0d\x35\x2b\x03\xee\xb1\xfa\xe7\xe7\x5f\xaf\ -\xae\x33\x08\x56\xff\xca\xf2\xef\xad\x4b\x94\x15\xf8\x26\x3b\x00\ -\xd2\xd7\x70\x22\x83\x54\xb0\x92\x36\xce\xcb\x97\x78\x07\xea\x2d\ -\x89\xc6\x5f\x21\xde\x83\x49\x5e\x05\xbd\xca\x12\xac\xb6\xd3\x4b\ -\xb7\xb9\xb8\x10\x89\x51\xee\x15\x06\xbb\x58\x36\x5a\xfc\x51\xc6\ -\x49\xf2\xbb\x1c\xa4\xe3\xe2\xeb\x4e\xe3\x32\x11\x1d\xbf\xbf\xa8\ -\x67\xdf\x78\xe4\xce\xe2\x9e\x17\xcd\xea\xab\xa7\x6d\x8b\x4a\xcf\ -\x2c\xae\x1b\x9d\xf0\x8d\x00\x15\xfd\xbb\x14\xce\x06\xd2\x6d\x9e\ -\x1d\xf6\xbb\x2c\x14\x75\xf3\x06\xcd\xed\xc0\xc1\x8f\xf6\xd3\x1d\ -\xd8\x6a\x15\xa0\x1c\x78\x4e\x64\x7b\x3e\xf2\x3d\xec\x56\x9e\xb3\ -\x7d\x62\xf6\x92\xb8\xd4\x43\xf4\x89\xd8\x10\x55\x99\x43\xdc\x8f\ -\x6d\xb0\xcf\x21\xa2\x74\x36\xb0\x52\x1a\x82\xe5\xa7\xf5\xe0\x50\ -\x7e\xea\x07\xf3\xb3\x74\xff\xb8\xd2\x2d\xd6\x29\xbe\xa9\xd5\x58\ -\xdd\x58\xd5\xda\x66\xc7\x44\x55\x9c\x82\x69\x79\xd4\xed\x16\xd7\ -\xf1\x36\x82\x1d\x5e\x3d\x22\x14\x04\x10\x69\xe5\xc3\x35\xd2\x3a\ -\x97\xc7\xfc\x90\x00\x59\x7a\x13\x69\x16\x86\x10\x8a\xf3\xec\xbb\ -\x58\xd5\x0e\xbc\x7e\xbc\x38\x0c\xa0\x2c\xf5\x23\x28\x8f\xc8\x13\ -\x30\xe4\x72\x45\x9a\xb2\x90\x83\x17\xce\x73\x7e\x5e\xa5\xf0\x12\ -\xd1\x94\x5e\x87\xea\x32\x88\x7b\x43\x38\x56\x7c\x07\x28\xad\x11\ -\xf2\xd2\x80\xc9\x79\x48\xcc\x04\x93\xda\x9e\x64\xfe\x2e\xbd\x37\ -\x98\xd6\x08\x05\x6d\xe0\x5c\x2e\x29\x32\x13\x4e\x07\xdb\xf7\x47\ -\x12\xa9\x91\x24\xc4\xf3\x0c\x45\xd2\xbf\x04\xe7\xbb\xc3\xe9\xaa\ -\xd0\x8c\x22\xcc\x31\x37\x13\x4d\xec\xd8\x95\x99\x93\xbb\x2b\xa7\ -\xff\x53\xc2\x09\xaf\x71\xf7\x77\x98\x96\xf7\x53\x62\xc9\x6c\xda\ -\x27\xe8\x77\xf3\x9b\x96\xd9\xb6\x8e\xfa\x40\x6a\xe3\x45\x16\x51\ -\xc1\x68\x04\x33\xba\x81\x51\x23\x23\x9a\xa2\x98\x06\x70\xa2\x1b\ -\x20\xf5\x70\x21\x75\xc0\x31\x82\x0d\xdd\x62\xa8\x8d\x05\x59\x4b\ -\xb5\x6f\x64\xcc\x34\x1c\x35\xf2\x1f\x0b\xff\x54\x40\x6a\x62\x3e\ -\x96\x32\x95\x61\x04\x8a\x37\xbe\xf0\xfe\x89\xa0\xa9\xd7\x6d\x03\ -\x52\x41\x43\xfc\xf4\xb1\x1d\x3a\x01\xa5\x01\x74\x67\x08\xa5\x4e\ -\xc6\x33\x91\xa1\x34\x80\xf1\x0c\xb1\xd4\x44\x7a\x94\xc1\xda\x08\ -\xd2\x33\x02\xa3\x3e\xde\xa3\x0c\xd7\x14\xc9\x8f\x71\x50\xea\xa4\ -\x3e\xca\xf7\x6b\x53\xb1\xd4\xc5\x7e\x94\x21\xc7\x54\x20\x75\x26\ -\x7d\xd4\xaf\x88\x46\xa0\x39\x16\xae\x35\x10\x4a\x34\x95\xf6\x31\ -\x80\x52\x2a\x60\xd4\x98\x45\x53\x87\x1e\x23\x88\xa5\x02\x50\xad\ -\xf9\x34\x75\xca\xdc\x08\x7e\xa9\x80\x54\x57\x66\x6d\x8a\xad\x1b\ -\x40\x33\x55\x68\x6a\xcc\xb1\xa9\x4d\x3e\x24\xe6\x86\x22\xad\xd9\ -\x36\x75\x74\x37\x1a\x52\x6d\x79\x37\xf5\xf1\x02\xa3\xf1\xd4\x4a\ -\x40\xb1\xfa\x9b\x1e\x23\x40\x1d\x33\x70\x1d\x14\x54\xf9\x7e\x29\ -\x63\xbb\xa9\x28\xea\x63\xa0\xca\x2c\x92\xc9\x70\xea\xe4\x9f\xca\ -\x50\x64\x32\xa0\x9a\xd8\xa7\x32\x05\x62\x34\x96\x1a\xf3\x9c\x13\ -\x5f\x94\x83\x35\x18\x0a\xa8\x4e\xea\x39\xf1\xae\x49\x08\x7f\xef\ -\xa7\x89\x54\x80\xea\x22\x9e\xca\xd8\x8e\xb9\x1f\xbd\xfb\xec\x92\ -\x0a\x4d\xbd\x79\x4f\x75\x3e\xde\xe7\x3c\x14\xef\x1c\xd3\x31\x67\ -\xa9\x25\xf1\xa9\xf4\x9c\x32\x09\xf2\xee\x43\x91\x02\x46\x9d\x89\ -\x4f\x25\xf1\x34\x19\x50\xcd\x89\x4f\x65\x34\x32\x19\x53\x6d\x99\ -\x4f\xe5\x77\x1d\x46\xa3\xa9\x33\xf3\x39\xc1\x96\x0c\xa0\x9f\x0a\ -\x44\xf5\x66\x3e\x27\x4f\x81\xbc\x7b\x02\xaa\x82\x54\x5f\xe6\xd3\ -\x6c\x0a\xaa\xc2\x53\x73\xe6\x53\x99\x4e\x36\x82\x83\x8e\xa1\xa7\ -\xf9\x34\xa2\x3a\x97\xbc\x09\x42\xd7\x7b\xef\x6a\xaa\x40\x54\xeb\ -\xa1\x44\x35\xc3\x37\x19\x52\x5d\x67\x13\xd5\x71\xc9\x68\x34\x35\ -\xa6\xee\x0c\x27\x4f\x0a\x44\xb5\x9e\x54\x9c\x3a\xcd\x64\x00\x79\ -\x52\x41\xaa\xed\xc0\xa2\x5a\x45\x8d\x20\x4f\x37\xc0\xe9\x39\x5f\ -\xa7\x8e\xec\x94\x72\xfe\xee\xdf\x3a\x87\x18\x6a\x3d\x5c\x37\x71\ -\xec\xd3\x4c\x34\x35\x27\x98\x26\x98\xbc\x99\x78\xea\x3b\x56\x37\ -\x71\x50\xde\x50\x28\xb5\x9e\xa9\x9b\xba\x11\xc5\x04\x7a\x34\x80\ -\x53\xf3\x81\xba\xe9\xbf\xa9\x7e\xff\xdc\x68\x88\xa7\xc6\xd3\x74\ -\x6a\xe5\x34\x94\x18\x69\x3f\x4a\x37\x41\x93\xfe\x8f\x52\x4a\x7b\ -\x5e\xbe\x76\x56\xd2\xde\x4a\x9a\xa6\xb0\xa2\x2c\xb7\x82\x43\xfe\ -\xc6\xcb\x43\x2e\x86\x17\xbf\xca\xb6\xae\xbf\x64\xbd\x37\x69\x79\ -\xcb\xe0\xac\x71\xa4\xfe\x13\xb5\x19\xf3\x7d\x07\xb1\x59\x30\x43\ -\x4f\x0e\xb3\x71\xf5\xc7\x2c\x8e\xfa\x41\x85\x5a\x7d\xf9\xc9\x14\ -\x28\xae\x8d\x09\x42\xde\x12\x91\xfd\xa9\x91\xc8\xab\x53\x61\x49\ -\xab\xcd\xa1\x2c\xbb\x65\xff\xce\xe2\x74\x55\x81\xa7\x17\x1f\x4a\ -\xfc\x5b\x74\x7c\x9b\x2c\x2f\xe8\x38\xf4\x72\x85\xb1\x0b\xe8\x5c\ -\x11\x70\x9f\x90\xfa\x41\x85\x4e\xfd\x85\xcf\x34\x3a\x1e\x65\x88\ -\x79\x0e\xbe\x1b\x3a\x43\x7b\x74\x6d\x8a\x08\xed\xdf\xb3\x2b\xed\ -\xd1\x83\x50\x80\xdc\x9e\xd9\xf4\xae\xb2\xec\xc7\xe1\x91\xe2\xeb\ -\xad\xcf\x78\x68\x94\xbd\xb2\xc6\x1a\x31\x63\xaa\x3f\x0c\xe8\x58\ -\x85\x0c\x16\xd5\xd1\xd6\x1e\x54\xd8\x76\x7c\x0f\x39\x98\xba\xf7\ -\x30\xb3\xe7\xc5\xb6\xfe\x45\x24\x49\xbc\x2f\xae\xd7\x60\x76\xe7\ -\x74\xc8\x93\x0f\x8f\xc3\x8b\x7c\x3f\xfe\xb8\x9b\x18\x5f\x08\xc2\ -\x4b\x4a\x10\xfb\x9f\x16\xf2\xd0\x81\x56\x2a\x35\x40\xdb\xfa\x5b\ -\x79\x3f\x2d\x68\x28\x71\xb1\x4b\x5b\x47\x20\xef\xa5\x75\x88\x2d\ -\x2f\xb4\x75\x5b\x5d\x90\x9a\xe0\xb8\x36\xa1\xa0\xae\x2d\x2b\xa8\ -\xfc\x78\x5d\xda\xde\x22\xdd\x53\xae\x9e\xae\x7b\x1e\xc6\xff\x0d\ -\xfb\x54\xec\xf0\x85\x9b\x90\x7b\x01\x23\xa7\x0b\xde\xb0\xd5\xd9\ -\xe6\x02\x5b\x66\x23\xcf\x71\xbd\x56\xd0\x86\x19\xe2\xfb\x68\x49\ -\x5b\x35\x3d\xc9\xcb\x7c\x7d\x1b\x7b\x3e\xed\x90\xd0\xcb\xc1\x1c\ -\xec\x53\x8c\x48\x1f\x4a\xdb\x01\x67\xe7\x7a\xac\x07\xa5\x6b\xfb\ -\x18\x75\x48\x57\xe7\x52\xd1\x3c\x2b\x79\x29\x3e\x58\x2e\xb3\x7d\ -\xe6\x53\xdf\xfd\x78\xbd\x43\x16\x54\xf4\x59\xde\xe1\xfa\xf2\xf0\ -\x1f\xe4\x46\xc2\x2a\ -\x00\x00\x12\xb2\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x61\x64\x64\x5f\x62\ -\x61\x6e\x64\x73\x65\x74\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\ -\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\ -\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\ -\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ -\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ -\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\ -\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ -\x2d\x36\x32\x2e\x30\x31\x39\x38\x31\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\x39\ -\x2e\x36\x30\x31\x37\x31\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x67\x33\x37\x31\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\ -\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\ -\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\ -\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\ -\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ -\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ -\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ -\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ -\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ -\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ -\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ -\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ -\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ -\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\ -\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ -\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\ -\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x32\x2e\x30\x34\x37\x32\x32\x33\x35\x37\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ -\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\ -\x39\x38\x34\x36\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x2e\x37\x36\x34\x34\x39\x34\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x34\x38\x2e\x39\ -\x34\x39\x35\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x34\x32\x2e\x36\x31\x30\x34\x35\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x35\x33\ -\x36\x34\x37\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\ -\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\ -\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x34\x33\x36\x37\x38\x34\x38\x2c\ -\x30\x2e\x35\x33\x36\x38\x34\x38\x37\x39\x2c\x30\x2c\x30\x29\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\ -\x37\x38\x39\x33\x37\x32\x39\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\ -\x33\x39\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x72\x79\x3d\x22\x32\x2e\x37\x31\x30\x39\x37\x38\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\ -\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x32\x36\x2e\x30\x36\x32\x32\x38\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x33\x33\x2e\x37\x33\x32\x30\x34\x34\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\ -\x37\x2e\x39\x31\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x39\x38\x34\x36\x35\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\ -\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\ -\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ -\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ -\x2e\x39\x31\x34\x34\x32\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x38\x32\x33\x34\ -\x33\x35\x34\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x33\x37\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ -\x74\x68\x3d\x22\x31\x39\x2e\x39\x38\x34\x36\x35\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\ -\x2e\x32\x31\x30\x36\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x32\x31\x2e\x38\x36\x33\x30\x39\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x31\x2e\x38\x32\x31\x39\x32\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ -\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x32\x2e\x39\x30\x36\x35\x38\x31\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ -\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\ -\x33\x36\x32\x35\x30\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\ -\x36\x38\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\ -\x2c\x30\x2c\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\ -\x2e\x37\x30\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x30\x31\x31\ -\x30\x32\x39\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\ -\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x2d\x33\x2e\x37\x38\x37\x36\x32\x39\x38\ -\x65\x2d\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x31\x39\x2e\x39\x30\x30\x39\x36\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x39\ -\x38\x34\x36\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x31\x2e\x37\x38\x38\x33\x39\x38\x33\x39\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x67\x33\x37\x30\x37\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x67\x33\x37\x31\x32\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x67\x33\x37\x31\x37\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x38\x30\x39\ -\x35\x32\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x31\x32\x2e\x31\x32\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x31\ -\x2e\x38\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x35\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\ -\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ -\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\ -\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ -\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x34\x2e\ -\x38\x37\x34\x39\x39\x39\x2c\x32\x32\x2e\x31\x32\x35\x20\x48\x20\ -\x32\x38\x2e\x38\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ -\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x34\x2e\x32\x33\x34\x34\x36\x31\x37\x38\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\ -\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ -\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\ -\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x6d\x20\x32\x31\x2e\x38\x37\x35\x2c\x31\x35\x2e\ -\x31\x32\x35\x20\x76\x20\x31\x34\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ -\x67\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x10\xf7\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x74\x63\x68\ -\x5f\x63\x68\x65\x63\x6b\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\ -\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\ -\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ -\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\ -\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x38\x39\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\ -\x6f\x6c\x6f\x72\x3a\x23\x61\x61\x34\x34\x30\x30\x3b\x73\x74\x6f\ -\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\ -\x74\x6f\x70\x33\x37\x39\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x39\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\ -\x30\x2e\x34\x39\x33\x31\x35\x30\x36\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x61\x61\x34\x34\x30\x30\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x34\ -\x31\x31\x37\x36\x34\x37\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\ -\x6f\x72\x3a\x23\x61\x61\x34\x34\x30\x30\x3b\x73\x74\x6f\x70\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\ -\x70\x33\x37\x39\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\ -\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\ -\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x30\x66\x65\ -\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\ -\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\ -\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ -\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\x30\x36\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x62\x62\ -\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\ -\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ -\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\ -\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\x74\x6f\x70\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x30\x33\x39\ -\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\ -\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\ -\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x36\x39\ -\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x61\x31\x61\ -\x39\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ -\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x37\x31\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\ -\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\ -\x73\x65\x74\x3d\x22\x30\x2e\x36\x34\x33\x38\x33\x35\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x37\x36\x63\x36\ -\x63\x61\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x30\x2e\x34\x39\x38\x30\x33\x39\x32\x32\x3b\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x65\x63\x65\x63\x65\x63\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\ -\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x73\x74\x6f\x70\x33\x37\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\x66\x69\x6c\x74\x65\x72\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\ -\x6f\x6c\x6f\x72\x2d\x69\x6e\x74\x65\x72\x70\x6f\x6c\x61\x74\x69\ -\x6f\x6e\x2d\x66\x69\x6c\x74\x65\x72\x73\x3a\x73\x52\x47\x42\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x66\x69\x6c\x74\ -\x65\x72\x34\x35\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x2d\x30\x2e\x30\x32\x33\x37\x34\x38\x36\x32\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x2e\ -\x30\x34\x37\x34\x39\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x2d\x30\x2e\x30\x32\x34\x32\x35\x36\x37\x35\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x31\x2e\x30\x34\x38\x35\x31\x33\x35\x22\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x66\x65\x47\x61\x75\x73\x73\x69\x61\x6e\x42\x6c\x75\ -\x72\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ -\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x64\x44\x65\x76\x69\x61\x74\x69\x6f\x6e\x3d\x22\x30\x2e\x32\x37\ -\x39\x32\x33\x37\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x66\x65\x47\x61\x75\x73\x73\x69\x61\x6e\x42\ -\x6c\x75\x72\x34\x35\x30\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x66\x69\x6c\x74\x65\x72\x3e\x0a\x20\x20\x3c\x2f\x64\x65\ -\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ -\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x78\x3d\x22\x2d\x39\x34\x2e\x30\x33\x34\x39\x39\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ -\x3d\x22\x2d\x36\x2e\x35\x33\x38\x34\x34\x37\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ -\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ -\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\ -\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ -\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ -\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ -\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ -\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ -\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ -\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ -\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ -\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ -\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x65\x33\x64\x62\x64\x62\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x33\x31\x32\x35\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ -\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x74\x65\x72\x3a\x75\x72\ -\x6c\x28\x23\x66\x69\x6c\x74\x65\x72\x34\x35\x30\x35\x29\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x34\ -\x35\x30\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x32\x37\x2e\x35\x38\x37\x33\x31\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x38\x2e\ -\x31\x37\x39\x33\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x2d\x33\x30\x2e\x30\x36\x39\x36\x34\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x39\x33\x30\x30\x32\x30\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\ -\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x39\x30\x2e\ -\x30\x38\x33\x30\x39\x34\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x31\x32\x66\x66\x32\x32\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x39\x39\x39\ -\x39\x39\x37\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x6d\x20\x34\x2e\x37\x39\x32\x32\x32\x36\x32\ -\x2c\x31\x34\x2e\x31\x39\x37\x30\x34\x33\x20\x63\x20\x30\x2c\x30\ -\x20\x38\x2e\x36\x38\x39\x38\x39\x33\x38\x2c\x31\x36\x2e\x33\x36\ -\x33\x30\x30\x38\x20\x39\x2e\x33\x37\x31\x38\x32\x38\x38\x2c\x31\ -\x32\x2e\x35\x33\x36\x38\x37\x33\x20\x43\x20\x31\x37\x2e\x39\x37\ -\x32\x39\x38\x34\x2c\x35\x2e\x33\x36\x33\x31\x37\x38\x33\x20\x32\ -\x38\x2e\x38\x31\x32\x39\x30\x33\x2c\x34\x2e\x30\x39\x38\x31\x35\ -\x36\x32\x20\x32\x38\x2e\x38\x31\x32\x39\x30\x33\x2c\x34\x2e\x30\ -\x39\x38\x31\x35\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x34\x35\x30\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ -\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\ -\x63\x73\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ -\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x12\x74\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x7a\x6f\x6e\x61\x6c\ -\x5f\x73\x74\x61\x74\x5f\x72\x61\x73\x74\x65\x72\x5f\x74\x6f\x6f\ -\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\ -\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ -\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ -\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\ -\x6d\x3d\x22\x31\x2e\x33\x39\x39\x37\x32\x35\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ -\x2d\x32\x35\x35\x2e\x35\x32\x38\x32\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x33\ -\x2e\x32\x36\x38\x34\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\ -\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\ -\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\ -\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\ -\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\ -\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\ -\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ -\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ -\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ -\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ -\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ -\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ -\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\ -\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ -\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\ -\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ -\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x36\x36\x34\x32\ -\x34\x38\x37\x37\x2c\x30\x2e\x37\x34\x37\x35\x31\x31\x35\x38\x2c\ -\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x33\x2e\x35\x32\x36\x30\x38\x37\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x36\x30\x36\x39\x38\x31\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x36\x2e\x34\ -\x35\x39\x39\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x33\x31\x2e\x30\x35\x36\x34\x31\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x33\x2e\x33\x30\ -\x35\x31\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ -\x74\x68\x3d\x22\x32\x31\x2e\x38\x37\x33\x31\x39\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\ -\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x38\x66\x66\x66\x38\x66\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x32\x38\ -\x34\x31\x37\x31\x33\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x66\x66\x61\x33\x61\x33\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\ -\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\ -\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\ -\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\ -\x39\x31\x33\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x38\x2e\x37\x38\x35\x32\x35\x36\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x31\x2e\x33\x37\x39\x32\x32\x38\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\ -\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ -\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\ -\x32\x35\x30\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\ -\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\ -\x2c\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\ -\x30\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x32\x31\x31\x37\x36\ -\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ -\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x37\x32\x2e\x37\x38\x30\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x34\x30\x2e\x31\x36\x32\x35\x32\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x32\x31\x2e\x32\x32\x37\x36\x39\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\ -\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\ -\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ -\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ -\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x31\x2e\x39\x30\x37\x36\x32\x34\x39\x36\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ -\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\ -\x72\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\ -\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\ -\x31\x32\x2e\x38\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\ -\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\ -\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\ -\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\ -\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\ -\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\x64\x27\x3b\x6c\x65\x74\ -\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\ -\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\ -\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x39\x2e\x34\x33\x31\x30\x35\x32\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x33\x30\x2e\x34\x32\x38\x31\x35\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\ -\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\ -\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\x39\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x39\x2e\ -\x34\x33\x31\x30\x35\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x33\x30\x2e\x34\x32\x38\x31\x35\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x32\x35\x2e\x36\x30\x30\ -\x30\x30\x30\x33\x38\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\ -\x67\x68\x74\x3a\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\ -\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x32\x22\x3e\xcf\x83\x3c\x2f\x74\x73\x70\ -\x61\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\x20\x20\x3c\ -\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x34\x33\x36\x33\x34\ -\x39\x36\x33\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x34\ -\x2e\x36\x36\x36\x36\x36\x37\x2c\x2d\x31\x37\x2e\x32\x20\x2d\x31\ -\x2e\x30\x39\x35\x37\x38\x30\x35\x2c\x31\x35\x2e\x36\x38\x38\x38\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x33\x37\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ -\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x31\x2e\x34\x33\x36\x33\x34\x39\x36\x33\x70\x78\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ -\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ -\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x4d\x20\x2d\x31\x38\x2e\x34\x34\x34\x34\x34\x34\ -\x2c\x34\x2e\x31\x33\x33\x33\x33\x34\x31\x20\x48\x20\x32\x36\x2e\ -\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x37\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ -\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ -\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\ -\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x31\x2e\x34\x33\x36\x33\x34\x39\x36\x33\ -\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ -\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x2d\x32\x35\x2e\x37\ -\x37\x37\x37\x37\x37\x2c\x39\x2e\x34\x36\x36\x36\x36\x37\x36\x20\ -\x48\x20\x31\x38\x2e\x36\x36\x36\x36\x36\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x37\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x34\x33\x36\ -\x33\x34\x39\x36\x33\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ -\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\ -\x33\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\x2d\x31\x37\x2e\x32\x20\ -\x39\x2e\x35\x37\x30\x38\x38\x37\x2c\x31\x35\x2e\x36\x38\x38\x38\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x33\x37\x37\x35\x2d\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ -\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0a\ -\x00\x00\x06\x71\ -\x00\ -\x00\x16\x14\x78\x9c\xed\x57\x6d\x8f\x9b\x46\x10\xfe\x7e\xbf\x82\ -\x72\x5f\x12\x15\x96\x7d\x7f\x71\x6c\x47\x6a\xa3\x48\x91\xda\x2f\ -\x6d\xaa\x7e\x8c\x30\xac\x7d\x34\x18\x2c\xc0\x67\x3b\xbf\xbe\xb3\ -\x18\x30\xbe\xf3\xe9\x1c\xe5\x22\x45\x55\xad\x44\xa7\x9d\x99\xdd\ -\x9d\x9d\x79\x66\xe6\x61\xfa\x76\xbf\xce\xbd\x7b\x5b\xd5\x59\x59\ -\xcc\x7c\x82\xb0\xef\xd9\x22\x29\xd3\xac\x58\xcd\xfc\xbf\x3e\xbe\ -\x0f\xb5\xef\xd5\x4d\x5c\xa4\x71\x5e\x16\x76\xe6\x17\xa5\xff\x76\ -\x7e\x33\xfd\x29\x0c\xbd\x5f\x2b\x1b\x37\x36\xf5\x76\x59\x73\xe7\ -\x7d\x28\x3e\xd7\x49\xbc\xb1\xde\xab\xbb\xa6\xd9\x4c\xa2\x68\xb7\ -\xdb\xa1\xac\x13\xa2\xb2\x5a\x45\xaf\xbd\x30\x9c\xdf\xdc\x4c\xeb\ -\xfb\xd5\x8d\xe7\x79\x70\x6f\x51\x4f\xd2\x64\xe6\x77\x1b\x36\xdb\ -\x2a\x6f\x0d\xd3\x24\xb2\xb9\x5d\xdb\xa2\xa9\x23\x82\x48\xe4\x9f\ -\xcc\x93\x93\x79\xe2\x6e\xcf\xee\x6d\x52\xae\xd7\x65\x51\xb7\x3b\ -\x8b\xfa\x76\x64\x5c\xa5\xcb\xc1\xda\x79\xb3\x63\xad\x11\x31\xc6\ -\x44\x98\x46\x94\x86\x60\x11\xd6\x87\xa2\x89\xf7\xe1\xf9\x56\xf0\ -\xf1\xd2\x56\x8a\x31\x8e\x40\x77\xb2\xbc\xce\x6a\x52\x43\x40\x37\ -\xf0\x7f\x30\xef\x05\xa8\x2e\xb7\x55\x62\x97\xb0\xcf\xa2\xc2\x36\ -\xd1\xbb\x8f\xef\x06\x65\x88\x51\xda\xa4\xa3\x63\xfa\x78\x9e\xdd\ -\x7a\x16\xe4\x22\x5e\xdb\x7a\x13\x27\xb6\x8e\x7a\x79\xbb\x7f\x97\ -\xa5\xcd\xdd\xcc\x67\x12\x71\xac\xb5\x69\x65\x77\x36\x5b\xdd\x35\ -\x0f\x84\x59\x3a\xf3\xc1\x77\x6a\xb4\x68\xd7\x23\x68\x90\xa3\x41\ -\x77\xec\x64\xd0\x60\x64\x28\x22\x5e\x45\x04\x53\x47\x9b\xfe\x01\ -\x93\xb4\x4c\x9c\x47\x70\xa4\x5d\x67\xf1\xb6\x29\xd7\x90\xb3\x24\ -\xc9\xe3\xba\xce\x96\x59\x02\x8b\xb2\xd8\xe4\xdb\x55\x56\x7c\xaa\ -\x37\x36\x69\xaa\x38\xff\x94\x66\x0e\x6f\x89\x45\x7d\x08\x87\x1b\ -\xed\x7e\x53\x56\x4d\xb8\x4f\x37\x10\x48\xa9\x2e\x2a\x0f\x63\xe5\ -\x7d\x66\x77\xbf\x94\x7b\x70\xd1\xc3\x1e\xa3\xf0\xcf\x9f\x83\x7c\ -\x9a\xda\x65\xed\xf4\xc7\xe7\xba\x15\xbc\x57\xf9\x5e\xd4\x6a\x07\ -\xef\x9d\xeb\xa9\x3b\xe3\x64\xbb\x88\xeb\x63\x40\x3d\x6f\x13\xaf\ -\x00\x7c\x79\x59\xcd\xfc\xdb\x65\xfb\xeb\x14\x8b\xb2\x4a\x6d\xd5\ -\xab\x64\xfb\x3b\x53\x95\x90\xa0\xac\x39\x1c\xcb\xad\x3b\xbb\x7f\ -\x86\x3b\x75\xd0\xe3\xcb\xfa\xfa\x2e\x4e\xcb\xdd\xcc\xa7\x0f\x95\ -\x5f\xca\x72\x3d\xf3\x05\x12\x46\x1b\x8c\xcd\x43\x75\x02\x91\x08\ -\x35\x43\x02\x4b\x4a\xf8\x23\x2d\x5c\x28\x11\xc6\x4a\x1b\x4a\x1e\ -\x29\xb7\x55\x05\x05\x19\xe6\xf1\xc1\xc2\xab\xda\x3f\xbd\x51\x7d\ -\x57\xee\x56\x95\x8b\x4e\x53\x6d\xed\xc3\x9d\x4e\x13\x2e\x16\x2e\ -\x0b\x97\xd4\x80\x90\xad\x2b\xf5\x70\x5b\x64\x0d\x94\xd3\x66\x3f\ -\x3e\x75\x9b\xa5\xb6\xbe\xbc\x71\x97\x15\x10\x84\xb0\x03\x36\x61\ -\x43\x8c\x1f\x5a\xf4\x30\x57\x58\x3f\x61\xe1\x00\xf2\x84\xea\xf0\ -\xb4\x6a\x1d\xef\xb3\x75\xf6\xc5\xc2\xbb\x1f\x85\xab\x2e\xe2\x4d\ -\xb8\xca\xcb\x45\x9c\x77\xde\xcf\x5b\x8b\xe9\x59\x58\x8e\x9b\x3c\ -\xaf\x39\xb8\x92\xde\x1f\x9c\xcc\xef\x85\x2e\x9e\x4e\xc0\x94\x14\ -\x83\xb0\xac\x32\xa8\x95\x91\xbf\xbd\xe8\x30\x16\xb9\x06\x00\xfd\ -\x7b\xdf\x02\xac\x85\x9f\x7a\xa8\x3b\x8c\x75\x1d\xee\xa3\xc7\xc0\ -\x6f\xe5\x6b\xdb\xc4\x69\xdc\xc4\xa7\x2a\xe8\x25\xd4\x18\xdc\xbf\ -\x0c\x7a\xe9\xe4\x8f\x77\xef\xe7\xdd\x45\xd3\x24\x99\xfc\x5d\x56\ -\x9f\xfb\x7b\x3d\xcf\x19\xc4\x8b\x72\x0b\xa9\xf0\xe7\x83\x78\x9a\ -\x26\x13\xe8\x7e\xd0\x17\xe6\xd9\x1a\xb0\xed\x1a\xe7\xcf\xd0\xed\ -\xa6\xd1\x49\x71\x66\xec\x82\x75\x3a\xf4\x78\x6c\x65\x8f\x6d\xf4\ -\xe2\x2c\x49\x93\x75\xe6\x36\x45\x7f\x36\x59\x9e\x7f\x70\x97\x74\ -\x2f\x1e\x1d\x9a\x35\xb9\x3d\x09\xa7\x51\xe7\x7d\xf7\xb6\x68\xf4\ -\xb8\x69\xd4\xbf\xbe\x5d\xad\x4e\x51\x39\x2b\x8a\x21\xd1\x79\xbc\ -\xb0\x00\x82\xdf\x9c\xd2\x7b\xa4\x5d\x55\xe5\x76\xb3\x2e\x53\xdb\ -\x6d\xef\xa3\xb9\x89\x9b\xbb\x21\x65\xcd\x21\x07\xfd\x12\xbc\x9f\ -\x14\x30\x84\xdf\xd4\x4d\x55\x7e\xb6\x93\x5b\x6a\x53\x18\x35\xdd\ -\xf2\x58\x09\x13\x8a\xb0\xd0\x52\x43\x89\xf7\xf2\x3c\x2b\x2c\xdc\ -\x35\x59\x6c\x9b\x66\x2c\xfb\xa7\xcc\x8a\x09\x84\xc6\x56\xbd\xb4\ -\x5d\xe4\x00\xea\x66\xc2\x7b\x59\x1a\x43\xb7\xa9\xaa\xf8\x30\xbe\ -\x3a\xec\x3a\xd4\x84\x0c\xb8\x72\xa8\xf0\x18\x47\x8a\x6a\xc2\x59\ -\x10\x32\xc4\x8c\xd2\x5c\x70\x2f\x24\x88\x61\x4c\xa8\x08\x18\xc2\ -\x94\x73\x89\x89\xf4\x18\xa2\x58\x08\x4a\x03\x83\x94\xd1\x58\x2b\ -\x05\x86\x14\x69\x42\x8c\x30\x01\x47\x92\x72\x62\xa8\x80\xcd\x14\ -\x71\xad\x29\x57\x01\x9c\x03\x52\x4e\x94\x17\x0a\xa4\x08\x87\xc3\ -\x03\x8a\x14\x37\x92\x50\x2f\x34\x88\x48\x62\x60\x00\xb9\x5b\x8c\ -\x81\x06\xe7\x85\x1a\x19\x81\x29\x55\x1a\x0e\x14\x94\x33\x71\x56\ -\x5c\x2e\xc4\x1c\xb3\x53\x69\x9c\x9a\x5d\x59\x40\xc8\x9a\xb2\x0a\ -\xa1\xed\xdd\xc7\xcd\xb6\xb2\xae\xbc\x7a\x7c\x4c\x2b\x50\x5e\x4a\ -\xce\x2d\x86\x37\xa5\xfc\x8d\x5b\x9c\x42\x74\x5c\x56\xdb\x1c\x66\ -\xd4\xbd\x2d\xca\x34\x1d\x12\x88\xdb\xdf\x79\x02\x31\x52\xca\x08\ -\x41\xa4\x7e\x89\xb4\xb8\x87\x3a\x77\xa1\x52\xd9\x20\xec\x7a\xa6\ -\x42\x52\x4b\xce\xb4\x1c\x14\x7d\xab\x94\x88\x01\x89\x91\xe4\x14\ -\x9b\xbd\xeb\x9f\x48\x68\x3e\x48\xa0\x83\x08\x86\x14\x66\x00\xb5\ -\x41\x58\xed\x5b\x3a\x00\xa9\x00\xff\x4f\x17\x56\xed\x2c\x33\x42\ -\x52\x6a\xa4\x19\xc4\x30\xee\x8b\xda\xd5\x38\x60\x27\x6e\xaa\x6c\ -\xff\x8a\x04\x38\x00\xd6\xa3\x25\x56\x5c\x60\x1d\xc0\x95\xd8\x60\ -\x26\xa9\x04\x05\x7e\xfd\x38\x55\x97\x28\xc1\x25\x83\x81\x16\x5c\ -\x4c\xe2\xd3\x8e\x10\xcc\x05\xd5\xc2\x39\xa2\x85\xc6\x4c\xab\x73\ -\x47\xaa\x63\x23\x25\x42\x48\xfd\x5c\x14\xc0\x94\x03\x9a\x15\xe6\ -\x67\x71\x15\x1a\x69\x8e\x05\xe6\x17\xd2\xa0\x08\xa5\xfc\x9a\xcc\ -\xf5\x79\x86\x69\x31\xea\xf5\xe7\xd8\x8c\x63\xc0\xda\xb7\x62\x93\ -\xc2\xc0\x30\xe6\x9b\xb0\xf9\x7c\x1d\x2d\x97\xed\xdd\xdf\xe8\xab\ -\x34\xd0\x75\xb0\x7a\xc9\x32\x82\xf0\x9a\xeb\xcb\x48\x21\x22\x38\ -\x74\x39\x71\x96\x6e\x8c\x88\x51\x1c\xab\x31\x2e\x18\x43\xe0\xac\ -\x32\xe4\x9a\x4a\x02\xbc\x41\x43\xd4\x5a\x3f\x5f\x48\x4a\x62\xc6\ -\x0d\x60\x16\x49\x6e\x04\x61\x86\x1d\xe1\x3b\xa4\xe0\xaa\x39\xb3\ -\x5c\x9a\x98\xa4\x3f\xcc\x9c\xf9\xdd\xcd\x19\xc6\xe0\x8b\x45\x07\ -\xa1\x42\x98\xc1\xbb\xa4\xf1\x20\x86\xae\x3e\x15\x0c\x1f\x0e\x34\ -\x56\x1a\x26\x60\xce\x48\x04\x33\x83\x05\x30\x31\x0c\x21\xc2\x19\ -\x71\x46\x19\xa7\x01\xc1\x88\xc3\x17\x0b\x67\x1e\x85\x38\x73\x8e\ -\x0d\x0f\x34\x58\x61\x43\xb5\x47\x04\x82\x56\x05\xa5\x17\x10\x82\ -\x04\x54\x27\xf7\x80\x1a\x4b\xc5\xe0\x8c\x80\xc0\x78\xe2\x50\xf2\ -\xa6\x9d\x58\x9a\x1a\xc8\x72\x40\xdc\x00\x72\x3d\xeb\xe2\x8c\x09\ -\xd9\xd7\x4f\x99\xab\x52\x83\x21\xbf\xda\xfe\x30\xa9\x01\x0a\x20\ -\x20\x0e\x86\x2a\x03\x98\xe3\xae\x65\x0a\x29\x07\x0a\xc0\x7a\x0a\ -\x40\x38\xef\x29\x80\xec\x29\x00\x31\x8f\x19\x00\xbf\x44\x00\x78\ -\x4f\x00\x04\xe9\x09\x00\x19\x08\x80\xd0\x3d\x01\xe0\x03\x01\x80\ -\xa6\x7d\x24\x00\xa3\xc6\x7b\x96\x1d\xf1\xa3\x72\x00\xf6\xd2\x1c\ -\x20\x7c\x6a\x96\x98\xeb\x48\x00\x75\x3d\x45\x1b\x71\xd6\xbd\xa0\ -\x20\xb8\x56\xec\xbb\xf1\x00\xf5\x9f\xe3\x01\x1a\xd8\x31\xe3\xd0\ -\x30\xc6\xb1\x25\xae\x74\xa8\x92\xe4\xab\x89\x80\xb9\xc8\x03\x42\ -\xf9\x3f\x13\xf8\xae\x4c\x20\x54\x57\x17\xd3\x45\x2a\x40\xda\x62\ -\x12\xa3\xef\x7b\x47\x05\x00\x04\x30\x67\xf4\xb3\x30\x7a\x51\x2a\ -\x30\x8d\x56\xf3\x9b\xa9\xfb\xf8\x9e\xdf\xfc\x0b\x55\x91\x2b\xcd\ -\ -\x00\x00\x0c\x67\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x70\x6c\x69\x74\ -\x5f\x72\x61\x73\x74\x65\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x78\x3d\x22\x2d\x36\x36\x2e\x34\x38\x32\x37\x34\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x79\x3d\x22\x35\x2e\x31\x34\x39\x30\x32\x30\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ -\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ -\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ -\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ -\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ -\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ -\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ -\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ -\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ -\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ -\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ -\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ -\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\x6c\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ -\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x31\x31\x36\x30\ -\x36\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\ -\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\x2e\ -\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x34\x32\x2e\x38\x35\x36\x30\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x35\x38\x2e\x35\x30\x31\x32\x35\x35\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\ -\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ -\x61\x74\x72\x69\x78\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\ -\x2c\x2d\x30\x2e\x37\x39\x31\x31\x33\x38\x38\x2c\x2d\x30\x2e\x30\ -\x39\x31\x33\x30\x32\x37\x38\x2c\x30\x2e\x39\x39\x35\x38\x32\x33\ -\x31\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ -\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\x2c\x2d\x30\x2e\x37\ -\x39\x31\x31\x33\x38\x38\x2c\x30\x2e\x30\x30\x32\x38\x38\x31\x37\ -\x34\x2c\x30\x2e\x39\x39\x39\x39\x39\x35\x38\x35\x2c\x30\x2c\x30\ -\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ -\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x32\x2e\x30\x32\x36\x37\ -\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x38\ -\x2e\x39\x35\x36\x30\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ -\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ -\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x37\x32\x32\x37\x33\ -\x32\x33\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x35\x39\x33\x33\x33\x30\x33\x38\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\ -\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\ -\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\ -\x34\x35\x36\x37\x38\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x31\x30\x2e\x33\x37\x38\x31\x39\x34\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\ -\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ -\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\x2c\x2d\x30\ -\x2e\x37\x39\x31\x31\x33\x38\x38\x2c\x30\x2e\x30\x38\x35\x30\x35\ -\x32\x34\x36\x2c\x30\x2e\x39\x39\x36\x33\x37\x36\x34\x37\x2c\x30\ -\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ -\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x08\xc4\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x74\x72\x61\x69\x6e\ -\x69\x6e\x67\x5f\x69\x6e\x70\x75\x74\x2e\x73\x76\x67\x22\x0a\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\ -\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\ -\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\ -\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ -\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\ -\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\ -\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ -\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\ -\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x34\x2e\x39\x31\x38\x38\ -\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x79\x3d\x22\x32\x31\x2e\x39\x38\x36\x31\x39\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\ -\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\ -\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ -\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\ -\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ -\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ -\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ -\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ -\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ -\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ -\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ -\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ -\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ -\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ -\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ -\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ -\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ -\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\ -\x35\x30\x31\x32\x38\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\ -\x3d\x22\x35\x2e\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\x37\x38\x35\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0a\ -\x00\x00\x08\xf2\ -\x00\ -\x00\x32\x55\x78\x9c\xe5\x5a\x4b\x8f\xdb\x38\x12\xbe\xf7\xaf\xe0\ -\xba\x2f\x09\xd6\x92\xf9\xd0\x83\x52\xbb\x7b\x0e\x13\x0c\x32\xc0\ -\xe4\xb2\x33\x3b\x0b\xec\x25\x90\x25\xda\xd6\x46\x96\xbc\x14\xdd\ -\xb6\xf3\xeb\xa7\x48\xbd\x65\x3b\xe8\x74\x67\x83\x78\x5b\x41\x60\ -\xa9\xaa\xf8\xfa\xf8\x55\xb1\xc8\xe6\xfc\xa7\xc3\x26\x43\x8f\x42\ -\x96\x69\x91\xdf\x4f\x88\x8d\x27\x48\xe4\x71\x91\xa4\xf9\xea\x7e\ -\xf2\xcf\x3f\x7e\xb1\xf8\x04\x95\x2a\xca\x93\x28\x2b\x72\x71\x3f\ -\xc9\x8b\xc9\x4f\x0f\x37\xf3\xbf\x59\x16\xfa\x59\x8a\x48\x89\x04\ -\xed\x53\xb5\x46\xbf\xe6\x9f\xca\x38\xda\x0a\xf4\x66\xad\xd4\x36\ -\x9c\xcd\xf6\xfb\xbd\x9d\xd6\x42\xbb\x90\xab\xd9\x5b\x64\x59\x0f\ -\x37\x37\xf3\xf2\x71\x75\x83\x10\x82\x76\xf3\x32\x4c\xe2\xfb\x49\ -\x5d\x60\xbb\x93\x99\x31\x4c\xe2\x99\xc8\xc4\x46\xe4\xaa\x9c\x11\ -\x9b\xcc\x26\x9d\x79\xdc\x99\xc7\xba\xf5\xf4\x51\xc4\xc5\x66\x53\ -\xe4\xa5\x29\x99\x97\xb7\x3d\x63\x99\x2c\x5b\x6b\xdd\x9b\x3d\x33\ -\x46\x24\x08\x82\x19\xa6\x33\x4a\x2d\xb0\xb0\xca\x63\xae\xa2\x83\ -\x35\x2c\x0a\x7d\x3c\x57\x94\x62\x8c\x67\xa0\xeb\x2c\x9f\x66\x15\ -\x96\x00\xe8\x16\xfe\xb7\xe6\x8d\xc0\x2e\x8b\x9d\x8c\xc5\x12\xca\ -\x09\x3b\x17\x6a\xf6\xee\x8f\x77\xad\xd2\xc2\x76\xa2\x92\x5e\x35\ -\x0d\x9e\x83\x56\x07\x20\xe7\xd1\x46\x94\xdb\x28\x16\xe5\xac\x91\ -\x9b\xf2\xfb\x34\x51\xeb\xfb\x09\x73\x6c\xc2\xe0\x71\x8d\x70\x2d\ -\xd2\xd5\x5a\x8d\xa5\x69\x72\x3f\x81\xde\xd3\x80\x57\xdf\x3d\x72\ -\x90\xca\xa0\xae\x38\x6c\x35\xd8\x0e\xa8\x4d\x90\x24\x2e\xf3\x2b\ -\x9b\x66\x08\x61\x52\xc4\xba\x4f\x50\xa5\xd8\xa4\xd1\x4e\x15\x1b\ -\x98\xb5\x38\xce\xa2\xb2\x4c\x97\x69\x0c\x1f\x45\xbe\xcd\x76\xab\ -\x34\xff\x08\x95\x2a\x25\xe4\x47\x29\x4a\xa1\x3e\x6e\x8b\xec\xb8\ -\x2a\x72\xbb\x01\xb2\x6d\x55\x1c\xb6\x85\x54\xd6\x21\xd9\x02\x9c\ -\x9e\x7f\x56\x79\x6c\x94\x0f\xa0\x9d\x27\x62\x59\x6a\xab\x6a\x6c\ -\xfa\x0b\x06\xe7\x4f\xd0\xcc\x68\xdb\xae\xea\x7e\x26\x8f\xa9\xd8\ -\x77\xb6\x8b\xa8\xac\xf0\x43\x68\x1b\xad\x80\x6b\x59\x21\xef\x27\ -\xb7\x4b\xf3\xd4\x8a\x45\x21\x13\x21\x1b\x95\x67\x9e\x81\xaa\x80\ -\xf9\x48\xd5\xb1\xf2\xae\xba\xee\xa6\xbf\xba\xd6\x56\x8f\xcf\xeb\ -\xcb\x75\x94\x14\xfb\xfb\x09\x1d\x2b\x3f\x17\xc5\x46\xd7\x1a\xf8\ -\x81\x4b\xb0\x3b\x56\xc7\x87\xfb\x89\xc5\x88\x67\xd3\x80\x38\xa7\ -\x5a\x68\xd0\x0d\x6c\xee\xbb\xbe\x4b\x4e\x94\x3b\x29\xc1\xff\xac\ -\x2c\x3a\x0a\x18\x95\xf9\x69\x8c\xca\x75\xb1\x5f\x49\x8d\x8e\x92\ -\x3b\x31\x2e\xa9\x35\xd6\x62\x51\x1c\xce\xab\x81\x0e\x3b\xed\xd9\ -\xd6\x2e\x4f\x15\x78\xcf\xf6\xd0\xaf\x75\x97\x26\xa2\x3c\x5f\x70\ -\x9f\xe6\x00\x82\x55\xf3\x98\xb0\x16\xe3\xb1\x45\x43\x6a\x1f\xf3\ -\x0b\x16\xd0\xb5\x13\x9c\x6b\xd5\xf1\xb2\x6a\x13\x1d\xd2\x4d\xfa\ -\x59\xc0\xb8\x4f\xe0\x2a\xf3\x68\x6b\xad\xb2\x62\x11\x65\x75\xef\ -\x1f\x8c\xc5\x7c\x00\x4b\x55\x08\x21\x75\xd4\x1e\x7c\x38\x6a\xd9\ -\xa4\x11\x6a\x3c\xb5\x80\xf9\x9e\xdb\x0a\x0b\x99\x82\x63\xf4\xfa\ -\xdb\x88\x8e\x7d\x91\xf6\x77\x08\xd7\x07\x43\x30\x43\x3f\x7f\xac\ -\x3b\xf6\x75\x35\xef\x67\xa7\xc4\x37\xf2\x8d\x50\x51\x12\xa9\xa8\ -\xf3\x82\x46\x42\x83\x00\x37\x23\x83\xd0\x19\xfe\xe3\xdd\x2f\x0f\ -\x75\x43\xf3\x38\x0e\xff\x55\xc8\x4f\x4d\xbb\x08\x69\x83\x68\x51\ -\xec\x60\x2a\x26\x0f\xad\x78\x9e\xc4\x21\x04\x3b\x08\x02\x0f\xe9\ -\x06\xb8\xad\xe3\xe4\xdf\x21\xb8\xcd\x67\x9d\x62\x60\xac\xc1\xea\ -\x2a\xad\xaa\x85\x00\x61\xa2\xe6\xd9\xa5\x23\x89\x37\xa9\x2e\x34\ -\xfb\x5d\xa5\x59\xf6\xab\x6e\xa4\x1e\x71\xaf\xd2\x54\x65\xa2\x13\ -\xce\x67\x75\xef\xeb\xb1\xcd\x7a\x83\x9b\xcf\x9a\xd1\x9b\xaf\x55\ -\x87\xca\xc0\x29\xda\x89\xce\xa2\x85\x00\x12\xfc\xa6\x95\xe8\x44\ -\xbb\x92\xc5\x6e\xbb\x29\x12\x51\x17\x6f\xd0\x5c\x0d\x68\xc0\xb0\ -\xcb\xda\x19\x54\x32\xca\x4b\x8d\x0c\xcc\x43\xa4\x64\x7a\x78\x83\ -\x6d\xee\x11\xf3\x4c\xb1\xfe\xd7\x7d\x42\x28\xe0\x2e\xe1\x2e\x9d\ -\x52\xdb\x77\xcd\xf3\xb6\x05\x7f\x2e\x45\xac\x3a\x28\xcf\xd5\xeb\ -\xbb\x3c\x08\xb8\x47\xa1\x4e\x0f\x22\x4a\x40\x29\x9b\xc2\x22\xe4\ -\xfb\x3e\xc3\x4c\x37\x67\x7b\x10\x4b\xa8\x47\xb9\x6e\xf7\xed\xa4\ -\x37\xdb\x15\xc3\x5c\xc6\x3c\x16\xf4\xe5\xc0\x4a\x6a\x3b\x8e\xe7\ -\x11\x9f\xf4\xe4\x60\xae\x2b\x0e\x30\xc5\x1e\xf6\x7b\x0a\x6d\xef\ -\xd9\x9e\xc7\x3c\xee\xf6\xc4\x8d\x57\x73\x9b\xbb\x01\x76\xb9\xd3\ -\xd3\x35\x31\xc1\xb1\x3d\xee\x73\xaf\x5f\x4c\xc3\xa9\x87\x0d\xcc\ -\x0d\x2c\x6e\xb1\x9e\xaa\x54\xc7\x0c\xa6\x61\x09\x24\x09\x6f\x45\ -\x10\x2d\x88\x77\xa7\x3f\xac\x3a\x1c\x87\xa4\xfa\x94\xbb\x0c\x96\ -\x95\x47\x91\x17\x49\x72\x57\x2a\x59\x7c\x12\xe1\x2d\xe1\x89\xb7\ -\x5c\xd6\x9f\x55\x50\x0a\x71\xf3\x09\xfc\x13\x32\x83\x60\xa1\x42\ -\xa7\x91\x25\x11\x44\x71\x29\xa3\x63\x98\x43\x1a\xd5\x48\xdb\xa6\ -\x7a\x0c\x7d\xc2\x34\x05\xd4\x21\xae\x17\xf8\x30\x1f\x8c\x53\x4c\ -\x68\xe0\x9a\x69\xd2\x13\x46\x38\xcc\x0d\xbc\x3a\xc0\x04\xe6\x9c\ -\x9f\x26\x9f\xbb\x2e\xe5\x7c\x34\x4d\x40\x1e\x8a\x41\x1e\x8c\xa6\ -\x29\xb0\x03\xcc\x58\xe0\x8c\x66\x89\xb8\xb6\xc3\x59\xc0\xcf\x4c\ -\x12\xa8\x30\xf1\x7c\x97\x9d\x99\x24\x62\xbb\xd0\x5d\x4e\x2e\x4f\ -\x92\x7f\x85\xb3\x24\xcd\xea\xed\x62\x9f\x01\xcd\xc7\xfc\x07\x5e\ -\x92\xc0\x73\x19\x1d\x02\x4b\x7d\xdb\xd7\x59\x97\x33\xc4\xd5\xb5\ -\x19\xeb\x92\xb1\x21\xb0\x8e\x4d\x4d\x0c\x0f\x4e\x81\x3d\x57\xdb\ -\x18\x58\x8b\xbf\x0e\x64\xf1\x77\x43\xf4\x3a\xf1\x64\x36\xc7\x0e\ -\x84\x4a\x77\x04\x27\xb3\x5d\x97\xb9\x7e\xe0\x7d\x11\x4e\x5a\x6d\ -\x16\x06\xb8\xb4\x3b\x09\x7a\x06\x47\x62\x9f\xd8\x0f\x71\xbc\x06\ -\x14\xb7\x91\x5a\xf7\xba\xd9\xa6\x4e\xb0\x96\xeb\x6c\x03\xb2\xd6\ -\xf8\xc2\xd3\x1f\x76\x9b\x5f\x17\x79\x0e\xc3\x2f\xa4\x05\x99\xf6\ -\x63\xa4\x76\x52\x0c\x71\x1e\x00\xd4\x27\x27\xc8\x3f\x20\x58\x69\ -\x2b\x4a\x4f\x2d\xd8\x94\xa1\x3f\x11\x46\x8c\x22\xc6\xe0\x7d\x8d\ -\xb4\x84\x41\x30\x37\x8f\x8f\x2a\x03\x50\xff\x86\x98\x6b\x43\x66\ -\x00\x39\xbf\xc9\x03\x11\x75\x6c\xb7\xaa\x85\xf0\x7a\x4e\xd1\x23\ -\xb2\x3c\xdb\x69\x6d\x6b\x31\x33\x9f\x95\x2d\xd6\x36\xc4\xb4\x64\ -\x7e\xac\x5e\x5b\x9f\xd1\x06\x51\x53\x8e\xa2\xf7\xba\x3f\x55\x37\ -\xa1\x3a\x0a\x49\xc0\x94\x40\xfe\x50\x35\xfd\x27\x22\x81\x6d\xba\ -\xd4\xd8\x4c\x19\xac\x6b\xba\x50\xdd\x0e\x43\xff\x3e\xa5\x85\xd9\ -\x64\x85\xb7\xd8\x3c\x77\xcb\x02\xf6\x11\x46\x03\xd3\x00\x99\x63\ -\x56\x49\x1e\x23\x99\x46\xb9\x1a\xc8\xf6\x86\x9f\x03\x11\x4c\xb6\ -\x50\xf1\x7a\x28\x83\xfc\x3e\x84\x5c\x38\xdd\x6d\xee\xb2\x34\x17\ -\xf5\x66\x62\x60\xb3\x8c\x36\x69\x76\x0c\x7f\x87\x65\xf9\xce\x6a\ -\x26\xd4\xaa\x8a\x6f\x45\xdc\x6e\x6a\x2b\x0b\x25\x0e\x0a\xac\x12\ -\xd8\xf2\x00\x15\xcd\x57\x94\xa5\xab\x3c\x2c\x55\x24\x55\x25\x48\ -\x60\x5f\x29\xab\x32\x86\x86\x23\xa1\xa5\x7b\x52\x69\x32\xa1\x37\ -\xc8\x56\x9d\xd4\x37\xdd\xda\xc3\x2e\x73\x2c\x33\x75\xb4\xb9\x43\ -\x55\x7a\x2f\x53\x05\x26\x96\xce\x3f\xc3\x4c\x5a\x6a\x71\x97\xa4\ -\x9a\x64\xba\xe5\x4c\xc9\x3b\xbd\xdb\x35\xc3\x2e\xd7\xe9\x52\x85\ -\xcd\x67\xdd\xed\x3c\x5e\x03\xf8\x55\xbf\x93\xb4\xdc\x42\x02\x1b\ -\xa6\xb9\x31\x28\x1e\x85\x5c\x66\xc5\x3e\x7c\x4c\xcb\x74\x91\x89\ -\x3b\xf3\x9b\x66\xda\x8b\x1a\x51\xe5\xd2\xb5\x8b\x3e\xd5\xa5\xfb\ -\x6e\x59\xf9\x33\x50\xd2\x77\x21\xe5\xe1\xec\x6e\x13\xc9\x4f\x42\ -\x56\x36\x22\x8f\xa0\x11\x6b\x11\xc5\x9f\x74\x8e\x9d\x27\x61\x14\ -\xc3\x4e\x73\x97\x45\x4a\x5c\x76\xe3\xaf\xf3\x47\x5d\x96\x05\xd8\ -\x19\x7a\x23\x30\xbe\x0e\x70\xe0\x47\x7e\xb5\xc9\xf2\x51\x8c\xc0\ -\x8d\xa6\xda\x95\x46\xbf\x97\x62\x1d\x07\x46\x73\x3c\x06\xa6\x89\ -\x6c\xcb\x8a\xf1\x03\x24\x88\xcd\x1d\xdf\xa5\x98\xb3\xed\xa1\xd1\ -\xe8\xd9\x80\x01\x85\x8b\x9d\x52\x7d\xd9\x7f\x8a\x34\x0f\x4d\x04\ -\xfc\x8a\x20\xf7\x2c\x74\xbc\x13\x74\xea\x65\x74\x88\x8e\xd5\xc0\ -\x72\xf2\x72\x09\x20\x8c\x3d\x46\x4e\x98\xf3\x25\x80\xda\x85\xca\ -\xf9\x91\x00\x72\x2c\x7a\x99\x40\x1a\x88\xd7\x4b\x1d\x8b\x5c\x26\ -\x4f\x85\xcc\xab\xa6\xcd\x29\x3c\x7a\xcd\xac\xf3\x80\x6e\xa9\x7e\ -\xcd\xfc\x39\x03\x91\xdf\xf8\xd6\x00\xa2\xd7\x4d\x24\x7f\x8c\x92\ -\xd5\x9e\x0e\x4e\x2d\xc8\xc0\x5e\x37\x87\x82\x31\x3a\xcd\x06\x92\ -\x35\xe0\xbc\x6e\xf6\x9c\xe0\x83\xa7\x94\xdb\xfc\x75\x93\xc6\x19\ -\xef\xd1\xf4\xd8\x0d\x2c\x3f\x03\x3e\x7a\xfb\x34\xfc\x79\x0d\x44\ -\x39\x49\x74\xba\xf5\xaa\x5d\xd8\x5f\x37\x6b\x4e\xb2\xe5\x6e\xb9\ -\xea\x23\x74\x8d\xf1\x66\x3e\x5b\xd5\x2f\x7d\xac\xfa\x9d\xec\x6d\ -\xee\xda\x3d\xfd\x85\x2e\x7d\x7d\x87\x9e\x73\xdc\x73\xd3\xcd\xc4\ -\x07\x70\x53\xac\xcf\x4d\xea\x3f\x8d\x77\x67\xd2\xcd\x0c\xd2\xa0\ -\x77\x4e\xf6\x54\x02\x9c\x3f\x37\xea\x30\xbb\x4e\xa8\x5a\x90\xa6\ -\xed\x1b\x7a\x8f\xf0\x39\xc8\xf8\x8f\x03\x99\x3e\xb6\xf2\x30\x75\ -\xf9\xcb\xf8\x3e\x40\xa2\x4b\xa3\xea\xd0\xcf\xf4\x69\x98\x7e\x3d\ -\x79\x39\x41\x87\xf9\x3e\xb5\xf0\x93\xf1\xf9\x26\x9c\x21\xbe\xeb\ -\x10\xd7\xfd\x66\x08\xf4\x73\x25\xb3\xd8\xc5\xe0\x47\x56\x7d\xc8\ -\xee\x5f\x7a\x3f\x85\x82\x3b\x57\x0f\x44\x7b\xd8\xf9\x52\x20\xac\ -\xa7\xfb\xcc\x0f\x0a\x45\x77\xbe\xf1\x52\x28\x82\xab\x87\xc2\xfb\ -\x56\xac\xb8\x7a\x07\x61\xf4\xc5\x18\xb0\x6b\xc7\x80\x78\x2f\xc6\ -\xe0\xe9\x49\xc8\x8f\xb8\x64\x6e\xfa\x4b\x26\xb3\x9d\xe6\x7c\xb8\ -\x3d\xab\x81\x2c\xec\xc2\xfb\x85\x05\xb4\xb7\xeb\xb8\x76\x40\xba\ -\x3f\xcb\xbd\x08\x10\x72\xd5\x80\xf4\x93\x2a\x42\xdb\xa4\xca\xbc\ -\x9e\xbc\x5c\x82\xe0\x7b\x06\x8a\xff\x2d\x27\xfc\xca\x47\x5e\xea\ -\x24\xce\xff\x0d\x20\xfd\x53\xdd\x17\x00\xf2\x8c\xcc\x62\x7c\x69\ -\x8f\x9d\xbd\xb4\x67\x5e\xf5\x9f\x21\xdf\x70\x88\xe5\x6d\x2a\x74\ -\xf1\x5e\x9e\xbe\xa0\xe1\xc0\xe8\x98\x13\xd0\xfe\x4d\xa8\xe3\xf8\ -\x9e\x76\xf5\xe8\x3b\xbe\x9e\x6f\x13\xf3\x07\xf8\x33\x37\x32\xce\ -\xdd\xbe\x78\xc2\xc5\x0c\x86\x49\xff\xd8\x62\x70\xb6\xb0\x5c\x56\ -\x7f\x7e\x7f\xea\xb5\x8c\xea\xb6\xf4\x98\x13\x5e\x45\x15\x3a\xa6\ -\x44\xf9\xdf\x5d\x24\xc5\x97\x49\xf1\xf4\x1d\xab\x96\x16\xcb\x65\ -\x29\x54\x77\x13\xe4\xd9\xf7\x3b\x9e\x7d\x93\xa3\xe2\x19\x1f\x9d\ -\x87\x7d\x40\x96\xe7\xd6\x7f\x12\x9d\x3a\x0e\x84\xb1\xf7\xc8\x72\ -\x2e\xdd\x86\x19\xb8\xd9\x39\x48\x1d\xdb\xd5\x97\xee\x82\xef\x74\ -\x02\x30\x3a\xe7\x31\x3f\x73\x7d\x9d\xf7\xe1\xe6\x2f\x67\xa7\x75\ -\x87\ -\x00\x00\x05\xc2\ -\x00\ -\x00\x16\xb0\x78\x9c\xed\x58\x59\x8f\xdb\x36\x10\x7e\xdf\x5f\xa1\ -\x6a\x51\xf4\x82\x6e\xcb\xb6\xb4\xb6\x03\xb4\x41\x80\x00\x7d\x6a\ -\x52\xf4\x31\xa0\x45\xca\x66\x57\x22\x55\x92\xf2\x91\x5f\xdf\x21\ -\x75\xdb\xde\x74\xdb\x34\x2d\x10\x44\xc6\x42\xcb\x39\xc8\x99\x6f\ -\x0e\x92\x5a\xbd\x38\x95\x85\x75\x20\x42\x52\xce\xd6\x76\xe0\xfa\ -\xb6\x45\x58\xc6\x31\x65\xbb\xb5\xfd\xeb\xdb\x57\xce\xd2\xb6\xa4\ -\x42\x0c\xa3\x82\x33\xb2\xb6\x19\xb7\x5f\x6c\xee\x56\x5f\x39\x8e\ -\xf5\x93\x20\x48\x11\x6c\x1d\xa9\xda\x5b\xaf\xd9\xa3\xcc\x50\x45\ -\xac\x6f\xf7\x4a\x55\xa9\xe7\x1d\x8f\x47\x97\xb6\x44\x97\x8b\x9d\ -\xf7\x9d\xe5\x38\x9b\xbb\xbb\x95\x3c\xec\xee\x2c\xcb\x82\x75\x99\ -\x4c\x71\xb6\xb6\x5b\x85\xaa\x16\x85\x11\xc4\x99\x47\x0a\x52\x12\ -\xa6\xa4\x17\xb8\x81\x67\x0f\xe2\xd9\x20\x9e\xe9\xd5\xe9\x81\x64\ -\xbc\x2c\x39\x93\x46\x93\xc9\xfb\x91\xb0\xc0\x79\x2f\xad\xad\x39\ -\x46\x46\x28\x48\x92\xc4\xf3\x43\x2f\x0c\x1d\x90\x70\xe4\x99\x29\ -\x74\x72\xa6\xaa\x60\xe3\x2d\xd5\xd0\xf7\x7d\x0f\x78\x83\xe4\xf3\ -\xa4\x52\x09\x80\x56\xf0\xd7\x8b\x77\x04\x57\xf2\x5a\x64\x24\x07\ -\x3d\xe2\x32\xa2\xbc\x97\x6f\x5f\xf6\x4c\xc7\x77\xb1\xc2\xa3\x69\ -\x3a\x3c\x27\xab\x4e\x40\x66\xa8\x24\xb2\x42\x19\x91\x5e\x47\x37\ -\xfa\x47\x8a\xd5\x7e\x6d\x47\x33\x37\x88\xe0\x89\x0d\x71\x4f\xe8\ -\x6e\xaf\x2e\xa9\x14\xaf\x6d\xb0\x3e\x4c\x96\xcd\x78\x94\x1c\x41\ -\x23\xd0\x4e\x9c\xf6\x1c\xdf\x4d\x42\x37\xb0\x44\x10\x47\x8b\x46\ -\xa6\x73\x21\xc5\x3c\xd3\x36\xc1\x94\xa4\xa4\xa8\x56\xbc\x84\xa8\ -\x65\x59\x81\xa4\xa4\x39\xcd\x60\xc0\x59\x55\xd4\x3b\xca\xde\x6d\ -\x21\xcb\x32\x54\x64\xef\x14\xe7\x85\xdb\x01\xd8\xaf\x46\x4e\x15\ -\x17\xca\x39\xe1\x0a\x60\x9c\x2f\x6e\x32\xcf\x1d\x73\x03\xdc\x15\ -\x26\xb9\xd4\x52\x8d\x4f\x7a\x04\x4e\x2d\x6c\xcb\x33\xdc\xde\x44\ -\x6d\x1f\x3e\x50\x72\x1c\x64\xb7\x48\x36\xb8\x59\x56\x85\x76\x90\ -\x63\x05\x17\x6b\xfb\x3e\x37\x4f\xcb\xd8\x72\x81\x89\xe8\x58\x73\ -\xf3\x4c\x58\x1c\xe2\x40\xd5\xb9\xa9\xaa\x76\xee\xce\x5e\x3d\x6b\ -\xcf\xf7\x6f\xf3\xe5\x1e\x61\x7e\x5c\xdb\xe1\x25\xf3\x3d\xe7\xa5\ -\x9e\x35\x4a\x92\x45\x18\x47\x97\xec\xec\xb4\xb6\x9d\x70\xb1\x70\ -\x83\x65\x32\xbf\x52\xce\x60\xc1\x38\x72\x63\x3f\x48\x82\xd9\x15\ -\xb3\x16\x02\xea\xce\x29\xd0\x99\x80\x57\xe6\x15\xb4\x42\x72\xcf\ -\x8f\x3b\xa1\xd1\x51\xa2\x26\x97\x9a\x9a\xe3\x6c\xb7\xfc\x74\x9b\ -\x0d\x69\x50\xeb\x8a\x76\x6a\x46\x15\x54\x4d\x75\x1a\xcf\x5a\x53\ -\x4c\xe4\x6d\x45\xc9\x50\xe5\xec\x0a\xbe\x45\xc5\x6d\x81\x23\x65\ -\x80\x92\xd3\x26\x78\x10\xf5\x41\xb8\x94\xe8\xb2\x7d\xe1\x2f\x9f\ -\x90\x00\xdb\xaf\x02\xd1\xb2\xce\x4f\xb3\x4a\x74\xa2\x25\x7d\x4f\ -\x00\x98\xe0\x0a\x15\xed\xd9\x18\x96\x8d\x11\x58\x4d\x60\x6b\x74\ -\x2c\x4b\x9d\x75\x65\x9f\xce\x9a\x66\x77\x44\x8d\xb7\x26\x84\x10\ -\xeb\x9e\xc8\x05\x85\x82\x19\x99\xdb\x91\xce\x63\x92\xee\x03\xd0\ -\xc6\x4f\x26\x01\x4d\x7a\x2e\x2e\x79\xe7\x31\xaf\xad\x0b\xef\xba\ -\x30\x0c\xbd\x24\x0a\x61\xa4\xd0\x50\x25\x1d\x05\x6c\xf3\x3b\xcf\ -\xa0\xa5\xa6\xbf\xbc\x7c\xb5\x69\x17\x5a\x65\x59\xfa\x1b\x17\x8f\ -\xdd\xba\x96\xa5\x05\xd0\x96\xd7\x10\x09\x7b\xd3\x93\x57\x38\x4b\ -\xa1\x09\x42\x73\xd8\xd0\x12\x72\x5f\xf7\xcf\x1f\xa0\xe9\xad\xbc\ -\x81\x31\x11\xd6\x60\x0d\x93\x36\xd3\x0a\xd2\x74\xd3\x9b\x5b\x0a\ -\xce\x4a\xaa\x95\xbc\x37\x8a\x16\xc5\x6b\xbd\x48\xeb\xf1\x68\x52\ -\xaa\x0a\x32\x10\x57\x5e\x6b\x7d\xeb\x9b\x37\x72\x6e\xe5\x75\xde\ -\x9b\xd1\x6e\x40\x65\x52\x34\x7d\xa0\x0b\xb4\x25\x90\xc1\x3f\x6b\ -\xa6\x75\x9d\x27\x82\xd7\x55\xc9\x31\x69\xd5\x7b\x34\x49\xa6\xfa\ -\x90\xa9\x73\x01\x7c\xd3\x70\xd2\x7b\xdf\x3c\x0f\x98\xca\x0a\x34\ -\x60\x67\x28\x28\x23\x0f\x1c\x5a\x72\x5e\xf0\x63\x7a\xa0\x92\x6e\ -\x0b\xf2\x60\xde\xb4\x00\xcf\x7b\x52\x0e\xee\x1b\xfd\x3c\x0c\xcd\ -\xc0\x69\x1b\x51\x1a\x34\x43\x51\x17\x24\x65\x9c\xbd\x87\x16\xf6\ -\x20\x95\xe0\x8f\x24\xbd\x8f\x43\xfd\x6b\x87\x4d\xb5\xa5\x81\x1b\ -\x26\x10\xfb\x38\x8a\x3a\xba\x36\x02\x1c\x4a\xb7\xb5\x52\x63\xda\ -\xef\x9c\xb2\x14\xf0\x27\xa2\xa3\x9a\x41\x01\x85\xa3\xd2\x59\x47\ -\xc3\x08\x5a\x9e\x10\xe0\x0e\xac\x4e\xc6\x54\x9e\xe7\x92\xa8\xd4\ -\xef\x68\x83\xc5\x25\x12\x8f\x44\x34\x0a\x84\x21\x70\xd0\xd9\xa2\ -\xec\x51\x03\xca\x70\x8a\x32\x68\x3b\x75\x01\xc7\x94\x49\x41\x69\ -\x58\x23\x3f\x98\xf7\xc4\x6e\x7b\x0c\x7b\xca\xed\xbd\x51\x3f\x37\ -\xeb\xe9\x7c\x8b\x28\x80\x3a\x73\xe7\x21\x68\x07\xc1\x60\xc0\x87\ -\x36\xb4\x5b\x02\xfd\xa6\xd6\x65\xe6\xad\xb4\x68\xa2\x8a\x23\xfd\ -\x7b\x3a\xaa\xe4\x40\x18\xc7\xb8\x8f\x6a\x2b\x3f\x89\x6a\xe8\xce\ -\x02\x3f\x9a\x47\xb3\xd9\x65\x54\xe5\x1f\x35\x12\xe4\x3f\x89\xeb\ -\x75\xb8\x16\xcb\xab\x70\x85\x91\x3b\x9b\x22\xde\x45\x2d\xf0\xdd\ -\x8b\x58\x40\xd4\x62\x37\x8a\xa6\xa1\x84\xf8\x44\x6e\x78\x11\xaf\ -\x28\x9a\x45\x09\xe4\xc6\x87\xd0\x9e\x62\x9b\xde\x27\xf1\x92\x90\ -\xc5\xf3\x71\x6f\xe5\x27\xb8\xc3\x21\x2a\x9e\xf9\x71\xbc\xb8\xaa\ -\xa6\xff\x15\xf7\x65\x74\x85\xfb\x35\x90\x1d\xee\x61\x53\x2c\xd1\ -\x6c\x8c\xfb\xdc\x9d\x99\x66\x15\x8c\x71\x0f\x03\xf7\x42\x52\x98\ -\xcd\xeb\xef\xa0\xde\xf6\xc0\xcf\x14\x75\xe7\x63\x71\x0f\x66\x6e\ -\x62\xa8\xcf\xc1\xfd\xaa\xf9\x28\x81\x98\xd4\x3b\xaf\x93\xc1\xb9\ -\x8d\x08\xc7\xf4\xbd\xf9\x33\x04\x61\x3e\xe7\xf2\x54\xf1\xa5\x8c\ -\x20\xa0\xf1\x47\x06\xf4\xba\xdf\x7d\x29\xa4\xe7\xe0\xbe\xf8\x24\ -\x0d\x6c\xee\x4e\xee\x7c\xff\x04\xf7\x65\x8c\xfc\x3c\xff\x6c\x71\ -\x4f\x3e\x49\x03\xfb\x17\x70\xff\xcc\xf3\xdd\xff\x24\x7d\xe6\xaf\ -\x70\x57\xe4\xd4\xe3\x0e\x37\xb7\xd4\x7c\x86\x82\x9b\x3e\xdc\xca\ -\x88\x38\x0c\x07\xf0\xee\xc0\xca\x99\x72\xcc\xff\xe0\x2e\xdc\xef\ -\x8a\x07\x43\x39\x1a\xc3\x26\x24\x09\x97\xeb\x34\x08\xdd\x65\x53\ -\x84\x49\x75\x7a\xd0\xa0\xb6\x17\xfa\xd4\xff\xba\x11\xcb\x51\x49\ -\x8b\x73\x2a\x61\x37\x72\x60\x45\x9a\x3f\x14\x44\xe9\xfd\xa8\xbd\ -\xeb\xa6\x3e\x28\x1e\xb9\xc0\x13\xc2\x87\x12\xa2\x0d\xff\x38\x1a\ -\xdd\xc5\xa7\xdd\xdd\xc2\x31\x6c\x8b\x06\xb5\x8b\x5b\x41\xe0\x2e\ -\xa6\x00\x9b\x2f\x28\x80\x15\x1c\x32\xe1\xd6\xbc\x52\x60\x0d\x1b\ -\x6e\xb2\xfd\xe5\x5b\x70\x8d\x92\x76\xd4\x1e\xb8\x46\x57\x2b\x80\ -\x72\x38\xa2\xdf\x5c\xfd\x89\xf5\xa7\x11\x68\xf1\xde\xf2\x02\x8f\ -\xd1\x6e\xcf\xcf\xf3\x64\x79\x81\x36\xdc\xf9\xe2\xa7\xf0\x76\xba\ -\x33\x81\xd3\xcc\x54\x91\xac\xff\xc6\x97\x7e\xf3\x06\x04\xad\x1f\ -\x61\x9d\x6f\x9e\x04\x73\x13\x7c\x1f\xae\x3c\xe3\xe0\x06\xde\x00\ -\x52\x73\xd5\xde\x6d\xee\x56\xfa\x8b\xc0\xe6\xee\x4f\xda\x83\xd1\ -\x26\ -\x00\x00\x0c\x45\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6d\x6f\x76\x65\x5f\ -\x75\x70\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ -\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ -\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\ -\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ -\x22\x2d\x32\x39\x2e\x32\x37\x34\x38\x32\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\ -\x31\x2e\x31\x35\x36\x39\x35\x33\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\ -\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ -\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ -\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ -\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ -\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ -\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ -\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ -\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ -\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ -\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x64\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\ -\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\ -\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\ -\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\ -\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\ -\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ -\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\ -\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ -\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\ -\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\ -\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\ -\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\ -\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\ -\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\ -\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\ -\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\ -\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\ -\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\ -\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\ -\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\ -\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\ -\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\ -\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\ -\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\ -\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\ -\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\ -\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\ -\x3a\x23\x30\x30\x30\x30\x32\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x33\x2e\x36\x32\x36\x36\x36\x36\x37\x38\x3b\x6d\x61\ -\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\ -\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\ -\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x6d\x20\x31\x35\x2e\x38\x31\x34\x32\x31\x37\x2c\x35\x32\ -\x2e\x39\x35\x36\x39\x39\x36\x20\x32\x2e\x36\x33\x33\x34\x37\x34\ -\x2c\x2d\x30\x2e\x30\x35\x32\x34\x39\x20\x30\x2e\x38\x30\x34\x31\ -\x31\x37\x2c\x30\x2e\x30\x34\x31\x36\x31\x20\x4c\x20\x31\x39\x2e\ -\x32\x2c\x32\x30\x2e\x32\x36\x36\x36\x36\x37\x20\x6c\x20\x34\x2e\ -\x31\x32\x35\x31\x30\x39\x2c\x2d\x30\x2e\x30\x31\x33\x31\x20\x2d\ -\x35\x2e\x39\x33\x32\x38\x34\x36\x2c\x2d\x31\x35\x2e\x33\x30\x31\ -\x37\x35\x30\x34\x20\x2d\x35\x2e\x37\x35\x34\x39\x36\x32\x2c\x31\ -\x35\x2e\x33\x33\x38\x37\x36\x35\x34\x20\x34\x2e\x31\x32\x35\x31\ -\x30\x39\x2c\x2d\x30\x2e\x30\x31\x33\x31\x20\x7a\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x31\ -\x33\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ -\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\ -\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\ -\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0a\ -\x00\x00\x08\xcc\ -\x00\ -\x00\x49\x37\x78\x9c\xe5\x5c\x6d\x8f\xdb\xb8\x11\xfe\xbe\xbf\x42\ -\x75\xbe\xe4\x50\x53\xe6\x8b\xc4\x17\x67\x77\x0f\x48\x83\x3b\x1c\ -\xd0\x7e\xb9\x5e\xd1\x8f\x01\x2d\xd1\x5e\x35\xb2\x64\x48\xf2\xda\ -\xbe\x5f\xdf\xa1\x6c\xc9\x96\xed\xbc\x30\x2b\x17\x6a\xd6\x49\x90\ -\xd5\xcc\x90\x22\x9f\xe1\x3c\x33\xa4\xe4\xbd\xff\x79\xbb\x4c\xbd\ -\x67\x53\x94\x49\x9e\x3d\x8c\x88\x8f\x47\x9e\xc9\xa2\x3c\x4e\xb2\ -\xc5\xc3\xe8\x5f\x7f\xfc\x82\xe4\xc8\x2b\x2b\x9d\xc5\x3a\xcd\x33\ -\xf3\x30\xca\xf2\xd1\xcf\x8f\x77\xf7\x7f\x41\xc8\xfb\x5b\x61\x74\ -\x65\x62\x6f\x93\x54\x4f\xde\x6f\xd9\xa7\x32\xd2\x2b\xe3\xbd\x7d\ -\xaa\xaa\xd5\x74\x32\xd9\x6c\x36\x7e\x72\x10\xfa\x79\xb1\x98\xfc\ -\xe4\x21\xf4\x78\x77\x77\x5f\x3e\x2f\xee\x3c\xcf\x83\xfb\x66\xe5\ -\x34\x8e\x1e\x46\x87\x06\xab\x75\x91\xd6\x86\x71\x34\x31\xa9\x59\ -\x9a\xac\x2a\x27\xc4\x27\x93\xd1\xd1\x3c\x3a\x9a\x47\xf6\xee\xc9\ -\xb3\x89\xf2\xe5\x32\xcf\xca\xba\x65\x56\xbe\x39\x31\x2e\xe2\x79\ -\x6b\x6d\x47\xb3\x61\xb5\x11\x51\x4a\x4d\x30\x9d\x50\x8a\xc0\x02\ -\x95\xbb\xac\xd2\x5b\xd4\x6d\x0a\x63\xbc\xd6\x94\x62\x8c\x27\xa0\ -\x3b\x5a\x7e\x9b\xd5\xb4\x04\x40\x57\xf0\xaf\x35\x6f\x04\x7e\x99\ -\xaf\x8b\xc8\xcc\xa1\x9d\xf1\x33\x53\x4d\x3e\xfc\xf1\xa1\x55\x22\ -\xec\xc7\x55\x7c\xd2\x4d\x83\x67\xe7\xae\x1d\x90\x33\xbd\x34\xe5\ -\x4a\x47\xa6\x9c\x34\xf2\xba\xfd\x26\x89\xab\xa7\x87\x11\x0b\x7c\ -\xc2\xe0\x13\xd6\xc2\x27\x93\x2c\x9e\xaa\x73\x69\x12\x3f\x8c\x60\ -\xf4\x54\xc9\xfd\xf5\xc9\xe2\x20\x7b\x83\x43\xc7\xd3\x56\x83\x7d\ -\x45\x7d\xe2\x15\x24\x64\x62\x6f\xd3\x4c\x61\x1a\xe7\x91\x1d\x13\ -\x74\x69\x96\x89\x5e\x57\xf9\x12\xbc\x16\x45\xa9\x2e\xcb\x64\x9e\ -\x44\x70\x91\x67\xab\x74\xbd\x48\xb2\x8f\xb5\xf0\x63\x99\x2c\x32\ -\x5d\xad\x0b\xf3\xb1\xca\xf3\xd4\x6f\x70\x6c\x6f\x6a\xb6\xab\xbc\ -\xa8\xd0\x36\x5e\x01\x9a\x5c\x5c\x55\xee\x4e\x95\xcf\x89\xd9\xbc\ -\xcf\xb7\x30\x4a\x0f\x7b\x8c\xc2\xdf\xd1\x23\xc8\xef\x63\x33\x2f\ -\xad\x7e\x3f\x63\x7b\x05\x53\x16\xb5\x0e\xb4\xf3\x24\xad\x4c\xb1\ -\xd7\x9f\xdc\x20\xca\xd3\xd4\x44\x80\x99\x4e\x37\x7a\x57\x8e\x1a\ -\x83\xb2\xda\xa5\x30\x49\x50\xe7\x05\x4a\x32\x68\xba\xca\xd3\x7a\ -\x72\x68\xdf\x13\xac\x81\xdf\x7f\x7d\xdf\xda\xdb\x5b\xee\x15\x2a\ -\xc4\xad\x14\x06\x09\x3e\xc7\x8c\xf2\x40\x4a\x22\x5b\xf9\xc1\x7b\ -\x10\x9d\x3c\xa4\x4a\xf0\x56\xb1\xdb\x37\x08\x30\x21\x42\x52\xda\ -\xca\x1b\xcf\x42\x0b\x89\x29\x0b\xf9\x61\x5a\x76\x62\xe6\x57\xbd\ -\x06\xf0\x75\xf6\x3e\x5d\xb7\x13\xfc\x86\x29\xda\x49\xc6\x1f\xcc\ -\x73\x52\x4f\xab\xee\x1b\x53\x15\x84\xe1\x89\x45\x3d\xad\xce\x0d\ -\x54\x48\x47\xde\xe4\x00\xea\x64\x3f\xe5\x1a\xfe\x89\x45\xbc\xfe\ -\xa9\x5d\x2b\x76\xa1\xc4\xd6\x5d\x47\xb7\xcc\x74\x69\x0e\xfd\xaf\ -\xf4\xc2\xd4\xf8\x3e\x8c\xde\xcc\xeb\xcf\x41\x31\xcb\x8b\xd8\x14\ -\x8d\x8a\xd7\x9f\x8e\x2a\x87\x80\x48\xaa\xdd\x9e\xde\xee\xba\xb3\ -\xb5\xbd\xb6\x7a\x7c\x5d\x5f\x3e\xe9\x38\xdf\x3c\x8c\xe8\xb9\xf2\ -\xcf\x3c\x5f\x42\xf8\xf8\x2a\x54\x98\x62\x75\xae\x8e\xac\x3f\xa5\ -\xf2\x03\xc1\xb0\x14\x17\x5a\xb8\x21\x15\x7e\xc8\xc3\xe0\x42\xb5\ -\x2e\x0a\xa0\x3f\x94\xea\x9d\x81\x39\xd5\xff\x91\x83\x51\xf9\x94\ -\x6f\x16\x85\xc5\xa6\x2a\xd6\xe6\xbc\xa5\xd5\xa0\xd9\xcc\x2e\xf7\ -\x6b\x6a\x88\xc6\xb5\x25\x56\xb4\xce\x92\x0a\xc8\x6b\xb5\x3d\xed\ -\x75\x9d\xc4\xa6\xbc\xde\x70\x93\x64\x00\x01\x6a\x16\x22\x6b\x11\ -\x3e\xb7\x68\x56\x9e\xc0\xf2\x33\x16\x36\x12\x3f\xa3\xda\x7d\x5e\ -\xb5\xd4\xdb\x64\x99\xfc\x69\x60\xde\xe4\xdc\xa4\xcc\xf4\x0a\x2d\ -\xd2\x7c\xa6\xd3\xcf\xa0\x62\x67\x76\x0a\xcb\x61\x3d\x76\x60\x6b\ -\x56\x71\xb5\xb3\x04\xbb\xdd\x59\x59\x27\x5e\xad\x80\x09\x7e\x5c\ -\xef\x79\x91\x00\x6f\x9d\xcc\xa7\x11\xed\x4e\x45\x96\x8e\x21\x9b\ -\x6e\x8f\x03\x6f\x65\x76\x49\x1e\xa3\xa3\x8d\x83\x7a\xb8\x8d\xe9\ -\x2a\x2f\x93\x7d\xc0\x21\x8e\xc7\x9d\x3b\x81\x23\x9b\x58\x3c\x51\ -\xd4\x43\xb5\x3d\xa8\xe0\x44\xd8\xcc\x34\xcd\xa3\x4f\x16\xc4\xb9\ -\x4e\x21\xb2\xf6\xf7\xbe\x9f\x5c\x86\x60\x2d\x5f\x9a\x4a\xc7\xba\ -\xd2\xc7\x78\x6c\x24\x54\x29\xdc\xa0\x08\x59\x74\xfa\xfb\x87\x5f\ -\x5a\x86\x89\xa2\xe9\xbf\xf3\xe2\xd3\x91\x15\xac\x81\x9e\xe5\x6b\ -\x58\x16\x2d\x0f\x59\x02\x8e\xa6\x90\xf7\x20\x1f\x3c\x26\x4b\x88\ -\x32\x9b\x32\xff\x0a\x79\x0e\x98\xa1\x55\x74\x8c\xad\x63\x8e\x9d\ -\xee\xbb\x2d\xcc\x3e\x81\x5e\xad\x22\xe2\x68\x99\xd8\x46\x93\x7f\ -\x56\x49\x9a\xfe\x66\x6f\xd2\xa2\xdd\x76\x9a\x54\xa9\x39\x0a\xef\ -\x27\x87\xd1\x37\x8c\x75\x32\xb9\xfb\x49\x33\xfb\xfa\x6a\x71\x44\ -\xa5\x13\xa0\x47\xa8\xf5\xcc\xc0\x82\xfc\xbb\x55\x7a\x17\xda\x45\ -\x91\xaf\x57\xcb\x3c\x36\x87\xe6\x2d\x9a\xc0\xbd\x67\x59\x05\x58\ -\x33\x9d\xbe\xc1\x38\x8a\xe6\xf3\x77\xf6\x02\x1d\x18\x6b\x4a\xf6\ -\x97\xc5\x3a\x85\xdc\xf7\x6c\xb2\x3c\x8e\xdf\x95\x55\x91\x7f\x32\ -\xd3\x03\x47\x1e\x2e\xf7\x91\x3b\xc5\xcd\x25\x00\x63\x8a\x14\x22\ -\xaa\x9a\x06\x8d\x2c\xd6\x40\x74\x45\xa1\x77\xd3\x0c\x4a\xbd\x46\ -\xda\xde\xaa\xb3\xc0\xec\x28\x43\xc9\x54\x2b\x3c\x30\x43\xd0\x0a\ -\x1a\x22\x38\x4a\xf6\xd9\x8d\xd0\x10\xea\xa3\x63\x6f\x36\x06\x8e\ -\xdd\x14\x36\x4c\x7c\x56\x7f\x8e\x2d\x8b\xdd\xa9\xb4\x0d\x98\x2f\ -\x40\xa5\x75\x1c\x0c\x0c\x2a\x44\x1c\xc1\x62\xbe\x14\xe1\x8d\x71\ -\x0a\x20\x7f\x0f\x0e\x27\x84\x1d\x91\x22\xe4\xe6\x50\xcd\xe7\x54\ -\x53\x3d\x38\xa8\x98\x2b\x52\x9d\xda\x31\xe8\x80\x84\x7f\x34\x70\ -\x90\x44\xa1\x23\x3e\x34\x78\x4d\xf8\x60\xe4\xba\x7e\xa8\xbc\x05\ -\x3e\x03\xe5\x6b\x14\x38\xa2\x73\xc9\xd8\x61\xcf\x34\x84\x31\xe7\ -\x12\x0f\x0f\x29\xe9\x9c\xdd\xc4\xff\x00\xab\x81\x66\x37\x24\x1c\ -\xb1\xba\x92\xdf\xfa\x06\x6b\x3e\x57\x6a\x80\x60\x31\xc4\x5d\xb1\ -\xea\x64\x38\xdc\x13\x43\x0d\x14\x1e\x24\x10\x75\xc4\x87\xe2\xd7\ -\x84\x0f\x54\x00\xc8\x75\x93\xd2\xad\x01\xfa\x42\x68\x90\xdb\x37\ -\x74\x71\xc6\xf8\xd5\x0c\xc7\x69\xa0\x94\xea\x94\x01\x54\xf4\x4c\ -\x46\x43\xad\x07\xa4\x2b\x5c\x02\xe0\x0a\x6f\x0c\xd5\x50\x93\x9c\ -\x33\x71\x5f\x24\xb9\xde\xc1\x92\xd8\x7e\x06\x07\x16\x73\x26\xf1\ -\x6e\x92\x23\xb4\x27\x8e\x1a\x28\x3e\x90\xe5\x9c\xf7\x29\xf8\x55\ -\x01\x64\xd3\x9c\x2b\x37\x75\xd3\xdc\x0f\x0f\x11\xec\x75\x9d\xeb\ -\xee\xee\x6e\xb7\x37\x88\x86\x59\x0a\x60\xe7\xed\xee\xf5\xd3\x5c\ -\xca\x3a\x30\xfd\xb8\xd5\x40\xe0\x4c\xdb\x17\xe7\x03\x37\xc0\x6a\ -\xb0\xe7\x03\xce\x67\x71\x17\x27\x04\x37\x40\x6b\xa8\xc5\x93\x70\ -\xde\xb5\x5c\x29\x9f\xfa\x86\x2b\x0e\x06\x49\xed\x0c\xf1\x17\x16\ -\x50\xb2\x03\xd4\xf7\x13\xfb\x40\x01\xb2\xa7\x04\xee\xb9\x0f\xbf\ -\x26\x84\x6c\x75\x40\x9d\xcf\x30\xbb\xf5\x41\x5f\x18\x59\x06\x1f\ -\x22\x46\xd2\x79\x0d\x09\xbf\xbb\xfb\x0d\x7a\x26\x24\x8c\x19\x1b\ -\x60\xb6\x83\xa5\xe4\x7c\xc2\xdb\xe1\x23\xda\xdf\xa1\x53\x10\xe8\ -\x01\x3e\x78\x12\xee\x0f\xe6\xf0\x4d\x00\x92\x02\x6a\x4b\x33\x3c\ -\x80\xea\xdd\xca\xcb\x1e\xce\xf5\x86\x91\xad\x91\x86\xc9\x47\x50\ -\x53\xba\x17\x95\x5d\x4a\xc2\x3d\x53\xd2\x50\xc1\xb2\x25\xa5\xeb\ -\xfe\x0e\x4a\xca\xdb\x82\x35\x58\xfe\xe6\xce\xfc\x74\x76\x22\xc7\ -\x7b\x8a\x3d\xaa\xc5\x7c\x78\x47\x05\x87\xe7\x2a\xee\xa7\x72\xc1\ -\x4d\x40\x1a\x32\x89\x53\xe7\x97\x99\xce\x0e\x9d\xfa\x02\x69\x16\ -\xc5\x2c\x1c\xe2\x4a\x72\x7f\x75\x80\x9d\xd1\xd2\xd9\xc1\xdc\xcb\ -\x79\x69\xb0\x58\x41\xcc\xbd\xb4\x06\x7f\x35\x60\x61\x60\xf1\xef\ -\x78\x06\x75\x63\xb4\x06\x9b\xf2\xe8\x0b\x53\x1e\xed\x6b\xfb\x3b\ -\xdc\x3d\x0b\x73\xae\xa0\xce\x76\x2d\x7d\x41\x34\xe4\xaa\xe0\xa5\ -\xef\x5c\xf6\x06\x92\x94\x5a\x0f\xaf\x12\xc7\x28\x70\xce\x77\x08\ -\xfb\xc2\xbe\x74\x71\xf6\xcd\x2f\xd9\x33\x35\x0d\x13\xb0\xfa\x39\ -\x8b\x73\xd6\x3b\x2f\x11\x5e\x0b\x56\xf5\x93\x03\xe7\xba\xfc\x22\ -\xed\xf5\x0d\xd7\x60\xb3\x1e\xff\x8e\x02\xfd\x2c\xef\xf5\xf7\x12\ -\xf4\x50\xf3\x1e\x84\xdf\x0b\x1f\x1f\xf4\x06\xd2\x90\x33\x9f\x25\ -\x77\xe7\xcd\x5e\x70\x13\x98\x86\xbd\x23\x26\x2f\x7c\xd0\xd2\x03\ -\x4c\xcd\x48\xb1\xaf\x44\xfd\xc2\x0a\x7d\xd7\xbc\xc8\x3a\xbf\x58\ -\x60\xd8\x0f\x09\xa7\x1c\x13\xfa\x45\xc0\x88\x4f\x48\x18\xe0\x80\ -\x93\x46\x9e\x26\x99\x89\xf4\x6a\x5a\xe4\xeb\x2c\x3e\x15\xfe\x27\ -\x4f\xb2\x69\x8d\xeb\x15\x90\xa9\x1f\x7e\x23\xcc\x76\x98\xd0\x6c\ -\xba\x2e\xd2\xb7\x6f\xe6\xcd\xd7\xc9\x7f\xba\x40\x5f\xca\x8b\xc2\ -\x55\x30\x5f\xc0\x94\xc4\x25\xf0\xa1\xf2\x6d\xad\xa1\xf8\xa9\x03\ -\x10\xe9\xe4\x07\x24\x0e\x36\xc7\xed\x51\x55\xe8\xac\xb4\x5f\xdb\ -\x7c\x18\x2d\x75\x55\x24\xdb\xb7\xd8\xe7\x42\x12\xc9\x09\x1d\x63\ -\xfb\xc7\xdf\x7f\x35\x9b\x87\x63\x14\xf8\x92\x0a\x8a\x25\x1d\x23\ -\xba\x17\x87\xfc\xa7\xa3\xc3\x56\xba\x7a\xba\xb6\xae\x4f\x40\xb0\ -\x7c\x29\x0d\xc6\x67\x2e\x58\x6d\xcf\xb1\x9f\xad\xab\xea\xcb\xd0\ -\x5f\xae\x5a\x80\xed\x1f\x1e\x62\xbe\x92\x82\x0b\x1a\x8c\x49\xe8\ -\x0b\x26\x03\x26\x3d\x64\x17\x0c\x57\x81\x82\xa1\x93\xc0\x17\x82\ -\x50\x2f\xf4\x09\x56\x0a\xe3\x70\xcc\x7d\xc9\x04\x96\xc4\x23\xf6\ -\xcd\x18\x1c\x62\x36\x0e\x7d\xa9\x08\x0f\x02\xe1\x41\x27\x98\x52\ -\x62\x9b\xa9\x20\xe4\x84\x79\x14\x8f\x89\xf0\x52\x8f\xfb\x2a\x0c\ -\x95\x1c\x07\x3e\x16\x1c\x73\xe9\x01\xba\x9c\x4b\xca\xc6\xcc\xc7\ -\x52\x60\xaa\x3a\x1e\xb5\xe8\x04\x98\x1d\x19\xf9\xe4\xab\xfb\x19\ -\x4c\xba\xca\x0b\x14\xad\x8b\xe7\xfa\xb7\x28\xd8\xf0\x78\x39\xae\ -\x30\xe4\x3a\x4a\x2e\x56\xf6\xd7\xd1\x75\x67\x0f\x7c\x88\x60\xc6\ -\xfe\xcf\x1c\x72\x52\x77\x7d\xcd\x25\x17\x76\x6d\xf8\xa0\xc8\xd8\ -\x5f\x1f\x81\xea\xba\x2b\x0c\x58\x48\x82\x6f\xb0\xde\xff\x22\x08\ -\xc5\x94\x92\x21\x17\x8e\x1e\x9f\xcf\x31\x23\xb3\x61\x7a\x1c\x13\ -\x2c\x28\xe5\x63\x4a\xc1\x05\x82\x32\xe1\x61\xf8\xb9\xf6\x11\x96\ -\x5c\x86\x38\x18\x5b\x32\x62\x01\xa1\x04\x1c\x0f\xe6\x1c\x33\x3e\ -\xb6\x60\x04\x80\x1e\xf7\xec\x44\x48\xa8\xf8\x58\xf9\x38\x64\x4a\ -\x10\x2b\x11\x42\x2a\x35\xa6\x20\x81\x35\x14\x34\xfe\x26\xee\x0e\ -\x3f\x39\x61\xea\xd5\xe5\x57\x56\xd2\x17\x7d\xae\x88\xbb\xcf\x31\ -\xd6\x37\x65\xcf\x81\xbb\x8e\x38\xf2\xe7\xfd\x64\xf1\x78\x77\x6f\ -\x7f\x4b\xc1\xe3\xdd\x7f\x01\x5f\xd9\x98\x1e\ -\x00\x00\x08\xcc\ -\x00\ -\x00\x49\x37\x78\x9c\xe5\x5c\x6d\x8f\xdb\xb8\x11\xfe\xbe\xbf\x42\ -\x75\xbe\xe4\x50\x53\xe6\x8b\xc4\x17\x67\x77\x0f\x48\x83\x3b\x1c\ -\xd0\x7e\xb9\x5e\xd1\x8f\x01\x2d\xd1\x5e\x35\xb2\x64\x48\xf2\xda\ -\xbe\x5f\xdf\xa1\x6c\xc9\x96\xed\xbc\x30\x2b\x17\x6a\xd6\x49\x90\ -\xd5\xcc\x90\x22\x9f\xe1\x3c\x33\xa4\xe4\xbd\xff\x79\xbb\x4c\xbd\ -\x67\x53\x94\x49\x9e\x3d\x8c\x88\x8f\x47\x9e\xc9\xa2\x3c\x4e\xb2\ -\xc5\xc3\xe8\x5f\x7f\xfc\x82\xe4\xc8\x2b\x2b\x9d\xc5\x3a\xcd\x33\ -\xf3\x30\xca\xf2\xd1\xcf\x8f\x77\xf7\x7f\x41\xc8\xfb\x5b\x61\x74\ -\x65\x62\x6f\x93\x54\x4f\xde\x6f\xd9\xa7\x32\xd2\x2b\xe3\xbd\x7d\ -\xaa\xaa\xd5\x74\x32\xd9\x6c\x36\x7e\x72\x10\xfa\x79\xb1\x98\xfc\ -\xe4\x21\xf4\x78\x77\x77\x5f\x3e\x2f\xee\x3c\xcf\x83\xfb\x66\xe5\ -\x34\x8e\x1e\x46\x87\x06\xab\x75\x91\xd6\x86\x71\x34\x31\xa9\x59\ -\x9a\xac\x2a\x27\xc4\x27\x93\xd1\xd1\x3c\x3a\x9a\x47\xf6\xee\xc9\ -\xb3\x89\xf2\xe5\x32\xcf\xca\xba\x65\x56\xbe\x39\x31\x2e\xe2\x79\ -\x6b\x6d\x47\xb3\x61\xb5\x11\x51\x4a\x4d\x30\x9d\x50\x8a\xc0\x02\ -\x95\xbb\xac\xd2\x5b\xd4\x6d\x0a\x63\xbc\xd6\x94\x62\x8c\x27\xa0\ -\x3b\x5a\x7e\x9b\xd5\xb4\x04\x40\x57\xf0\xaf\x35\x6f\x04\x7e\x99\ -\xaf\x8b\xc8\xcc\xa1\x9d\xf1\x33\x53\x4d\x3e\xfc\xf1\xa1\x55\x22\ -\xec\xc7\x55\x7c\xd2\x4d\x83\x67\xe7\xae\x1d\x90\x33\xbd\x34\xe5\ -\x4a\x47\xa6\x9c\x34\xf2\xba\xfd\x26\x89\xab\xa7\x87\x11\x0b\x7c\ -\xc2\xe0\x13\xd6\xc2\x27\x93\x2c\x9e\xaa\x73\x69\x12\x3f\x8c\x60\ -\xf4\x54\xc9\xfd\xf5\xc9\xe2\x20\x7b\x83\x43\xc7\xd3\x56\x83\x7d\ -\x45\x7d\xe2\x15\x24\x64\x62\x6f\xd3\x4c\x61\x1a\xe7\x91\x1d\x13\ -\x74\x69\x96\x89\x5e\x57\xf9\x12\xbc\x16\x45\xa9\x2e\xcb\x64\x9e\ -\x44\x70\x91\x67\xab\x74\xbd\x48\xb2\x8f\xb5\xf0\x63\x99\x2c\x32\ -\x5d\xad\x0b\xf3\xb1\xca\xf3\xd4\x6f\x70\x6c\x6f\x6a\xb6\xab\xbc\ -\xa8\xd0\x36\x5e\x01\x9a\x5c\x5c\x55\xee\x4e\x95\xcf\x89\xd9\xbc\ -\xcf\xb7\x30\x4a\x0f\x7b\x8c\xc2\xdf\xd1\x23\xc8\xef\x63\x33\x2f\ -\xad\x7e\x3f\x63\x7b\x05\x53\x16\xb5\x0e\xb4\xf3\x24\xad\x4c\xb1\ -\xd7\x9f\xdc\x20\xca\xd3\xd4\x44\x80\x99\x4e\x37\x7a\x57\x8e\x1a\ -\x83\xb2\xda\xa5\x30\x49\x50\xe7\x05\x4a\x32\x68\xba\xca\xd3\x7a\ -\x72\x68\xdf\x13\xac\x81\xdf\x7f\x7d\xdf\xda\xdb\x5b\xee\x15\x2a\ -\xc4\xad\x14\x06\x09\x3e\xc7\x8c\xf2\x40\x4a\x22\x5b\xf9\xc1\x7b\ -\x10\x9d\x3c\xa4\x4a\xf0\x56\xb1\xdb\x37\x08\x30\x21\x42\x52\xda\ -\xca\x1b\xcf\x42\x0b\x89\x29\x0b\xf9\x61\x5a\x76\x62\xe6\x57\xbd\ -\x06\xf0\x75\xf6\x3e\x5d\xb7\x13\xfc\x86\x29\xda\x49\xc6\x1f\xcc\ -\x73\x52\x4f\xab\xee\x1b\x53\x15\x84\xe1\x89\x45\x3d\xad\xce\x0d\ -\x54\x48\x47\xde\xe4\x00\xea\x64\x3f\xe5\x1a\xfe\x89\x45\xbc\xfe\ -\xa9\x5d\x2b\x76\xa1\xc4\xd6\x5d\x47\xb7\xcc\x74\x69\x0e\xfd\xaf\ -\xf4\xc2\xd4\xf8\x3e\x8c\xde\xcc\xeb\xcf\x41\x31\xcb\x8b\xd8\x14\ -\x8d\x8a\xd7\x9f\x8e\x2a\x87\x80\x48\xaa\xdd\x9e\xde\xee\xba\xb3\ -\xb5\xbd\xb6\x7a\x7c\x5d\x5f\x3e\xe9\x38\xdf\x3c\x8c\xe8\xb9\xf2\ -\xcf\x3c\x5f\x42\xf8\xf8\x2a\x54\x98\x62\x75\xae\x8e\xac\x3f\xa5\ -\xf2\x03\xc1\xb0\x14\x17\x5a\xb8\x21\x15\x7e\xc8\xc3\xe0\x42\xb5\ -\x2e\x0a\xa0\x3f\x94\xea\x9d\x81\x39\xd5\xff\x91\x83\x51\xf9\x94\ -\x6f\x16\x85\xc5\xa6\x2a\xd6\xe6\xbc\xa5\xd5\xa0\xd9\xcc\x2e\xf7\ -\x6b\x6a\x88\xc6\xb5\x25\x56\xb4\xce\x92\x0a\xc8\x6b\xb5\x3d\xed\ -\x75\x9d\xc4\xa6\xbc\xde\x70\x93\x64\x00\x01\x6a\x16\x22\x6b\x11\ -\x3e\xb7\x68\x56\x9e\xc0\xf2\x33\x16\x36\x12\x3f\xa3\xda\x7d\x5e\ -\xb5\xd4\xdb\x64\x99\xfc\x69\x60\xde\xe4\xdc\xa4\xcc\xf4\x0a\x2d\ -\xd2\x7c\xa6\xd3\xcf\xa0\x62\x67\x76\x0a\xcb\x61\x3d\x76\x60\x6b\ -\x56\x71\xb5\xb3\x04\xbb\xdd\x59\x59\x27\x5e\xad\x80\x09\x7e\x5c\ -\xef\x79\x91\x00\x6f\x9d\xcc\xa7\x11\xed\x4e\x45\x96\x8e\x21\x9b\ -\x6e\x8f\x03\x6f\x65\x76\x49\x1e\xa3\xa3\x8d\x83\x7a\xb8\x8d\xe9\ -\x2a\x2f\x93\x7d\xc0\x21\x8e\xc7\x9d\x3b\x81\x23\x9b\x58\x3c\x51\ -\xd4\x43\xb5\x3d\xa8\xe0\x44\xd8\xcc\x34\xcd\xa3\x4f\x16\xc4\xb9\ -\x4e\x21\xb2\xf6\xf7\xbe\x9f\x5c\x86\x60\x2d\x5f\x9a\x4a\xc7\xba\ -\xd2\xc7\x78\x6c\x24\x54\x29\xdc\xa0\x08\x59\x74\xfa\xfb\x87\x5f\ -\x5a\x86\x89\xa2\xe9\xbf\xf3\xe2\xd3\x91\x15\xac\x81\x9e\xe5\x6b\ -\x58\x16\x2d\x0f\x59\x02\x8e\xa6\x90\xf7\x20\x1f\x3c\x26\x4b\x88\ -\x32\x9b\x32\xff\x0a\x79\x0e\x98\xa1\x55\x74\x8c\xad\x63\x8e\x9d\ -\xee\xbb\x2d\xcc\x3e\x81\x5e\xad\x22\xe2\x68\x99\xd8\x46\x93\x7f\ -\x56\x49\x9a\xfe\x66\x6f\xd2\xa2\xdd\x76\x9a\x54\xa9\x39\x0a\xef\ -\x27\x87\xd1\x37\x8c\x75\x32\xb9\xfb\x49\x33\xfb\xfa\x6a\x71\x44\ -\xa5\x13\xa0\x47\xa8\xf5\xcc\xc0\x82\xfc\xbb\x55\x7a\x17\xda\x45\ -\x91\xaf\x57\xcb\x3c\x36\x87\xe6\x2d\x9a\xc0\xbd\x67\x59\x05\x58\ -\x33\x9d\xbe\xc1\x38\x8a\xe6\xf3\x77\xf6\x02\x1d\x18\x6b\x4a\xf6\ -\x97\xc5\x3a\x85\xdc\xf7\x6c\xb2\x3c\x8e\xdf\x95\x55\x91\x7f\x32\ -\xd3\x03\x47\x1e\x2e\xf7\x91\x3b\xc5\xcd\x25\x00\x63\x8a\x14\x22\ -\xaa\x9a\x06\x8d\x2c\xd6\x40\x74\x45\xa1\x77\xd3\x0c\x4a\xbd\x46\ -\xda\xde\xaa\xb3\xc0\xec\x28\x43\xc9\x54\x2b\x3c\x30\x43\xd0\x0a\ -\x1a\x22\x38\x4a\xf6\xd9\x8d\xd0\x10\xea\xa3\x63\x6f\x36\x06\x8e\ -\xdd\x14\x36\x4c\x7c\x56\x7f\x8e\x2d\x8b\xdd\xa9\xb4\x0d\x98\x2f\ -\x40\xa5\x75\x1c\x0c\x0c\x2a\x44\x1c\xc1\x62\xbe\x14\xe1\x8d\x71\ -\x0a\x20\x7f\x0f\x0e\x27\x84\x1d\x91\x22\xe4\xe6\x50\xcd\xe7\x54\ -\x53\x3d\x38\xa8\x98\x2b\x52\x9d\xda\x31\xe8\x80\x84\x7f\x34\x70\ -\x90\x44\xa1\x23\x3e\x34\x78\x4d\xf8\x60\xe4\xba\x7e\xa8\xbc\x05\ -\x3e\x03\xe5\x6b\x14\x38\xa2\x73\xc9\xd8\x61\xcf\x34\x84\x31\xe7\ -\x12\x0f\x0f\x29\xe9\x9c\xdd\xc4\xff\x00\xab\x81\x66\x37\x24\x1c\ -\xb1\xba\x92\xdf\xfa\x06\x6b\x3e\x57\x6a\x80\x60\x31\xc4\x5d\xb1\ -\xea\x64\x38\xdc\x13\x43\x0d\x14\x1e\x24\x10\x75\xc4\x87\xe2\xd7\ -\x84\x0f\x54\x00\xc8\x75\x93\xd2\xad\x01\xfa\x42\x68\x90\xdb\x37\ -\x74\x71\xc6\xf8\xd5\x0c\xc7\x69\xa0\x94\xea\x94\x01\x54\xf4\x4c\ -\x46\x43\xad\x07\xa4\x2b\x5c\x02\xe0\x0a\x6f\x0c\xd5\x50\x93\x9c\ -\x33\x71\x5f\x24\xb9\xde\xc1\x92\xd8\x7e\x06\x07\x16\x73\x26\xf1\ -\x6e\x92\x23\xb4\x27\x8e\x1a\x28\x3e\x90\xe5\x9c\xf7\x29\xf8\x55\ -\x01\x64\xd3\x9c\x2b\x37\x75\xd3\xdc\x0f\x0f\x11\xec\x75\x9d\xeb\ -\xee\xee\x6e\xb7\x37\x88\x86\x59\x0a\x60\xe7\xed\xee\xf5\xd3\x5c\ -\xca\x3a\x30\xfd\xb8\xd5\x40\xe0\x4c\xdb\x17\xe7\x03\x37\xc0\x6a\ -\xb0\xe7\x03\xce\x67\x71\x17\x27\x04\x37\x40\x6b\xa8\xc5\x93\x70\ -\xde\xb5\x5c\x29\x9f\xfa\x86\x2b\x0e\x06\x49\xed\x0c\xf1\x17\x16\ -\x50\xb2\x03\xd4\xf7\x13\xfb\x40\x01\xb2\xa7\x04\xee\xb9\x0f\xbf\ -\x26\x84\x6c\x75\x40\x9d\xcf\x30\xbb\xf5\x41\x5f\x18\x59\x06\x1f\ -\x22\x46\xd2\x79\x0d\x09\xbf\xbb\xfb\x0d\x7a\x26\x24\x8c\x19\x1b\ -\x60\xb6\x83\xa5\xe4\x7c\xc2\xdb\xe1\x23\xda\xdf\xa1\x53\x10\xe8\ -\x01\x3e\x78\x12\xee\x0f\xe6\xf0\x4d\x00\x92\x02\x6a\x4b\x33\x3c\ -\x80\xea\xdd\xca\xcb\x1e\xce\xf5\x86\x91\xad\x91\x86\xc9\x47\x50\ -\x53\xba\x17\x95\x5d\x4a\xc2\x3d\x53\xd2\x50\xc1\xb2\x25\xa5\xeb\ -\xfe\x0e\x4a\xca\xdb\x82\x35\x58\xfe\xe6\xce\xfc\x74\x76\x22\xc7\ -\x7b\x8a\x3d\xaa\xc5\x7c\x78\x47\x05\x87\xe7\x2a\xee\xa7\x72\xc1\ -\x4d\x40\x1a\x32\x89\x53\xe7\x97\x99\xce\x0e\x9d\xfa\x02\x69\x16\ -\xc5\x2c\x1c\xe2\x4a\x72\x7f\x75\x80\x9d\xd1\xd2\xd9\xc1\xdc\xcb\ -\x79\x69\xb0\x58\x41\xcc\xbd\xb4\x06\x7f\x35\x60\x61\x60\xf1\xef\ -\x78\x06\x75\x63\xb4\x06\x9b\xf2\xe8\x0b\x53\x1e\xed\x6b\xfb\x3b\ -\xdc\x3d\x0b\x73\xae\xa0\xce\x76\x2d\x7d\x41\x34\xe4\xaa\xe0\xa5\ -\xef\x5c\xf6\x06\x92\x94\x5a\x0f\xaf\x12\xc7\x28\x70\xce\x77\x08\ -\xfb\xc2\xbe\x74\x71\xf6\xcd\x2f\xd9\x33\x35\x0d\x13\xb0\xfa\x39\ -\x8b\x73\xd6\x3b\x2f\x11\x5e\x0b\x56\xf5\x93\x03\xe7\xba\xfc\x22\ -\xed\xf5\x0d\xd7\x60\xb3\x1e\xff\x8e\x02\xfd\x2c\xef\xf5\xf7\x12\ -\xf4\x50\xf3\x1e\x84\xdf\x0b\x1f\x1f\xf4\x06\xd2\x90\x33\x9f\x25\ -\x77\xe7\xcd\x5e\x70\x13\x98\x86\xbd\x23\x26\x2f\x7c\xd0\xd2\x03\ -\x4c\xcd\x48\xb1\xaf\x44\xfd\xc2\x0a\x7d\xd7\xbc\xc8\x3a\xbf\x58\ -\x60\xd8\x0f\x09\xa7\x1c\x13\xfa\x45\xc0\x88\x4f\x48\x18\xe0\x80\ -\x93\x46\x9e\x26\x99\x89\xf4\x6a\x5a\xe4\xeb\x2c\x3e\x15\xfe\x27\ -\x4f\xb2\x69\x8d\xeb\x15\x90\xa9\x1f\x7e\x23\xcc\x76\x98\xd0\x6c\ -\xba\x2e\xd2\xb7\x6f\xe6\xcd\xd7\xc9\x7f\xba\x40\x5f\xca\x8b\xc2\ -\x55\x30\x5f\xc0\x94\xc4\x25\xf0\xa1\xf2\x6d\xad\xa1\xf8\xa9\x03\ -\x10\xe9\xe4\x07\x24\x0e\x36\xc7\xed\x51\x55\xe8\xac\xb4\x5f\xdb\ -\x7c\x18\x2d\x75\x55\x24\xdb\xb7\xd8\xe7\x42\x12\xc9\x09\x1d\x63\ -\xfb\xc7\xdf\x7f\x35\x9b\x87\x63\x14\xf8\x92\x0a\x8a\x25\x1d\x23\ -\xba\x17\x87\xfc\xa7\xa3\xc3\x56\xba\x7a\xba\xb6\xae\x4f\x40\xb0\ -\x7c\x29\x0d\xc6\x67\x2e\x58\x6d\xcf\xb1\x9f\xad\xab\xea\xcb\xd0\ -\x5f\xae\x5a\x80\xed\x1f\x1e\x62\xbe\x92\x82\x0b\x1a\x8c\x49\xe8\ -\x0b\x26\x03\x26\x3d\x64\x17\x0c\x57\x81\x82\xa1\x93\xc0\x17\x82\ -\x50\x2f\xf4\x09\x56\x0a\xe3\x70\xcc\x7d\xc9\x04\x96\xc4\x23\xf6\ -\xcd\x18\x1c\x62\x36\x0e\x7d\xa9\x08\x0f\x02\xe1\x41\x27\x98\x52\ -\x62\x9b\xa9\x20\xe4\x84\x79\x14\x8f\x89\xf0\x52\x8f\xfb\x2a\x0c\ -\x95\x1c\x07\x3e\x16\x1c\x73\xe9\x01\xba\x9c\x4b\xca\xc6\xcc\xc7\ -\x52\x60\xaa\x3a\x1e\xb5\xe8\x04\x98\x1d\x19\xf9\xe4\xab\xfb\x19\ -\x4c\xba\xca\x0b\x14\xad\x8b\xe7\xfa\xb7\x28\xd8\xf0\x78\x39\xae\ -\x30\xe4\x3a\x4a\x2e\x56\xf6\xd7\xd1\x75\x67\x0f\x7c\x88\x60\xc6\ -\xfe\xcf\x1c\x72\x52\x77\x7d\xcd\x25\x17\x76\x6d\xf8\xa0\xc8\xd8\ -\x5f\x1f\x81\xea\xba\x2b\x0c\x58\x48\x82\x6f\xb0\xde\xff\x22\x08\ -\xc5\x94\x92\x21\x17\x8e\x1e\x9f\xcf\x31\x23\xb3\x61\x7a\x1c\x13\ -\x2c\x28\xe5\x63\x4a\xc1\x05\x82\x32\xe1\x61\xf8\xb9\xf6\x11\x96\ -\x5c\x86\x38\x18\x5b\x32\x62\x01\xa1\x04\x1c\x0f\xe6\x1c\x33\x3e\ -\xb6\x60\x04\x80\x1e\xf7\xec\x44\x48\xa8\xf8\x58\xf9\x38\x64\x4a\ -\x10\x2b\x11\x42\x2a\x35\xa6\x20\x81\x35\x14\x34\xfe\x26\xee\x0e\ -\x3f\x39\x61\xea\xd5\xe5\x57\x56\xd2\x17\x7d\xae\x88\xbb\xcf\x31\ -\xd6\x37\x65\xcf\x81\xbb\x8e\x38\xf2\xe7\xfd\x64\xf1\x78\x77\x6f\ -\x7f\x4b\xc1\xe3\xdd\x7f\x01\x5f\xd9\x98\x1e\ -\x00\x00\x08\xf1\ -\x00\ -\x00\x5b\x07\x78\x9c\xed\x5c\x59\x73\xe3\x36\x12\x7e\xf7\xaf\xc0\ -\xca\x2f\x49\xad\x40\xe1\xe0\x6d\xd9\xa9\xda\x4c\xa5\x92\xaa\xe4\ -\x25\xc7\x6c\xd5\xbe\x6c\x51\x24\x24\x71\x4d\x91\x2a\x92\xb2\xa4\ -\xf9\xf5\xdb\x0d\x5e\xba\x3c\x71\xd6\xce\x8e\xed\x80\x1a\xc9\x44\ -\x77\x83\x00\x1a\xfd\x75\x37\x48\x0c\xa7\xdf\xec\x56\x19\x79\x50\ -\x65\x95\x16\xf9\xed\x88\x5b\x6c\x44\x54\x1e\x17\x49\x9a\x2f\x6e\ -\x47\xbf\xfd\xfa\x1d\xf5\x47\xa4\xaa\xa3\x3c\x89\xb2\x22\x57\xb7\ -\xa3\xbc\x18\x7d\x73\x77\x35\xfd\x1b\xa5\xe4\xdb\x52\x45\xb5\x4a\ -\xc8\x36\xad\x97\xe4\x87\xfc\xbe\x8a\xa3\xb5\x22\x5f\x2d\xeb\x7a\ -\x1d\x4e\x26\xdb\xed\xd6\x4a\x5b\xa2\x55\x94\x8b\xc9\xd7\x84\xd2\ -\xbb\xab\xab\x69\xf5\xb0\xb8\x22\x84\x40\xbb\x79\x15\x26\xf1\xed\ -\xa8\xad\xb0\xde\x94\x99\x16\x4c\xe2\x89\xca\xd4\x4a\xe5\x75\x35\ -\xe1\x16\x9f\x8c\x06\xf1\x78\x10\x8f\xb1\xf5\xf4\x41\xc5\xc5\x6a\ -\x55\xe4\x95\xae\x99\x57\xd7\x07\xc2\x65\x32\xef\xa5\xb1\x37\x5b\ -\xa9\x85\x78\x10\x04\x13\x26\x26\x42\x50\x90\xa0\xd5\x3e\xaf\xa3\ -\x1d\x3d\xae\x0a\x7d\xbc\x54\x55\x30\xc6\x26\xc0\x1b\x24\x9f\x26\ -\x15\x56\xa0\xd0\x35\x7c\x7b\xf1\x8e\x60\x55\xc5\xa6\x8c\xd5\x1c\ -\xea\x29\x2b\x57\xf5\xe4\xc3\xaf\x1f\x7a\x26\x65\x56\x52\x27\x07\ -\x97\xe9\xf4\x79\xd4\xea\x91\x92\xf3\x68\xa5\xaa\x75\x14\xab\x6a\ -\xd2\xd1\x75\xfd\x6d\x9a\xd4\xcb\xdb\x91\xb4\x2d\x2e\xe1\x70\x34\ -\x71\xa9\xd2\xc5\xb2\x3e\xa5\xa6\xc9\xed\x08\x7a\x2f\x02\xbf\x29\ -\x1f\x18\x07\x6f\x04\xda\x0b\x87\x3d\x87\x59\x81\xb0\x38\x29\xb9\ -\x23\xbd\x46\xa6\x1b\x42\x98\x14\x31\xf6\x09\x2e\xa9\x56\x69\xb4\ -\xa9\x8b\x15\xcc\x5a\x1c\x67\x51\x55\xa5\xf3\x34\x86\x42\x91\xaf\ -\xb3\xcd\x22\xcd\xff\xbd\x2c\x56\xca\xea\xf4\xd6\x37\xa2\x76\xeb\ -\xa2\xac\xe9\x2e\x59\x83\xf6\x5c\xef\x22\x73\x7f\xc8\x7c\x48\xd5\ -\xf6\x1f\xc5\x0e\x7a\x45\x18\x91\x02\xfe\x8d\xee\x80\x3e\x4d\xd4\ -\xbc\x42\x7e\x33\x42\x2c\xc1\x10\xbd\x11\x99\x68\x6e\xdf\x61\xec\ -\x6d\x82\xd7\x18\x64\x67\x51\xd5\x68\x91\x90\x75\xb4\x00\x8b\xcb\ -\x8a\xf2\x76\x74\x3d\xd7\x47\xcb\x98\x15\x65\xa2\xca\x8e\xe5\xea\ -\xe3\x88\x55\xc0\xac\xa4\xf5\xbe\xc1\x58\x7b\xed\x6e\x18\x78\xd5\ -\x9e\xcf\x2e\xf3\xab\x65\x94\x14\xdb\xdb\x91\x38\x65\x7e\x2a\x8a\ -\xd5\xed\xc8\xb1\x9c\xc0\x0f\x18\x3f\xe5\xc6\xa0\x08\x6a\xfb\x96\ -\xf4\x1d\x21\xfd\x33\x2e\xb4\xe7\x59\x8e\xf4\x3d\xee\x9c\x57\xdd\ -\x94\x25\x80\x90\x66\xd1\x5e\xc1\xa0\xf4\x9f\x4e\xa8\x5a\x16\xdb\ -\x45\x89\xca\xa9\xcb\x8d\x3a\xad\x89\x1c\x3a\x9b\xe1\x24\x5c\x62\ -\x83\x4d\x6c\x10\xde\x74\x93\xa7\x35\x40\x68\xbd\x3b\xbc\xea\x26\ -\x4d\x54\x75\xb9\x62\x95\x47\x6b\xba\xc8\x8a\x59\x94\x5d\x16\xd8\ -\xa6\x39\x28\x89\xb6\xd6\xce\x65\x3f\x07\xa7\x12\x9d\xe9\x7b\xec\ -\x4c\x27\xad\x04\x1a\xd0\x23\xac\xfd\xe3\xac\x55\xb4\x4b\x57\xe9\ -\x27\x05\x8a\x39\xd3\xa7\x1e\xd9\xa1\x5a\xee\xb4\xc0\xf4\x48\x6d\ -\x4d\x1d\x42\xea\x3d\xc2\x7c\xb7\x47\xda\xa8\x23\xa2\xbe\x91\x20\ -\x82\xc0\xeb\x89\x45\x99\x02\x7a\x0e\xba\xdb\x91\xf6\x87\x24\x74\ -\x0a\xe0\xd3\x77\x43\xbf\x7a\x1a\xda\x64\x07\x83\xc9\x39\x0e\x34\ -\x7d\xa5\xea\x28\x89\xea\x68\x00\x45\x47\x81\xbe\xb0\x6e\x24\xe0\ -\x4f\xc3\x9f\x3f\x7c\x77\xd7\x36\x30\x8d\xe3\xf0\x9f\x45\x79\xdf\ -\xb5\x47\x08\x0a\x44\xb3\x62\x03\x9a\x1f\xdd\xf5\xe4\x69\x12\x87\ -\xe0\x01\xc1\x33\xdc\xa5\x2b\x30\x75\x74\x9e\x7f\x07\x8f\x37\x9d\ -\x0c\x8c\x23\x61\x54\xce\x70\xd1\xe6\xb2\xa5\x6a\x5c\xe9\xc5\x78\ -\x92\xc4\xab\x14\x2b\x4d\x7e\xa9\xd3\x2c\xfb\x01\x1b\x69\x47\x7c\ -\x70\xd1\xb4\xce\xd4\x40\x9c\x4e\xda\xde\xb7\x63\x9b\x1c\x0c\x6e\ -\x3a\xe9\x46\xaf\x4b\x8b\x41\x2b\x47\x20\xe9\x27\x36\x8b\x66\x0a\ -\x2c\xf6\x47\x64\x92\x73\xbb\x28\x8b\xcd\x7a\x55\x24\xaa\xad\xde\ -\x69\x73\x1d\xd5\xcb\x7e\xaa\xea\x7d\x06\xfc\x39\xf4\x3e\xbc\xb6\ -\x13\xfc\xdc\x60\x81\xb6\x6e\x23\xe4\x4d\xb1\xdc\x64\xe0\x15\x1f\ -\x54\x5e\x24\xc9\x4d\x55\x97\xc5\xbd\x0a\xaf\x3d\x17\x3f\x6d\xb1\ -\x01\x47\xc8\xba\x22\x28\x46\x95\x19\x18\x6d\x1d\xda\x1d\x2d\x89\ -\xc0\xdb\x94\x65\xb4\x0f\x73\x08\xfa\x1d\xb5\x6f\xaa\x37\x20\x34\ -\x03\x22\xb8\x65\xdb\xc2\x96\xce\x58\x5a\x0e\x79\x20\xc2\x27\xdf\ -\x13\xce\x2d\x3f\x70\x03\x9f\x64\x84\x8d\xa9\x0b\x14\xd7\xe2\x6e\ -\xe0\x31\x2f\x00\x11\x20\x64\x84\x3a\x96\x27\xf0\x13\x38\x63\x86\ -\x44\x09\x24\x42\x7d\xf2\xe9\xc8\xde\x4b\x15\xd7\x32\x10\x92\x3a\ -\x03\xb9\xf7\x50\x45\x9e\x03\xbb\x28\x29\xf8\xaa\x87\xa8\xde\x94\ -\xea\xc8\xe6\x7b\x5b\x06\xe5\xe2\xf4\x83\x5b\x89\x87\xa3\xb7\x80\ -\xc7\x35\x2d\x65\x14\xb3\xe7\x6a\xda\xe2\xe0\x5c\x25\xe7\xfc\x73\ -\x2a\x7f\x44\xb9\xb2\x57\x2e\x24\x03\x0e\xe8\x52\x32\xb2\x24\x14\ -\x7c\xb6\x8b\x2a\xe3\x12\x34\x6b\x37\x22\xb6\xd6\x2c\xf7\x2e\xea\ -\x8f\xfb\x2f\xa9\xbd\x27\x68\x6e\xee\x47\x73\x9b\xbf\x1a\x1b\x75\ -\x3b\x35\xf2\xce\x46\x41\x8b\x9c\x35\xb6\xb8\xc4\x1f\x7d\x76\xa2\ -\xcc\xcf\x5b\xe4\x9f\x67\x8f\x8b\x3e\x0a\x94\x51\x5e\xa1\x07\x84\ -\x56\x8b\x1a\xb2\xed\xaf\x02\x36\xe6\xb6\x15\x78\x5c\x70\x6f\xcc\ -\x1d\xcb\xd6\x67\x5f\x1f\x87\x08\xdb\x73\x7c\x7a\xe0\xe7\xcf\x9d\ -\x47\xef\x7d\x8f\x66\xf0\xf3\x93\x3e\x48\x3d\x75\xc0\x4d\x77\xb0\ -\x05\xd0\xa8\x43\x83\x03\x06\xd0\x7f\x22\x62\x1c\xa0\xca\xc9\xb7\ -\xc4\x1e\xfb\x16\x0f\xbc\x80\xbb\x1e\x9c\x7b\x96\xcf\x04\xf3\xa5\ -\xc4\x73\x98\x12\xdf\xb5\x1d\x28\xc1\xb9\x03\x99\xaa\x63\x83\x14\ -\x9c\xbb\xf0\xfd\x48\x1c\xac\x6d\xb9\x4d\xdd\xb1\x43\xa4\x25\x9b\ -\xba\x70\x2e\xf4\xd7\xb5\x84\x0c\xb0\x3e\x9c\x7b\x96\xe7\x32\xac\ -\xaf\xdb\xfe\xd7\x41\x87\x5a\x25\xe9\x0c\x2e\xbc\x66\xfa\xb8\x99\ -\x17\x90\xa5\x68\x0e\x28\x04\xe2\x50\xd6\x50\x1e\xa2\x32\x8d\xf2\ -\xfa\x88\xb6\xd5\x19\xc5\x11\x09\x6c\x52\xd5\xf1\xf2\x98\x06\xc9\ -\x41\x08\x91\x35\xdd\xac\x6e\xb2\x34\x57\x6d\x26\x72\x24\x33\x8f\ -\x56\x69\xb6\x0f\x7f\x81\xb9\xbf\xa1\x9d\xae\x69\x53\x7d\xad\xe2\ -\x3e\x6f\x6e\x24\x6a\xb5\xab\x41\x2a\x81\x84\x0a\x10\xa3\x4b\x51\ -\x96\x2e\xf2\x10\x96\x6d\x65\xdd\x10\x12\x48\x5a\xcb\xa6\x8e\x46\ -\xcb\x09\x91\x62\x4f\x1a\x4e\xa6\x6a\xc0\x1a\x6d\x53\x83\xae\x5b\ -\x5b\x48\x61\x4f\x69\xfa\x1a\xbd\x81\x36\xb5\xb7\x65\x5a\x83\x08\ -\xc5\x68\x16\x66\x25\xad\x67\x37\x49\x8a\x78\xc1\x96\xb3\xba\xbc\ -\xc1\x54\x5a\x0f\xbb\x5a\xa6\xf3\x3a\xec\x8a\x6d\xb7\xf3\x78\x09\ -\xca\x6f\xfa\x9d\xa4\xd5\x1a\xc2\x21\xac\x79\xb4\x40\x01\x8b\x8d\ -\x79\x56\x6c\xc3\x87\xb4\x4a\x67\x99\xba\xd1\x7f\xd3\x0c\xc1\xde\ -\x91\xfe\xa7\xe8\x78\xe8\x3d\x1a\xb7\xc3\x2d\xc8\x69\xf0\x70\x6e\ -\x56\x51\x79\xaf\xca\x46\x46\xe5\x11\x34\x42\x67\x51\x7c\x8f\x11\ -\x3b\x4f\xc2\x28\x86\x3c\x76\x93\x01\x2c\x0f\x92\x89\xa7\x02\xea\ -\x99\x70\x92\x0e\xb5\xcf\xe1\xc4\x9d\x1e\x4f\x5c\x36\xa0\x40\x3c\ -\x71\xd1\x82\x02\xcf\x39\x88\x08\x12\x43\x2c\xe1\x1d\x95\x8d\x45\ -\x27\xcc\xc6\xf6\x81\xbb\x33\xb0\x30\xb0\xf8\xff\xc2\xe2\xd9\xc0\ -\x10\x1e\xf5\x8e\x81\xb1\x22\xdc\x1d\x0b\x07\x4c\x1e\x72\x28\xdb\ -\xf5\x3d\xcc\x37\x29\x24\x02\x92\x0b\x7d\x2a\x74\xfe\x89\x98\x80\ -\xb5\x39\xe3\xb0\x50\x06\x82\xb4\x98\xed\x0a\xc6\xe1\xd4\x86\x2f\ -\xc3\x04\xcc\xc7\xbb\x24\x08\x17\x2a\x21\x9b\x85\x03\xf1\x42\x6d\ -\x4c\x20\x1a\x44\x31\xab\x8d\x34\x08\xae\x36\xd0\x00\xb8\x0c\xa2\ -\x0c\xa2\xde\x5e\xa0\xe9\x57\x5e\x1e\xf5\x4f\x11\xe5\x8f\x85\x87\ -\x16\xdf\x25\x6a\x1a\x30\x78\x67\x15\xb2\x52\x00\x0c\xc0\x08\x41\ -\xf5\x23\xe1\xa2\x47\x5e\x23\x89\x78\x93\x5d\xaa\x87\x05\x04\x97\ -\x81\x87\x81\xc7\x5b\x0d\x38\xc2\x95\x94\x9d\xc2\x43\xe0\xda\x04\ -\xe1\xa1\xd7\x2d\x68\xf4\x10\x6e\x20\x1a\x68\x93\x17\x3a\x9c\xf0\ -\xf6\x2b\x20\x7a\x34\xc1\x03\x42\x12\x67\xae\xf4\xa5\x8d\x05\x61\ -\x05\x0e\x83\xb1\x07\x4d\x88\x01\x00\x05\x92\x33\x29\x5a\x00\xf9\ -\x8e\x0c\x02\x83\x1f\x83\x9f\xcf\xe1\x47\xda\x3e\x4e\xff\xab\xc6\ -\x8f\x64\x9c\xca\x33\xfc\x34\xe1\x05\xd2\xb1\xc0\xb1\x99\xad\xef\ -\x7e\x41\x66\xe6\x12\xd9\xa6\x63\x1f\x89\xc0\x85\xbf\xd3\x26\x71\ -\x50\xb0\xdb\xd4\x0e\x4f\xdb\x1f\xbb\xff\x91\xc3\x9a\x47\x2f\x76\ -\x3c\xdf\xf1\xb8\x6d\x16\x3b\x06\x3b\x5f\x14\x3b\x2f\x91\x9a\x79\ -\x54\x9c\x27\x67\x4f\xcd\xcd\x10\x43\x9c\x37\xe9\x18\xde\x3c\xf3\ -\xfb\x3a\x70\x0e\x5f\x73\x83\xcc\x80\xe3\x2d\xaf\x5b\xec\x83\xa7\ -\x46\xdd\xbd\x00\xfb\x08\x1d\x8f\x82\x03\xcd\xff\xf2\xba\xc5\x2c\ -\x5b\x0c\x3a\xde\x07\x3a\xf8\xf9\xc2\x5e\xb0\x27\xc1\x43\xd8\x06\ -\x1e\x06\x1e\xef\x10\x1e\xfd\xd3\x15\x87\xba\xe7\xcf\x57\x04\x1f\ -\x9e\xaf\x04\x07\xcf\x57\xfc\x83\xe7\x2b\x9e\x79\xbe\x62\x80\xf1\ -\x6a\x81\xf1\x52\x8b\x0e\xfb\x42\xe8\x70\xf1\xf9\xe3\xef\xc7\x0e\ -\xc9\xf0\x21\xa4\x0e\x1e\x02\x16\x58\x82\x77\xcf\x60\x68\x73\x67\ -\x8c\xf5\x77\xc6\xa8\x66\xf5\x7c\x83\x1b\x83\x9b\xb7\x8f\x9b\x4b\ -\xc8\x61\x18\x59\x9e\x94\x75\x71\xcf\x20\xc7\x20\xe7\xcb\x23\x67\ -\x3a\x59\x9c\x6e\x56\xeb\xb7\x9e\xf5\xc6\x76\x79\xfb\x9a\x73\x61\ -\xfb\xda\x17\xd8\x8e\x66\x36\xa3\x19\x8c\xfe\xe9\x18\x65\x7c\x96\ -\x24\xc1\xab\x8f\x6e\xcf\x5e\x2e\x99\xad\x68\x06\x14\xef\x0d\x14\ -\x2f\xb0\x15\xcd\x6c\x44\x33\x78\x32\x78\x7a\xb9\x5b\xd6\x66\x1b\ -\x9a\x01\xc7\xfb\x04\xc7\x0b\x6c\x43\x33\x9b\xd0\x0c\x7a\x5e\x21\ -\x7a\xde\xc8\x26\x34\xb3\x05\xcd\x20\xe7\x2f\x88\x9c\x17\xb9\xab\ -\x6d\x36\xa0\x19\x68\xbc\xbf\x94\xec\x45\xb6\xd8\x98\xed\x67\x06\ -\x1b\x06\x1b\x97\xb1\x71\x9e\x73\x99\xcd\x67\x06\x1c\x7f\x61\x70\ -\x0c\x9b\xcf\xcc\xd6\x33\x03\x8b\xf7\x06\x8b\x17\xdb\x42\x63\x36\ -\x9e\x19\xd4\x18\xd4\xfc\xf1\x8d\x67\x66\xdb\x99\xc1\xcd\x1b\xc7\ -\xcd\xb0\xed\xec\xf1\x37\xcf\xe9\x63\x78\xb1\x9c\x8f\x9f\x47\x5e\ -\x2c\x87\x43\x87\xc9\x0f\x67\x9b\xba\x3e\xa4\xfd\xa7\x48\xf3\x50\ -\xbf\x75\xee\xec\xc5\x72\x4f\x7f\x27\xdd\xf1\x2b\xe8\x82\xb1\x67\ -\x39\xda\xea\x1d\xb2\x24\x3e\xf9\x08\x6b\x7c\x48\xd7\x9a\xf7\xcc\ -\x59\xb6\x56\x08\x3e\x85\xb1\x02\x06\x1f\x8e\x7c\xae\xf9\xc3\x2d\ -\xb0\x2e\x45\xf4\x9d\xe1\xbf\x7c\xfe\x9e\x47\x78\xc2\x9b\xfa\x8e\ -\xf5\xd5\x22\xf3\xb9\xfa\x7a\xe6\x2b\xfb\x7e\x22\xe0\x83\x6c\xcb\ -\xe7\xf0\x11\x04\x3c\x0e\x97\x48\x81\xcc\xb7\x21\x5d\xd0\x89\xfd\ -\x07\x75\xa2\x4d\x69\x8a\xef\x1a\xbd\xbb\xfa\x2f\xbb\x92\xfa\xa3\ -\ -\x00\x00\x0b\x27\ -\x00\ -\x00\x5a\x95\x78\x9c\xed\x5c\x59\x8f\xdb\xc8\x11\x7e\xf7\xaf\x60\ -\x64\x04\xbb\x46\xd4\x14\xfb\x60\x1f\x1a\xcd\x2c\x10\x1b\x0b\x2c\ -\xb0\x79\xc9\x6e\x10\x20\x2f\x0b\x0e\x49\x69\x08\x53\xa4\x40\x52\ -\x23\x8d\x7f\x7d\xaa\x78\x89\xd4\xe1\x38\x96\xb4\xd6\x48\xa6\x31\ -\x9e\x51\x55\x1f\xd5\x5f\x57\x55\x7f\x4d\xb1\x39\xf9\x69\x3d\x8f\ -\xad\xe7\x30\xcb\xa3\x34\xb9\x1f\x50\xdb\x19\x58\x61\xe2\xa7\x41\ -\x94\xcc\xee\x07\xff\xfa\xfd\x67\xa2\x07\x56\x5e\x78\x49\xe0\xc5\ -\x69\x12\xde\x0f\x92\x74\xf0\xd3\xc3\x9b\xc9\x5f\x08\xb1\xde\x67\ -\xa1\x57\x84\x81\xb5\x8a\x8a\x27\xeb\x97\xe4\x63\xee\x7b\x8b\xd0\ -\xfa\xf1\xa9\x28\x16\xe3\xd1\x68\xb5\x5a\xd9\x51\x2d\xb4\xd3\x6c\ -\x36\x7a\x67\x11\xf2\xf0\xe6\xcd\x24\x7f\x9e\xbd\xb1\x2c\x0b\xfa\ -\x4d\xf2\x71\xe0\xdf\x0f\xea\x0a\x8b\x65\x16\x97\x05\x03\x7f\x14\ -\xc6\xe1\x3c\x4c\x8a\x7c\x44\x6d\x3a\x1a\x6c\x8a\xfb\x9b\xe2\x3e\ -\xf6\x1e\x3d\x87\x7e\x3a\x9f\xa7\x49\x5e\xd6\x4c\xf2\xb7\x9d\xc2\ -\x59\x30\x6d\x4b\xa3\x35\x2b\x5e\x16\xa2\xc6\x98\x91\xc3\x46\x8c\ -\x11\x28\x41\xf2\x97\xa4\xf0\xd6\xa4\x5f\x15\x6c\xdc\x57\x95\x39\ -\x8e\x33\x02\xdd\xa6\xe4\x97\x95\x1a\xe7\x00\xe8\x02\x7e\xda\xe2\ -\x8d\xc0\xce\xd3\x65\xe6\x87\x53\xa8\x17\xda\x49\x58\x8c\x3e\xfc\ -\xfe\xa1\x55\x12\xc7\x0e\x8a\xa0\xd3\x4c\x83\x67\xaf\xd7\x1e\xc8\ -\x89\x37\x0f\xf3\x85\xe7\x87\xf9\xa8\x91\x97\xf5\x57\x51\x50\x3c\ -\xdd\x0f\xb8\xb0\x29\x87\xcb\x2d\x85\x4f\x61\x34\x7b\x2a\xb6\xa5\ -\x51\x70\x3f\x00\xeb\x99\xd1\xd5\xe7\x8e\x73\xd0\xaa\x40\xdd\xf0\ -\xb8\xd5\x38\xb6\x61\x36\xb5\x32\xea\x72\x55\x95\x69\x86\x30\x0e\ -\x52\x1f\x6d\x82\x26\xc3\x79\xe4\x2d\x8b\x74\x0e\xb3\xe6\xfb\xb1\ -\x97\xe7\xd1\x34\xf2\xe1\x43\x9a\x2c\xe2\xe5\x2c\x4a\xfe\xc8\xc2\ -\xbe\xf8\x8f\x22\x4d\x63\xbb\x01\xb2\xed\x35\x5c\x2f\xd2\xac\x20\ -\xeb\x60\x01\x70\x4a\xb5\x57\xf9\xd2\x28\x1f\x40\x3b\x09\xc2\x69\ -\x8e\xa5\xaa\xb1\xe1\x27\x18\x9c\x1a\x58\xa3\x52\xdb\x9a\x8a\x76\ -\x06\xcf\x51\xb8\xda\x94\x7d\xf4\xf2\x0a\x3f\xcb\x5a\x78\x33\xf0\ -\xb5\x38\xcd\xee\x07\x6f\xa7\xe5\x55\x2b\x1e\xd3\x2c\x08\xb3\x46\ -\x25\xcb\xab\xa7\x4a\x61\x3e\xa2\xe2\xa5\x8a\xae\xba\xed\xc6\x5e\ -\x6c\xb5\xd5\x3b\xfb\xf5\xf9\x93\x17\xa4\xab\xfb\x01\xdb\x56\x7e\ -\x4a\xd3\x39\xb4\x0a\xf3\x62\x94\x76\x76\xd4\xfe\xfa\x7e\x40\xa8\ -\x6b\x1b\x18\xac\x31\x3b\x5a\x34\x48\xd8\x5a\x70\xc1\xc4\x8e\x72\ -\x99\x65\x10\x7f\x24\xf6\x5e\x42\x18\x55\xf9\x8b\xd6\x85\xf2\xa7\ -\x74\x35\xcb\x10\x9d\x22\x5b\x86\xdb\x35\x51\x43\x1e\x1f\xd3\xf5\ -\x7e\x35\xb8\xc3\x12\x23\x9b\x2c\x93\xa8\x80\xe8\x59\xac\xbb\xad\ -\x2e\xa3\x20\xcc\xf7\x57\xcc\x13\x6f\x41\x66\x71\xfa\xe8\xc5\xfb\ -\x0b\xac\xa2\x04\x50\x22\xb5\xa3\x53\xde\x4e\xc2\x76\x89\xc6\xeb\ -\x95\xa3\x0f\x94\x00\xdb\x77\x26\xa2\x56\xbd\x1c\x56\xcd\xbd\x75\ -\x34\x8f\x3e\x85\x00\x0c\x2d\xfd\x0e\x7c\xab\x07\x4b\x55\xcd\xb2\ -\x8a\x17\x8c\xe0\xf5\x0b\xca\x06\x8d\x10\xf1\x44\x01\x33\x46\xb5\ -\xc2\x34\x8b\x20\x30\x3a\xe6\x34\xa2\x97\xae\x08\xe3\x1d\xd2\xf5\ -\xba\x74\xb0\xd2\xfd\xd4\xb6\xee\xa5\xab\xab\xfd\x7e\xb4\xeb\xf8\ -\xa5\x7c\x1e\x16\x5e\xe0\x15\xde\x26\x0a\x1a\x09\xd8\xe6\x34\x23\ -\x83\xd4\x39\xfe\xe7\x87\x9f\x1f\xea\x8e\x26\xbe\x3f\xfe\x77\x9a\ -\x7d\x6c\xfa\xb5\x2c\x2c\xe0\x3d\xa6\x4b\x40\x7a\xf0\xd0\x8a\x27\ -\x81\x3f\x86\x64\x07\x49\xe0\x21\x9a\x83\x6f\x63\x9e\xfc\x1b\x24\ -\xb7\xc9\x68\xa3\xe8\x15\x46\xb0\x36\x8d\x56\xcd\x66\x61\x95\x35\ -\xf7\x2e\x1d\x81\x3f\x8f\xb0\xd2\xe8\xb7\x22\x8a\xe3\x5f\xb0\x93\ -\x7a\xc4\x9d\x46\xa3\x22\x0e\x37\xc2\xc9\xa8\xb6\xbe\x1e\xdb\xa8\ -\x33\xb8\xc9\xa8\x19\x7d\xf9\x69\xb6\x41\xa5\x17\x14\xed\x44\xc7\ -\xde\x63\x08\x1e\xfa\x2b\x2a\xad\x1d\xed\x2c\x4b\x97\x8b\x79\x1a\ -\x84\x75\xf5\x06\xcd\x85\x57\x3c\xb5\x53\x56\xbc\xc4\xa0\x2f\x13\ -\xca\xf8\xad\x53\x5e\x77\xd3\x14\x62\xa6\xd4\x8c\x13\x44\x29\xae\ -\x24\xcf\x5e\x16\x79\x49\xd1\x93\xad\x4a\xff\xee\x89\xf2\x22\x0b\ -\x0b\xff\xa9\x2f\x03\x57\x1d\xc3\xbc\x47\xcb\xf9\x5d\x1c\x25\x61\ -\x1d\x17\xbd\x32\x53\x6f\x1e\xc5\x2f\xe3\xdf\xbc\x24\xbf\x23\xcd\ -\x20\x48\x55\x7d\x11\xfa\x6d\xa6\xae\x4a\x14\xe1\xba\x80\x52\x01\ -\x84\xf7\xd8\xa9\x3e\x79\x71\x34\x4b\xc6\xc0\x1f\xb2\xa2\x12\x04\ -\x90\x43\xb3\xaa\x4e\x02\x7c\x62\x5b\x48\xd0\x92\x4a\x13\x87\x45\ -\x11\x66\xa4\x76\xe0\xc6\xac\x15\x64\xd4\x6d\x59\xd9\x46\x91\x81\ -\x09\xe8\x40\x55\xed\x55\x16\x15\x50\x84\x20\xd6\xe3\x38\x23\xc5\ -\xe3\x5d\x10\xc1\x02\x53\xf6\x1c\x17\xd9\x1d\x66\xf6\x72\xd8\xf9\ -\x53\x34\x2d\xc6\xcd\xc7\xda\xec\xc4\x7f\x02\xf0\x2b\xbb\x83\x28\ -\x5f\xc0\x64\xc1\xe2\x5b\x16\x48\x61\xd5\x9b\xc6\xe9\x6a\xfc\x1c\ -\xe5\xd1\x63\x1c\xde\x95\xbf\xa3\x18\x9c\xae\x15\x4d\xc1\xf3\x36\ -\x53\x07\x1f\x48\x9d\xe3\xc7\xf4\x0e\xe6\x22\xfd\x58\x8f\xb1\xfa\ -\xbb\xca\x59\x63\x6e\x8b\x72\x15\x16\xec\x6e\xee\x65\x1f\xc3\xac\ -\x2a\x13\x26\x1e\x34\x49\x1e\x3d\xff\x23\x7a\x4f\x12\x8c\x3d\x1f\ -\x72\xe8\x32\x06\xee\xd5\x86\x39\xb8\xe3\x3f\x2c\x48\xf5\x9a\x71\ -\x43\xd5\x90\x41\xac\x3b\x86\x31\x65\xbd\xb7\x28\xac\x2a\xda\x50\ -\xa1\x86\x40\x27\xb4\x96\x98\x60\x2c\x69\x6b\xe5\x30\x25\x39\x14\ -\xe5\xda\x28\x25\xb4\xc5\x6d\xaa\x98\x16\x54\x0e\x95\x2d\x38\x33\ -\x8e\xab\xad\x5f\x2d\xa8\x44\x1d\xe1\x2a\x6e\xd4\xd0\x05\x9a\xa0\ -\xa9\x2b\x85\x45\x6d\x25\x05\x93\xda\x1d\x42\xa7\x42\x30\x57\x18\ -\x8b\xd9\x4a\x6b\x6a\x04\x43\x19\xa3\xda\x11\x1c\x3b\x17\x54\x1b\ -\x57\x0d\xe1\x2f\xce\x1d\xa9\x24\xf4\x2d\x86\xda\x76\x79\x79\x59\ -\x3e\xd6\x63\xc6\xe5\xd4\x0c\x09\xb3\x8d\xd6\x5c\x6a\x65\x41\xab\ -\x2e\x13\x4a\x0f\x89\x8b\x32\x41\x0d\xb5\x0c\x66\x30\xb0\x60\x48\ -\x90\xaf\x50\xa6\xa9\x82\xca\x38\x1e\x4e\x87\x8e\xcd\x34\xa7\x94\ -\xa2\x1d\x06\x86\xa6\x0d\x8e\xd7\x35\x52\x51\xe9\x5a\xd0\xb9\xab\ -\x94\x16\xd8\x05\x17\x94\x32\x65\xac\x4f\xbd\xdc\x8b\x11\x08\xac\ -\x40\x13\x45\x36\x99\x75\xb3\x1e\xa6\x49\x02\xce\x93\x66\x04\x56\ -\xc6\x67\xaf\x58\x66\x61\x2f\x03\xb7\x99\x14\xdc\x0d\x93\x0f\x2c\ -\x62\x7e\x73\xb5\xd9\xe7\x7b\x94\x7f\x8f\xf2\x63\xa3\x7c\x6e\x51\ -\x0d\x01\x07\xdc\x5c\x0d\x39\xb5\x99\xe3\x4a\x2a\x21\x88\x5c\x5b\ -\x19\x88\x48\x03\xf1\xac\x99\x70\x18\xb5\xb4\x6d\x84\x70\x65\x15\ -\x06\xb0\x25\x51\xda\xa2\x0c\xc3\x4e\x38\x06\xa3\x4a\x0a\xea\xb8\ -\xca\x8a\x21\xee\x39\x83\x72\x1a\xaa\x32\x26\x98\x05\x21\xe2\x68\ -\x68\x1f\xe2\x0c\x82\x96\x49\x46\xa9\x45\x80\x3d\x50\x0d\x81\x8c\ -\x71\x26\x24\xe7\x20\x52\xd0\xac\x70\x8d\x81\xb4\xe0\x08\xc3\xb4\ -\xb1\x84\x0d\xe6\x08\x41\x87\x90\x1e\x28\x75\x20\x4f\xf8\xd8\x9a\ -\x94\xae\xe3\x9a\x21\x87\x62\x12\xec\xb0\xa0\x73\xce\x38\x83\xe4\ -\x21\x21\xb7\x70\xcc\x1d\x04\xac\x55\x2e\xb0\xd4\xa1\x00\x9d\x80\ -\x84\x83\x15\xb9\xe3\x32\xd7\xc5\x01\x30\x0e\x79\xad\x34\x0d\x8c\ -\xe0\x0a\xcd\x90\xae\x96\x0e\xc5\xfc\xc4\x1d\x25\x15\x26\x3d\x2e\ -\x20\xff\xe9\x43\x81\x7d\xb6\xb0\x9e\xf5\x38\x9c\x70\xa8\xdb\xe9\ -\xab\x8e\xf3\xae\xaf\xb4\xba\xd6\x9b\x91\xd1\xc2\x9f\x38\xd9\x3f\ -\x12\xa6\x6c\x55\xe6\xc6\x21\xcc\x97\x7e\xd7\x92\xa7\x09\x3a\x76\ -\x87\x5f\x95\x9c\x4e\x30\xbc\xf8\xa0\x23\xef\xd1\x45\xcb\x82\x62\ -\x0c\xa7\xb1\xb3\x2d\xc1\x0b\x4a\x31\x69\xcb\x6d\x71\x43\x8e\x45\ -\x5d\xc3\x74\x74\x35\xb5\xde\xa7\xc2\x91\xa3\x79\xae\xe6\x86\x50\ -\x4e\x18\x91\x84\x76\xf4\x7b\x50\xd8\x8e\x98\xf2\x63\xb6\x84\xd4\ -\x17\x3e\x87\x00\x78\xd0\xc4\x50\xbd\xdb\xea\x87\x91\xd3\x7c\x04\ -\xb2\x17\x66\x31\x10\xef\x62\x2c\x1a\x59\xe0\xc1\x96\x29\xcb\x20\ -\x9a\xbb\xf1\xd7\x76\xd5\xa1\x83\x27\xc7\x94\xc3\x56\x18\xe7\x8e\ -\x9d\x1a\x53\x58\x97\x38\x31\x44\xdc\x24\xa8\xc0\x27\x70\x74\xf4\ -\xe4\xa0\x6a\xe2\xc2\x0f\x27\xce\x4d\xc2\x6a\x6c\xd1\xdf\x2d\x9e\ -\x0a\x56\x07\x20\x55\xe0\xad\x97\x0f\xeb\x64\x34\xdb\x9b\xc5\xb9\ -\xd1\x8c\xf0\xcf\x67\x6a\x4c\xcf\x40\x28\x61\x29\x7d\xf7\xd9\x74\ -\x7f\x82\x09\xd4\xb0\xbc\xe3\xd5\x9f\x40\x6a\xce\x15\x17\x4e\x19\ -\x19\xec\xe2\xa7\xef\x28\x50\x45\xbd\x09\xf9\xf3\x40\x55\x44\x60\ -\x5c\x5c\x35\xac\x5c\xd9\x7c\x7b\x05\x3c\x33\xac\x12\xfe\x89\x57\ -\x90\x6c\x8e\x82\x95\xd7\xf7\xef\xfe\x4c\x6f\x35\x90\xc7\x25\x51\ -\x17\x0f\xec\xa1\x2c\x8e\x5c\xfc\x08\x26\xae\xaa\xf5\x51\xaa\xe1\ -\xe6\xcf\x57\xcb\xc7\x2f\x7e\x12\x5f\x1f\x1b\xbf\x49\x48\xcf\xcd\ -\xc5\x6f\x12\xd4\x73\x33\xf1\x8b\x07\xf5\x73\x3c\xfc\x7f\x64\x69\ -\xbc\x9f\x8c\xff\x5d\x27\x09\xbf\xf8\x99\x7b\x8d\x14\xfc\xaa\x41\ -\xfd\x56\x04\xfc\xba\x41\xfd\x66\xf4\xfb\xe2\x61\xdd\xa4\xee\x2e\ -\xba\x3d\x5b\xa7\x53\xe6\x31\xef\x1b\xda\xfa\x66\x2f\xc8\x9b\x39\ -\x3f\x38\x2f\x87\x27\x13\x67\x7f\x33\x39\xe8\x22\xf6\x26\xe2\xfa\ -\x1e\xd4\xf7\xb3\x16\xb7\xd7\x06\x57\x27\x6f\x7e\x1d\x5e\xbb\xec\ -\xe7\x26\x60\xeb\xae\xe2\x5f\x09\xdc\xce\x3a\x79\x13\xc0\x39\xe4\ -\xd8\x08\xdd\xe5\x6c\x27\x06\xce\x18\xd7\xbd\x38\xe0\xba\xab\xc6\ -\x29\x32\x1b\xd9\x7d\xae\xec\x2a\x71\x83\x25\x97\x9d\x23\xc5\xdd\ -\x0c\x7e\xb8\x85\x37\xe7\xc8\x75\x27\x47\x50\x7f\x6b\xf6\x74\x28\ -\x72\x8f\x75\xc0\x7e\xe4\x52\x5a\x3d\x4b\x20\xae\x1b\x36\xbc\x1d\ -\x77\x8e\xc0\xbd\x15\xf8\xca\x5b\x6f\xe7\x88\xdb\x5b\x01\xb0\xbc\ -\xcd\x76\x0e\xae\x72\x6a\x00\x03\x71\x91\x00\xe2\xd7\x4c\xa7\xcd\ -\x7c\xed\x17\x36\xd7\x0d\x1c\x52\x96\xf3\xec\xcb\x6e\x05\xc0\x92\ -\xb3\x74\xbe\x3c\x3e\x61\xf6\xbb\x15\x08\x31\xfb\xb1\xce\xf3\x7e\ -\x27\xcc\x7f\xa7\x86\x50\x08\xd7\xbd\x3c\x08\x9d\x63\xd9\xcb\x1e\ -\x7e\xbc\xf7\xdb\xa6\x6b\x04\x8f\x1e\xbd\xdb\xed\xde\x10\xb8\x21\ -\xd8\xf4\xd1\x0b\xc7\x6e\x74\xde\x10\x7c\xce\xd1\x94\x79\x97\xdc\ -\x9d\x01\x3e\xe6\x73\x75\x79\xf0\x39\x47\xfb\xde\xfe\x94\x47\xaf\ -\x1b\x36\x4a\xc4\xa9\xb3\xdd\xd5\x23\xa6\xe1\xc7\x3d\xf6\x0e\xfc\ -\xde\x4c\x77\xf5\xd0\x95\x5f\x97\x9f\x23\xc9\x9d\x0c\x39\xad\x3d\ -\xef\x12\x91\xd3\xfa\x68\x3e\xbc\xcd\x4a\x76\xe8\xf1\x95\x22\x07\ -\xbb\xb1\xf3\xf0\x92\x1b\x01\xb0\x7c\x1c\xe3\x2c\xcc\xe4\xc4\x00\ -\x4a\xa9\x2f\x70\x3b\xeb\xc0\x12\x7b\x6c\xe8\x1e\xd8\x8e\xed\xdc\ -\x23\xb8\x46\xfc\x90\xa2\x1c\x7f\x4b\x6a\x3b\xf9\xdd\x08\x74\x25\ -\x57\x39\xfa\x66\xd4\xfe\xf4\x77\x23\x10\xd6\x0f\x4e\x9d\x25\x01\ -\x7e\x1d\x84\xdf\x8f\xfd\x5f\xe1\xb1\x7f\xed\xec\x73\xff\xda\xd9\ -\xcf\x71\xec\x5f\xd9\x5c\xe3\x4b\x32\xb8\x83\x6f\xe1\x30\xc2\xec\ -\x39\xf5\xcf\xfe\xef\x53\xff\xa6\x3e\xf5\x8f\x27\xe9\xeb\x73\xff\ -\x66\x73\xee\x7f\x73\xf0\x5f\x34\x07\xff\x59\x7d\xf0\x5f\x36\xc7\ -\xfe\x75\x73\xec\x9f\x35\xc7\xfe\xdd\xcd\xb1\x7f\xd9\x9c\xfa\x97\ -\xed\xa9\x7f\xd9\x9c\xfa\xd7\xf5\xa9\x7f\xdd\x9c\xf9\x17\xed\x99\ -\x7f\x71\xa2\x33\xff\x1b\xe1\x69\x4f\xfc\xbf\x3a\x4e\x88\xdb\x91\ -\xa3\x73\xe2\x01\x56\x73\x62\x56\x78\xd1\xcf\xb6\x1c\xff\x74\xcb\ -\xbe\x2f\x39\xbe\xf6\xe9\x16\x4c\x67\x6d\xdb\xf3\x78\x5c\xbe\xf8\ -\x0f\xbc\x3f\x0b\xf3\x30\x7b\xde\x24\x90\x06\xdf\xfd\xcb\xcc\xbe\ -\x25\x05\x97\x0f\x3c\xde\x5c\xae\x4f\xd4\x2c\xd6\xbd\x55\xc4\xf9\ -\x6b\x6f\x05\xc9\x21\x39\x13\xe8\x31\x9a\x6e\xe7\x75\x07\x2a\xf6\ -\x92\x3a\x0a\x9a\x69\x2e\xa7\xed\x4b\xf3\x67\x8b\x10\xeb\xad\xd2\ -\x3b\x8f\x5f\x23\x50\x60\x77\x6f\x12\x11\x26\x4c\x25\x83\x87\x49\ -\x01\x86\x24\x8d\xae\x13\xee\x59\x8a\x00\xe1\x18\x07\x1b\x6d\x59\ -\x17\x2b\x40\xe5\xee\xd3\xed\x07\x9e\xfb\xde\xee\xba\x8f\x7b\x8d\ -\xf2\x63\x1a\x07\x5d\x8c\x55\x35\x2e\xe5\xca\x2d\x8c\xa9\xcd\xdc\ -\x43\x28\x7f\x76\xb5\xfe\x01\x97\x6b\xeb\xef\xd0\xcf\x0f\x5f\x00\ -\xf5\x2e\xbc\x0f\x74\x32\x2a\x47\xfd\x00\xbf\x01\xb9\xef\xbe\x56\ -\x47\x6e\xf5\x8e\xcc\x3e\x23\xdc\x3d\x60\xd8\x75\x38\xc8\xb8\xc7\ -\xb8\x1c\xd9\x3e\x1f\xba\x63\xc1\x01\x1b\x5e\xab\xe7\xb1\xbd\x9e\ -\xf7\x9d\x3e\x5f\x21\x7d\x46\x9a\xf4\xa7\xbe\x1b\x4f\xd8\x4a\x30\ -\xe9\x68\x60\x91\xda\xb8\x94\xe3\x2b\xa6\xde\xe3\x2b\xe5\x80\x22\ -\xf3\xf2\xd5\x73\x40\x3c\x1d\x43\x0d\x92\x6a\x20\x9c\x12\x78\x30\ -\x44\x02\xc3\x03\x88\xd2\x02\xad\xa1\xc0\xa2\x19\x90\x57\x26\x81\ -\xe5\x72\x89\xef\xc6\xa3\x36\xd5\xae\x06\x02\x0a\x34\xd7\x28\xc6\ -\x81\x8b\x5b\xc0\x52\x35\x33\x40\x53\xe9\x10\x3a\x65\x40\x53\x81\ -\x6f\x03\x33\x76\x24\x90\x6b\x83\x32\xe8\x88\xb9\xf8\x3a\x3b\xce\ -\x95\x14\x86\x0e\x8d\x4d\xa5\xd0\x9a\xe3\x6b\xef\x38\xd5\xd2\x94\ -\xef\xe0\xe3\x50\x53\x00\x05\x7f\x0f\xa4\xde\x01\x96\x0b\xcd\x23\ -\x53\x56\x86\x2a\x26\xf0\xcd\x7a\x0a\xec\x90\x68\x25\xca\x80\xfb\ -\x43\xd3\x5c\x43\x41\x7c\xd5\x16\x14\x66\xae\x81\x62\x12\xcc\x81\ -\x0d\x01\x88\x5c\x0a\x2c\x9a\x72\xdc\x49\x30\xad\x24\xc5\x17\x7e\ -\x49\x6e\x5c\xd8\x3f\x34\xf0\x50\xde\xc0\x43\x5d\x66\xfd\x67\x2f\ -\xa7\xee\xdc\xda\x39\x25\xab\x2e\x4f\x11\x4d\xf0\x75\xa0\x0f\x6f\ -\xfe\x0b\x1d\xb4\x71\xa7\ -\x00\x00\x1c\xc8\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x6f\ -\x73\x62\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x6f\ -\x70\x65\x6e\x73\x77\x61\x74\x63\x68\x62\x6f\x6f\x6b\x2e\x6f\x72\ -\x67\x2f\x75\x72\x69\x2f\x32\x30\x30\x39\x2f\x6f\x73\x62\x22\x0a\ -\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ -\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\ -\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\ -\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\ -\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\ -\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\ -\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\ -\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\ -\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ -\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\ -\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ -\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\ -\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\ -\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\ -\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\ -\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\ -\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\ -\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\ -\x67\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\ -\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\x22\x0a\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\ -\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\ -\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\ -\x69\x6e\x5f\x73\x65\x6e\x74\x69\x6e\x65\x6c\x33\x5f\x74\x6f\x6f\ -\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ -\x22\x2d\x35\x30\x2e\x34\x31\x39\x32\x32\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\ -\x32\x2e\x34\x34\x30\x37\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ -\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x30\x30\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x39\x39\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x34\x36\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\ -\x34\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\ -\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\ -\x6f\x72\x3a\x23\x36\x61\x35\x61\x35\x61\x3b\x73\x74\x6f\x70\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x35\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\ -\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\ -\x3a\x23\x31\x34\x32\x37\x34\x61\x3b\x73\x74\x6f\x70\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\ -\x74\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x35\x38\x32\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x73\x62\ -\x3a\x70\x61\x69\x6e\x74\x3d\x22\x73\x6f\x6c\x69\x64\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x36\x30\x30\x30\x30\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x37\x38\ -\x38\x32\x33\x35\x33\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x38\ -\x32\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\ -\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\ -\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x38\x31\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x73\x62\x3a\x70\x61\x69\x6e\x74\ -\x3d\x22\x73\x6f\x6c\x69\x64\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\ -\x3a\x23\x66\x66\x62\x37\x62\x37\x3b\x73\x74\x6f\x70\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\ -\x38\x31\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\ -\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\ -\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x37\x31\x36\x22\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\ -\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x31\x31\x32\x34\x31\ -\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\ -\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x73\x74\x6f\x70\x35\x37\x31\x38\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x37\x32\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ -\x65\x74\x3d\x22\x30\x2e\x36\x39\x38\x36\x33\x30\x31\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x31\x62\x63\x36\ -\x63\x36\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ -\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x35\ -\x36\x34\x38\x61\x38\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x37\x32\x30\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x38\x32\x37\x2d\x30\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\ -\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x35\x61\x30\x30\x66\x66\x3b\ -\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x73\x74\x6f\x70\x33\x38\x33\x38\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x38\x33\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\ -\x74\x3d\x22\x30\x2e\x38\x36\x39\x38\x36\x33\x30\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x61\x38\x37\x66\x37\ -\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ -\x2e\x35\x39\x36\x30\x37\x38\x34\x33\x3b\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x38\x33\x31\ -\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\ -\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\ -\x6f\x72\x3a\x23\x66\x36\x66\x66\x30\x30\x3b\x73\x74\x6f\x70\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x31\x39\x36\x30\x37\x38\ -\x34\x33\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\ -\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\ -\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x35\x38\x32\x37\x2d\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x33\x38\x35\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\ -\x3d\x22\x75\x73\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\ -\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x2d\x33\x2e\x32\x33\x32\x33\x32\x33\x32\x2c\x32\x2e\ -\x34\x31\x33\x34\x36\x38\x2c\x2d\x30\x2e\x38\x31\x30\x36\x39\x32\ -\x32\x2c\x2d\x30\x2e\x39\x34\x35\x38\x30\x37\x35\x39\x2c\x37\x34\ -\x2e\x36\x36\x30\x35\x32\x36\x2c\x2d\x38\x2e\x38\x34\x34\x38\x37\ -\x33\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\ -\x31\x35\x2e\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\ -\x22\x31\x37\x2e\x37\x39\x34\x38\x39\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x66\x78\x3d\x22\x31\x35\x2e\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x66\x79\x3d\x22\x31\x37\x2e\x37\x39\x34\x38\x39\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\x31\x38\x2e\ -\x35\x36\x32\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\ -\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\ -\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x35\x37\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\ -\x38\x34\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\ -\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\ -\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x72\x65\x61\x64\x4d\x65\x74\x68\x6f\x64\x3d\x22\ -\x70\x61\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x31\x3d\x22\ -\x38\x2e\x32\x32\x38\x38\x36\x30\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x31\x3d\x22\x31\x39\x2e\x39\x36\x39\x37\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x32\x3d\x22\x32\x34\x2e\x33\x35\ -\x33\x38\x36\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\ -\x22\x31\x39\x2e\x39\x36\x39\x37\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\ -\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x33\x33\ -\x34\x38\x33\x38\x36\x2c\x30\x2c\x30\x2c\x30\x2e\x39\x33\x37\x37\ -\x36\x34\x32\x38\x2c\x2d\x32\x32\x2e\x33\x34\x33\x38\x33\x36\x2c\ -\x2d\x33\x30\x2e\x34\x30\x34\x34\x37\x37\x29\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ -\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\ -\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x34\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x33\x38\x34\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\ -\x3d\x22\x75\x73\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\ -\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x30\x2e\x38\x33\x32\x34\x37\x36\x39\x2c\x2d\x30\x2e\ -\x32\x36\x37\x32\x30\x30\x30\x35\x2c\x2d\x30\x2e\x38\x32\x31\x36\ -\x32\x39\x35\x39\x2c\x2d\x30\x2e\x36\x36\x37\x38\x38\x37\x37\x39\ -\x2c\x2d\x30\x2e\x35\x39\x37\x38\x39\x36\x34\x33\x2c\x32\x34\x2e\ -\x33\x35\x30\x32\x38\x35\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x31\x3d\x22\x31\x31\x2e\x37\x31\x34\x36\x30\x35\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x79\x31\x3d\x22\x30\x2e\x30\x31\x35\x31\ -\x30\x30\x34\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x32\ -\x3d\x22\x33\x31\x2e\x38\x30\x30\x32\x30\x33\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x32\x3d\x22\x30\x2e\x30\x31\x35\x31\x30\x30\ -\x34\x39\x36\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\ -\x30\x30\x32\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\ -\x65\x72\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x33\x38\x35\x37\x29\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x36\x36\x33\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x63\x78\x3d\x22\x31\x30\x2e\x31\x33\x33\x33\x33\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x31\x31\ -\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x32\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x79\x3d\x22\x32\x32\x2e\x34\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x38\x34\x34\ -\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ -\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ -\x2e\x30\x37\x32\x33\x31\x33\x35\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x38\x2e\x31\ -\x33\x33\x33\x33\x33\x2c\x32\x33\x2e\x33\x38\x36\x31\x38\x20\x31\ -\x31\x2e\x32\x36\x37\x31\x32\x36\x2c\x2d\x33\x2e\x35\x32\x33\x33\ -\x31\x31\x20\x63\x20\x30\x2e\x39\x38\x32\x35\x37\x34\x2c\x2d\x30\ -\x2e\x33\x30\x37\x32\x36\x20\x2d\x32\x2e\x35\x39\x37\x31\x38\x39\ -\x2c\x2d\x32\x2e\x38\x37\x39\x31\x38\x32\x20\x2d\x33\x2e\x34\x38\ -\x39\x35\x35\x37\x2c\x2d\x33\x2e\x36\x39\x38\x30\x38\x37\x20\x4c\ -\x20\x32\x33\x2e\x38\x33\x37\x38\x36\x38\x2c\x31\x34\x2e\x32\x36\ -\x32\x34\x30\x34\x20\x43\x20\x32\x32\x2e\x39\x34\x35\x34\x39\x35\ -\x2c\x31\x33\x2e\x34\x34\x33\x34\x39\x39\x20\x32\x30\x2e\x35\x35\ -\x35\x32\x34\x34\x2c\x31\x32\x2e\x34\x39\x32\x37\x34\x32\x20\x31\ -\x39\x2e\x35\x37\x32\x36\x36\x36\x2c\x31\x32\x2e\x38\x20\x4c\x20\ -\x38\x2e\x33\x30\x35\x35\x33\x39\x36\x2c\x31\x36\x2e\x33\x32\x33\ -\x33\x31\x32\x20\x43\x20\x37\x2e\x30\x35\x33\x36\x33\x36\x35\x2c\ -\x31\x36\x2e\x37\x31\x34\x37\x39\x20\x36\x2e\x37\x33\x38\x31\x31\ -\x32\x35\x2c\x31\x38\x2e\x30\x30\x31\x38\x32\x36\x20\x37\x2e\x36\ -\x33\x37\x33\x37\x31\x31\x2c\x31\x39\x2e\x30\x34\x38\x38\x20\x63\ -\x20\x30\x2c\x30\x20\x2d\x30\x2e\x33\x33\x34\x30\x38\x34\x34\x2c\ -\x31\x2e\x33\x36\x32\x37\x34\x32\x20\x33\x2e\x37\x36\x34\x30\x37\ -\x33\x39\x2c\x33\x2e\x35\x30\x36\x35\x31\x39\x20\x34\x2e\x30\x39\ -\x38\x31\x35\x39\x2c\x32\x2e\x31\x34\x33\x37\x37\x35\x20\x35\x2e\ -\x36\x30\x35\x31\x37\x37\x2c\x31\x2e\x31\x38\x33\x31\x39\x32\x20\ -\x36\x2e\x37\x33\x31\x38\x38\x38\x2c\x30\x2e\x38\x33\x30\x38\x36\ -\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x72\x65\x63\x74\x34\x32\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ -\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x73\x73\x73\ -\x73\x73\x73\x63\x7a\x73\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ -\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x35\x32\x37\x39\x37\ -\x33\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ -\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ -\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x6d\x20\x31\x32\x2e\x38\x2c\x31\x38\x2e\x31\x33\ -\x33\x33\x33\x33\x20\x63\x20\x30\x2c\x38\x20\x30\x2c\x35\x2e\x33\ -\x33\x33\x33\x33\x34\x20\x30\x2c\x35\x2e\x33\x33\x33\x33\x33\x34\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x33\x38\x34\x36\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ -\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x65\x32\x62\x66\x33\x32\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x64\x64\x63\x34\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x30\x2e\x37\x34\x36\x36\x36\x36\x36\x37\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x30\x2e\x36\x35\x35\x36\x37\x37\x38\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x30\x2e\x32\x36\x36\ -\x36\x36\x37\x2c\x31\x32\x2e\x38\x20\x63\x20\x30\x2c\x31\x36\x20\ -\x30\x2c\x31\x30\x2e\x36\x36\x36\x36\x36\x37\x20\x30\x2c\x31\x30\ -\x2e\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x36\x2d\x34\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\x6e\ -\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x38\x34\x32\x29\ -\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ -\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x31\x31\x31\x38\x38\x32\x32\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x72\x65\x63\x74\x34\x32\x35\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x35\x37\x34\x31\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x36\x2e\x35\x36\x34\x33\x34\x39\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\x31\x2e\x32\x37\x36\x32\x30\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x31\x34\ -\x2e\x39\x35\x39\x37\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x32\x2e\x38\x31\x33\x32\x39\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x33\x33\x34\x38\x33\ -\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\ -\x39\x38\x38\x39\x32\x32\x36\x39\x2c\x30\x2e\x31\x34\x38\x34\x33\ -\x31\x34\x39\x2c\x2d\x30\x2e\x32\x35\x32\x38\x31\x34\x36\x38\x2c\ -\x2d\x30\x2e\x39\x36\x37\x35\x31\x34\x37\x32\x2c\x30\x2c\x30\x29\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x65\x63\x65\x63\x65\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x30\x35\x33\x31\x36\x31\x31\ -\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x38\x37\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ -\x22\x36\x2e\x37\x30\x30\x39\x32\x34\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x2e\x31\x30\x38\ -\x37\x34\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x2d\x34\x2e\x38\x31\x37\x39\x39\x33\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x2d\x33\x30\x2e\x39\x37\x31\x36\x35\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x30\x2e\x38\ -\x34\x35\x39\x31\x38\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x30\x2e\x35\x34\x38\x33\x36\x31\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\x38\x37\x37\x30\ -\x39\x36\x34\x36\x2c\x30\x2e\x34\x38\x30\x33\x31\x34\x32\x38\x2c\ -\x2d\x30\x2e\x36\x36\x36\x36\x32\x37\x38\x2c\x2d\x30\x2e\x37\x34\ -\x35\x33\x39\x30\x37\x36\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\ -\x33\x30\x32\x30\x32\x38\x38\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x38\x2e\x35\x37\x38\ -\x36\x30\x38\x33\x2c\x31\x32\x2e\x38\x20\x63\x20\x30\x2c\x38\x20\ -\x30\x2c\x35\x2e\x33\x33\x33\x33\x33\x33\x20\x30\x2c\x35\x2e\x33\ -\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x36\x2d\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ -\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ -\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ -\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x12\x12\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x5f\ -\x70\x72\x6f\x63\x65\x73\x73\x69\x6e\x67\x2e\x73\x76\x67\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\ -\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\ -\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\ -\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ -\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ -\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\ -\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ -\x2d\x33\x37\x2e\x31\x36\x36\x36\x37\x33\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x33\x2e\ -\x33\x35\x36\x32\x36\x33\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\ -\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\ -\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ -\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\ -\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x6f\x63\x6b\x67\x75\x69\x64\x65\ -\x73\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\ -\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ -\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\ -\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\ -\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ -\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ -\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ -\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ -\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ -\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ -\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\ -\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ -\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\ -\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x30\x30\x30\x66\x32\x32\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x66\x32\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x30\x2e\x36\x31\x33\x39\x36\x38\x38\x35\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\ -\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x4d\x20\x2d\x31\x39\x2e\x30\x33\x31\x32\x34\ -\x2c\x32\x32\x2e\x31\x30\x32\x37\x20\x39\x2c\x32\x32\x20\x39\x2e\ -\x36\x35\x35\x30\x30\x34\x35\x2c\x33\x31\x2e\x37\x33\x34\x32\x36\ -\x37\x20\x33\x33\x2e\x31\x33\x34\x33\x33\x36\x2c\x31\x36\x2e\x30\ -\x36\x39\x35\x36\x34\x20\x37\x2e\x35\x35\x38\x39\x39\x31\x38\x2c\ -\x30\x2e\x35\x38\x34\x35\x38\x36\x32\x20\x38\x2e\x32\x31\x33\x39\ -\x39\x36\x35\x2c\x31\x30\x2e\x33\x31\x38\x38\x35\x37\x20\x2d\x31\ -\x39\x2e\x38\x31\x37\x32\x34\x35\x2c\x31\x30\x2e\x34\x32\x31\x35\ -\x36\x32\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x38\x31\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ -\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ -\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x37\x37\x31\x63\x38\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\ -\x32\x30\x32\x35\x33\x32\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x38\ -\x2e\x30\x32\x39\x32\x31\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x2e\x33\x35\x36\x38\x37\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x35\x30\x2e\ -\x38\x38\x32\x32\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x34\x30\x2e\x34\x39\x35\x32\x33\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ -\x34\x33\x37\x34\x34\x35\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x39\x33\x39\x32\x33\x38\ -\x35\x2c\x30\x2e\x34\x34\x38\x32\x31\x38\x38\x37\x2c\x30\x2c\x30\ -\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\ -\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\x2d\x32\x2e\x34\x32\x34\x32\ -\x31\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\ -\x65\x6e\x74\x65\x72\x2d\x79\x3d\x22\x32\x32\x2e\x37\x31\x39\x32\ -\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\ -\x38\x35\x32\x36\x32\x39\x31\x34\x2c\x30\x2e\x35\x32\x32\x35\x31\ -\x36\x35\x35\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x72\x79\x3d\x22\x32\x2e\x35\x38\x33\x30\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\ -\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\ -\x2e\x35\x37\x31\x34\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x34\x30\x2e\x38\x31\x32\x36\x31\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x2e\x36\ -\x36\x34\x37\x35\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x38\x2e\x30\x32\x39\x32\x31\x39\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x32\x31\x34\x34\x37\x38\ -\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ -\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x35\x66\x35\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\ -\x30\x33\x37\x35\x35\x35\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\ -\x2d\x32\x2e\x34\x38\x38\x31\x36\x35\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\x22\ -\x32\x30\x2e\x38\x35\x39\x31\x36\x31\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x31\x31\ -\x32\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ -\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x30\x2e\x39\x37\x39\x32\x36\x36\x34\x36\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\ -\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\ -\x3d\x22\x38\x2e\x30\x32\x39\x32\x31\x39\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x2e\x30\x31\ -\x36\x33\x39\x32\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x33\x33\x2e\x33\x30\x35\x34\x38\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x32\x32\x2e\x39\x31\x35\x32\x30\x35\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\ -\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x32\x2e\x37\x35\x33\x34\x30\x34\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ -\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x30\x39\ -\x38\x39\x37\x37\x32\x2c\x30\x2e\x35\x38\x36\x35\x37\x31\x31\x32\ -\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x2d\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\x2d\x32\x2e\x34\x38\ -\x38\x31\x36\x39\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x2d\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\x22\x31\x38\x2e\x36\x34\ -\x33\x30\x36\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\ -\x30\x2e\x37\x38\x38\x35\x31\x35\x36\x34\x2c\x30\x2e\x36\x31\x35\ -\x30\x31\x34\x37\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x34\x36\x39\x30\x34\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\ -\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ -\x22\x31\x37\x2e\x37\x33\x37\x33\x32\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x3d\x22\x32\x38\x2e\x36\x36\x38\x37\x31\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x37\x2e\x32\x30\x36\x36\x35\x35\x35\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x38\x2e\x30\x32\x39\x32\x31\ -\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ -\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\ -\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ -\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\ -\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x30\x2e\x39\x35\x36\x33\x35\x33\x36\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\ -\x72\x2d\x78\x3d\x22\x2d\x32\x2e\x34\x32\x34\x32\x31\x37\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\ -\x72\x2d\x79\x3d\x22\x31\x36\x2e\x32\x36\x38\x36\x36\x39\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x09\x8b\ -\x00\ -\x00\x24\xa6\x78\x9c\xdd\x59\xdb\x72\xdb\xc8\x11\x7d\xd7\x57\x4c\ -\xe8\x97\xa4\x42\x0c\xe7\x7e\xa1\x29\xed\x83\xb7\xb6\xb2\x55\x9b\ -\x97\xec\x26\x79\x74\x41\x00\x28\x21\x06\x01\x16\x00\xea\xe2\xaf\ -\xcf\x19\x10\x00\x49\x91\xb4\xe5\x98\x71\x9c\xa5\x4a\x45\xa0\x7b\ -\x7a\xa6\xe7\xf4\xe9\xee\x01\xb8\xf8\xe1\x69\x55\x90\x87\xac\x6e\ -\xf2\xaa\xbc\x9e\x70\xca\x26\x24\x2b\x93\x2a\xcd\xcb\xbb\xeb\xc9\ -\xdf\x7f\xfb\x29\x72\x13\xd2\xb4\x71\x99\xc6\x45\x55\x66\xd7\x93\ -\xb2\x9a\xfc\x70\x73\xb5\xf8\x43\x14\x91\x77\x75\x16\xb7\x59\x4a\ -\x1e\xf3\xf6\x9e\xfc\x5c\x7e\x68\x92\x78\x9d\x91\x3f\xde\xb7\xed\ -\x7a\x3e\x9b\x3d\x3e\x3e\xd2\xbc\x17\xd2\xaa\xbe\x9b\xfd\x89\x44\ -\xd1\xcd\xd5\xd5\xa2\x79\xb8\xbb\x22\x84\x60\xdd\xb2\x99\xa7\xc9\ -\xf5\xa4\x37\x58\x6f\xea\xa2\x1b\x98\x26\xb3\xac\xc8\x56\x59\xd9\ -\x36\x33\x4e\xf9\x6c\xb2\x1b\x9e\xec\x86\x27\x61\xf5\xfc\x21\x4b\ -\xaa\xd5\xaa\x2a\x9b\xce\xb2\x6c\xde\xec\x0d\xae\xd3\xe5\x38\x3a\ -\x78\xf3\x28\xbb\x41\xdc\x7b\x3f\x63\x62\x26\x44\x84\x11\x51\xf3\ -\x5c\xb6\xf1\x53\x74\x68\x0a\x1f\x4f\x99\x0a\xc6\xd8\x0c\xba\xdd\ -\xc8\xd7\x8d\x9a\x37\x00\x74\x8d\xff\x71\xf8\x20\xa0\x4d\xb5\xa9\ -\x93\x6c\x09\xbb\x8c\x96\x59\x3b\xfb\xf1\xb7\x1f\x47\x65\xc4\x68\ -\xda\xa6\x7b\xd3\x0c\x78\x1e\xac\x7a\x00\x72\x19\xaf\xb2\x66\x1d\ -\x27\x59\x33\x1b\xe4\x9d\xfd\x63\x9e\xb6\xf7\xd7\x13\xa9\x28\x97\ -\xf8\xe8\x4e\x78\x9f\xe5\x77\xf7\xed\x4b\x69\x9e\x5e\x4f\xe0\xbd\ -\xf0\x6e\x7b\xbf\x47\x0e\xbe\x1d\xd0\x4f\x3c\x1f\x35\x8c\x7a\x41\ -\x39\xa9\xb9\x96\x76\x3b\x66\xd8\xc2\x3c\xad\x92\xe0\x13\xa6\xcc\ -\x56\x79\xbc\x69\xab\x15\xa2\x96\x24\x45\xdc\x34\xf9\x32\x4f\x70\ -\x53\x95\xeb\x62\x73\x97\x97\xef\x7f\x79\xf7\xeb\xfb\xf6\xbe\xce\ -\x9a\xfb\xaa\x48\xdf\x37\x59\xfb\xbe\xad\xaa\x82\x0e\x48\x8e\xcb\ -\x66\x4f\xeb\xaa\x6e\xa3\xa7\x74\x0d\x3c\x8d\x3d\xa9\x7c\x1e\x94\ -\x37\xd0\x2e\xd2\x6c\xd9\x84\x51\xdb\xcd\x85\x3b\xec\xce\x4e\xc8\ -\xac\xd3\x8e\xbe\x06\x47\xd3\x87\x3c\x7b\xdc\x8d\xbd\x8d\x9b\x2d\ -\x80\x84\xac\xe3\x3b\x90\xad\xa8\xea\xeb\xc9\x9b\x65\xf7\xe9\x15\ -\xb7\x55\x9d\x66\xf5\xa0\x32\xdd\xe7\x40\x55\x21\x20\x79\xfb\xbc\ -\x4d\xaf\x7e\xee\xc1\xdf\x30\xeb\xa8\x67\xa7\xf5\xcd\x7d\x9c\x56\ -\x8f\xd7\x13\xf1\x52\xf9\xb1\xaa\x56\x98\x15\x81\xf1\xd6\xb1\x23\ -\x75\xf2\x74\x3d\x89\x84\xa2\xcc\x7a\xee\xd5\x91\x16\x0b\x1a\x2a\ -\x19\xb3\xda\xe8\x23\xe5\xa6\xae\x91\x80\x51\x11\x3f\x67\xd8\x55\ -\xf7\xc5\xfb\x41\x88\xcf\xe3\x5d\x1d\xd0\x69\xeb\x4d\xf6\xd2\x32\ -\x68\xa2\xdb\xdb\xea\xe9\xb4\x1a\x7c\xd8\x84\xd4\x8e\x36\x65\xde\ -\x22\x7d\xd6\x4f\xfb\xb3\x6e\xf2\x34\x6b\x4e\x1b\x36\x65\xbc\x8e\ -\xee\x8a\xea\x36\x2e\x4e\x0f\x78\xcc\x4b\xa0\x14\xf5\x4c\xe7\x72\ -\x0c\xc2\xcb\x11\x03\xed\x2d\x73\x67\x46\xc0\xf7\xa3\x40\xf4\xaa\ -\xe7\xf3\xaa\x55\xfc\x94\xaf\xf2\x8f\x19\x80\xe1\x47\xa8\x84\x9d\ -\xed\xc3\x72\xd3\x0d\x58\x1c\xc0\xb6\xb5\x21\xa4\x7d\x0e\x29\xfe\ -\xf4\x1c\x64\x93\x41\x18\xf0\x0e\x02\xe1\xbd\x1d\x85\x55\x9d\x23\ -\x73\xf6\xdc\x1d\x44\xcf\xfb\xa2\x50\x10\x50\xcf\x9f\x3a\x02\x76\ -\xf4\xb4\x2f\x75\xcf\xfb\xba\x3e\x2f\x66\xc7\x89\xd1\xc9\x57\x59\ -\x1b\xa7\x71\x1b\xef\xb2\x64\x90\xc0\x37\x36\xec\x0c\xb5\x75\xfe\ -\xb7\x1f\x7f\xba\xe9\x17\x5a\x24\xc9\xfc\x9f\x55\xfd\x61\x58\x97\ -\x90\x30\x20\xbe\xad\x36\x88\xc4\xe4\x66\x14\x2f\xd2\x64\x8e\x6a\ -\x88\x2a\x71\x93\xaf\xc0\xfd\x50\x48\xff\x8c\xea\xb7\x98\xed\x14\ -\x07\x83\x03\x58\xbb\x49\xb7\xd3\xa2\x86\x74\x65\xf5\x64\x6f\x49\ -\x93\x55\x1e\x8c\x66\xbf\xb6\x79\x51\xfc\x1c\x16\xe9\x77\xbc\x37\ -\x69\xde\x16\xd9\x4e\xb8\x98\xf5\xde\xf7\x7b\x9b\xed\x6d\x6e\x31\ -\x1b\x76\xdf\xdd\xdd\xed\x50\x39\x48\x9a\x31\xd0\x45\x7c\x9b\x81\ -\xc1\xbf\x04\x25\x39\xe6\x49\x5d\x6d\xd6\xab\x2a\xcd\x7a\xf3\x11\ -\xcd\x2c\x69\xc7\x90\xb5\xcf\x05\xf4\x5d\xc1\x99\xbf\x61\xdd\xe7\ -\x6d\x9a\x37\x6b\x58\xa0\x45\x14\x79\x99\xbd\xad\x50\x9b\x97\x45\ -\xf5\x38\x7f\xc8\x9b\xfc\xb6\xc8\xde\x76\xdf\x79\x81\x9d\x8f\xa2\ -\x25\xb6\x3f\xef\x4b\x59\x77\x13\xf5\x85\x68\xce\xb7\xb7\xf5\xa6\ -\xc8\xe6\x65\x55\x7e\x44\x09\x7b\xdb\xb4\x75\xf5\x21\x1b\xd7\xdb\ -\xde\x6e\xb3\x6d\x3e\x52\x47\x0c\xf2\xe0\x04\x36\x34\xbf\xdd\xb4\ -\xed\xbe\xec\x5f\x55\x5e\xce\x81\x7f\x56\x0f\xd2\xee\xa6\x40\xe2\ -\xb4\x73\x35\xc8\xd2\x18\x25\xaf\xae\xb1\x1d\xac\x9e\xed\x4b\xab\ -\xe5\x12\x8d\x61\x3e\xae\xbf\xf3\x78\x15\xd7\x1f\xb2\x7a\x6b\x90\ -\x95\x31\x36\x18\xdd\xc6\xc9\x87\x00\x68\x99\xce\xe3\x04\x65\x67\ -\x53\xe0\xbc\x72\x90\x50\x01\x56\xe9\xb8\x1e\x85\x43\x9f\xb4\x34\ -\x34\x44\x29\x46\xc5\xd8\x2b\x8f\x34\x07\xd9\x87\x3c\x8a\x24\xdd\ -\x29\x6b\x08\x24\x95\x68\x8c\xc6\xbb\x91\x66\x8b\x75\xdc\xde\xbf\ -\x08\xe7\x36\x1a\x3d\xba\x2f\xa2\xb1\x8f\x3d\x4f\xce\x61\xbf\x7e\ -\xfa\x72\xf4\xc7\x35\x46\x8f\x81\xca\x5f\x89\xe2\xd4\x28\xc3\xd5\ -\x94\x0b\xea\x0c\xb7\x9a\x93\x77\x04\x5b\x57\x96\x33\x6f\xa7\xdc\ -\xa1\xe3\x08\x29\x14\x11\x96\x5a\xe5\x8d\x75\x53\xae\xa8\x37\x42\ -\x0b\x4d\x04\xdf\x42\x24\x3b\x6b\xc2\x2d\x14\xd2\x07\x33\xcc\x6a\ -\x94\xe2\x9e\x70\x34\x1e\xe3\xb4\xb6\x53\x43\x8d\x74\xcc\x4a\x12\ -\xc6\x0a\xc9\x9d\x98\x06\x9d\x17\xcc\x5a\xe2\x28\x74\x4e\x7a\x0d\ -\x19\x93\x58\x90\x29\xa2\xa8\x73\x5e\x79\xc6\xa7\x5c\x53\xc6\x95\ -\x35\x9a\x74\x18\x58\xef\x7c\x58\xd1\x0a\x63\x8d\x23\x91\xa0\xda\ -\x2b\xc1\x3c\x06\x32\xaa\xa5\xd6\x4a\x92\x88\x53\xcf\x95\x13\x4c\ -\x4e\x05\xf5\x52\xf8\xe0\x0b\xe5\x5c\x32\xcd\xec\x14\xe7\x2d\x78\ -\x02\xbd\x23\x9a\x6a\xe1\x8c\xd7\x7a\x1a\x29\xaa\xb4\x81\xfb\x70\ -\x51\xc2\x7f\x66\x9c\x9a\x62\x1e\x2e\x95\x53\x1a\xe6\x9e\x5a\xeb\ -\x35\x7c\x0c\xe6\x0c\x43\x1d\x97\x44\x4a\xaa\x8d\xe5\x8a\x63\x1d\ -\x2d\x9d\xb6\xd2\x76\x32\xe5\xe0\xdc\x14\x14\xb1\xd6\x00\x21\x4f\ -\xa4\xa3\xaa\x43\x1a\xc6\x01\x68\xa1\x25\x49\x88\xa4\x90\xe1\x0f\ -\xd6\x96\x0b\x27\x1c\xc0\xd0\x70\x9d\x3b\xa9\xa7\x1e\xf0\x5a\xf8\ -\x01\x19\xa8\xd6\x6d\x19\x47\x5a\xef\x94\x25\x1f\x0f\xd8\x1d\x58\ -\x26\x61\x11\xed\xf8\xb9\x6b\xf0\x55\x09\x8e\xb4\x55\x1d\xa1\xd5\ -\x3f\xc4\xed\xa6\xce\x0e\x5a\xc6\x58\xfa\x51\x8b\x42\xb5\x44\x57\ -\x8e\xc3\xa7\x69\xe2\x57\xd0\x58\xeb\x54\x7d\x8a\xc6\x4a\x7e\x1b\ -\x1a\x23\xf0\xd6\x4b\x44\x01\x8c\x15\xc6\x49\x6e\x03\x8f\x0d\x55\ -\x4c\xe1\x04\x38\x15\x88\x88\x07\x9d\x88\x00\x0d\x03\xca\x7e\x2a\ -\x58\x60\x1f\x83\x88\xc1\xc2\x68\xa9\x3a\x5b\x66\xb4\x51\x81\xb6\ -\xce\x5b\x0e\x4b\x90\x9a\x59\x86\x23\x32\x01\x0b\x25\x43\xe0\x5c\ -\x08\x04\x43\x2c\x25\x28\xcf\x29\x0e\x55\x80\x3e\x50\xde\x5a\x6d\ -\x41\x1e\xd4\x0d\x8e\x65\x59\x27\x53\xd2\x39\xd8\x4a\x50\x5e\x18\ -\x1f\xe2\xcc\xa8\x12\x38\x84\x13\xd6\x25\x57\x97\x3e\x24\x0a\x7c\ -\xe3\x8c\xb9\x8e\xeb\x20\x33\x92\x2f\xf0\x1a\x0c\x33\x38\xd0\x4d\ -\x91\x1e\xd2\x2b\x07\x6a\x81\x3c\x0a\xc9\xc7\xad\x9c\xea\x90\x7c\ -\x0a\x03\x90\x29\x20\x91\xf3\xc6\x80\x5b\xc8\x18\xf0\x51\xdb\x90\ -\x66\xda\x63\x75\x3d\x55\x54\x58\x6e\x43\x02\xb8\x40\x32\xeb\x0d\ -\x6c\x11\x35\x87\x5d\x83\x82\x20\xbb\x75\x56\xab\xc0\x41\xad\x14\ -\xc6\x9a\x4e\x06\x70\xe0\x4f\xc7\x60\x66\xa4\x76\xc1\x1c\x71\xd3\ -\x4a\x77\x14\xb6\x4a\x1f\xb3\xd7\x0d\xe4\x35\x23\x79\xf5\xc0\x5d\ -\xd7\x55\x3c\x7d\x86\xba\xdf\x9a\xb8\x9f\xaf\xbf\xe7\x7b\xdf\xc5\ -\x88\xbb\x22\x82\x76\x73\x6a\x40\xa8\xa9\x41\x34\x04\x15\x5c\x3b\ -\x30\x6e\x1a\xe2\x6f\x1d\x38\x48\x4c\xb8\x80\xd0\x86\x68\x18\xc1\ -\x51\x34\x09\x4a\xdd\xd6\x1b\x15\x84\x02\xb8\x1b\x6f\x98\xf2\x88\ -\x8d\xd1\x88\x05\x27\x9e\x0a\xcd\x42\xf9\xc4\x85\x47\x1e\x82\xd5\ -\xa8\xdc\x81\x6f\x81\x50\x7a\xcb\x3c\x48\x9c\x44\x39\x0e\x35\x2d\ -\x4c\x86\x4a\x8f\x08\x5a\x54\x6f\x2c\x86\xa0\x29\x14\x5b\x33\x2e\ -\x86\x82\x36\x5e\x76\x5e\x09\x38\x8b\xe0\x87\xfa\xc9\x82\x44\x80\ -\x9a\x21\x09\xa1\xf3\x8c\x49\x4f\x7a\xd0\xec\x54\x60\x2e\x82\x12\ -\x2b\xc0\x49\x23\xc0\x49\xcd\x64\xd8\x5b\x04\xa7\xb4\x0e\x9d\x01\ -\x32\x13\x12\x32\x14\x6f\xd7\x6f\x6e\xca\x90\x06\x20\x97\x06\xab\ -\x85\x00\x24\x9a\x3a\xb4\x07\xdf\x99\x29\xae\xad\x92\xc1\x0e\x15\ -\xdf\xea\x7d\x3b\x15\x0c\x65\x40\xc2\x4a\xa4\x76\x80\xc8\xa3\xaf\ -\x00\x37\x5c\xa1\xcd\x04\x80\x65\xb7\x41\xcd\xe0\x32\x47\x36\x46\ -\x21\xd3\x3b\xe3\xd3\x0c\x95\x91\xfb\xd6\x1c\x15\x5c\x29\xeb\x3e\ -\xc5\x51\x9c\xe7\xfe\xfb\x1c\x45\x05\x18\xda\x7c\x4f\x20\xb9\x23\ -\x2a\x17\x9f\x24\x2a\xdf\x71\xc7\x7e\x9a\xa8\xc7\x34\x95\x03\x4d\ -\x55\xa8\xe5\x0a\x65\xd5\x72\x24\x0a\xfa\xb0\xf6\x5e\xa0\xc9\xcb\ -\x50\x91\xd1\x0f\xf9\x14\x87\x13\x67\x1c\x43\xe5\x56\x0c\x13\x19\ -\xa2\x7a\x76\x76\x07\x1b\xb1\xa5\xa7\xea\xf9\x39\x45\x13\xd0\x5b\ -\x7a\xaa\x91\x9f\x52\x84\x76\x61\xad\x70\x4c\x4d\x71\xd5\xd3\x33\ -\x0c\x85\x93\x26\x88\x7a\x76\x06\x26\x87\xe1\xc8\x18\x19\x78\xc9\ -\x61\x60\x28\x47\xbb\xe7\xe8\x3a\x38\x03\x39\x25\xf0\xa0\xdd\x4d\ -\x12\x78\xa9\xf6\x00\x84\x59\xb2\x23\xa6\xf4\x27\x88\xc9\xd5\x97\ -\x12\xf3\x5b\xd3\xb2\x7f\x90\xf8\x74\xad\xf4\x08\xb2\xd0\xee\x82\ -\x3d\x7e\xe4\xf6\xb6\x96\xbc\xeb\xfa\x4a\x77\x79\x74\x71\x0c\x13\ -\x02\x1b\xb1\x48\xbc\x1a\xaa\xef\x14\x85\xd5\x1e\x0a\x3b\x5a\x84\ -\x64\xe4\x3d\xc3\xd8\xb9\xeb\x73\x98\xf0\xdf\x15\x26\xbc\x4f\xb5\ -\xaf\xc3\xe4\xf5\x29\xf5\x9d\x62\xb2\x9f\x2d\x66\x4c\x16\xd3\xa7\ -\xc8\xde\xf7\x39\x04\xd4\xff\x3b\x02\x07\xac\x18\xae\xbe\x8e\x15\ -\xfe\xdb\x62\x32\x78\xa4\xd4\x97\x43\xf2\xfa\x77\x2d\x67\xe8\x13\ -\xda\xce\x88\xda\x3f\xc2\x13\x2d\x3b\x7c\x9d\x38\x60\x23\x10\xb8\ -\x8b\x34\xa0\x24\xf9\x3c\x6c\x7b\x8e\x7f\x87\x98\x0d\xbf\xae\xa0\ -\xcd\x0f\x70\x91\xbf\x90\x63\x3a\x01\xb2\xcb\x1c\x25\x5f\x03\xd9\ -\x2b\x99\x86\xe7\x5a\x1c\xa7\xf5\x05\xd3\x4f\xf7\xef\x86\x80\xc6\ -\x80\x0b\xd2\x8f\x85\xd7\x2c\x62\xfb\x00\x71\xe6\xfa\xc4\x19\x47\ -\xbd\xfe\xbd\xc6\x45\x38\x74\x79\x34\xc2\xf3\xef\x45\x80\x88\x5e\ -\x9f\x6d\xdf\x29\x14\xc2\x5d\x0a\x8a\x0b\x1e\xe7\xfe\x47\x50\x8c\ -\x2f\x50\x2f\x82\x87\xfd\x3d\x35\xed\xf0\xc2\xf9\xeb\x8f\x72\x5f\ -\x8e\xc8\x89\x1f\x60\xfa\x57\x9d\xcb\xf0\x77\xf8\x34\x8e\x67\x58\ -\x65\x99\x76\x4e\x8c\x48\xa9\x65\x6a\x96\xf2\x25\x79\x84\xb2\x9a\ -\x4b\x66\xfe\xf3\x66\xc3\xf0\x60\xe9\x84\xd4\xc2\x1f\x6c\x35\xb8\ -\x8b\x86\xb2\x13\x0e\x3f\x6c\xf4\x2d\x68\x47\x95\xf1\x87\x8d\x23\ -\xcd\xc9\xdf\x0b\x9f\x4f\x09\x6b\x0c\xd5\x78\x34\xc5\x43\xb2\xdb\ -\x45\x6e\xfb\xdb\x87\xc7\xf3\x39\xb3\xfe\x15\xdc\xf2\xdd\x67\x44\ -\xec\x80\x6a\x3d\x62\x38\x9e\xaa\xf0\x8e\x9d\xa9\x4b\x92\x6b\x78\ -\x62\x9a\xda\xe0\x2d\x53\x6a\x9b\x6e\xdc\x53\xde\xb9\x64\xcf\xdf\ -\x9c\xe0\x97\xf1\x97\x2c\xc6\x6f\x1c\x0b\x7f\x9f\x41\x45\x3b\xcf\ -\xbc\xe6\x97\x7c\xbd\x63\xa9\x3a\xf1\x44\x89\x9d\x8b\x2e\xe7\x43\ -\x9e\x9d\xbd\x39\x55\x87\xbe\xb4\x0a\x2d\x66\x77\x37\x57\x8b\xf0\ -\xf3\xef\xcd\xd5\xbf\x01\x5a\x78\x2f\x26\ -\x00\x00\x14\x49\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x3c\x00\x00\x00\x3c\x08\x06\x00\x00\x00\x3a\xfc\xd9\x72\ -\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ -\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\ -\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ -\xdd\x08\x11\x15\x26\x08\x6d\x49\xb4\xe7\x00\x00\x00\x19\x74\x45\ -\x58\x74\x43\x6f\x6d\x6d\x65\x6e\x74\x00\x43\x72\x65\x61\x74\x65\ -\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x57\x81\x0e\x17\x00\ -\x00\x13\xb1\x49\x44\x41\x54\x68\xde\xed\x9b\x69\xac\x5d\xd5\x75\ -\xc7\x7f\x6b\x9f\xe1\x0e\xef\x79\x7c\x1e\x62\x0c\xc6\x53\x08\x83\ -\x6d\x0c\x24\x81\xb4\x0c\xcd\xd0\xd0\x14\xda\x8c\x2d\x49\x54\x94\ -\x34\x52\xa4\x56\x8d\x54\x94\xa0\x14\x45\x95\x9a\x2f\x19\xd4\x08\ -\x21\x94\x34\x49\x45\x5b\x29\x80\x4a\x49\x49\x43\xa2\x26\xa4\x19\ -\x4a\x08\x04\xcc\x10\x1c\x08\x60\x0c\xd8\xc6\xf6\xf3\xf3\xb3\xdf\ -\x3c\xdc\x7b\xcf\xb0\xf7\x5e\xfd\x70\xce\xbd\xef\xde\xf7\x3c\x12\ -\x42\x3f\x24\x47\xba\xda\xf7\xbc\x7b\xd6\xde\x67\xed\x35\xfe\xd7\ -\x5e\x0f\x7e\xcb\x2e\xb9\xe4\x9e\x45\xd5\xd7\x64\x25\x9d\xfb\x28\ -\x80\x2f\x46\xe9\xba\x6f\x3f\xa7\x5a\xfe\xde\xa6\xa1\x9b\x56\x41\ -\xa5\xeb\x79\xed\x79\xae\x4d\xdb\x5e\xa7\xb6\x31\x48\x9f\xb8\x76\ -\xaa\x3d\x0b\x21\x70\xcb\xff\xfb\xb6\x6b\xd7\x57\xed\xbd\x7f\x45\ -\x9b\x3a\x77\xd5\xa7\x7f\x61\xff\x11\x78\xb6\x9b\xe1\xbf\x7a\xad\ -\x18\xd2\xf9\x0c\x6a\xef\xfb\xa9\x6f\xff\x28\xc7\xa0\x57\x14\x29\ -\x99\xd2\x79\xf4\x82\xaa\x22\xf3\x18\x16\x81\x7c\xd4\xaf\x5f\xfb\ -\xa1\xca\x7b\x0f\xdd\x95\x8e\xb7\x19\x7e\x6d\x98\xd5\x5e\xb5\xee\ -\x5c\x7e\xde\xbd\xca\x31\x9e\x53\x54\xa5\x98\xa4\x33\x76\x99\x46\ -\xb9\x01\x3a\x6f\x3d\x11\x50\xcf\x5a\x0c\x51\xb7\x84\x5f\x53\xfb\ -\x5d\xb0\x01\x2c\xdc\x10\x9d\x67\xef\xe2\xa5\x6b\x1e\x9d\x23\xf3\ -\x0b\x6d\x7c\xc1\xe6\x82\xeb\x5e\xe9\xb4\x18\x5e\xa9\x55\xd6\x50\ -\x27\x44\x30\x08\x1e\xed\x8c\x85\x62\x49\xa9\x78\xe5\xa8\x82\xd7\ -\xb9\x7b\x04\x0c\x82\xd3\x92\x4e\x8a\xbf\x89\x2f\xe6\xe8\xd0\x99\ -\x39\x69\xab\x2a\x6a\xc0\x28\x9d\xf5\x9c\x2f\xd6\x33\x08\xea\x0b\ -\x13\xf0\xe5\x7a\x28\xe4\xea\xd9\x93\xcd\x30\xab\xf9\x02\x1e\x4e\ -\x8b\xe1\x4b\x59\xcd\xd5\x66\x29\x15\x00\xad\x83\xb4\x40\xab\xc5\ -\x88\x01\x8d\x41\x72\xd0\x10\x24\x29\x7e\xc3\x82\x46\x20\x59\xa9\ -\x7f\x35\x20\x01\x6a\x40\x13\x6d\xd3\x91\x97\xaf\x93\x00\x95\xf2\ -\xd9\xa0\xa0\xc7\x95\xcf\xcf\xd1\x15\x76\x5e\x05\xd2\x92\xbe\x05\ -\xc4\x18\x84\x69\x6f\xf9\x97\xc9\x7d\xec\xcc\x27\x5e\x01\xc3\x5d\ -\x3e\xa4\x26\x86\xf3\x09\xa8\x1a\x43\xd3\x47\xd4\x4d\x4e\xd3\xc7\ -\xd4\x8d\x45\x55\x48\x09\x89\x44\x71\x12\x12\x4b\x4c\xa6\x21\x01\ -\x90\x6b\x48\x45\x3c\x22\xda\x79\xbe\xa0\x8f\x50\x85\x44\x23\x2a\ -\xe2\xc9\x29\x47\x0d\x11\x3c\x8e\x80\x08\x30\xd2\x5e\x6f\x8e\x0e\ -\xa0\xe5\x23\xaa\x62\x49\x35\xa2\x6a\x1c\x56\x43\x14\x98\x71\x42\ -\x9f\x84\xc7\xf4\xf6\x27\x67\x58\xe0\xe3\x9c\xc3\x66\xea\x2c\xa7\ -\x1f\xab\x4a\xe2\x21\xd3\x0a\xc6\xfb\x72\x74\x78\x02\x72\x8d\x70\ -\x84\x38\x02\x14\x21\xd5\x0a\x01\xc5\x8b\x78\x02\x8c\xba\x05\x74\ -\x8a\x21\xd3\x0a\x8a\xc1\x6a\x04\x06\x32\x8d\x31\x28\x0e\x83\xc3\ -\x12\x74\xe8\xb4\x43\xdf\x9e\x1f\x8a\xe7\x45\x95\x5c\x23\x40\x48\ -\xb0\x18\x91\x63\x85\xa9\x53\x53\xe9\xcd\xd4\xb9\xd4\x54\xc9\x34\ -\xa0\x22\x09\x06\x8f\x25\x26\x92\x0c\x4b\x48\x2c\x19\x8e\xa0\x98\ -\x50\x72\x8c\x86\x44\x9a\xd1\x72\x01\x5e\x1d\x56\x05\x63\x2c\x91\ -\xc9\x09\x25\x22\x92\x8c\x96\x8b\x09\x4c\x86\x18\x83\xc7\x60\x34\ -\x23\x77\x06\xe3\x1c\x16\x47\x64\x1c\xa1\x31\x44\x62\x09\xb0\xe4\ -\x44\xe5\x7a\xc5\x08\x52\x68\x80\x64\x78\x0c\x11\x19\x94\x0e\xdc\ -\xe0\xf0\xea\x4f\x4f\xc2\x2b\xb5\xca\xa5\xac\xa6\x26\x86\xe5\xf4\ -\x93\x69\x40\xae\x31\x82\x22\x14\xbb\x19\x50\x21\xd7\x98\x14\x87\ -\xc7\x90\x6b\x84\xc7\x90\xba\x80\xe7\x26\xfa\xf8\xde\xbe\x35\x0c\ -\xcd\xc6\x28\xc2\x9a\xbe\x84\x2b\xd6\x8e\xb3\x65\x75\x4a\x10\x3a\ -\xee\xdc\x75\x26\x97\xac\x1c\x63\xdb\xaa\x19\x12\x1f\xf3\xb3\x03\ -\x2b\xf8\xd9\xe0\x00\x2d\x2b\xf4\xc5\x9e\x6d\x2b\x66\x79\xd7\xc6\ -\x11\xfa\xa2\x80\x80\x90\x5c\x63\x0c\xbe\xb3\xae\x22\x0b\xfe\x96\ -\x13\xa1\x08\x5e\x2d\x81\x9a\x63\xf2\x75\x5c\x86\xd7\x50\xe7\x6a\ -\xb3\x94\xf3\x09\xb0\xaa\x54\x24\x41\x50\x2a\x92\x62\x4a\xfb\xaa\ -\x48\x82\x23\xa0\x2a\x2d\x1c\x01\x82\x12\x92\xf1\xe8\xf0\x4a\xbe\ -\xf0\xd8\x66\xde\x73\xd9\x19\x7c\xe0\x8d\x1b\x31\x62\xd8\xb9\xeb\ -\x65\x9e\x1c\x7c\x99\x95\xfd\x7b\x59\xb9\x74\x9c\xff\x3d\xb4\x96\ -\x15\x4b\xfb\xb8\xd4\xec\xe4\xbe\x7d\xab\xf8\xa7\x9d\xeb\xf9\xcc\ -\x75\x17\xb0\x69\xed\x52\xf6\x0f\x4f\xf0\xfc\x4b\xfb\x68\xda\x49\ -\x96\xc7\xb3\x84\x58\x3c\x86\xaa\xb4\xf0\x18\x2a\x92\x94\xdb\x2e\ -\x54\x24\x05\x28\xdf\xcf\x03\x42\x0b\x8b\xa3\x4b\xc2\x72\x0a\x0c\ -\x5b\x3c\x11\x50\x35\x86\xc4\x83\xc1\x23\x68\x31\x8a\x62\xd4\x63\ -\xca\x51\x84\xe2\x1e\x8f\xf5\xf0\xe5\xa7\xce\xe1\xe3\xef\xbf\x82\ -\xeb\xce\x3d\x82\x3f\xfc\x1d\xac\x1a\xce\xbb\xe8\x0d\x98\xcb\xb7\ -\x33\xbb\x77\x1c\xd3\x38\x4c\x5c\xeb\x27\xec\x8b\x30\x38\x1e\x38\ -\xba\x89\x6b\xaf\xdc\xc2\xdb\x56\x3f\x47\x34\xb5\x87\x0d\x2b\xce\ -\xe6\xed\x1b\x37\x90\xee\xaf\x60\x5a\xc5\xfc\xa2\xda\x59\xcf\x88\ -\x16\x99\x55\xfb\x7d\x98\x7b\x87\x82\x3b\xc5\xfb\xb9\x84\xec\x84\ -\x12\xbe\x52\x57\xf1\x69\xb9\x10\xc4\x22\x6a\x68\xfa\x9c\x4c\x2b\ -\x58\xe2\xd2\x29\x05\x18\xf5\xb4\xb4\x86\x7a\x21\xd5\x2a\x78\x4a\ -\xa7\x15\x32\xd4\xa8\xb0\x7f\x42\xb8\x66\xed\x0b\x4c\x3e\xfb\x43\ -\x04\x47\xc3\xc6\xc8\xd1\x41\x22\xb1\xa8\xa9\xe0\x83\x3e\x50\xf0\ -\x5e\x68\x68\x1f\xdb\xce\xdb\xc4\x7d\x8f\xed\x66\x53\xe3\x45\xd6\ -\xd4\x9b\x2c\xab\x3f\xc3\x9a\xfe\x5f\xe0\x35\x20\x90\x3e\x02\x75\ -\x24\xe5\x7a\x89\x56\xd1\x32\x11\x49\xb5\x5a\x9a\x52\x8c\xfa\xc2\ -\xe9\x29\x14\x3e\x40\x82\x53\xb3\xe1\x1c\x47\x4d\x9a\x04\x52\x78\ -\xd0\x58\x32\x8c\xf7\x44\x92\x11\x50\x29\x9c\x96\x28\xea\x85\x3e\ -\xd3\x00\x0f\x75\xd3\xc4\xa9\x21\x20\x66\xc6\xaf\xa2\x12\x87\xf4\ -\x0f\x7f\x87\xd4\x40\x2b\x83\x1d\x87\x06\xd8\x3b\x59\xa3\x6a\x2c\ -\x57\xad\x9b\x64\xeb\xf2\x46\x91\x38\x88\x23\xd6\x26\x7f\xbe\x35\ -\x61\xb2\xb5\x9e\x7b\x77\xa5\xd4\xc3\x94\x8a\x64\x5c\xbe\xe6\x30\ -\x7f\xb4\x61\x8c\xaa\xc9\x09\xc5\x81\x87\x9a\x34\x01\xe8\x33\x8d\ -\x22\x75\x44\xa9\x4a\x8b\x14\x47\xcd\xb4\xc8\x4b\x86\x13\xef\xc8\ -\xd5\x9d\x9a\x97\x8e\x08\x68\x69\x9d\x00\x47\x23\x0b\x18\x9a\x59\ -\xc2\xa6\xe5\x16\x5b\x3a\x8e\xb6\x84\xdb\x92\x4d\xb5\x8a\x78\xed\ -\x38\xad\xbe\xc5\x03\xe4\xd6\x31\x9d\x06\x78\x89\xc9\xc2\x2a\xcb\ -\xcf\xbc\x80\x3d\x52\xe3\xa7\x2f\x4c\xb3\x7e\xcd\x38\x1b\x7d\xf1\ -\xe2\x5e\x03\x9a\xf4\xc3\xd0\xfd\xdc\x78\xf5\x9f\x71\xf0\xaa\xab\ -\x39\x70\x78\x9c\x27\x5f\x1c\xe1\x8e\x27\x17\xd3\x57\xd9\xcb\xe5\ -\x67\x8e\xcd\x49\x18\xe9\xac\xd7\x0e\x4b\x73\x12\x16\x2c\x45\x5c\ -\xb7\x58\xa2\x32\x6a\x9c\x82\x84\x2d\x75\xd3\x24\xc0\x72\xe7\xee\ -\xb3\x79\xc7\xba\x23\x38\xeb\xcb\x50\xa0\x40\x82\x31\x8a\x7a\x83\ -\xd3\x14\xa7\x82\x37\x29\xd5\xd0\x13\x4a\x85\x8d\xf5\xa3\xac\x5a\ -\x76\x1e\x0f\x1c\x58\xc2\x3b\x37\x8c\xb1\x28\xc8\xb8\x7c\xf5\x38\ -\xaf\x5f\x77\x01\x43\xb3\x55\xe2\x9a\x2d\x34\x03\xc5\x88\xa3\x2e\ -\x4d\x9c\xcd\xe1\xe9\x5b\x58\xd3\xb7\x81\x0d\x8b\x56\xf1\x96\x3f\ -\xd8\xc6\x81\xf1\x33\xd9\xdd\xb2\xbc\x53\x0e\x10\x88\xef\x68\x92\ -\x78\xa5\x6e\x8a\x0d\x13\xef\xa9\x49\x8b\x94\x2a\x55\x93\x90\x6b\ -\x08\x02\x69\xb7\x84\x4f\xc6\xb0\x20\x38\x35\x20\x01\xc3\x8d\x2a\ -\xcd\x2c\xe4\xae\xdd\x67\xb0\x7d\xe5\x24\x0d\x5b\x01\x6f\xa9\x04\ -\x0e\x27\x31\xcf\x1c\xad\x71\xf6\xd2\x8c\x46\x0a\x1f\x3e\x7f\x88\ -\x7a\x6c\x08\xd3\x61\x3e\xf1\xbe\xeb\xf9\xea\x37\x67\x98\xce\xf6\ -\x71\xc9\xea\x09\xcc\xc4\xf3\x3c\x72\x74\x96\xc1\x23\xeb\x30\x1b\ -\xc0\xa9\x21\xb3\x1e\xe7\xc1\x18\xc3\x5d\xbb\x5e\xc7\x40\xa5\xc5\ -\xfa\xa5\x53\xf4\x99\x61\x76\x1c\x39\xcc\xde\x43\x17\x70\xcd\x3b\ -\xd6\xe1\x09\x10\x2d\x34\xc8\xa9\xc1\x13\xe0\xd5\x14\xe1\x87\x00\ -\x57\x7e\x54\x85\xa6\x87\x59\xe7\x19\x77\x96\xcc\xfb\x36\xa8\xea\ -\x01\x9b\x0b\x18\x0e\x28\xe2\xad\xc7\xb1\xb2\xcf\x72\xee\xca\x84\ -\x47\x8e\x5a\x2e\x3f\x73\x86\xef\xef\xab\xb3\x61\x69\x8b\xbd\x93\ -\x55\x36\x2f\xcf\x69\x64\xc2\x95\x67\x37\x78\xf8\x60\x9d\x5c\x63\ -\x72\x35\xa8\xcb\xb9\x62\xe9\x93\xd4\xae\x7f\x07\x0f\x3c\xf4\x10\ -\x4f\x3c\x3b\x89\x02\x03\xcb\x97\xf3\xb1\x6b\x2e\x62\x6b\x65\x07\ -\xd9\x64\xcc\x55\xdb\xd7\x71\xd6\xc0\x41\x32\x1f\xb2\xe8\x8c\x0b\ -\x79\xfc\xe5\x19\x7e\x72\xb8\x89\xa8\xa3\x6f\xf1\x32\x3e\x76\xed\ -\xc5\xbc\x69\xd1\x0e\xb2\x91\x98\x80\x00\xab\x11\x19\x15\x72\x0d\ -\xc9\x28\x62\x7b\xf1\x37\x8f\xd5\x88\x94\x98\x3d\x99\xe5\xbf\xa7\ -\x26\x78\x31\x19\x67\x5f\x3a\xd3\x9b\x2e\x1e\x8f\x61\x8f\x27\x92\ -\x9c\x00\xc7\xb6\x15\x53\x84\xe4\x6c\x59\x31\x43\x2d\x4c\x79\xfd\ -\xb2\x59\x32\xeb\xd8\xbe\x62\x92\x5a\x25\x24\x1c\x68\x51\x0b\x95\ -\xf3\x97\x4f\xd1\x17\xa6\x04\x12\x12\x4a\x8e\x0c\xff\x94\xb7\xad\ -\x99\x62\xdb\xbb\x2f\xa6\xe5\x62\x54\x85\x7a\xd0\x60\x49\x6b\x07\ -\xe9\xc8\x33\x44\x92\xf3\x91\x37\x7b\xaa\x13\x87\x09\x27\x32\xfe\ -\xf0\x1c\xc7\xe5\xdb\xb7\x92\xfa\x1a\xa6\xcc\xb2\x96\xa4\x3b\x71\ -\x87\x1e\x23\x94\x7c\x5e\xa6\x55\xac\x51\x64\x5a\x21\x91\x64\xe4\ -\x0a\x42\xca\x84\x6d\xf2\x78\xe3\x30\x07\xf3\x19\x50\x10\xd1\x53\ -\x53\x69\x4b\x88\x22\x5c\xb2\xa6\x81\x97\x90\x0b\x57\x37\x11\x42\ -\xce\x5b\x91\x50\x91\x14\x11\x4f\xcb\xd7\x59\xb7\xa8\x45\xcb\xd7\ -\xd8\xb2\xaa\x89\xd7\x80\xbc\x54\x3f\xa7\x9e\x6c\xe8\x61\xaa\xf1\ -\x1e\xfa\xc3\x0a\x8e\x80\xc0\xcd\xe0\xb3\x09\xac\xab\xe0\x4c\x88\ -\xd9\xff\x1d\x8c\x4e\xe1\x34\xc4\x1f\xd9\xc1\xe2\x78\x27\x36\xa8\ -\x53\x91\x8c\xcc\x7a\x6c\x3a\x89\x57\x2d\x5e\x51\x0a\x07\xe7\x08\ -\x71\x1a\xe0\x24\x44\x15\x9c\x06\xa4\x04\xbc\x94\xe6\x3c\x38\x3b\ -\xc2\xa8\xcb\x99\x76\x49\x17\x96\x96\x93\x33\xec\x70\x54\x25\x21\ -\x28\xd3\xc5\x48\x72\x14\x21\x26\x2b\x33\xad\x04\x11\x70\x12\x52\ -\x91\x14\x27\x86\x8a\x64\x05\x9a\x55\x4f\x2c\x79\x27\xbf\x26\x3b\ -\x42\x98\x59\x32\x8d\xa8\x48\x86\x88\xe2\x84\x82\xce\x4e\x50\x31\ -\x4d\x54\x0a\x24\x58\x49\x47\x11\x62\x22\x49\x41\xa3\x22\x89\x91\ -\x80\x88\x1c\x23\x8a\x93\x80\x8a\x49\x71\x3e\x28\xb2\x2b\x01\xf5\ -\x86\xaa\xa4\xec\xcd\x66\xf9\xc6\xc4\xcb\xf3\x8a\x07\x65\xc9\xa3\ -\xd0\x67\x39\xa1\x0d\x27\x5a\x25\xc0\x75\xd2\xb7\xb6\xfb\xcf\x34\ -\x2e\xb5\xc0\x93\x69\xdc\x41\x31\x81\xba\x52\xc2\x51\x29\x89\xa0\ -\x4c\x0c\x2a\x58\xc2\x42\x63\xd4\x60\x68\x3f\xdf\xa6\xb7\xa8\x1a\ -\x52\x2d\x73\x63\x22\x04\x2d\xd0\x0f\xa5\xa3\x22\x24\xc4\x76\xa1\ -\xac\x62\xdd\x5c\x95\x9d\xad\x9c\x23\xf9\x0c\xbb\x92\x66\x2f\xb3\ -\x85\x3e\xa3\x99\x82\x47\x4e\x98\x5a\x2a\x4a\x88\xed\x48\xb8\xfd\ -\x3d\x10\x4b\x40\x40\x20\x16\x83\x12\x88\x23\xc0\x12\x88\x23\xc4\ -\xe2\x44\xf1\x6a\x08\xc4\x82\x42\x48\x11\xbb\x03\x29\xb0\x72\x41\ -\xef\xe6\xd1\x39\xbc\x78\x82\xf2\x39\xaf\xc5\x7a\x8e\xa0\x93\xaf\ -\x87\x25\x5a\x32\xe2\xe6\xe6\xc0\xe2\x54\x79\x60\x76\x82\xfb\x67\ -\x0e\x90\xf6\x24\x19\x85\xdd\xfa\x5c\xc9\xc7\x3c\x6a\xf5\x16\x84\ -\xc9\xe3\x32\x6c\xda\xa8\x47\x4c\x47\x4d\xad\x86\x08\x8a\xd5\x10\ -\x43\x81\x50\xac\x86\xe4\x44\xe5\x18\xe3\xdb\x78\x16\x70\x04\x64\ -\x1a\x95\x92\x2d\xbc\x69\x21\xb1\x60\x1e\x5d\x54\xd2\x85\x9d\x39\ -\x33\x0a\x3a\x41\xf1\x1a\x94\xe1\xc7\xe0\xca\x75\x12\x1f\x30\xe1\ -\x95\x54\x95\xc1\x7c\x9a\x71\x97\xcc\xcb\x99\xa5\xcd\xac\xda\x59\ -\xfd\xa4\x4b\xf4\xdf\x86\xee\x4a\x53\x80\x4b\xee\x59\x24\xc7\xb4\ -\xe1\x48\xb2\x22\xb5\xd4\xc2\x3e\x7d\x89\x3b\x15\x21\x2e\xd1\x92\ -\x25\x2a\x71\x70\x48\x2c\xe9\x02\x3c\x5c\x91\x0c\x2d\x25\x2e\x68\ -\x99\x9a\xba\x2e\xfc\x1c\x11\x4b\x8a\xa7\xd8\xd8\x22\xb1\x81\x8a\ -\x64\xa0\x82\x88\xc7\x77\x49\xd8\x96\xeb\x8c\x58\xcb\x67\x0e\xff\ -\x0a\x03\x1c\xce\xd2\x52\x8d\xcb\x6a\x26\x8a\xcf\x69\x33\x7b\xa3\ -\x6b\xe9\xd7\x86\xfe\xa3\x60\xf6\x84\x2a\x1d\x48\x11\xd2\xbd\x68\ -\x89\x8c\x8a\xf0\x6e\xca\x50\x5f\x20\x13\x47\x20\xbe\x83\x5e\x50\ -\x87\x2b\x7f\x57\x91\x82\xae\x4c\x0b\x3c\x41\x41\x5f\xa2\x9d\x82\ -\xae\xb8\x17\x9d\x9b\xd7\xe1\x3a\x74\x06\x0f\x22\x18\x5c\x29\xe3\ -\x82\x0e\x84\xfd\x79\x73\x5e\x25\xb4\x30\x52\xb5\x90\x8f\x7b\x6f\ -\x67\xf4\x26\xd7\xd2\x2f\x0f\xdd\x9d\xf6\x54\xf1\x7e\xf1\x81\x19\ -\x3d\x46\x2e\x1d\xd2\xf4\xf5\x52\xc2\x82\x95\x36\x5a\x8a\x7a\x72\ -\xe9\x64\x01\x5a\x2a\x4c\x21\x27\x2a\x43\x47\x50\x38\x28\x29\x4a\ -\x3c\x96\xf0\x04\x74\xc5\xbc\x56\x23\xbc\x2f\x4a\x45\xd2\xf1\x09\ -\x31\x01\x8e\x07\x1b\x39\xcf\x24\x93\x8c\xe6\x49\x6f\x39\xb7\x9d\ -\x3f\x58\xc8\xc7\xbc\xcd\xa7\xf5\xb3\x76\x5a\x6f\x1e\xfe\xaf\xd4\ -\xb7\xd5\xb8\xcd\xec\xc9\xd1\x92\xcc\x47\x4b\xae\x07\x2d\x55\x69\ -\x60\x15\x62\x69\xe1\x55\x30\xc4\xc4\x92\x77\x42\x56\xa0\x1e\xbc\ -\x45\x7d\x4c\x28\x19\xa1\xf1\x78\x7a\x51\x96\x57\x21\xc5\x11\x4b\ -\x4a\x4e\x4c\xd5\x24\xa5\x97\x9e\x73\x5a\xa1\x38\x9e\x4f\x27\xf9\ -\xe6\xc4\x1e\xb2\xb2\x74\x53\x14\xdf\x8b\xba\x95\x5a\xb0\x13\x2e\ -\xcb\x27\xf5\x8b\x83\xb7\x27\x9f\x3b\x51\xb9\xea\x38\x68\xa9\x8f\ -\x80\x22\x64\x58\x09\xbb\x24\x3c\x87\x87\x9b\xbe\xca\x37\x5f\x78\ -\x1d\xc3\xcd\x1a\xd5\x20\xa7\x1a\x28\xe7\xae\x68\xb2\x7d\xd5\x14\ -\x22\x85\x84\x87\x1a\x75\xee\xdb\x3b\xc0\xaf\x46\xfa\x11\x94\xb5\ -\x8b\x12\xde\xb9\x71\x9a\xad\x03\x90\xf4\xa0\xac\x18\x47\x58\x14\ -\xfb\x7c\x71\x2f\xe2\xc9\xbc\x30\x6c\x9b\x38\xf5\x8c\xe6\x29\x16\ -\xed\x39\x5e\x41\x41\x9d\x92\x4f\xf8\x24\x1b\xd7\x5b\x07\x6f\x4f\ -\xfe\x61\x3e\x3f\x6d\xc9\x1e\x9b\x61\x85\x5c\x2d\xf5\xa0\x51\xda\ -\x70\x5b\xc2\x8e\x58\xb2\x02\x95\x48\x82\x88\x62\xbd\xf0\xe3\xa1\ -\xf5\x2c\x5f\x5c\xe3\x2d\x1b\x2b\xec\x1f\x69\xf1\xa5\xc7\x66\x79\ -\xdf\xa6\x03\x5c\xbf\x65\x08\x75\x96\x2f\x3d\x7e\x01\xd5\xfe\x15\ -\x7c\xf4\xbd\x5b\xa8\xc5\xc2\xa3\xcf\xec\xe7\x85\xd9\xbd\x5c\xb6\ -\x72\xb0\x83\x7a\x54\x85\xa4\xd4\x9c\x8c\x98\xaa\x49\xc9\xd4\x62\ -\xf0\xcc\xaa\xe7\x0b\x47\x9e\xe3\xb9\x74\xa6\xf7\x7c\xaa\xad\xd2\ -\x0e\xf2\x09\x6d\x66\x63\xfa\xf5\xc1\x3b\x92\x9b\xda\x6c\xcc\x57\ -\xe3\x13\x32\x2c\x08\x5e\x0d\x22\x1e\x55\x29\xe7\x36\x1d\x6f\x5a\ -\x54\x18\x3d\x2a\x01\x95\xbe\x65\x5c\xb9\x7d\x15\xd7\x9d\x7b\x04\ -\xfa\xcf\xe1\xae\xa7\xea\xfc\xf0\xc1\x27\xf8\xa0\x1b\xe6\x85\xf1\ -\x65\xb4\xa2\xb5\xdc\xf0\xa7\xe7\xb0\xc9\x3e\x4c\xa8\x0d\xde\xf8\ -\xd6\x0b\x49\xd3\x4d\xf8\xbd\x4f\x14\xf3\xa9\xf4\xcc\xab\x18\x54\ -\x21\xf5\x4a\xae\x9e\x69\xef\xba\xb2\x86\xc2\x13\x4b\x69\xbb\xa5\ -\x64\x9b\xd9\xa8\xde\x36\x78\x47\xf2\xa9\xf9\x52\x6d\x33\x7d\x7c\ -\x86\xcb\xbd\x08\x35\x28\xeb\xc9\x45\x3e\xad\x2a\x64\x5d\x40\xbb\ -\x3c\xab\x23\xf7\x31\xaa\xca\xec\xd8\x41\x1a\x2f\xfd\x98\x96\x0d\ -\x98\x1e\x79\x2b\x95\xbe\xa5\xa4\xd4\xe8\x5f\xb9\x01\xdd\x6d\xd8\ -\xf1\xc8\x03\xc8\xf2\x7d\xf4\x47\x29\x8b\x87\x77\xe3\x4c\x95\xaa\ -\x54\xc9\x35\x26\x29\xb3\xb9\xac\xcc\xb4\xda\xf1\xfa\xd9\x34\xe7\ -\x47\xb3\x13\xec\x4b\x27\xd9\xd7\xf1\xc8\xe5\x71\x0d\x52\x4a\xb6\ -\xc3\xec\x0d\xc7\x92\xec\xb1\xa4\x3b\xc7\x70\x57\x5a\x66\x29\xd4\ -\xb7\xc8\x90\x0c\x95\x32\x56\xb6\xe3\x64\x3b\x0e\x67\x12\xe3\xbd\ -\xb2\x7b\xd8\xf2\x93\xd6\x62\x5e\x9a\x5a\xc2\xc3\x23\x09\x1f\x7c\ -\xdb\xd9\xd4\x83\x9c\x81\x45\x23\x5c\x73\xd9\x15\xdc\x7e\xdf\x24\ -\xdf\x0f\x36\xb3\x6e\x71\x8b\x37\xad\x1a\xe5\xf7\xcf\x9a\x61\x71\ -\x2d\xc5\x11\x52\x91\xa4\x23\xe1\x58\x52\x9c\x3a\x22\x12\x46\x6d\ -\x83\x87\x66\x0f\x71\xd4\x36\x7a\x0f\xd1\x55\x50\xab\xe4\xe3\x3e\ -\x29\xd5\xf8\x94\x25\x3b\xc7\xf0\xbc\x53\xbd\x80\x76\x31\xcc\x60\ -\xb5\x88\xa7\xed\x0c\xca\x96\x49\xbd\x94\x59\x91\x57\x18\x9c\x0e\ -\x79\x4c\xb6\xf0\xf2\x54\xc4\x92\xa5\x4b\xb8\x68\xd9\x20\xf9\x94\ -\xc1\xcc\x0c\xf3\xfe\x73\x86\xb9\xfa\xf7\x3e\xcc\xe3\xcf\xee\xe7\ -\xe9\xe7\xf7\xf1\xb5\x47\x0f\xf1\xcc\xc4\x34\x7f\xff\xe6\x67\xcb\ -\xac\x2a\xee\x9c\x38\x38\x75\xbc\x98\x39\x9e\x4a\x26\x39\x98\x25\ -\xb4\x7c\xd6\x75\x5a\x58\x24\x15\x45\x9c\xd5\x2c\x1b\xd7\x5b\xdb\ -\x36\xbb\xfd\x8e\x7e\xf9\xe5\xf5\xb3\x7a\x3c\x27\xb5\x30\x93\xec\ -\x76\x04\xbe\x90\x70\xd5\xb4\xa8\x48\x8b\x47\x07\xeb\x04\x9a\x61\ -\x5d\x86\xda\x14\xe3\x53\xaa\xd2\xa2\x6a\x52\x62\x49\x89\x42\xe1\ -\xfd\x57\xbd\x81\xcf\xff\xe5\xc5\xfc\xeb\xa7\xaf\x66\xa0\x3f\xe4\ -\x9f\xff\xe7\x20\x91\x16\x30\x52\xf7\x7e\x8b\x25\x4f\xdd\xc4\xdb\ -\x97\xec\xe0\xef\xfe\x78\x31\x9f\xfb\x9b\x6b\xf9\xc1\x9e\x45\x54\ -\x4d\x42\x2c\x29\x55\x53\xcc\x57\x91\x84\x3e\x49\x78\x2a\x19\xe1\ -\x2b\xa3\x2f\x72\xef\xd4\x41\x66\x7c\xde\x03\xde\x35\x17\xb2\x31\ -\x6f\xb3\x71\xff\xc5\xc1\xdb\xe7\x1c\xd4\x2f\xaf\x9f\xd5\x4b\xee\ -\x59\x24\x27\x93\x6c\x47\xc2\x3a\xef\x40\xda\x74\x6c\xd8\x71\xff\ -\xc1\x95\x0c\xd4\x72\x1e\x3c\xb4\x82\xb3\xfa\x9b\x2c\xad\x2b\x97\ -\xaf\x19\xed\x20\x1a\xeb\x3c\xd3\x87\x77\xd1\xd4\x1f\xe2\x4d\x9d\ -\x77\xbf\xf9\x23\xdc\x72\xef\xeb\xf8\xe9\xe0\x11\xde\xb2\x66\x94\ -\x97\x67\x16\xb1\x38\xca\xa8\x4e\x3f\x8e\xd9\xf3\x08\x7b\x46\x2f\ -\x66\xf5\xc0\x32\x32\x8d\xc9\x35\x26\x53\x4b\xea\x0b\x9b\x1d\xb3\ -\x0d\x0e\x66\x49\x6f\x97\x40\xa9\xca\x9a\x2b\xd9\xa8\xf7\xf9\x94\ -\x7e\xf6\x78\x71\xf6\x64\x92\xed\x55\xe9\x2e\x3b\xd6\xc2\x57\x62\ -\xf0\x6c\x5e\xda\x64\x75\x3d\xa1\x16\x7a\x36\x2f\x6b\xb0\x6f\x7a\ -\x11\x22\xa5\x3f\x35\x9e\xb5\x2b\xfa\x59\xda\x3f\x83\xc1\xa3\xbe\ -\xc5\xeb\x79\x92\xcb\xb6\x6e\x61\xdf\x6c\x93\x33\x66\x73\xbe\x7f\ -\x70\x3d\x81\x4f\x59\x14\x67\xe4\x1e\x7e\x39\x51\xe1\xaf\xdf\x73\ -\x11\xd2\xfa\x5e\x39\x8f\x27\x57\xcf\x8f\x66\x27\x78\xa8\x71\xa8\ -\x4b\x8d\x3b\x4e\x19\xcd\x20\x1b\xf5\x6a\xa7\xf5\x26\x3b\xad\x37\ -\x9f\x8e\x83\x3a\x25\xa7\x65\xca\x43\x2a\x50\xb6\xad\x6a\x30\xd2\ -\xaa\x72\xce\x40\x8b\xe9\x2c\xe2\xbc\x81\x26\x4e\x43\x54\x8a\xb3\ -\xdb\xbf\xb8\x62\x05\xfd\xc9\x24\x6e\x3a\xc4\xab\xa1\xd2\xdc\xc3\ -\x87\x2e\xde\xc2\xf0\xf8\x5a\xce\x70\xa3\x5c\xb3\x7e\x3b\xbb\x0f\ -\xcd\x32\x31\xdd\xa4\x3f\x0e\xf9\xd4\xd5\xe7\xb3\xd9\x3c\x85\x3b\ -\x18\x90\x79\x61\xb6\x0c\x3d\x2f\x67\x93\x1c\xb5\xb3\xbd\xed\x0e\ -\xd2\x91\xac\xda\x19\xbd\x11\xe1\x2b\xc3\xdf\x4e\xfd\xe9\x38\xa8\ -\x53\x72\x5a\x1e\x25\x24\x27\x10\xc7\x96\x15\xd3\x54\x24\x21\xd1\ -\x84\x48\x72\x52\xad\x14\x68\x08\x4f\x68\x32\xce\xcb\x7e\x40\x2b\ -\x4b\x08\xc9\xf1\x12\xe0\xed\x34\x2b\xc6\xbe\xcb\xf2\xea\x6a\xa2\ -\xd9\xfd\x2c\x96\x80\x6d\x5b\x37\xe0\xa3\x65\x04\xbe\x81\x8e\xdd\ -\xc3\xec\xf8\x01\x6a\x62\x19\xb6\x4d\xbe\x70\xf4\x39\x8c\x08\x7b\ -\xb3\xe6\x1c\xb3\xa5\xd9\xfa\x1c\xb2\x11\xaf\x76\x46\x3f\xe9\x9a\ -\xfa\xb5\xa1\xbb\xd3\xac\x2d\xd9\xb6\x44\x4f\x47\xb2\x3d\x12\xee\ -\xb6\x1b\x2f\xbe\x03\xb4\x8d\x18\x8c\x28\x81\x96\xa0\xbd\xac\x3e\ -\x88\x40\xa0\x0e\x33\xb5\x0b\xf1\x75\x02\xe3\x11\x55\x02\x02\x4c\ -\x6b\x18\x6d\x8d\x62\x24\x43\x26\x9f\xc3\x4f\x3e\x5d\xa6\x8a\x69\ -\x59\x58\xed\x23\x14\x87\x53\xcf\xae\x6c\xa6\xab\x7b\xa7\xcb\x74\ -\xe7\x98\xbd\x51\x9d\x7e\x7d\xe8\xee\x5e\x88\xd7\xcd\xf4\x69\x33\ -\x3c\xbf\xbb\x26\x22\xa4\xe5\xfb\x08\xc4\xe1\x55\x8a\x94\x52\x8b\ -\xa3\xc8\xa2\x7c\x6b\x10\x55\x12\xad\x81\xa7\x33\xb6\x0b\x00\x9d\ -\x32\x4f\x89\x96\x8c\x38\x5c\x1b\x2d\xe1\x79\xb0\x99\xf3\x7c\x3a\ -\xc9\x98\x4b\x7b\xdb\x96\x7c\x8f\x1a\x7b\x3b\xad\x37\x29\xfa\x95\ -\xc1\xdb\x0b\xc9\x9e\xae\x73\x3a\x65\x95\xce\xd5\x51\x95\x56\x51\ -\x72\x29\x0b\x74\xe2\x0b\x00\x6f\xf0\x54\xa5\xd5\x41\x4b\x35\x69\ -\xa2\x48\xe7\x6c\x29\xa3\x42\x54\x16\x05\x2a\x26\xc5\xf8\x42\x5b\ -\x72\x62\x62\x49\x09\xc4\xf3\x4c\x32\xc9\x7f\x4e\xee\xc1\x96\x79\ -\x53\x8f\xcd\x5a\x25\x1b\xf5\x36\x9f\xd4\xcf\xda\x29\x7f\xf3\xf0\ -\xbd\x99\x3f\x59\x6e\xfc\x8a\x54\xba\xbb\x75\x28\xf5\xca\x7e\x27\ -\x40\xc8\x32\x13\xd3\x3f\x0f\x2d\xb5\x73\xe9\x44\xab\x9d\x13\xbc\ -\x02\xf5\x14\xa7\x87\xb6\x5d\x4a\xf5\x41\x51\x70\xc3\x91\xf8\x80\ -\x11\x67\x01\x61\xd4\x25\x64\xf8\x85\x6d\x4b\x16\xb2\x51\xcd\xf2\ -\x89\x93\x43\xbc\x5f\xab\xd7\xf2\xa2\x3b\x17\x69\x6f\xc5\xaf\x18\ -\x2f\x94\xe5\x7c\xa2\x76\x16\x5b\xa3\x88\xc4\x57\x89\x24\x23\xd3\ -\xb9\xd3\xc3\x86\xef\xa3\xcf\x34\x68\xfa\x7a\x89\x6b\x8b\xaa\x66\ -\x28\x79\x99\x36\xa6\x65\x3c\xb7\x0c\xe5\xca\xdf\x1e\xf9\x15\xfb\ -\xb3\xf9\xd5\xc5\xd2\x6f\x58\x25\x1f\xd3\x24\x1b\xf5\xb7\x76\xa3\ -\x9e\xdf\xc4\x65\xe6\x57\x0e\xba\xef\x33\x2d\x50\x8b\xed\x40\x86\ -\xf2\xd3\xd5\x00\xd6\x2e\x76\xb7\x7f\xa3\xeb\xf7\x5c\x95\x4c\x95\ -\x14\xc5\x1c\xab\x0b\xaf\x0d\xde\xc7\x7c\x33\x1b\xf5\x5f\x9d\x0f\ -\xf1\x5e\x49\xd8\x39\x75\x95\x6e\xe7\xad\x65\x78\x78\xd1\x4d\x73\ -\x5b\x73\x98\x88\x80\x8f\xd6\x37\xf2\x86\xb0\x56\x1c\x4b\x96\xed\ -\x63\xa9\x56\xcb\xb1\x82\x78\x5f\x56\x24\xa3\xce\xe9\x80\x7a\xc3\ -\xce\x24\xe7\x67\x8d\x09\x06\xf3\x69\x0e\xe7\xe9\xdc\xc6\xea\x1c\ -\xb3\xd9\xb8\x6f\x66\x23\x7a\xdb\xe0\x9d\xa7\x0f\x04\x7e\x6d\x2f\ -\xdd\xe9\x67\x44\x68\x78\xcb\x93\x7a\x04\x80\xf7\xf8\x01\xaa\xd2\ -\x87\xaa\xa3\x5a\x3a\xaf\xee\x9e\x8b\x5a\xd9\xe3\x91\x51\x94\x82\ -\x52\x02\xaa\x92\x72\x24\x9f\xe1\xfe\xc6\x01\xc6\xdb\xc7\x1f\xc7\ -\x62\xf6\xa8\xbb\x6d\xf0\xce\xf4\x86\x5f\x37\x83\x3a\x2d\x95\x9e\ -\x83\x5f\xda\x01\x11\xdd\xb1\xf9\xe9\xac\xc1\x77\x5b\x33\x3c\x6f\ -\x3d\x0d\x1f\x91\x68\xd9\xbd\xa3\xd5\xce\xd8\xfe\xde\xf4\x31\xbb\ -\x33\xcf\xb7\xa6\x67\xd9\x95\x35\x49\xbd\x2b\xa6\xed\xee\x85\x74\ -\x90\x8d\xfb\x24\x1b\x71\x5f\x1f\xbc\x33\xbd\xe1\x4f\x74\x40\x5e\ -\xad\xb0\x73\x8a\xb9\xb4\x42\xa7\x81\x53\x7a\xc3\x85\xc2\xbf\xb7\ -\xf6\x02\xf0\xe1\xda\x46\xb6\x45\xcb\xa8\x18\x83\x7a\x43\xcd\xb4\ -\x8a\x62\x9e\x49\xf0\x2a\x64\x54\x10\x12\x1e\x6a\x8e\xf0\x8d\xc9\ -\x97\x3b\xf4\xed\x2a\x45\x11\x67\x21\x1b\x75\x59\x36\xaa\xb7\x0e\ -\xde\x91\xde\x74\x9d\xae\x94\xdd\xb7\xb7\x78\x35\x63\xed\x49\x6c\ -\x58\x3b\x4d\x22\x1d\x4e\x17\x38\x98\x42\xd5\xc7\x5c\xca\xcf\xd3\ -\x84\x8a\x40\xa0\xe0\x68\x61\x00\xa7\x4d\x84\x00\x83\x23\xd1\x94\ -\x51\x9b\x2f\x2c\xa5\xb6\x99\x1d\x71\x36\x1b\xd7\x2f\x0e\xde\x51\ -\x14\xdc\xee\x96\x11\x7d\xb5\x63\xed\x89\x19\x16\x29\xba\x57\x3b\ -\x1e\x77\xde\x99\x79\x79\x2b\x0a\x3f\x4f\x8f\xf0\x62\x3e\x8b\x60\ -\xf0\xea\x31\x5a\x8c\x82\xe9\xb4\xe2\x7b\x55\x46\x5d\xb3\x33\x45\ -\x7b\x26\x9f\x2a\xe9\x88\xfa\x7c\xb2\x80\x78\x6f\x3f\xb0\x4c\x7e\ -\xb2\x6e\x42\x5f\x2b\xc9\x76\x44\x77\xfe\xcd\x7d\x7a\xdc\x3e\xe6\ -\x6e\x09\x9d\xa8\x2f\xb9\xeb\x59\xa1\x97\xa6\xfd\xdd\x4e\x79\xec\ -\xb4\x7e\x3a\x9f\xf2\x37\x0f\x7f\xfb\xd5\xcf\xa0\x4e\x59\xc2\xc9\ -\x21\xff\xf9\xe3\xfd\xff\x01\xf3\x7a\x24\xda\xff\x94\xd1\xd3\xd4\ -\x2d\xf3\x36\x03\x16\x74\xa7\xa3\x84\xae\xa9\xcf\xf9\x54\xef\x6a\ -\x33\xfb\x9b\x0c\x3d\x27\x94\xf0\xaa\x77\xc5\xf5\x9e\x83\x72\xe9\ -\xd5\x68\x99\xff\x45\x7a\xff\xa7\xe0\x18\x6d\x14\x0b\x9e\x17\x83\ -\x1c\xbe\x27\x6b\xf0\xdb\x7a\xfd\xa6\xb2\xa8\xdf\x5d\xbf\xbb\x7e\ -\x0b\xaf\xff\x03\x05\xf2\x7b\x06\xf0\x22\xce\x4f\x00\x00\x00\x00\ -\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x11\x80\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x7a\x6f\x6f\x6d\x5f\x74\x6f\ -\x5f\x52\x4f\x49\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ -\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\ -\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x30\x66\ -\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ -\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\ -\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\x30\x36\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x62\ -\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\ -\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\ -\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\x74\x6f\ -\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x30\x33\ -\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ -\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\ -\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\x2e\x36\ -\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x66\ -\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\ -\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\x31\x34\ -\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ -\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\x32\x34\ -\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\x38\x2c\ -\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\x35\x38\ -\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\ -\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\ -\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ -\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ -\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ -\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\ -\x39\x30\x32\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x33\x38\x2e\x33\x32\x38\ -\x32\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x79\x3d\x22\x31\x39\x2e\x31\x31\x38\x33\x31\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ -\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ -\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ -\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\ -\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\ -\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ -\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ -\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ -\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ -\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ -\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ -\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ -\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ -\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ -\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\ -\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x30\x2e\x35\x37\x30\x37\x35\x32\x33\x2c\x30\x2c\x30\x2c\ -\x30\x2e\x35\x37\x30\x37\x35\x32\x33\x2c\x39\x2e\x36\x38\x35\x37\ -\x32\x32\x36\x2c\x34\x2e\x37\x33\x30\x33\x34\x31\x35\x29\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\ -\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\ -\x3d\x22\x35\x2e\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x72\x65\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\x38\x33\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ -\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x37\x2e\x30\x36\ -\x36\x36\x36\x37\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x63\ -\x20\x30\x2c\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\ -\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\ -\x32\x30\x30\x30\x30\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\ -\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ -\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x33\x2e\x32\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ -\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\x36\x36\x36\x36\ -\x36\x37\x2c\x31\x36\x2e\x36\x30\x32\x32\x38\x39\x20\x63\x20\x31\ -\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\ -\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\x30\x30\ -\x30\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x38\x30\x38\ -\x30\x38\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ -\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x33\x2e\x35\x38\x39\x30\x39\x35\x31\x32\x70\x78\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\ -\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\ -\x38\x34\x30\x39\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\ -\x3d\x22\x31\x39\x2e\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x63\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\ -\x2e\x34\x38\x34\x34\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x31\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x35\x35\x32\x32\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\ -\x2e\x30\x35\x31\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\ -\x2e\x32\x35\x37\x38\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x32\x31\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\ -\x35\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ -\x2e\x37\x32\x30\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\ -\x28\x2d\x33\x39\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x08\x75\ -\x00\ -\x00\x59\x6c\x78\x9c\xe5\x5c\xdb\x8e\xe3\x36\x12\x7d\xef\xaf\xd0\ -\x6a\xb0\x48\x06\x3b\xa4\x48\x51\xf7\xb6\x1d\x60\x77\x10\x24\x40\ -\xf6\x65\x93\xc5\x3e\x06\x6a\x89\xed\xd6\x8e\x2c\x19\x92\xdc\xb6\ -\xe7\x6b\xf6\x5b\xf2\x65\x29\x52\x17\x4b\xb6\xbc\x99\x8c\xe4\xa4\ -\x7b\xa8\x46\x63\x46\x55\x45\x91\x3c\x75\xaa\x78\x11\x5b\x8b\x6f\ -\x0e\x9b\x54\x7b\xe6\x45\x99\xe4\xd9\x52\xa7\x98\xe8\x1a\xcf\xa2\ -\x3c\x4e\xb2\xf5\x52\xff\xf7\x4f\xdf\x22\x4f\xd7\xca\x2a\xcc\xe2\ -\x30\xcd\x33\xbe\xd4\xb3\x5c\xff\x66\x75\xb7\xf8\x0b\x42\xda\x3f\ -\x0a\x1e\x56\x3c\xd6\xf6\x49\xf5\xa4\x7d\x9f\x7d\x28\xa3\x70\xcb\ -\xb5\xaf\x9f\xaa\x6a\x1b\x18\xc6\x7e\xbf\xc7\x49\x23\xc4\x79\xb1\ -\x36\xde\x6a\x08\xad\xee\xee\x16\xe5\xf3\xfa\x4e\xd3\x34\xa8\x37\ -\x2b\x83\x38\x5a\xea\x4d\x81\xed\xae\x48\xa5\x61\x1c\x19\x3c\xe5\ -\x1b\x9e\x55\xa5\x41\x31\x35\xf4\x93\x79\x74\x32\x8f\x44\xed\xc9\ -\x33\x8f\xf2\xcd\x26\xcf\x4a\x59\x32\x2b\xdf\xf4\x8c\x8b\xf8\xb1\ -\xb3\x16\xad\xd9\x33\x69\x44\x7d\xdf\x37\x88\x69\x98\x26\x02\x0b\ -\x54\x1e\xb3\x2a\x3c\xa0\x61\x51\x68\xe3\x58\x51\x93\x10\x62\x80\ -\xee\x64\xf9\x69\x56\x41\x09\x80\x6e\xe1\xb7\x33\x6f\x05\xb8\xcc\ -\x77\x45\xc4\x1f\xa1\x1c\xc7\x19\xaf\x8c\xf7\x3f\xbd\xef\x94\x88\ -\xe0\xb8\x8a\x7b\x8f\x69\xf1\x1c\xd4\x3a\x00\x39\x0b\x37\xbc\xdc\ -\x86\x11\x2f\x8d\x56\x2e\xcb\xef\x93\xb8\x7a\x5a\xea\xcc\xc2\x94\ -\xc1\x65\x4b\xe1\x13\x4f\xd6\x4f\xd5\xb9\x34\x89\x97\x3a\xb4\xde\ -\xf4\xbd\xfa\xbe\x47\x0e\x5a\x1b\x34\x0f\x0e\x3a\x0d\xc1\xbe\x89\ -\xa9\x56\x50\x9b\xb9\xb5\x4d\xdb\x85\x20\xce\x23\xd1\x26\x78\x24\ -\xdf\x24\xe1\xae\xca\x37\xe0\xb5\x28\x4a\xc3\xb2\x4c\x1e\x93\x08\ -\x6e\xf2\x6c\x9b\xee\xd6\x49\xf6\x73\x54\xe4\x65\xf9\xf3\x50\x85\ -\x5b\x1c\xbb\x4a\xf9\x61\x9b\x17\x15\x3a\xc4\x5b\x40\xd3\x71\x47\ -\x95\xc7\x56\xb9\x02\xed\x22\xe6\x8f\xa5\xb0\xaa\xbb\x26\xee\xa0\ -\x6f\xae\xae\x19\x52\xdb\xb5\x54\x34\x33\x7e\x4e\xf8\xfe\x64\xfb\ -\x10\x96\x35\x7c\x9a\xb6\x0d\xd7\x40\xb5\x34\x2f\x96\xfa\x9b\x47\ -\x79\x35\x8a\x87\xbc\x88\x79\xd1\xaa\x1c\x79\x0d\x54\x39\xb8\x23\ -\xa9\x8e\x75\x70\x35\xcf\x6e\xdb\x2b\x9e\xda\xe9\xc9\xb8\xbe\x7c\ -\x0a\xe3\x7c\xbf\xd4\xcd\x73\xe5\xc7\x3c\xdf\x2c\x75\x1b\xdb\xbe\ -\xe7\x13\x7a\xae\x8d\x0e\x4b\x1d\xd9\x26\x76\x2c\xe6\x78\x17\x65\ -\x23\xa8\x0f\x51\x8a\x99\xe7\x38\xd6\x85\x72\x57\x14\x10\x7d\x28\ -\x0d\x8f\x1c\x3a\x25\xff\x69\x9f\x5f\x3e\xe5\xfb\x75\x21\xc0\xa9\ -\x8a\x1d\x3f\x2f\x29\x34\xe8\xe1\x21\x3f\x8c\xab\x81\x0c\x3b\x11\ -\xd7\x68\x97\x25\x15\xc4\xce\xf6\xd0\x7f\xea\x2e\x89\x79\x39\x5e\ -\xb0\xcc\xc2\x2d\x5a\xa7\xf9\x43\x98\x8e\x1b\xec\x93\x0c\x40\x42\ -\x0d\xcd\x29\xeb\x7c\x70\x6e\xd1\x72\xde\x25\xde\x15\x0b\x68\xfb\ -\x85\x1f\x1a\xd5\xf1\xba\x6a\x13\x1e\x92\x4d\xf2\x91\x03\x30\x54\ -\xd2\x0e\xa8\x35\x80\xa5\x2e\xa6\x69\xd5\x51\xc4\xef\xe1\x28\x64\ -\x7a\x2b\x14\x78\x0a\x81\xe9\xfb\x6e\x27\xcc\x8b\x04\xc2\xa2\xd7\ -\x9c\x56\x74\xec\x8b\x44\xb4\x43\xb2\x3e\x48\x7e\x49\xf6\xb9\xe7\ -\xba\x63\x5f\xd7\xd0\xde\xb8\xe4\xbd\x94\x6f\x78\x15\xc6\x61\x15\ -\x9e\x82\xa0\x95\x40\xdb\x48\xdb\x33\x48\x9c\xc1\xbf\xde\x7f\xbb\ -\x6a\x2a\x5a\x44\x51\xf0\x9f\xbc\xf8\xd0\xd6\xab\x69\xc2\x20\x7c\ -\xc8\x77\x80\xb4\xbe\xea\xc4\x8b\x38\x0a\x20\xd5\x41\x0a\x58\x25\ -\x1b\xa0\xb6\xc8\x92\x7f\x83\xd4\xb6\x30\x4e\x8a\x81\xb1\x00\xeb\ -\xf4\xd0\xfa\xb1\x05\xaf\x73\xe6\xe8\xc0\x11\x47\x9b\x44\x14\x32\ -\x7e\xac\x92\x34\xfd\x5e\x54\xd2\xf4\xb8\xf7\xd0\xa4\x4a\xf9\x49\ -\xb8\x30\x9a\xd6\x37\x7d\x33\x7a\x9d\x5b\x18\x6d\xef\xe5\xdd\xfa\ -\x84\xca\x20\x28\x3a\x47\xa7\xe1\x03\x07\x86\xfe\x20\x94\xda\x85\ -\x76\x5d\xe4\xbb\xed\x26\x8f\x79\x53\xbc\x43\x93\x47\x55\xe7\xb2\ -\xea\x98\x82\xfe\x11\x5a\x1f\xbc\x09\x89\x19\x99\xd1\xbd\xb8\x41\ -\x4d\x9a\x08\x68\x7d\x5b\xec\x52\x48\x77\xcf\x3c\xcb\xe3\xf8\xbe\ -\xac\x8a\xfc\x03\x0f\x9a\xc4\xd4\xdc\xd6\xc1\x10\x10\x6c\x31\xdf\ -\x12\xbe\x6f\xe5\x80\x10\x2f\x52\x60\x6b\x15\x58\xad\x2c\x0e\x21\ -\xcd\x14\x45\x78\x0c\x32\x18\xe6\x5b\x69\x57\xe7\x80\xa8\xa2\xb9\ -\xb6\xc7\x7c\x44\x91\x87\x4e\xaa\x26\xf6\x6c\xcc\xd8\x69\x30\x11\ -\x57\x1b\x72\x16\xf6\xa5\xc6\xea\x34\x82\xb4\x04\x9f\x91\x56\x66\ -\xa6\x0b\x2a\x17\x83\x38\x28\x24\xa5\x1d\x4b\x5c\x4e\xe7\xe0\x57\ -\x0d\xa4\x7f\x0b\x20\x29\xc3\xee\xd0\xf2\x8b\xc7\x91\x22\xfb\x16\ -\x48\x7a\xd8\x23\xe2\x32\x67\x42\x92\x10\x0f\x7e\x5e\x34\x92\xee\ -\x2d\x70\x34\x19\x76\xd4\x81\x10\xc8\x78\x13\x36\x52\x0f\x0f\x66\ -\x9a\x0a\x40\xe9\xdf\x86\x8f\x8c\x61\x4b\x9d\x91\x66\x22\x82\x64\ -\x80\x1c\xf6\x66\xe5\xe0\xcb\x46\x0e\x38\x68\x4d\x44\xef\xd2\x5c\ -\xc1\xa9\x8e\x37\x27\x05\x15\x9b\xde\x90\xc9\x14\x1c\xa0\xa7\xd8\ -\x94\x86\xb0\x39\xc1\x53\x67\x1e\x43\x26\x0f\xbc\xc3\x98\x55\x6e\ -\xea\x32\x7d\x91\x3c\x3a\x72\xcc\x3d\x73\x79\xe1\x40\x42\xf2\x9b\ -\x8c\xe3\x30\x82\x3d\x6c\x4b\x13\x85\xf0\x9b\x77\x00\x51\x6b\xee\ -\xdc\x20\x68\xce\x89\xa0\x6a\xb3\x3f\xb1\x90\xb3\xa6\x72\xd0\x74\ -\xce\x47\x10\xb9\x1a\x71\xd9\x9c\xd1\xfc\x0a\x80\xa4\x93\x07\xe6\ -\x51\x24\x81\x93\x73\xcd\x08\x5f\x05\x88\xf6\xe4\x0d\xc3\x51\x18\ -\xbd\xf3\xcd\x86\x2f\x7a\x74\x69\x76\x68\x26\x67\xc7\xf1\xd8\x66\ -\xf5\x43\x94\xa1\xa5\x85\xcc\xa9\xeb\x64\x93\xe2\x33\xa1\x52\xa1\ -\xed\xa1\xa9\xab\x3d\x3a\xa0\x20\x9d\x6f\xb9\xf7\xc2\x91\x93\xb3\ -\x1c\x6b\x2a\xfd\xa8\xc2\xb9\x90\xb0\xe9\x5b\xd5\x03\xf8\x4c\xb5\ -\x56\x7a\x14\x39\xd3\x87\xe4\xb1\xf4\xa7\x18\x8e\x04\xc6\xe3\x79\ -\xe3\x98\xaa\xb5\x64\x16\x03\xb1\x83\xd8\xd4\x5d\x87\x51\x2e\x2a\ -\x07\xa5\xd8\x06\x43\x3e\xb9\x05\x96\x73\xcf\x0f\x5f\x38\x96\xcd\ -\x4e\xce\xf4\x73\x0e\x2a\x4f\xb2\x9b\xcd\x1c\xe4\x3b\xb3\xa2\xa8\ -\xce\x0c\xbb\xde\xca\x99\xbc\xe0\xeb\xf1\x4d\xd9\x5d\x1c\x34\x95\ -\x83\x43\x10\xd5\xe2\xa0\x08\xe5\xa9\xb3\x9c\x21\x7e\xea\xac\xf5\ -\xba\x0d\xb0\xc9\x6f\x56\x86\x08\xaa\xb5\xde\x93\x67\xe5\x60\x28\ -\x99\xba\xe8\x1b\x62\xa8\xd8\x62\xa5\x3d\x2d\x87\x88\x33\xf3\x98\ -\x32\xdf\x4c\x7b\x08\xdb\xab\x80\x54\xee\xc9\x4e\xde\x0b\x43\xcc\ -\x3d\x9f\x1c\xfe\xee\x19\x63\x2b\xad\x8a\x30\x2b\xc5\x59\xff\xa5\ -\x5e\x46\x61\xca\xbf\x46\xf4\x1d\x7d\xfb\xc5\x10\x58\x4e\x2c\xa7\ -\xbe\xe1\x3a\xcb\x04\x1e\x56\xe4\x80\x13\x9d\xbe\x5f\x31\x7a\xc6\ -\x73\xe6\x93\x8a\xaf\x85\x89\xb7\xc0\x72\xee\x53\x13\x2f\x9d\x91\ -\x13\x31\x1c\x3f\xb9\xa3\xda\xc9\x59\x6f\x6a\x58\x8f\xc2\xa8\xd8\ -\xe9\x4f\xf9\x5a\xf0\x16\x38\x2a\x76\x0e\x94\x4e\x5e\x6e\x8f\xa2\ -\xa8\xce\x81\x50\xb9\x2d\x7e\x93\x80\x56\xed\x68\xa8\x35\xc3\xaa\ -\x71\x9c\x8c\x8a\x8d\xd2\xf5\x3e\xd0\x44\x24\x47\xcf\x9e\xcc\xb8\ -\x19\xf4\xe2\xe9\xd8\xad\xc0\x6f\x02\xa4\x72\x2f\xbc\xda\xe5\xe0\ -\x2d\xd0\x54\x67\x4d\x38\xef\x51\x0a\xe5\x5e\x30\x4c\x3e\x90\x37\ -\xfa\xc2\x55\x35\x14\xbd\xe9\xe7\xc9\xc6\x4f\x01\x28\xf4\xaa\x41\ -\x4c\x76\x6e\x72\xaa\x51\xad\xb7\x0d\xf5\x8b\x6b\x6f\xde\xe3\x8d\ -\x33\x0e\x27\x2f\x1c\xbe\x66\xd2\x3d\x79\x63\x67\xfc\x80\x99\x42\ -\x30\x7a\xb7\x3a\xed\x3d\xf7\x8b\xaf\x06\x99\x01\x92\xe4\xff\x20\ -\x49\x2c\xb1\x19\x32\x44\xd2\xc2\x1e\xf1\x6d\xdf\xf7\xbc\x11\x24\ -\x61\x34\x94\xfb\x27\xc4\xfe\x5c\x48\x4d\xdf\xbf\xfc\xd3\x7c\x82\ -\x99\x4b\x98\xe3\x5f\x42\xe9\x61\xd7\x22\x2e\xf3\xfa\x50\x12\xec\ -\x99\xbe\xc3\x88\x3d\x5c\x51\x63\xe6\x9b\xb6\x6f\xd9\x03\x2c\x3d\ -\x90\x12\xe6\xdb\xe6\x00\x53\x1b\xbb\xbe\xcd\xfc\xde\x47\x02\xba\ -\x0f\x17\x75\xef\x6c\x50\xc4\x33\xe8\xb7\xf8\x46\x16\x72\xb0\x4b\ -\x1d\x62\x79\xee\x27\xd8\x1f\xa5\xbd\xe5\x7b\xae\xe3\xd8\x27\x9f\ -\x6d\xc3\xea\x69\xcc\x67\x3d\xd4\x44\x24\x5c\xfa\x83\x02\xb3\x1d\ -\x66\x41\x87\xb7\x87\x56\x93\x26\x19\x87\xda\x83\x87\x5d\x55\xf5\ -\x65\xff\xcd\x93\x2c\x90\xee\xba\xee\x08\xf0\xc3\x3f\x35\x44\xb1\ -\x2b\x2f\xf3\x1d\x2c\x56\xe4\x17\xf1\x98\xf6\x9d\x66\x99\xe7\xe3\ -\x8b\x70\x9b\x68\x3a\x03\xdb\xcb\xce\x47\x79\x06\x0d\xa9\xf2\x02\ -\x45\xbb\xe2\x39\xac\x76\x05\x17\xf4\xed\x3a\x5d\xf1\x43\x47\xd4\ -\xc3\x26\x0d\xe4\xe7\xfa\xe0\x81\x05\x2f\x79\xf1\xcc\xf5\x73\x40\ -\xf2\xac\x42\xf2\xff\x00\x4b\xb1\x09\xd3\x7b\x29\xd9\x4b\x32\x04\ -\x0f\x79\x1a\xd7\x82\x32\xf9\xc8\x03\x6a\x36\x7b\x79\xd4\x07\x60\ -\x44\xef\x9b\x0f\x9e\x05\xe4\xaf\xb5\xd9\x63\xb8\x49\xd2\x63\x50\ -\x82\x83\x10\xd4\x97\x3c\xde\xa3\xb6\xe5\xa8\x7e\xce\x96\x47\xdd\ -\xe7\xf7\x82\xaf\x7e\x04\x43\xed\xef\x50\xcb\x57\xf7\x29\xaf\x84\ -\x2f\x9b\x8f\x8a\x05\x04\x6a\xd8\xe7\x45\x3c\x10\xb4\xc9\x4b\xba\ -\xec\x2c\x79\x35\x0e\xed\x87\x44\x9b\xa7\xcc\x1a\x6d\xeb\xd3\xf3\ -\xd4\x20\x8d\x40\x04\x7a\xb6\x3f\xdc\x01\xf1\x21\x2a\x2d\x9f\x0d\ -\x83\x4d\x60\xcf\x3c\xea\x8b\x83\x5f\x9d\xe2\xe2\x8d\x24\xc5\x84\ -\x51\xcb\xa4\xe6\x3b\x82\x7d\x07\x82\xc2\x21\xf4\xad\xbe\x5a\x54\ -\xd0\xd3\xac\x2d\xd5\xfb\xc6\x61\x91\x0b\x47\x09\xb4\xf5\x93\x56\ -\x56\x27\x0a\x30\xcf\xa4\xa8\x7f\x24\x7c\xbc\xcd\x57\x5a\x3d\xe4\ -\xc1\x55\xaf\xfb\xa6\x4b\x2d\xfb\xcc\xe7\x14\x9b\xf6\x64\xaf\xff\ -\xb6\x47\xa7\x78\x71\x65\x2e\x0c\x89\xd2\xef\x44\xf7\x2a\x82\x96\ -\x8d\x3d\x87\x79\x8e\x32\x08\x8e\x32\x0e\x92\xec\xea\x97\xff\x75\ -\xd0\x1a\x82\xf7\xb7\x48\x3f\x7d\xd1\x67\x27\xa0\x9b\xe5\x95\xee\ -\x8f\x6b\xcd\x7e\xb6\xa0\x30\xb0\x5a\xd4\xa5\xde\x60\xa0\xb4\xb1\ -\x45\x4c\xdb\x76\xae\xa6\x8b\x3f\x3e\x61\x20\x3a\x24\xfc\x65\xc3\ -\xaf\x34\xfd\x4f\x67\xfc\x35\x2f\xac\xe8\x67\x47\xfb\x95\xce\x33\ -\x8a\x6d\x87\xf6\x27\x21\x67\xcc\xfd\xdc\xbe\xfe\x16\x91\xce\xc2\ -\x0d\x39\xe3\x01\xb7\x30\xd6\xab\xbb\x85\xf8\xce\xe5\xea\xee\x57\ -\xee\x92\xd2\xac\ -\x00\x00\x0a\x6e\ -\x00\ -\x00\x92\x59\x78\x9c\xed\x9d\x5b\x6f\xdb\x46\x16\xc7\xdf\xf3\x29\ -\xb8\xca\x4b\x83\x15\xa9\xb9\x5f\xe4\x4b\x1f\x5a\x14\x28\x90\x7d\ -\xd9\x76\xb1\xc0\xbe\x2c\x68\x91\xb2\xb9\xa1\x48\x81\xa4\x2c\x3b\ -\x9f\xbe\xff\x21\x45\x4a\x74\xdc\xdc\xd3\x95\x94\x11\x12\xc8\x3c\ -\x73\x1f\xce\xef\x9c\x33\x67\x26\xce\xe5\x8f\x0f\xab\x3c\xb8\x4f\ -\xab\x3a\x2b\x8b\xab\x09\x8d\xc8\x24\x48\x8b\x45\x99\x64\xc5\xed\ -\xd5\xe4\x5f\xbf\xff\x12\x9a\x49\x50\x37\x71\x91\xc4\x79\x59\xa4\ -\x57\x93\xa2\x9c\xfc\x78\xfd\xe2\xf2\x6f\x61\x18\xfc\x54\xa5\x71\ -\x93\x26\xc1\x36\x6b\xee\x82\x5f\x8b\x37\xf5\x22\x5e\xa7\xc1\x0f\ -\x77\x4d\xb3\x9e\xcf\x66\xdb\xed\x36\xca\x76\xc2\xa8\xac\x6e\x67\ -\xaf\x82\x30\xbc\x7e\xf1\xe2\xb2\xbe\xbf\x7d\x11\x04\x01\xda\x2d\ -\xea\x79\xb2\xb8\x9a\xec\x0a\xac\x37\x55\xde\x66\x4c\x16\xb3\x34\ -\x4f\x57\x69\xd1\xd4\x33\x1a\xd1\xd9\x64\x9f\x7d\xb1\xcf\xbe\x70\ -\xad\x67\xf7\xe9\xa2\x5c\xad\xca\xa2\x6e\x4b\x16\xf5\xcb\x83\xcc\ -\x55\xb2\x1c\x72\xbb\xde\x6c\x79\x9b\x89\x5a\x6b\x67\x84\xcd\x18\ -\x0b\x91\x23\xac\x1f\x8b\x26\x7e\x08\xc7\x45\xd1\xc7\xe7\x8a\x32\ -\x42\xc8\x0c\x69\xfb\x9c\x1f\x97\x6b\x5e\x63\x42\xd7\xf8\x3b\x64\ -\xef\x05\x51\x5d\x6e\xaa\x45\xba\x44\xb9\x34\x2a\xd2\x66\xf6\xf3\ -\xef\x3f\x0f\x89\x21\x89\x92\x26\x39\xa8\xa6\x9f\xcf\x51\xab\xa3\ -\x49\x2e\xe2\x55\x5a\xaf\xe3\x45\x5a\xcf\x7a\x79\x5b\x7e\x9b\x25\ -\xcd\xdd\xd5\x84\x8b\x88\x72\x7c\x64\x2b\xbc\x4b\xb3\xdb\xbb\xe6\ -\xa9\x34\x4b\xae\x26\xe8\x3d\xb3\xa6\x7b\x3e\x58\x1c\xb4\xcb\xb0\ -\xab\x78\x3e\xa4\x90\xc8\xb2\x88\x06\x15\x95\x5c\x77\x79\xfa\x21\ -\xcc\x93\x72\xe1\xfa\x84\x2a\xd3\x55\x16\x6f\x9a\x72\x85\xb7\xb6\ -\x58\xe4\x71\x5d\x67\xcb\x6c\x81\x87\xb2\x58\xe7\x9b\xdb\xac\xf8\ -\xef\x4d\xdc\x2c\xee\xa2\x7e\xe2\x86\x56\xd2\x87\x75\x59\x35\xe1\ -\x43\xb2\xc6\xf4\x29\xfd\x6c\xe2\x63\x9f\x78\x8d\xd4\xcb\x24\x5d\ -\xd6\x2e\x57\x37\x16\xf7\x84\xc1\xe8\x49\x30\x6b\x53\x87\xae\xb9\ -\x7e\x25\xf7\x59\xba\xdd\xe7\xbd\x89\xeb\x6e\xbe\x82\x60\x1d\xdf\ -\x62\x6d\xe5\x65\x75\x35\x79\xb9\x6c\x3f\xbb\x84\x9b\xb2\x4a\xd2\ -\xaa\x4f\x52\xed\x67\x94\x54\x62\xfe\xb3\xe6\xb1\xa3\x69\x57\x77\ -\xdf\x5f\x57\xeb\x90\x4e\x9e\x4f\xaf\xef\xe2\xa4\xdc\x5e\x4d\xd8\ -\xd3\xc4\xb7\x65\xb9\xba\x9a\xe8\xc8\x52\x43\x04\x35\x4f\x93\x17\ -\x0f\x57\x93\x10\xef\x52\x2b\xc2\x38\x7f\x27\x15\x0d\x32\x1e\x51\ -\x2d\xfa\x17\x7d\x98\xb8\xa9\x2a\xf0\x16\xe6\xf1\x63\x8a\x51\xb5\ -\x5f\x74\x97\xa9\xbe\x2b\xb7\xb7\x95\x9b\x9d\xa6\xda\xa4\x4f\x4b\ -\xba\x94\xf0\xe6\xa6\x7c\x78\x3e\x19\xaf\x7f\xe3\x48\x0e\x37\x45\ -\xd6\x80\x96\xf5\xc3\x61\xad\x9b\x2c\x49\xeb\xe7\x0b\x6e\xb3\x02\ -\x93\x10\xee\xd6\x2d\xe5\xc3\x1c\x3f\xcd\xd1\x2f\x62\x4d\xde\x99\ -\x90\x5d\x0e\x74\xed\x9d\x79\xde\x25\x3d\xfe\x79\xd2\x2a\x7e\xc8\ -\x56\xd9\xdb\x14\xe3\xa6\x4f\xb3\xd4\x45\xbc\x0e\x6f\xf3\xf2\x26\ -\xce\x77\xbd\xbf\x6e\x73\x5c\x8e\xa6\xa5\x2b\x14\x04\xcd\xa3\x23\ -\xf6\xe1\xd1\xc9\x26\xbd\xd0\xcd\xa7\x13\x70\xad\xe4\x20\x2c\xab\ -\x0c\x20\x1c\xf4\xb7\x17\x3d\x1e\x8a\x1c\xdf\x50\xcf\x0f\xed\x02\ -\x6b\x97\x9f\x7e\x9a\xf6\x78\x98\xb6\x5b\xf7\xb3\x77\x17\x7e\x2b\ -\x5f\xa5\x4d\x9c\xc4\x4d\xbc\xa7\xa0\x97\x30\x6b\x49\x3f\x32\xa8\ -\xca\xf9\x3f\x7f\xfe\xe5\x7a\xd7\xd0\xe5\x62\x31\xff\x77\x59\xbd\ -\xe9\xdb\x0d\x02\x97\x21\xbe\x29\x37\x78\x15\x93\xeb\x41\x7c\x99\ -\x2c\xe6\x50\x6e\x80\xfe\x3a\x5b\x61\x6d\x3b\xbd\xf8\x77\x28\xb3\ -\xcb\xd9\x3e\x61\x94\xd9\x4d\xd6\xbe\xd2\xae\xda\x2a\xed\xb4\xe4\ -\xb3\xa6\x22\x59\xac\x32\x57\x68\xf6\x5b\x93\xe5\xf9\xaf\xae\x91\ -\xdd\x88\x0f\x2a\xcd\x9a\x3c\xdd\x0b\x2f\x67\xbb\xde\xef\xc6\x36\ -\x3b\x18\xdc\xe5\xac\x1f\x7d\xfb\x74\xbb\x9f\x95\x11\x14\xc3\x8b\ -\xce\xe3\x9b\x14\x8b\xe0\xb5\x4b\x0c\xde\x49\xbd\xad\xca\xcd\x7a\ -\x55\x26\xe9\xae\xf8\x30\x9b\xe9\xa2\x19\x5e\x59\xf3\x98\x23\xbd\ -\x55\x28\xf3\x97\xa4\xfd\x5c\x24\x59\xbd\x46\x09\x68\xfc\x3c\x2b\ -\xd2\x8b\x12\xaa\x76\x99\x97\xdb\xf9\x7d\x56\x67\x37\x79\x7a\xd1\ -\x7e\x67\x39\x46\x3e\x88\x96\x18\xfe\x7c\xa7\xaa\xda\x87\x70\xa7\ -\x68\xe6\xb4\x7b\xac\x36\x79\x3a\x2f\xca\xe2\x2d\x54\xd4\x45\xdd\ -\x54\xe5\x9b\x74\x68\xaf\x7b\xec\x70\x9b\x0f\x8f\xae\x6d\x8c\x63\ -\x7e\xb3\x69\x9a\x43\xd9\xff\xca\xac\x98\x63\xda\xd3\xaa\x97\xb6\ -\x0f\x39\x80\x69\xe6\xa2\x97\x25\x31\x34\x59\x55\x61\x14\x68\x34\ -\x3d\x94\x96\xcb\x65\x9d\x36\x73\x16\x19\xce\x0c\xa1\xd2\xf4\x89\ -\xfb\x1e\xaf\xe2\xea\x4d\x5a\x75\x25\xd3\x22\xc6\x00\xc3\x9b\x78\ -\xf1\xc6\x4d\x68\x91\xcc\xe3\x05\xd4\xca\x26\x87\xfb\x31\x02\xca\ -\x4d\xab\x20\x4a\x0c\xc2\xde\xec\xe9\xc8\xd9\x37\xb6\x4f\x18\x4c\ -\x9f\x89\x60\xb3\x14\x67\x43\x8a\x53\xa2\x94\xd2\xc8\xba\xcf\x20\ -\x05\x50\xdc\x46\x62\x0c\x5b\x05\xa9\x8a\x94\xe6\xd4\x30\x39\x2c\ -\xba\x7e\xcd\xec\x18\xb7\x74\x5f\x77\x53\xc5\x45\xed\x56\x3d\x18\ -\x8b\x9b\x2a\x7b\xf8\x01\x26\x5e\x68\xc6\x85\x31\x6a\x1a\xd2\x88\ -\x09\xc3\x30\x25\x53\x1a\x71\x22\x09\xa1\x62\x4a\x22\x6e\x08\x23\ -\x5c\xf3\xa9\x88\x8c\x45\x06\x21\xa7\x9c\x47\xc6\x70\x6a\x5f\x0d\ -\xa4\xed\x1b\x1d\x16\x54\xb7\x1e\xba\xf7\x3b\xd9\xa7\xb6\x9d\xe2\ -\x96\xf1\x50\x1d\x48\xdf\xed\x99\xb3\xe9\x9c\x12\x46\xd1\x05\xd3\ -\x1a\x76\x65\xa7\xe8\x2e\x27\x5a\x68\xce\x9d\x58\x08\x4d\xf0\xc7\ -\x4c\x75\xa4\xa5\xe5\x4c\x99\x69\xc8\x22\x29\x19\xb5\x8a\xbf\x3a\ -\xd4\x02\xeb\xb8\xb9\x3b\xa4\xfa\xd9\x35\xbf\x2c\x61\x27\xda\x14\ -\xbc\x76\x68\x86\xbc\x93\xdc\xc7\x55\x16\x17\xcd\x48\xb6\x6d\x5f\ -\xdf\x48\x84\x15\x94\xc2\x7f\x18\xcb\xa0\xbf\xe7\xd0\x75\xd9\x66\ -\x75\xe1\xd6\xed\xce\x58\x8c\xf2\x2c\xe3\x55\x96\x3f\xce\x7f\xc3\ -\xf8\x2f\xc2\x1e\xdc\xb0\x2b\xbe\x4e\x17\x83\x93\xd2\xe5\x68\xd2\ -\x87\x06\xb9\x12\x98\x34\x60\xd2\x3e\xc5\x79\x76\x5b\xcc\xe1\x23\ -\x57\x4d\x27\x48\xe0\x37\x54\x5d\x99\x76\xf9\x3e\x11\xb6\x04\x75\ -\x29\x79\xda\x00\x9b\x70\xa7\xb4\xfb\x6e\x6d\xe1\x45\x3c\x95\xb5\ -\x75\x0c\x2f\xa9\x2b\xbd\xad\xb2\x06\x59\x42\xa7\x5f\xe6\x79\x15\ -\x36\x37\x50\x1b\x0e\x01\xd7\x72\xde\x54\x17\xce\x9b\x69\x87\x5d\ -\xdf\x65\xcb\x66\xde\x3f\xee\xba\x5d\x2c\xee\x30\xf9\x5d\xbf\x3f\ -\x5b\xdd\xf4\xaf\xee\x23\xd5\xcd\xa1\x22\xe8\x74\x8d\x8c\xa4\x35\ -\x16\x6c\xb2\x4f\x47\xde\x7d\x9c\xb9\x0a\x98\x00\xc5\xee\x33\xa5\ -\xba\x33\x7b\x3a\x58\x04\x58\xac\xd4\x58\x6d\xa7\xf0\x4d\x09\xa5\ -\x26\x00\x60\x58\x99\x10\x88\x88\x30\x03\xbc\x03\x2c\x57\xc3\xb4\ -\x12\x62\x2a\x23\x0e\x90\x6d\x90\x07\x3c\x92\x4c\x70\xe1\x72\x71\ -\x2e\x14\x63\xa8\x8a\x45\xda\x58\xca\xdd\xf2\x66\xc6\x58\x19\xa0\ -\x41\xa9\x08\x01\xb4\x32\x52\x80\x40\x68\x88\x8c\x21\x12\x8c\x58\ -\xb4\x62\x98\x08\xde\x8e\x3a\xea\xb8\x73\x18\x70\xc2\x54\x28\xf4\ -\x38\x6d\xf0\xc3\xca\x02\x1a\xb7\x29\xab\x10\x1e\xd9\x7d\xdc\x6c\ -\xaa\xd4\x59\xfe\x91\x3d\xf3\x2c\x79\x96\xbe\x25\x4b\xb0\x42\x8c\ -\x4b\x02\x96\x60\x02\xa8\x84\x71\x04\x00\x34\xd2\x82\x49\xd8\x23\ -\xea\x98\xe2\xda\x02\x09\xcb\xa5\xa4\x53\x1e\x11\xa2\xad\x56\xe0\ -\x86\x13\x6b\x38\x48\x22\x46\x30\xae\x81\x12\x3a\x44\x98\xa0\xca\ -\xd9\x0d\xab\x14\xe5\x32\xf8\x29\x60\x36\xe2\x56\x4a\xad\xa7\xb0\ -\xb2\xb0\x77\xe8\x72\xc0\x60\xa0\x15\x51\xdc\x4e\x4d\x04\x33\x0d\ -\xa2\xa4\x83\x1a\xa6\x4f\x0a\x35\x55\x11\xb3\x44\x58\x13\xfc\xe7\ -\xcf\x89\x52\xa1\xf1\x48\x79\xa4\x8e\x12\x29\x0a\x77\xad\x35\x4a\ -\x0e\x29\xd5\x9b\x27\xb8\x98\x42\xcb\x0e\x0e\x43\x29\xbc\x27\x98\ -\x10\xca\xe0\xe1\xf1\x4e\x64\x94\xb5\x22\x50\x9d\x41\x93\xe0\x8a\ -\xa9\x34\x14\xc1\xeb\x80\xc1\xa0\x31\x45\x8c\x93\x49\x18\x32\xb8\ -\x87\xe0\x8a\x9a\x08\xbe\x34\xb1\x6c\xea\xaa\xd1\x46\x51\x1b\x50\ -\xc0\x28\xb8\x55\xad\x8c\xc0\x16\x1a\x13\x80\x3a\x4d\xe1\xac\x69\ -\x94\x16\x56\x33\x01\x73\xf6\x5e\xb0\x78\x68\x99\x67\xcb\xb3\x75\ -\x9c\x6c\xd9\xc8\x55\x01\x77\x8d\xf1\x08\x6e\x9b\x96\xce\x5f\x0b\ -\x1d\x5c\x9c\xca\x76\xf3\xc2\xa8\x52\x70\xf5\x40\x80\x8b\x9b\x29\ -\x27\x12\x04\x9b\xb6\x20\x6c\xd9\x92\x86\x41\x44\xb0\x9d\x62\x30\ -\x59\xf0\xf0\xa8\x82\x03\xe8\xd8\xa2\xc2\x62\x0f\x84\xea\x60\xda\ -\xd0\x04\x57\x6e\x5f\x86\x2d\xab\xb4\x01\xdc\x4c\x63\x15\xa5\xad\ -\x84\x62\xa3\x14\x00\x6d\x41\x99\xe1\xda\xc1\x0b\xab\x47\xe8\xae\ -\x36\x03\xe7\xd3\xb9\x89\x30\xa5\x86\x99\xf7\x7a\x85\x21\xf7\x9c\ -\x79\xce\x8e\x92\x33\x1b\xc1\x2d\x53\xc2\x82\x01\x50\xa3\xa9\xd5\ -\x06\x60\xb8\xe8\x05\x30\x10\xed\xc6\x1f\xbe\x9a\xb3\x25\xce\x55\ -\x14\x42\x49\x31\x0d\x61\xf7\x18\x37\xda\x6d\xa9\x84\xe4\x14\xee\ -\x23\x28\xb4\x8c\x59\xa6\x61\xc6\x40\x2e\xe1\x82\x52\xe7\xe0\x61\ -\xf3\x45\xe1\x45\xc2\x8c\x29\x57\x06\x9b\x2b\xe7\x0a\xa2\x49\x03\ -\x1a\x61\x17\x9d\xef\x08\xff\xd3\xb9\x8c\xcc\xe0\x27\x83\x3a\xb5\ -\xe5\x4c\x4b\x74\x48\xe0\x47\x63\x89\xfe\xa0\x19\x0b\xfd\xb6\xcb\ -\xf3\x75\x8c\x7c\xfd\x23\xa0\x0c\x6b\xdc\x32\x6a\x9c\x1d\x23\x54\ -\x59\x21\x9c\x4f\xe7\x6c\x15\xf6\x52\x6c\x8a\x6d\x99\xd1\x56\x60\ -\xaf\x64\xd1\x9c\x62\x42\xd0\x29\x83\xa1\xb1\x0a\x62\xc8\x28\xfc\ -\x41\xee\x2c\x94\x81\x29\x63\x12\xd0\xbc\x06\x22\x0a\xfd\xa2\x92\ -\x4d\x69\x9b\x41\x51\x54\x29\x60\x25\xe1\x11\x4a\x3d\x85\x1b\xa9\ -\x2c\x25\x52\x82\x39\x09\x5b\x66\xc1\x17\x93\x91\x36\x06\xfe\xa4\ -\x8d\xd4\x14\xbb\x32\xdd\x86\x55\x3e\x0c\x16\x0f\x3f\xd7\x45\xbc\ -\x9c\xdd\xbe\x27\x88\xf9\x95\xa2\xe2\x84\xc8\x65\xa2\x3f\xf6\x1d\ -\xef\xde\xab\xdb\x9d\x62\x7b\xca\x95\xfc\x8b\xe2\xe1\xe4\x2b\x84\ -\xc1\xbf\x34\x94\xab\xb0\x3c\xa0\xa0\x15\x75\xda\x5b\x50\x4e\x94\ -\xe6\xaf\x9e\x0b\x1f\xfb\xf0\xee\x77\xa1\x1b\x3f\x85\x9b\x67\x74\ -\x23\x8d\xa4\xc1\x26\x97\x33\x7a\x52\x0c\x9d\x68\x5c\xd9\x7b\x37\ -\x9e\x60\x4f\xf0\x88\xe0\x13\x8d\x66\x7b\x92\x3d\xc9\x9e\xe4\x43\ -\x92\x4f\x3d\x88\xee\x89\xf6\x44\x7b\xa2\x47\x44\x9f\x53\xe8\xde\ -\xe3\xed\xf1\xf6\x78\x1f\xe2\x7d\x16\x27\x06\x1e\x6b\x8f\xb5\xc7\ -\x7a\x8f\xf5\xe9\x1f\x54\x7c\x93\x63\x8a\x0f\xdf\xb5\x1e\x79\x08\ -\x5f\x16\xa2\x37\x58\x3f\xf8\xc9\x5a\xa7\x1b\xa9\x24\x84\x1b\xe6\ -\x6f\x5b\x7f\x1f\xaa\xe7\xff\x7f\x54\x79\x7a\x51\xf1\x50\xe8\x90\ -\x7a\x43\xee\x69\x3a\x4e\x9a\x4e\x34\x42\x1d\x9a\xcf\x3e\xf2\xf7\ -\x50\x79\xa8\xfc\x8d\xeb\x0f\xdc\xb8\x0e\xa5\xa7\xcb\xd3\x75\x9c\ -\x74\x9d\x53\xe0\x36\xe4\xfe\xb4\xd5\x93\x76\xa4\xa4\x9d\x45\x0c\ -\x35\xd4\xfe\xf4\xd3\x13\x76\x94\x84\x9d\x7e\x38\x33\x64\xdf\x28\ -\xa4\xf9\x95\x6e\x5e\x53\x29\xa8\x56\xfe\xe6\xf5\xc7\xfc\x12\x0d\ -\x26\x39\x74\x39\x73\x8e\x8b\xdb\x56\x10\x4b\x9f\xbd\x79\x8d\x9d\ -\x81\xd7\x8f\xe7\xaf\x1f\x3f\x8d\x9c\x33\x3b\x67\x3a\xc1\x28\xb3\ -\xf7\x71\x3c\xc3\x9e\xe1\x31\xc3\xa7\x1a\xdb\xf6\xff\x4e\xd4\xb3\ -\xec\x59\x1e\xb1\x7c\xf2\x21\x75\xcf\xb4\x67\xda\x33\x3d\x66\xfa\ -\xac\x02\xf9\xfe\x0e\xb6\x07\xdc\x03\x3e\x02\xfc\x3c\xce\x0f\xfc\ -\x49\xb8\x07\xdb\x83\x7d\x00\xf6\x19\x1c\x5b\x7c\x2e\xd3\x5f\x7c\ -\x0f\x9b\x7e\xb5\x80\x3d\x75\xf3\xe9\xe6\xce\x39\x28\x56\x71\x0a\ -\x67\xc6\xdf\xc3\xfe\x1e\x94\xcf\x31\x1c\x5d\x9e\x60\x84\xdc\xdd\ -\xc3\xf6\x17\xb1\x3d\x4e\x47\x8a\xd3\xa9\x06\xab\x4d\x48\x3c\x54\ -\x1e\xaa\xa3\x84\xea\xe4\xa3\xc6\x96\xf9\xeb\xa1\x9e\xae\x63\xa5\ -\xeb\xac\xe2\xb7\xfe\x88\xc6\x93\x76\xac\xa4\x9d\x47\x20\xd5\xff\ -\x3b\x58\x4f\xd8\x71\x12\x76\x06\x11\x4d\xf6\xd9\x70\xfd\x45\xbf\ -\x02\x9b\x2c\xf1\x82\xfc\x45\xec\x0f\xc6\x75\xb1\x54\x04\xd3\x8c\ -\xc8\x29\x7c\x24\x83\x32\xf0\x84\x9e\xbf\x88\xad\xfc\x4d\xec\xef\ -\x44\x41\x7e\x02\x3a\x67\x76\xd6\x74\x82\x71\x66\xff\x3f\xc1\x79\ -\x86\x3d\xc3\x63\x86\x4f\x35\xb8\xed\x2f\x75\x79\x96\x3d\xcb\x23\ -\x96\x4f\x3e\xa6\xee\x03\xea\x9e\x69\xcf\xf4\x98\xe9\xb3\x8a\xe4\ -\xfb\x5f\x0c\xe6\x01\xf7\x80\x8f\x00\x3f\x93\x03\x04\xef\x8e\x7b\ -\xb2\x3d\xd9\x07\x64\x9f\xc1\xc1\x85\xfc\x5c\xa8\x87\x73\x8b\xdd\ -\x0f\xed\xd7\xe5\xac\xbe\xc7\xd7\x1f\x02\xa0\x5e\xaf\ -\x00\x00\x06\xc9\ -\x00\ -\x00\x4c\x0c\x78\x9c\xed\x5c\x5b\x93\x9b\x36\x14\x7e\xdf\x5f\xa1\ -\xb2\x2f\xed\x74\x25\x10\x17\x73\x89\xed\x3c\x34\x93\x69\x66\xd2\ -\x97\x36\x4d\x67\xfa\x92\x61\x41\xb6\x69\x30\x72\x05\xac\xed\xfc\ -\xfa\x4a\xdc\x8c\x6d\xb6\xe3\x5d\x20\xa3\x4d\x4c\x66\x67\xc3\x39\ -\x47\x42\x7c\xdf\xb9\x48\x02\x76\xfa\x7a\xb7\x8e\xc1\x03\x61\x69\ -\x44\x93\x99\x82\x91\xa6\x00\x92\x04\x34\x8c\x92\xe5\x4c\xf9\xf3\ -\xc3\x5b\xe8\x28\x20\xcd\xfc\x24\xf4\x63\x9a\x90\x99\x92\x50\xe5\ -\xf5\xfc\x66\xfa\x03\x84\xe0\x17\x46\xfc\x8c\x84\x60\x1b\x65\x2b\ -\xf0\x2e\xf9\x9c\x06\xfe\x86\x80\x1f\x57\x59\xb6\xf1\x54\x75\xbb\ -\xdd\xa2\xa8\x12\x22\xca\x96\xea\x4f\x00\xc2\xf9\xcd\xcd\x34\x7d\ -\x58\xde\x00\x00\xf8\x75\x93\xd4\x0b\x83\x99\x52\x35\xd8\xe4\x2c\ -\x2e\x0c\xc3\x40\x25\x31\x59\x93\x24\x4b\x55\x8c\xb0\xaa\x1c\xcc\ -\x83\x83\x79\x20\xae\x1e\x3d\x90\x80\xae\xd7\x34\x49\x8b\x96\x49\ -\x7a\xdb\x32\x66\xe1\xa2\xb1\x16\xa3\xd9\x1a\x85\x11\x76\x5d\x57\ -\xd5\x74\x55\xd7\x21\xb7\x80\xe9\x3e\xc9\xfc\x1d\x3c\x6e\xca\xc7\ -\xd8\xd5\x54\xd7\x34\x4d\xe5\xba\x83\xe5\x65\x56\x5e\xca\x01\xdd\ -\xf0\x9f\xc6\xbc\x16\xa0\x94\xe6\x2c\x20\x0b\xde\x8e\xa0\x84\x64\ -\xea\x9b\x0f\x6f\x1a\x25\xd4\x50\x98\x85\xad\x6e\x6a\x3c\x8f\xae\ -\x7a\x04\x72\xe2\xaf\x49\xba\xf1\x03\x92\xaa\xb5\xbc\x68\xbf\x8d\ -\xc2\x6c\x35\x53\x0c\x13\x61\x83\x1f\x56\x21\x5c\x91\x68\xb9\xca\ -\x4e\xa5\x51\x38\x53\xf8\xe8\x75\xd7\x29\xcf\x5b\xce\x81\x4b\x83\ -\xaa\x63\xaf\xd1\x68\xc8\xd5\x11\x06\x0c\x5b\x86\x5d\xda\xd4\xb7\ -\xe0\x85\x34\x10\x63\xe2\x5d\x92\x75\xe4\xe7\x19\x5d\x73\xd6\x82\ -\x20\xf6\xd3\x34\x5a\x44\x01\x3f\xa1\xc9\x26\xce\x97\x51\xf2\xa9\ -\x10\x7e\xca\xe8\x27\x4e\x6a\x46\x19\xff\x1f\x8d\x51\x8d\x63\x73\ -\x51\xb2\xdb\x50\x96\xc1\x5d\xb8\xe1\x68\x4e\xec\x4e\xe5\xbe\x56\ -\xce\xb9\x76\x1a\x92\x45\x2a\xac\xca\x5b\x13\x67\xfc\xde\x6c\x05\ -\xa8\x85\xb6\x19\xa9\x18\x66\xf8\x10\x91\xed\xc1\xf6\xde\x4f\x4b\ -\xf8\x00\xd8\xf8\x4b\xee\x6a\x31\x65\x33\xe5\x76\x51\x1c\x95\xe2\ -\x9e\xb2\x90\xb0\x5a\x35\x29\x8e\x23\x15\xe5\x74\x44\xd9\xbe\x0c\ -\xae\xaa\xef\x7a\xbc\xa2\xd7\x46\xaf\x75\xeb\xd3\x95\x1f\xd2\xed\ -\x4c\xd1\x4f\x95\x5f\x28\x5d\xf3\x5e\x39\x2d\xae\xed\x68\x67\xea\ -\x60\x37\x53\x20\x76\x90\x63\x1b\x66\xc5\x4a\x5b\x2b\x06\x64\x71\ -\xa5\xee\xd8\xd6\x99\x32\x67\x8c\x87\x1f\x8c\xfd\x3d\xe1\x77\x55\ -\xfc\xaa\x7b\x48\x57\x74\xbb\x64\x02\x9d\x8c\xe5\xe4\xb4\xa5\xd0\ -\xc0\xfb\x7b\xba\xeb\x56\x73\x6f\xc8\x45\x60\xc3\x3c\x89\x32\x1e\ -\x3c\x9b\x5d\xbb\xd7\x3c\x0a\x49\xda\xdd\x30\x4d\xfc\x0d\x5c\xc6\ -\xf4\xde\x8f\xbb\x0d\xb6\x51\xc2\x51\x82\x95\x9f\x63\xa3\x21\xe1\ -\xd4\xa2\x76\x7a\x5b\x73\x1e\xb1\xe0\x63\x3f\x23\xa2\x52\xed\x1f\ -\x57\xad\xfd\x5d\xb4\x8e\xbe\x10\x0e\x0c\x2e\xfc\x8e\xfb\xd6\x11\ -\x2c\x65\x33\x00\xb2\xbd\x08\xe0\xdd\x5e\xc8\x94\x5a\x28\xf0\x14\ -\x02\xdd\x75\xed\x46\x48\x59\xc4\xe3\xa2\x35\x9c\x5a\xb4\x6f\x8b\ -\x44\xb8\xf3\x6c\xbd\x2b\x1c\xac\x70\x3f\xfb\x54\xb7\x6f\xeb\x2a\ -\xbf\x57\xcf\x1d\xbf\x90\xaf\x49\xe6\x87\x7e\xe6\x1f\xa2\xa0\x96\ -\xf0\xb1\x69\xf5\x9d\xf1\xcc\xe9\xfd\xfe\xe6\xed\xbc\xba\xd0\x34\ -\x08\xbc\xbf\x28\xfb\x5c\x5f\x17\x00\x61\xe0\xdf\xd3\x9c\x23\xad\ -\xcc\x1b\xf1\x34\x0c\x3c\x9e\xeb\x78\x0e\x98\x47\x6b\xee\xdb\x22\ -\x4d\xfe\xcc\x73\xdb\x54\x3d\x28\x8e\x8c\x05\x58\x87\x4e\xcb\x6e\ -\x19\x29\x93\x66\x67\xe5\x08\x83\x75\x24\x1a\xa9\x7f\x64\x51\x1c\ -\xbf\x13\x17\xa9\xee\xb8\xd5\x69\x94\xc5\xe4\x20\x9c\xaa\xd5\xe8\ -\xab\x7b\x53\x5b\x37\x37\x55\xeb\xbb\x2f\xce\x96\x07\x54\x8e\x82\ -\xa2\x21\x3a\xf6\xef\x09\xf7\xd0\xf7\x42\x09\xce\xb4\x4b\x46\xf3\ -\xcd\x9a\x86\xa4\x6a\xde\xa0\xc9\x13\x5e\x43\x59\xb6\x8f\xb9\x7e\ -\xc1\x47\xef\xdd\xea\xba\x65\x69\xda\x2b\x71\x02\xab\x3c\xe1\xe1\ -\xf2\x94\xe5\x31\xcf\x77\x0f\x24\xa1\x61\xf8\x2a\xcd\x18\xfd\x4c\ -\xbc\x5b\x8d\xe7\xa5\x60\x51\x9d\x96\xc1\xe0\x69\xc8\xb1\x8c\x22\ -\xbd\xd7\x72\x8e\x10\x61\x31\xf7\xd6\xcc\x33\x6b\x59\xe8\xf3\x3c\ -\xc3\x98\xbf\xf7\x12\x5e\xe7\x6b\x69\x73\xcd\x23\x47\x15\xc3\xb5\ -\x1c\xc3\x85\x18\x3a\xd0\x6c\x54\x55\xec\x59\xc8\x30\x0e\xd5\x44\ -\x1c\x75\xc8\x99\xc8\x2d\x34\x87\x26\xdc\x69\x0d\xad\x94\xea\x8d\ -\x70\x2f\x2c\x8b\x82\xd4\x12\xb2\xa3\x30\x60\x85\x47\x4f\x4c\x71\ -\x4c\x0e\x63\xfb\xbf\x1a\xd1\x65\xd0\xd4\x89\xda\x19\x5e\x34\x13\ -\x18\xba\x63\x70\xc1\x67\x21\x8e\x56\x1c\xf8\xca\xc6\xe5\x6c\xb8\ -\x50\x1f\x83\x0d\x6c\x5e\x49\x78\x4a\x48\x58\xd0\x1e\x83\x06\xb7\ -\x2a\xa7\x93\x2b\x1b\x97\xb3\x61\x8f\x53\x2c\x74\x03\x39\xc7\xd3\ -\x9e\x2b\x17\x97\x44\x86\x05\xb5\x51\x32\x94\x73\x2a\xbc\xd2\x71\ -\x41\xb5\x18\x29\x38\x0c\x03\xd9\xc7\x96\x57\x36\x2e\x2a\x1b\xda\ -\x38\xb3\x29\xdd\x41\xb6\x2b\x0e\x69\xf8\xb0\xac\xd0\x94\x98\x8f\ -\xbe\x2c\xe8\x1a\xd2\x8f\x2b\xb5\x94\xeb\x0b\xd3\xf4\x7d\x89\x59\ -\xc0\xd0\xec\x9b\x9e\x74\x0b\x5d\x39\xe8\xc9\x01\x74\x06\x26\x41\ -\xc6\xc5\x9d\xe4\x09\xa9\xff\x96\x47\x67\x4a\x92\x68\x61\x27\x7d\ -\x1c\x38\x0e\x9c\x0c\x1c\x08\x12\xc1\x2f\xb9\xff\x6b\x3c\x0d\xe1\ -\x51\x42\x40\xbe\x45\xb5\xf4\x91\x60\x42\x1d\x1a\x03\x87\x82\x7c\ -\x34\xc8\x1e\x11\x46\xff\xba\xdc\x15\x0f\xf2\x6d\x6c\x48\x1f\x0f\ -\x93\xc1\x0b\x83\x7c\x24\xc8\x1e\x0d\xd0\xee\xbd\xf5\xdd\x3d\x43\ -\x92\x6e\x63\x49\xfa\x70\x30\x79\x40\x0c\x5d\x1e\xae\x34\x3c\x67\ -\xbe\xda\xff\xe1\xdc\x29\x0f\xf2\xed\xec\x49\x9f\x98\x4c\xc1\xc5\ -\x28\x95\x5a\xba\x5d\x3d\xe9\x63\x42\xcc\x5c\xed\xde\x0f\xe7\xce\ -\xaa\xb5\x74\x44\xbc\x88\xa0\x18\x60\x63\xa9\x2b\x2c\xae\x29\xea\ -\x59\x6c\xe8\xe3\x6c\x7a\xcb\xb8\xd7\xf7\xd4\x87\x41\xe5\xab\x97\ -\x27\x7c\x8c\x51\xb1\x7b\x12\xe0\xa2\x49\x81\xb4\xd9\x26\xc0\x44\ -\xa5\xdf\x18\x17\xc1\xff\x82\xc1\x83\x78\x0c\xf8\xb8\xff\x9a\x4f\ -\xf1\xdf\x97\x0c\x60\xdf\x04\xd0\x09\x20\x36\xd1\x65\x99\xf8\x25\ -\x23\x87\xa1\x35\x06\x76\x2e\x32\x8b\x84\x7a\xd9\xaa\xe7\x25\x03\ -\xd8\x77\x4a\xd6\x09\x9f\x6e\x9e\x16\xa4\x6f\x15\x3e\xf1\x62\xcd\ -\x28\xc1\xeb\xa2\x13\xcb\x6f\x15\x41\x77\x1c\x17\x3c\xfe\xca\xe5\ -\x5b\x06\xb0\x78\x7d\x65\x94\x28\x76\x91\xfe\x8c\xfa\xbb\xf1\xb3\ -\x55\x27\x84\x65\x35\xef\x07\x21\x46\xba\x6b\x68\xb6\xed\x36\xb3\ -\xf1\x38\x4a\x08\x9f\x8e\x7a\xe9\xbf\xb9\xcf\x48\x5b\xfa\x0f\x8d\ -\x12\xaf\x80\xfa\xe9\xb8\x0b\x29\x5d\x2c\x52\x92\x1d\x58\x3b\xe7\ -\x82\x53\xf1\x1b\x10\x13\x15\x1d\xbb\x3a\x9f\xed\xdd\x61\x03\x4d\ -\xdc\x89\x6b\x83\x5f\x01\x9e\x80\x8f\xc0\x2e\x69\xd0\x2d\xf0\x1e\ -\x18\x1a\x32\x26\x2e\x76\xac\x3b\x6c\x23\x0b\x8b\x7f\xdc\xe8\x4e\ -\xb7\xab\x26\x1f\x81\x8e\x2b\xd6\x78\xf3\x56\xaf\xe0\xef\x33\xf2\ -\x0d\x07\xb7\x3c\xa2\xf9\x90\x87\x26\x49\xf1\x31\x15\x0c\x72\xf6\ -\xe0\x67\x39\x23\x47\x9f\x8e\x34\x9f\x80\xd0\x90\x88\xaf\x26\xd2\ -\x99\x12\x54\xc7\x08\x8b\xa9\xaf\x12\x01\x3d\xfd\x1e\x9e\x7f\x44\ -\x33\xc2\xcc\xfd\xa9\xbb\x33\x5f\x29\x77\xf4\xc4\xae\xae\xf1\xee\ -\x77\x08\x5d\xef\x97\x42\x3a\xc1\x1b\x7e\xc9\x23\x65\xcc\xf6\x5e\ -\x6e\x77\x47\xed\x80\xeb\x1d\x59\xbd\xce\xe9\x8b\x5c\xa7\xdb\x0d\ -\x08\x9c\x9c\xfe\xa6\xf5\x0e\xd7\x6e\x8f\x1b\x7a\x95\x28\xab\xdb\ -\x99\xbd\x9f\xf0\x76\xfa\xdd\xd0\xf0\x49\xea\x7c\x7d\x9f\xc8\x76\ -\xfb\xde\xd0\x4b\x6c\x59\x7d\xaf\xef\x0b\x1e\x9d\x9e\x37\x34\x78\ -\x92\x7a\x5e\xef\x95\xf5\x23\x85\x76\xe0\xbd\x09\x59\x5d\xcf\x1c\ -\xc7\xf9\xbe\x17\xf8\x9c\xfe\x0f\x06\x3a\xf1\x1b\x7a\x67\x47\xd6\ -\xe0\x35\x7b\xc3\xf7\x48\xe5\x78\xde\xb6\xce\x8b\xf3\xbf\xe2\x95\ -\x83\x51\xaa\xc7\xc0\x00\x4a\xec\x80\x23\x4d\x9c\xbf\xa3\x10\xee\ -\x3d\x75\xee\x46\xf0\x79\x5b\x05\x53\x75\x39\xbf\x99\x8a\x3f\xc3\ -\x32\xbf\xf9\x0f\xb1\xb1\x20\x51\ -\x00\x00\x08\xae\ -\x00\ -\x00\x1e\xc0\x78\x9c\xed\x59\x5b\x8f\xe2\x56\x12\x7e\xef\x5f\xe1\ -\x65\x5e\x12\x2d\x36\xe7\x7e\xa1\xe9\x8e\xb4\x19\x45\x8a\x94\x7d\ -\xd9\x4d\x94\xc7\xc8\xd8\x07\xda\x3b\xc6\x46\xb6\x69\x60\x7e\x7d\ -\xbe\x63\x63\x03\x0d\xcc\xcc\x6a\x7a\xd4\x59\x69\x21\x33\x83\xab\ -\xea\x5c\xea\x3b\x5f\xd5\xa9\x72\x66\x3f\xec\x56\x79\xf0\xec\xaa\ -\x3a\x2b\x8b\x87\x11\x8d\xc8\x28\x70\x45\x52\xa6\x59\xb1\x7c\x18\ -\xfd\xf6\xeb\x4f\xa1\x19\x05\x75\x13\x17\x69\x9c\x97\x85\x7b\x18\ -\x15\xe5\xe8\x87\xc7\xbb\xd9\xdf\xc2\x30\xf8\xb1\x72\x71\xe3\xd2\ -\x60\x9b\x35\x4f\xc1\xcf\xc5\x87\x3a\x89\xd7\x2e\xf8\xee\xa9\x69\ -\xd6\xd3\xc9\x64\xbb\xdd\x46\xd9\x41\x18\x95\xd5\x72\xf2\x7d\x10\ -\x86\x8f\x77\x77\xb3\xfa\x79\x79\x17\x04\x01\xd6\x2d\xea\x69\x9a\ -\x3c\x8c\x0e\x03\xd6\x9b\x2a\x6f\x0d\xd3\x64\xe2\x72\xb7\x72\x45\ -\x53\x4f\x68\x44\x27\xa3\xa3\x79\x72\x34\x4f\xfc\xea\xd9\xb3\x4b\ -\xca\xd5\xaa\x2c\xea\x76\x64\x51\xbf\x3b\x31\xae\xd2\xc5\x60\xed\ -\x77\xb3\xe5\xad\x11\xb5\xd6\x4e\x08\x9b\x30\x16\xc2\x22\xac\xf7\ -\x45\x13\xef\xc2\xf3\xa1\xd8\xe3\xb5\xa1\x8c\x10\x32\x81\xee\x68\ -\xf9\x65\x56\xd3\x1a\x80\xae\xf1\x67\x30\xef\x05\x51\x5d\x6e\xaa\ -\xc4\x2d\x30\xce\x45\x85\x6b\x26\xef\x7f\x7d\x3f\x28\x43\x12\xa5\ -\x4d\x7a\x32\x4d\x8f\xe7\xd9\xaa\x67\x20\x17\xf1\xca\xd5\xeb\x38\ -\x71\xf5\xa4\x97\xb7\xe3\xb7\x59\xda\x3c\x3d\x8c\xb8\x88\x28\xc7\ -\x47\xb6\xc2\x27\x97\x2d\x9f\x9a\x97\xd2\x2c\x7d\x18\x61\xf7\xcc\ -\x9a\xee\xf9\x84\x1c\xb4\x33\x38\x4c\x3c\x1d\x34\x24\xb2\x2c\xa2\ -\x41\x45\x25\xd7\x9d\x4d\xef\xc2\x34\x2d\x13\xbf\x27\x4c\xe9\x56\ -\x59\xbc\x69\xca\x15\x4e\x2d\x49\xf2\xb8\xae\xb3\x45\x96\xe0\xa1\ -\x2c\xd6\xf9\x66\x99\x15\x7f\x54\x65\xf6\x47\xb9\xf6\x82\x3a\xea\ -\xe1\x1b\xd6\x72\xbb\x75\x59\x35\xe1\x2e\x5d\x03\x44\xa5\xaf\x2a\ -\xf7\xa7\xca\xe7\xcc\x6d\xff\x51\xee\xb0\xb9\x80\x04\x9c\xe1\xbf\ -\xd1\x23\xe4\xb3\xd4\x2d\x6a\xaf\xef\x1c\xf5\x4f\xf0\x54\x8f\x82\ -\x49\xab\x1d\xf6\xed\x37\x9d\xfa\x39\x8e\xb6\xf3\xb8\xee\xc0\x0c\ -\x82\x75\xbc\x04\xf1\xf2\xb2\x7a\x18\xbd\x5b\xb4\x9f\x83\x62\x5e\ -\x56\xa9\xab\x7a\x95\x6a\x3f\x67\xaa\x12\x87\x93\x35\xfb\x2e\xd4\ -\x0e\x73\xf7\x6e\xf8\x59\x07\x3d\xb9\xae\xaf\x9f\xe2\xb4\xdc\x3e\ -\x8c\xd8\x4b\xe5\xc7\xb2\x5c\x3d\x8c\x74\x64\xa9\x21\x82\xea\x97\ -\xea\x04\x48\x84\x3a\xa2\x4c\x2b\xaa\x2e\x06\x27\x58\x90\xe9\x48\ -\x50\x6e\xe5\x85\x6e\x53\x55\x88\xc5\x30\x8f\xf7\x0e\x4e\xb5\xff\ -\xd0\x83\x51\xfd\x54\x6e\x97\x95\x07\xa7\xa9\x36\xee\xe5\x48\xaf\ -\x09\xe7\x73\x7f\x08\xd7\xd4\xa0\xc6\xc6\x47\x79\xb8\x29\xb2\x06\ -\x91\xb4\xde\x9d\xce\xba\xc9\x52\x57\x5f\x1f\x58\x17\xf1\x3a\x5c\ -\xe6\xe5\x3c\xce\xaf\x1b\x6c\xb3\x02\x20\x85\x07\xd2\x53\x3e\x9c\ -\xc1\x4b\x8b\x3e\x02\x34\xb1\x37\x2c\x3c\x81\x6e\xa8\xf6\xb7\x55\ -\xab\x78\x97\xad\xb2\x8f\x0e\xc0\xd0\x96\x76\xa0\xd6\x19\x2c\xdd\ -\xb0\x20\x68\xf6\x3e\x9a\x77\x7b\x2f\x1b\xf5\x42\x8f\xa7\x17\x30\ -\x6b\xf5\x20\x2c\xab\x0c\x41\x72\xb2\x9d\x5e\xb4\x3f\x15\xf9\xd8\ -\x47\xea\xde\xf9\x75\x5f\xc8\x3c\xe7\x7a\x9a\x4f\x2e\x79\xde\xca\ -\x57\xae\x89\xd3\xb8\x89\x8f\xa4\xef\x25\xd8\x0b\xe9\x3d\x41\xda\ -\x9c\xfe\xeb\xfd\x4f\x8f\x87\x05\x66\x49\x32\xfd\xbd\xac\x3e\xf4\ -\xeb\x05\x81\x37\x88\xe7\xe5\x06\xc8\x8e\x1e\x07\xf1\x2c\x4d\xa6\ -\x48\x74\x48\x00\x8f\xd9\x0a\x54\xf6\x39\xf2\xef\x48\x6c\xb3\xc9\ -\x51\x71\x66\xec\xc1\x39\x4e\xda\x4d\x5b\xb9\x2e\x63\x5e\xbd\x36\ -\xd2\x64\x95\xf9\x41\x93\x7f\x37\x59\x9e\xff\xec\x17\x39\x78\x7c\ -\x32\x69\xd6\xe4\xee\xb1\x5d\xb3\xfb\xd9\x7b\x31\x39\xb8\x71\x70\ -\x72\x72\xe2\xe5\x6c\xd2\xc3\xd0\x3e\x2d\x8f\xf0\x9c\x45\xc3\x70\ -\xc2\x79\x3c\x77\xa0\xe6\x2f\x5e\x19\x5c\x68\x97\x55\xb9\x59\xaf\ -\xca\xd4\x1d\x86\x0f\xb0\xba\xa4\x19\xce\xac\xd9\xe7\xd0\x2f\xe0\ -\xc6\xf4\x9d\xb3\xf1\x9c\xaa\x7b\xff\x10\x1e\xf2\xc3\x94\x76\x8f\ -\xd5\x26\x47\xfa\x7b\x76\x45\x99\xa6\xf7\x75\x53\x95\x1f\xdc\xf4\ -\x1d\x35\xa9\x5a\x2c\x0e\x8f\x5d\x14\x4c\x59\x44\xb8\x25\x5a\x08\ -\xd6\xcb\x01\x95\xab\x72\xd0\xb4\x99\x8a\x5e\x96\xc6\xc8\x2f\x55\ -\x15\xef\xa7\x05\x6e\xfb\x5e\x3a\xac\x79\xc6\x50\xbf\x5d\xb0\xc2\ -\x0e\xc2\xfe\x8e\x39\xb2\x71\xb8\x60\x8e\xa2\x33\x66\xee\x4f\x1f\ -\x2a\xa8\x44\x04\xca\x33\x76\x22\x84\x09\x8f\xa4\xd2\x44\x73\x35\ -\x9c\xe5\x6c\x1d\x37\x4f\x57\xa1\xb2\xed\x67\x40\xa2\xcb\xcd\xe7\ -\x48\x70\x20\xa1\xa5\x64\x6a\xbd\xeb\x15\x79\x56\x38\x1c\xcd\x74\ -\xbe\x69\x9a\x53\xd9\x7f\xca\xac\x98\xb6\x38\xdd\x86\xc2\xc7\x48\ -\x40\xd5\x58\x07\x49\x40\xc6\xd4\x1c\xff\x3a\x43\xcb\xef\x98\x6b\ -\x65\x43\x75\x14\x0f\x19\xb6\x2c\xb0\x7e\x53\x56\x21\x72\xed\x73\ -\xdc\x6c\x2a\xe7\x63\xfa\xf3\xde\x1a\xe2\xbf\x9f\xf1\x96\x2b\xa1\ -\xb5\x52\xf4\x15\xdd\xd5\x63\x2a\x71\x28\x02\x5f\x78\x4d\xcd\x98\ -\x1c\xff\xba\xf4\xda\x08\xfd\x8a\x3e\x0b\xc3\x35\xd7\x83\xcf\x4c\ -\xf8\xef\x4b\x9f\x19\xb7\x42\x0b\xfe\xdf\x3b\xfc\x35\x41\x01\x7f\ -\xff\x19\x50\x11\x11\xad\xb5\xe5\x63\xaa\x22\x49\x95\xd6\x01\x93\ -\x91\x11\x42\x80\x23\x32\xa2\x82\x58\x4b\xe9\x25\x48\x38\xc7\x57\ -\x04\x09\x15\xe8\x82\xb1\x2f\xcf\x18\xd7\x50\x44\x01\x22\x85\x20\ -\xc6\x7e\x0a\x9b\xdb\x28\x08\x61\x0c\x67\x63\x46\x23\x25\x24\x67\ -\x36\xd0\x91\xe2\xd6\x30\x39\x46\xa1\x21\x35\x15\x8c\x07\x3f\x42\ -\x48\x84\x22\x4c\x8f\x99\x89\x88\x31\x08\xfd\x40\x46\x8a\x31\x8c\ -\x1d\x7b\xdc\x94\xb1\xd4\x42\x44\xac\xc4\x91\x7a\x11\x52\x8e\x30\ -\x32\xf8\x25\xe0\x91\xd1\xf0\x13\x4b\xf0\xc8\x82\xe0\x42\x62\x3e\ -\xd0\x5d\x30\x49\xa5\x17\x0a\xa2\x19\xb1\x10\x51\xae\x09\x97\x7e\ -\x2b\xd6\x4a\xcc\x0d\x91\x06\xe0\xdd\xee\x84\x36\x82\xe9\x20\x0f\ -\x54\x64\x88\x25\x44\x8f\x43\x89\x72\x56\x11\xcb\x7d\x44\x47\x5a\ -\x2a\x29\xcd\x18\xb5\xb8\x92\x46\x48\x15\xa0\xd2\x25\xd4\x08\xeb\ -\x45\x9a\x2a\x82\xcd\x30\x1c\xb0\x31\x52\x79\x11\x65\x0c\xf5\x17\ -\x12\x00\xc2\x21\x02\xa8\x98\xdc\x8b\x89\xa2\x84\xc1\x90\x69\x69\ -\xe8\x98\x61\x73\x4a\x19\xe4\x89\xc8\x48\x8a\x08\xf1\x12\x70\x05\ -\xdb\x85\xad\xe4\x88\x58\x36\x06\x8d\xa9\xd4\x1c\x22\xea\x7f\x29\ -\xcd\x21\x42\xc0\x73\x61\x82\x8f\x17\xa9\x18\x4b\xc9\x2f\x66\xd0\ -\x40\x9a\xa1\x0c\xc0\x75\xe4\x6f\x4e\x54\x5c\x75\xfb\x49\x3e\xd6\ -\x47\x9e\xb9\x3c\xcf\xd6\xb5\xbb\x4a\xb5\x03\x75\xbe\x98\x6a\xd7\ -\x92\x14\x5c\x06\xd7\x08\xdc\x7f\xad\xcb\xa9\x8d\x29\xcb\x78\xc8\ -\x07\x71\x53\xc5\x45\xed\xcb\x0c\x64\xb0\xb8\xa9\xb2\xdd\x77\xfe\ -\x58\xa4\x54\x8c\xb2\xf6\x7c\xad\xc5\xf9\x52\xb0\xcc\xff\xd6\x4a\ -\x70\x21\xa5\xff\x0d\xec\x0d\x28\x24\xc7\x38\xd3\xef\x87\xe9\xda\ -\x82\x1a\x2c\x63\x4a\x58\x75\x5c\xc5\x57\xd2\xa1\xf0\x7c\x50\x18\ -\x73\x76\xb9\xf9\x54\xcc\x38\xe1\x67\x97\x1b\x8b\x2c\x98\xc1\xe9\ -\xe7\x83\xfa\xc4\xe9\x36\xc0\xf1\x79\x89\x22\x3a\x4f\xce\xd8\x9b\ -\xa4\x3d\x10\xd9\x52\x2e\xad\xbf\x19\x04\x27\x0c\xd1\x83\x4c\x68\ -\x18\x97\x6d\x94\x71\xa9\xb8\xd1\x17\x47\x24\x8d\x55\xe1\xe9\x21\ -\x7d\x4d\xea\x6b\xbb\xae\x01\x9a\x34\xab\xd7\x28\xaf\xd0\x33\x7b\ -\x97\xef\x4b\x34\xab\x8b\xbc\xdc\x4e\x9f\xb3\x3a\x9b\xe7\xee\xbe\ -\xfd\x37\xcb\xbd\x2f\xbd\xe8\x12\xe6\xb9\xf3\xdf\x97\x30\x6b\xf4\ -\x58\x08\x63\xf1\x2d\x71\xf6\xd2\x72\xb1\xa8\x5d\x33\x25\x17\xd8\ -\xdf\xaf\xe2\xea\x83\xab\xba\x01\xae\x88\xb1\xf9\x70\x1e\x27\x1f\ -\x7c\x65\x59\xa4\xd3\x38\x41\x63\xb5\xc9\xe3\xc6\x5d\x64\x65\x85\ -\xcb\x53\xd1\x31\xb5\x91\x30\xd6\x58\x1d\x58\xa4\x67\xa6\x6c\x9b\ -\x45\xa5\xb0\xf2\xd6\x11\xd1\x57\xbc\x9d\x98\xa2\x48\x96\x2f\x53\ -\x46\x8f\x79\xa2\xfd\xf7\x2d\x30\xbf\x55\xdc\xb1\xc8\x67\x03\x0f\ -\x1b\xae\x74\x8b\xe4\x1f\x84\xbe\x50\x45\xc2\x1e\x83\xe3\xd2\x2a\ -\x22\x6e\xc2\x16\xda\xd7\x03\xee\x0b\x32\x80\x36\xcc\x68\x66\xd4\ -\x1b\xa4\x80\x63\x99\xe3\x5f\x24\x28\x2a\x94\xf5\x05\x21\xbd\x49\ -\xa9\x57\x44\xe6\x46\xc1\x73\x82\x95\xd7\xfe\x65\x8a\x44\xe6\x19\ -\x65\x88\x42\x4d\x82\xb2\x82\x4a\xcb\xa5\xcf\xa0\xb8\x48\x8d\x46\ -\x06\xc5\xb5\xc4\x04\xd5\x97\xe9\xd2\x57\x89\xe1\x2b\x16\xd3\x7f\ -\x65\x42\xb5\x71\x87\x68\xb3\x40\xc9\xa2\xd4\x63\x82\x5b\x1a\x18\ -\xdc\x24\x04\x25\x16\x38\x86\x8a\x8a\x6a\x66\x6f\xb2\xeb\x35\x3b\ -\xad\x33\xa0\xae\x55\x30\x34\x22\xa8\x68\x95\xa0\xf4\x2d\x80\x22\ -\x91\x90\x8c\x0a\x04\x1b\x9a\x5b\xe9\x21\xeb\x81\xe2\x3d\x50\x97\ -\xe5\xd1\x80\x93\x0d\xd9\x57\x22\xd5\x57\x91\xdd\xdb\xac\xb8\x4a\ -\x46\xdf\xe4\x6a\xfe\x6c\x5b\x03\xac\x3e\xba\xaa\x3c\xb6\x35\xdc\ -\xc8\x23\x75\x0f\x94\xfe\x1f\xba\xb5\x8f\x95\xec\xc9\x6b\x96\x01\ -\xed\xb6\x02\x45\x68\xa0\x6d\xa2\xea\x8a\x1a\xd5\xa5\x8d\x38\x30\ -\x30\xea\xca\xe8\xae\x22\xd5\x16\xdd\xd2\x95\xc1\xdd\x7b\x17\x8b\ -\x89\xb9\xe1\xe7\x6c\x0b\x95\xef\xc6\xf4\x78\x98\x3b\x88\x83\x7e\ -\xa2\xf1\x30\x26\xf0\xaf\xdd\x69\x10\xfa\x56\x0b\x5d\x92\x90\x9d\ -\x0a\xcd\x11\xfd\xa4\xb5\x11\xaa\xed\xdf\xfc\x4f\xa2\x34\x7a\xc3\ -\xdb\xe6\x1c\x9d\x22\xca\x18\x36\xc6\x75\x8c\xc2\x97\x23\x9f\xa3\ -\x8f\x43\x0b\xa6\x14\x21\xc6\x9b\x53\x8d\x84\x2a\x4f\xba\xa5\xc1\ -\xc1\xba\x89\xab\xe6\x6a\x2b\xe4\x8a\xd4\xbf\x88\x42\x7b\x86\xc5\ -\x8f\xd0\x5c\x6f\x1f\xd0\x9f\xe2\x0a\x51\x5d\xfb\xa0\x51\xd7\x08\ -\x3e\x6e\x7f\xa2\x5c\x91\x5d\xdf\x87\x46\x58\x2b\xdb\x35\x0f\xff\ -\x0f\x9f\xb7\x0a\x9f\xf0\x46\x00\xa1\x37\x31\x56\xa0\xeb\xbb\x1e\ -\x40\x21\x13\xe8\xda\xa4\x22\xd7\x62\xe4\x10\x41\xd4\x72\xa2\x6f\ -\x87\x90\x7f\x1f\x70\x1e\x41\xa8\x94\x40\x2e\xca\xd0\x69\x0e\xd3\ -\x1f\x82\xa8\x9d\x6b\xdc\x0f\x3b\x0d\x22\x25\x4d\xa7\x00\xa7\xd5\ -\x27\x6d\xfd\x5b\x0a\x34\x62\x6d\x04\x69\x4e\x6f\xdb\xb6\xf1\xc3\ -\xb9\x38\xc4\x0f\xa6\x3e\x84\x8f\xb4\x86\xb5\xe1\x83\x82\xee\x5b\ -\x46\x0f\x91\x86\x09\x22\xda\x88\x41\xf7\xcd\x49\xd7\x7b\xfb\xdf\ -\x92\xb6\x3d\x39\xf1\xef\xa0\x38\xb2\xcd\x49\xf8\xcc\x26\xcb\xc7\ -\xbb\x99\xff\xbf\x07\x8f\x77\x7f\x02\x11\xca\xfc\x10\ -\x00\x00\x0a\x36\ -\x00\ -\x00\x25\xab\x78\x9c\xd5\x59\x5b\x6f\xdb\x46\x16\x7e\xf7\xaf\xe0\ -\x2a\x2f\x0d\x56\xa4\xe6\x7e\x51\xec\x14\x68\x83\x16\x05\xba\x58\ -\xa0\x6d\xb0\x8f\x05\x45\x8e\x64\x6e\x28\x52\x20\x29\x5b\xca\xaf\ -\xdf\x6f\xa8\x0b\x49\x59\x4a\xec\x44\xdb\xec\x52\x30\x2c\xce\x39\ -\x73\x39\xf7\xef\x8c\x6e\xbf\xdf\x2c\xf3\xe0\xc1\x55\x75\x56\x16\ -\x77\x23\x1a\x91\x51\xe0\x8a\xa4\x4c\xb3\x62\x71\x37\x7a\xff\xc7\ -\x4f\xa1\x19\x05\x75\x13\x17\x69\x9c\x97\x85\xbb\x1b\x15\xe5\xe8\ -\xfb\xb7\x37\xb7\x7f\x0b\xc3\xe0\xc7\xca\xc5\x8d\x4b\x83\xc7\xac\ -\xb9\x0f\x7e\x29\x3e\xd4\x49\xbc\x72\xc1\x77\xf7\x4d\xb3\x9a\x4e\ -\x26\x8f\x8f\x8f\x51\xb6\x1f\x8c\xca\x6a\x31\x79\x1d\x84\xe1\xdb\ -\x9b\x9b\xdb\xfa\x61\x71\x13\x04\x01\xf6\x2d\xea\x69\x59\xcf\xee\ -\x46\xbd\x19\xe5\xca\x15\xf5\x63\xdc\x24\xf7\xb3\xb2\xfc\xd0\xce\ -\x5b\x57\xd9\x84\x11\x62\x27\xe0\x1d\x75\x33\xd3\xe4\x38\x71\xb5\ -\xae\xf2\x96\x35\x4d\x26\x2e\x77\x4b\x57\x34\xf5\x84\x46\x74\xd2\ -\x63\x4f\x3a\xf6\xc4\x9f\x3b\x7b\x70\x49\xb9\x5c\x96\x45\xdd\xce\ -\x2c\xea\x57\x3d\xe6\x2a\x9d\x0f\x4e\xf5\xc8\x5b\x26\x6a\xad\x9d\ -\x10\x36\x61\x2c\x04\x47\x58\x6f\x8b\x26\xde\x84\xc3\xa9\x90\xee\ -\xdc\x54\x08\x40\x26\xa0\x75\x9c\xcf\xe3\x9a\x6e\x72\x28\xf1\xe2\ -\x61\x5a\x6a\x7f\x77\x18\x6e\x85\xbf\xe3\x84\xc3\x40\x54\x97\xeb\ -\x2a\x71\x73\xcc\x74\x51\xe1\x9a\xc9\xbb\x3f\xde\x1d\x89\x21\x89\ -\xd2\x26\xed\x2d\x73\xb0\xdb\x60\xdf\x81\x31\x8b\x78\xe9\xea\x55\ -\x9c\xb8\x7a\x72\x18\x6f\xe7\x3f\x66\x69\x73\x7f\x37\xe2\x22\xa2\ -\x1c\x8f\x6c\x07\xef\x5d\xb6\xb8\x6f\x4e\x47\xb3\xf4\x6e\x04\x59\ -\x99\xb5\xba\x7d\xef\x39\x21\xdd\x31\xec\x17\x9e\x1e\x29\x24\xb2\ -\x2c\xa2\x41\x45\x25\xd7\x3b\x9e\x83\x08\xd3\xb4\x4c\xfc\x99\xb0\ -\xa4\x5b\x66\xf1\xba\x29\x97\xb0\x71\x92\xe4\x71\x5d\x67\xf3\x2c\ -\xc1\x4b\x59\xac\xf2\xf5\x22\x2b\xfe\xac\xe1\x1f\x59\xe1\x72\xfa\ -\x67\x53\x96\x79\x74\xd0\xf7\x71\x3b\xb7\x59\x95\x55\x13\x6e\xd2\ -\x15\xf4\xa8\xf4\x59\xe2\xf6\x40\x7c\x0b\xea\xed\xf1\x14\xfe\x08\ -\xe9\x43\xe6\x1e\xfd\x9c\x9d\x88\xb3\xb8\xde\xa9\x26\x08\x56\xf1\ -\x02\x4e\x97\x97\xd5\xdd\xe8\xd5\xbc\x7d\xf6\x84\x59\x59\xa5\xae\ -\x3a\x90\x54\xfb\x0c\x48\x25\x54\x9d\x35\xdb\x5d\x80\xee\xd7\x3e\ -\x9c\xc8\xaf\x7a\xa4\x93\xf3\xf4\xfa\x3e\x4e\xcb\xc7\xbb\x11\x3b\ -\x25\x7e\x2c\xcb\xe5\xdd\x48\x47\x96\x1a\x22\xa8\x3e\x25\x27\x9b\ -\xbb\x51\x68\x22\xc5\x89\x36\xc2\x3e\xa1\x62\x43\xa6\x23\x4e\x08\ -\xd3\xfc\x09\x71\x5d\x55\x50\x74\x98\xc7\x5b\x07\xa9\xda\x7f\x74\ -\xcf\x54\xdf\x97\x8f\x8b\xca\x6b\xa7\xa9\xd6\xee\x74\xa6\xa7\x84\ -\xb3\x59\xb9\x39\x4f\x86\xa5\xd7\x3e\xc4\xc3\x75\x91\x35\x08\xa3\ -\xd5\xa6\xbf\xea\x3a\x4b\x5d\x7d\x7e\x62\x5d\xc4\xab\x70\x91\x97\ -\xb3\x38\x3f\xcf\xf0\x98\x15\xd0\x52\xb8\xf7\x61\xca\x8f\x46\x38\ -\xe5\x38\x38\xb4\x26\xe6\x02\x07\xce\xfe\xc4\x10\x7b\xd2\xf6\x32\ -\x69\x19\x6f\xb2\x65\xf6\xd1\x41\x31\xb4\xf5\x2c\xf8\xd6\x40\x2d\ -\xbb\x69\x3b\xc7\xf2\xef\x50\xbd\x1c\x1d\x06\x9b\xad\x8f\xd8\xcd\ -\xd6\x13\x8e\x83\x65\x95\xc1\xe7\x7b\xc7\x39\x0c\x6d\xfb\x43\x3e\ -\x94\x91\xf1\x37\xad\x83\xb5\xee\xa7\x4f\x69\xdb\x3e\x2d\x98\xb4\ -\x7e\x3f\x79\xea\xf8\xed\x78\xea\xe6\x75\x17\x01\xfe\x0d\x51\x6e\ -\x0f\x12\x21\x67\xb9\xb8\xfa\xb9\x8a\xd3\x0c\x66\xec\x8b\x34\xa4\ -\x48\x23\x0f\x73\x7c\x8c\x35\xe5\xea\xc0\x8b\x43\x35\xdb\xdc\x07\ -\x3b\x06\xc3\x36\x6e\xa6\xaf\x6c\x12\xc7\x84\xbc\x69\x87\xf6\xf1\ -\x30\xa5\x6f\x46\xdd\x9c\x72\x3e\xaf\x5d\xd3\x17\x7b\x9f\x84\x30\ -\x43\x1a\x45\xf7\x52\x3d\x73\x37\xca\x53\x3a\x7b\xc6\x6e\xf4\xfc\ -\x6e\xfc\xb8\xdb\xed\x64\x28\xf6\x8b\xb5\xc4\xba\x2d\x50\x22\x11\ -\xef\x59\x81\x7d\xeb\x32\x87\x1b\x3c\x5f\xa0\xb9\x42\xf1\x39\x51\ -\x1f\x89\xb4\x31\x8c\x4b\xfe\x02\x3d\xb2\x2b\x4a\x46\xe5\x55\x24\ -\x9b\xcf\xf4\x4c\x7f\xb1\x63\x50\x7d\x35\x81\x34\x55\x2f\x38\x37\ -\xa1\x94\x09\xfa\xa5\xe7\xd6\xd4\x5c\x76\xe8\x8e\x8b\x99\x73\x0b\ -\x46\xca\xc2\x45\x49\x4f\xff\x67\x4f\x48\x67\x89\x4a\xd4\x93\x13\ -\xbe\x24\x8e\xa4\x12\x26\x36\x5f\x1a\x47\x9a\x91\x2b\xc6\x91\x0e\ -\x49\x78\x31\xe3\xf4\x3c\xdc\x86\x3a\xa4\x9f\xb1\xc3\x39\x7b\x92\ -\x44\xdb\xf9\xf3\xb5\xd5\xed\xc8\x29\x4e\x76\xce\x50\xf4\xd3\x3b\ -\xce\xd5\x7c\xfe\x24\xa6\xdf\x7c\x4e\x63\xfe\x2d\xce\x9f\x68\xec\ -\x58\xd8\xcb\x3c\x77\x09\x36\x8f\xf3\xc7\x78\x5b\x1f\x4f\xd0\x62\ -\xd1\xe9\x7d\xe5\x80\x9d\x5f\x5d\xd0\x6d\x5f\xfd\xc3\x6d\xb8\x91\ -\x5d\xc9\x59\xec\x07\xdf\xef\x2a\xfc\xba\x76\xd5\xef\x1e\x6c\xfe\ -\xb3\x78\x7f\x04\x53\x1d\xd7\x1f\x55\x5c\xd4\x40\xb6\x00\x32\x00\ -\x7d\x55\xb6\xf9\x2e\xe4\x11\xe3\xed\x67\xcc\x22\x41\xb9\x50\x66\ -\x0c\x90\x6b\x28\x51\x96\x31\xff\xd5\x0a\x69\x88\x96\x76\xac\x45\ -\xa4\x14\x91\x4c\x8d\x81\x73\x8c\x10\x46\x73\xf1\xfa\xb8\x85\xc7\ -\x3f\x54\x46\x5d\x18\x78\xc8\x43\x75\xa4\xad\x30\xb6\x3b\xef\xfc\ -\x94\x6d\x7e\x96\x0d\x30\x88\x9a\x48\x2a\x26\x3b\x13\x5c\x70\xcf\ -\xaf\x51\xb6\xcf\x32\x97\xfd\x9c\x1b\xc1\x5e\xa8\xe8\x7a\x85\x8e\ -\x29\xfd\x87\x6b\xee\x4b\x2c\xb7\x8a\x3b\x74\xb1\xa1\x77\x23\x13\ -\x31\x66\x8c\x22\x9d\x75\xb7\x18\xa5\x36\xb2\xca\xea\x4e\xf8\x0d\ -\x03\x58\x14\x11\x8a\x89\x2f\xb5\x47\x56\x76\x86\xf5\xb2\x61\x69\ -\x04\x5b\x4a\x61\xc5\x98\xe0\x43\x23\x26\x90\x24\x39\x1f\x53\x16\ -\x71\x66\x0d\x17\xe3\x90\xd9\x48\x31\xa8\x40\xbe\xfe\xaf\x2a\xd9\ -\x63\x93\x4f\x2a\x59\x5c\xcd\x9b\xe1\xb8\x9c\x09\xad\xac\x77\x5c\ -\xa6\xb4\xef\x12\x65\xeb\xcf\x8c\x2a\x66\x65\x3b\x0e\x54\x66\x8c\ -\xd6\x16\x4a\x91\x5c\x0a\xf4\x47\x63\xe8\x95\x58\x2d\xb8\x7d\x3d\ -\xb0\x17\xa5\x91\xa6\x42\xf5\x80\xa3\xb7\x17\x1a\x07\x2a\x29\x21\ -\xc2\xaa\x81\xc9\x38\x8d\x0c\xf0\x3d\xe1\x03\x93\xf5\xb9\x3f\xa7\ -\xe5\xb3\x65\x30\x94\x7f\x65\x21\x0c\xc9\xf3\x4a\x61\x28\xce\x2d\ -\xfa\x7f\x54\x0c\x43\xf9\x65\xe5\xf0\x6c\x18\x5e\x88\xd8\xb3\xc1\ -\x7d\x36\x0f\x5c\xce\x1b\x2f\x8f\xf0\x10\x21\x2e\x85\xe2\x14\xe9\ -\x9b\xa1\x23\xf5\x89\x9a\xbf\x7e\x61\x8c\x9d\x0b\x54\x4b\x9f\x9b\ -\x54\xc3\xce\x01\x2e\xa6\x8e\xa3\xf6\xe7\x59\xde\xb8\xea\xd9\xa9\ -\x66\xef\x0c\xad\x1f\x84\x40\xb9\xae\x5a\x95\x79\x7b\x69\x11\xee\ -\x56\xaa\xa7\xf5\x6f\x3f\xff\x30\x90\x64\x47\x90\x44\x74\xc8\xc0\ -\xb7\xeb\x3e\x36\x35\xcc\xa3\x44\x27\xd9\xa1\xa5\x8d\x08\x97\x96\ -\xdb\x5e\x30\xef\x26\x70\x45\x19\x23\xb2\x1b\x3f\x74\xb8\x98\xa1\ -\x19\x13\x82\x76\xe1\x3a\x77\x3f\xc7\xeb\xba\xce\xe2\xe2\x87\x7c\ -\x5d\xf5\xfc\xf0\x73\x32\x7a\x29\xd3\x77\xee\x21\x6b\xe5\xf2\x81\ -\x45\x95\x21\x4a\xf6\xfc\x68\x2f\xd8\x60\x07\x49\x64\x1f\xe4\xed\ -\xa4\xde\xb5\x9f\xbe\xb3\x6c\xbf\x2d\x5d\x13\xa7\x71\x13\x77\x4d\ -\xe7\x61\xc4\x5f\x4e\x1c\x1a\xcf\x2a\x9d\x4f\x7f\x7b\xf7\xd3\x51\ -\x92\x24\x99\xfe\xab\xac\x3e\x74\x9b\x7b\x86\x78\x56\xae\x71\xf6\ -\xa3\xbc\xbe\x9d\x4d\xa6\xde\x47\xe3\xe6\x6d\xb6\x8c\x17\xce\xdf\ -\xd0\xfd\x7d\xb3\xcc\xb1\xff\x91\x30\x60\xf6\x8d\x78\xb7\xe8\x6e\ -\xd9\xca\xed\x6e\xe0\xce\x5e\x5a\xa6\xc9\x32\xf3\x93\x26\xbf\x37\ -\x59\x9e\xff\xe2\x37\xe9\xe5\x8d\xfd\xa2\x59\x93\xbb\x5e\x32\x99\ -\xec\x4f\x7f\xd0\x4b\x4f\xb8\xdb\xc9\x41\xfa\xf6\x6d\x71\x33\xb4\ -\xcf\xa2\x2a\xd7\xab\x65\x99\xba\xfd\xad\xcc\xe9\x65\x44\x1e\xcf\ -\x5c\x7e\x37\xfa\xd5\xd3\x82\x83\x0f\xb5\xa1\xb3\xbb\xc3\xd9\xef\ -\xe8\xf2\x3c\x5b\xd5\xee\xc4\x83\x61\x9e\x7c\x0a\xd1\xbe\x7b\xf5\ -\x14\xdf\xbd\x7e\xe3\xa9\xbd\xcc\xd6\xbe\x56\xeb\xdc\x4d\xdd\x83\ -\x2b\xca\x34\x45\xea\xab\xca\x0f\xce\x63\xe5\x7d\x37\xea\x5f\x77\ -\x37\x32\xd3\xe3\x2b\x94\xe5\xaa\x3c\xc3\xbf\xa9\x38\x8c\xa5\x71\ -\x7d\x1f\x57\x55\xbc\x9d\x16\x65\xe1\x0e\xa3\xc7\xad\x06\x81\xb3\ -\x8a\x9b\x7b\xa5\x78\x07\x83\x5a\x98\x47\x76\x97\x93\x5d\x0c\xb4\ -\x58\x0f\xc5\xd2\x0f\x76\x85\xa1\xda\xf8\xac\xd8\xbd\xfa\x3b\x30\ -\x80\xcc\xce\x43\x2b\xf8\xfe\x45\xa5\x3c\xcd\x3e\x5f\xab\x94\x88\ -\x32\x60\x5a\xae\xae\xa5\x1c\x7f\x7c\xc1\x24\x09\xd9\x69\xf6\x60\ -\x80\x16\x42\x68\xfb\x24\x49\x20\x1d\x03\x4c\x5b\x36\xcc\x43\xc8\ -\xe4\x68\xe0\x4d\x4f\xcd\xdb\xf6\x32\x11\xe9\x84\xcb\x5e\x95\xf0\ -\x1a\xe4\x11\x8a\xd7\x89\x92\x8f\x95\xa0\xbb\xe0\x3a\x03\x8d\x14\ -\xe0\x34\xa4\x1f\x93\x48\x4b\x21\x95\x12\x2d\x1a\xd2\xd2\x68\xaa\ -\x35\x1b\x7b\x06\x2a\xa8\x95\x6d\x3d\xe9\x41\x42\xef\x03\xcf\xb6\ -\x92\x10\x5f\x6d\x25\xa4\x51\x4e\x01\xcc\x3e\x65\xa6\xc1\xea\x20\ -\xef\x0e\xd3\xa5\xf9\xae\xdc\xf9\x04\x17\x30\x8f\x06\xfd\x75\xdc\ -\x18\x5d\xc5\xee\x62\x3d\x80\xbf\x02\x21\x52\x06\x7c\xc8\x23\xc9\ -\x38\xa7\x34\x48\x02\xf4\x3b\x86\x49\x2d\xbc\x6a\x38\x4e\xa2\x68\ -\x10\xa2\x9c\x5a\x40\x23\x34\x46\x2c\x32\xda\x52\xc3\x02\x4c\x41\ -\xbf\x22\xa5\xf2\x93\x01\x7a\x88\xd1\xc1\xaf\x01\x93\x11\x18\x19\ -\xa1\x63\xe0\x49\x02\x32\x46\x7f\xf4\xa3\xc4\x5f\x0e\xd9\x31\xf6\ -\xb6\xc8\xe2\x5c\x04\x88\x03\x65\x10\xe7\x7a\xac\xd1\x7f\x59\x83\ -\x12\x14\xc0\x69\x34\x91\xd6\xa2\xd3\x82\xf7\x68\x0a\x0f\xc2\x9a\ -\x08\x36\xc1\x81\x57\x81\xdc\x7d\x85\x21\x42\x69\x1c\x13\x2e\xc3\ -\x24\x16\xe3\x30\x1b\xb7\x54\x68\xe3\x87\xa4\xd2\x82\x29\x0f\x6c\ -\x01\x71\x25\xe5\x41\x8b\x76\x0d\x6a\x87\x40\x77\xa7\x99\x04\x14\ -\x08\x60\x5c\x3f\x8e\x40\x25\x46\x60\xd5\x88\xa3\x09\x10\x3c\x80\ -\x63\x29\x41\xb4\x10\x63\xa8\x03\xa7\x64\x81\x00\x28\x86\x5f\x5a\ -\xcc\xa5\x80\xc9\x5a\x06\x32\x02\x18\xa6\x5a\x61\x16\x45\xab\x6d\ -\x69\xa0\x10\xf4\x50\x8d\x19\x7b\xe8\x4d\x80\x7e\x82\x8f\x67\x62\ -\x44\x9c\xc5\x03\x45\x01\x22\x8a\x78\xb2\xae\x1e\xe2\x66\x5d\xb9\ -\xc1\x3d\xeb\xf1\xbe\x14\xe9\xd7\x67\x7c\x60\x95\xba\x7d\x92\x8f\ -\xf5\xe7\x9d\xb3\x17\xbd\x97\xfc\x4c\x48\x1f\x04\xe6\xe8\x53\xde\ -\x95\x71\xb2\xe9\x6c\xdd\x34\xfd\xb1\x7f\x97\x59\x31\x6d\x9d\xf0\ -\x1a\x89\xa3\xf5\x47\x8b\xce\x83\x29\x60\x05\x38\x4a\x7b\x99\xb8\ -\xf3\x3d\x18\xde\xee\x1e\x7c\x97\x51\x9b\x63\xd9\xe0\xfb\x93\xe4\ -\x8c\x88\x53\xcf\xd6\xed\x35\xb4\x26\x99\xb6\x9a\x13\xf5\x0d\xb4\ -\x46\x45\x64\xdb\x0a\xe3\x9b\x58\xd3\xaa\xad\xd5\x9a\xe9\x34\xc4\ -\x7b\x5f\xcf\xea\x2a\xfc\x6b\xb5\xa5\xc5\xee\x67\x80\x6f\xa0\x2d\ -\x5f\x6a\x5b\x1d\xc1\xab\xda\x53\x20\x47\x78\x6d\x51\xb9\x77\x32\ -\xe6\x5f\x7c\x82\xf0\xcf\xf0\xe5\xbc\xea\xc4\xcb\x55\xf7\xa2\x0a\ -\x2f\xd8\xff\x6a\x85\xff\xba\xfa\xce\x50\x2c\x2c\x2a\xee\xa0\xba\ -\xdb\x88\x11\xa6\x0d\x57\xdf\xb8\xba\x5f\xb2\xd0\x2b\x97\xf8\xcf\ -\x57\x17\x73\xd4\x1e\x94\x17\x7a\x4d\x8b\x70\xa3\xf9\xa9\x45\xfc\ -\x05\x0e\x53\x4c\xe8\x27\x26\x41\xf5\xd6\xa8\x8f\x92\x0d\x20\x97\ -\x46\xad\xe5\x4a\xdb\xa1\x51\xd0\xad\xa3\xde\xb1\xde\xe8\xce\x00\ -\xbe\xc0\x8a\x21\x92\xf5\xb1\x82\x0a\x4f\x85\xfd\x84\x59\xfc\xf5\ -\x29\x87\xa3\x68\xd9\x16\x6a\xa9\x08\x63\x94\xb6\x86\x31\x16\xfd\ -\x96\x69\x6f\x58\x15\x45\xa0\x02\x9b\x0c\x0d\xf3\x89\xa6\x61\x90\ -\x78\xfc\xbd\xf5\xa9\xde\x71\x62\x6b\x85\x62\x4a\x5e\xb3\x11\xd0\ -\x5d\x1c\xf8\x36\x00\x09\x06\xa5\x40\x93\x4e\xe5\xbe\x0d\x50\x28\ -\x68\x10\x98\xd2\xa1\x0a\x2d\x60\x0a\x40\x0e\x1f\xe8\xb0\xbd\xf7\ -\x35\x86\xd2\x6b\x49\x8d\x72\xce\xd1\xb7\x5f\xcd\xdb\x76\x52\x87\ -\x27\x72\xf3\xc8\x0a\xab\x0c\x1b\xc8\x2d\x23\x2f\x88\xe2\x43\xd7\ -\x61\x0a\x29\x89\x72\x33\x8c\x72\x86\x42\xa6\x98\xc4\x0a\x57\x91\ -\x9b\x45\x04\x49\x4a\x48\x62\xae\x2d\x77\xef\x77\x88\xbd\xc5\xa9\ -\x17\x46\x9e\x48\xae\x24\xcc\x38\x90\x9b\x23\xe5\x71\x8d\x50\x1a\ -\xca\x6d\xa1\x39\x00\x58\xfd\xc9\x4c\x86\xd2\xa4\x29\xdf\xfd\x0e\ -\x41\x00\x8e\x99\xa1\x1e\x5e\x22\x5b\x32\x61\x81\x64\x5b\x0e\xc5\ -\x70\x8c\x7e\xc4\xdc\x4e\x16\x6f\x6f\x6e\xfd\x85\xc3\xdb\x9b\xff\ -\x00\x66\xa4\x62\x3a\ -\x00\x00\x08\x74\ -\x00\ -\x00\x40\xa3\x78\x9c\xed\x5b\x59\x8f\xab\xc8\x15\x7e\xef\x5f\x41\ -\x7c\x15\x69\x46\x69\x8a\xda\x58\xdb\xf6\x3c\xe4\x6a\x94\x91\x66\ -\x5e\x92\x49\xf2\x38\xc2\x50\x76\x93\xc6\x94\x05\x78\xbb\xbf\x26\ -\xbf\x25\xbf\x2c\xa7\xca\x80\xc1\xc6\x69\x7b\xda\xd7\x69\x5f\x35\ -\x52\xcb\x70\xce\xa9\xe5\x7c\x67\x65\xe9\xe1\x0f\x9b\x79\x6a\xac\ -\x44\x5e\x24\x32\x1b\x0d\x08\xc2\x03\x43\x64\x91\x8c\x93\x6c\x36\ -\x1a\xfc\xfd\xd7\x1f\x4d\x6f\x60\x14\x65\x98\xc5\x61\x2a\x33\x31\ -\x1a\x64\x72\xf0\xc3\xf8\x61\xf8\x07\xd3\x34\xfe\x9c\x8b\xb0\x14\ -\xb1\xb1\x4e\xca\x67\xe3\xa7\xec\xa5\x88\xc2\x85\x30\xbe\x7b\x2e\ -\xcb\x45\x60\x59\xeb\xf5\x1a\x25\x15\x11\xc9\x7c\x66\x7d\x6f\x98\ -\xe6\xf8\xe1\x61\x58\xac\x66\x0f\x86\x61\xc0\xba\x59\x11\xc4\xd1\ -\x68\x50\x0d\x58\x2c\xf3\x54\x0b\xc6\x91\x25\x52\x31\x17\x59\x59\ -\x58\x04\x11\x6b\xb0\x17\x8f\xf6\xe2\x91\x5a\x3d\x59\x89\x48\xce\ -\xe7\x32\x2b\xf4\xc8\xac\xf8\xd4\x12\xce\xe3\x69\x23\xad\x76\xb3\ -\x66\x5a\x88\xf8\xbe\x6f\x61\x6a\x51\x6a\x82\x84\x59\x6c\xb3\x32\ -\xdc\x98\xdd\xa1\xb0\xc7\xbe\xa1\x14\x63\x6c\x01\x6f\x2f\x79\x9e\ -\x54\x50\x00\xa0\x0b\xf8\x6b\xc4\x6b\x02\x2a\xe4\x32\x8f\xc4\x14\ -\xc6\x09\x94\x89\xd2\xfa\xfc\xeb\xe7\x86\x69\x62\x14\x97\x71\x6b\ -\x9a\x1a\xcf\xce\xaa\x1d\x90\xb3\x70\x2e\x8a\x45\x18\x89\xc2\xaa\ -\xe9\x7a\xfc\x3a\x89\xcb\xe7\xd1\x80\x71\x44\x18\x1c\xb6\x26\x3e\ -\x8b\x64\xf6\x5c\x1e\x52\x93\x78\x34\x80\xdd\x53\xdf\xdb\x5d\xb7\ -\x9c\x83\xec\x04\xaa\x89\x83\x86\x83\x91\x4f\x11\x31\x72\x62\x33\ -\x77\x27\x53\xab\x10\xc4\x32\x52\x7b\x82\x29\xc5\x3c\x09\x97\xa5\ -\x9c\x83\xd5\xa2\x28\x0d\x8b\x22\x99\x26\x11\x5c\xc8\x6c\x91\x2e\ -\x67\x49\xf6\x5b\x18\x45\xcb\x3c\x8c\xb6\xbf\x95\x52\xa6\xa8\x06\ -\xb0\x59\x4d\x6c\x16\x32\x2f\xcd\x4d\xbc\x00\x18\x1d\xb7\x97\xb9\ -\xad\x99\x63\xe0\x0e\x63\x31\x2d\x94\xd4\x4e\x27\x75\x05\x4a\xb9\ -\x03\xc3\xd2\xdc\x66\x8b\x6a\x7f\xf1\x2a\x11\xeb\xbd\xec\x24\x2c\ -\x76\xb8\x19\xc6\x22\x9c\x81\x8f\xa5\x32\x1f\x0d\x3e\x4d\xf5\x51\ -\x31\x26\x32\x8f\x45\x5e\xb3\x1c\x7d\x74\x58\x12\xec\x90\x94\xdb\ -\x5d\x54\x55\x73\xd7\xfb\x55\xb3\x36\x7c\xdc\xcf\x2f\x9e\xc3\x58\ -\xae\x47\x03\x7a\xc8\xfc\x22\xe5\x7c\x34\xb0\x91\xed\x7b\x3e\x26\ -\x87\xdc\x68\x33\x1a\x98\x8c\x21\xee\x71\x97\x7a\x47\x5c\x58\x8f\ -\x12\xe4\x3a\x8c\x91\xa3\x89\x01\xff\x1c\xc2\xce\x4c\xc3\xad\x00\ -\xa5\xf4\x4f\x3d\x7f\xf1\x2c\xd7\xb3\x5c\x81\x53\xe6\x4b\x71\x38\ -\x52\x71\xcc\xc9\x44\x6e\xfa\xd9\xe0\x05\x4b\x15\xd0\xe6\x32\x4b\ -\x4a\x08\x9a\xc5\xa6\x3d\xeb\x32\x89\x45\xd1\x3f\xb0\xc8\xc2\x85\ -\x39\x4b\xe5\x24\x4c\xfb\x05\xd6\x49\x06\x20\x99\x95\x7f\x13\xd6\ -\xd8\xe0\x50\xa2\x76\x76\x17\x1f\x61\x52\x49\xc0\xde\x8f\xec\x50\ -\xb1\xb6\xa7\x59\xf3\x70\x93\xcc\x93\x2f\x02\x80\x21\xda\xed\xc0\ -\xb5\x3a\xb0\xec\x86\x19\x46\xb9\x55\x81\xbb\xd9\x2a\xda\xa0\x26\ -\x2a\x3c\x15\x81\xfa\xbe\xdb\x10\x65\x9e\x40\x3c\xb4\xb6\x53\x93\ -\xb6\x6d\x92\x0a\x73\xc8\xd2\x1b\xed\x5f\xda\xfb\xdc\x43\xde\xb6\ -\xcd\xab\xdc\xde\x3a\xf6\x7b\x4d\x9f\x8b\x32\x8c\xc3\x32\xdc\x07\ -\x41\x4d\x81\xbd\xe1\x5a\x33\xc8\x98\xc1\x5f\x3f\xff\x38\xae\x16\ -\x1a\x46\x51\xf0\x4f\x99\xbf\xd4\xeb\x1a\x86\x12\x08\x27\x72\x09\ -\x48\x0f\xc6\x0d\x79\x18\x47\x01\xe4\x38\x88\xfd\x71\x32\x07\xd7\ -\x56\xe9\xf1\x4f\x90\xd3\x86\xd6\x9e\xd1\x11\x56\x60\xed\x27\xdd\ -\x4d\x9b\x8b\x5d\xb2\xec\xad\x18\x71\x34\x4f\xd4\x20\xeb\x6f\x65\ -\x92\xa6\x3f\xa9\x45\x2a\x8d\x5b\x93\x26\x65\x2a\xf6\xc4\xa1\x55\ -\xed\xbe\xd2\xcd\x6a\x29\x37\xb4\x6a\xed\xf5\xd5\x6c\x8f\x4a\x27\ -\x28\x1a\x43\xa7\xe1\x44\x80\x87\xfe\xac\x98\xc6\x11\x77\x96\xcb\ -\xe5\x62\x2e\x63\x51\x0d\x6f\xd0\x14\x51\xd9\x98\xac\xdc\xa6\xc0\ -\xd7\xf9\x24\xf8\x84\xf5\xf1\x14\x27\xc5\x02\x46\x40\xe2\x4f\x93\ -\x4c\x3c\x49\xc8\xb8\xd3\x54\xae\x83\x55\x52\x24\x93\x54\x3c\xe9\ -\xdf\x24\x05\xcd\x1b\xd2\x14\xd4\x0f\xaa\x4c\xa5\x2f\xcc\x2a\xcf\ -\x04\x64\x77\x99\x2f\x53\x11\x64\x32\xfb\x02\x19\xea\xa9\x28\x73\ -\xf9\x22\xb4\xfc\x64\x3a\xa9\x2e\x77\xd1\x14\x40\x56\xc7\xcc\x73\ -\x99\xcb\x6b\xba\xda\x04\x28\x14\x4c\x96\x65\xd9\xa6\xfd\x4b\x26\ -\x59\x00\xf8\x8b\xbc\xa6\xea\x8b\x14\x02\xa3\x0c\x9a\xd1\x71\x08\ -\x19\x2d\xcf\x41\x1d\x58\x5d\xb4\xa9\x72\x3a\x2d\x44\x19\xe0\x9a\ -\xb6\xdf\xf1\x3c\xcc\x5f\x44\xbe\x1b\x20\xb2\x10\x14\x34\x27\x61\ -\xf4\xa2\x00\xcd\xe2\x40\x55\x8c\xf9\x32\x85\x2e\xa4\x13\x50\x0a\ -\x56\xe6\x7a\xc4\xc4\xe6\x3e\x5c\xea\x0c\xc1\x91\x47\xb8\x47\x9c\ -\x86\x51\x27\x06\x62\x23\x46\x3c\x9b\x78\x0d\x07\x42\x8b\x62\xe4\ -\x72\xec\x72\xda\x10\x21\xa6\x18\x45\x98\xfa\x0e\xf5\x1b\x62\x0e\ -\xa2\x2e\x72\x6c\x0c\xc1\xd6\xa2\xea\x78\xad\x1d\xee\x9d\x5b\x9b\ -\x20\xc6\x61\xf7\x84\x93\xfb\xb5\xb6\x6b\x7a\x47\xf6\x76\x90\x36\ -\x95\x7b\x64\x6f\x86\x91\xc3\x5c\x5c\x75\x3d\x95\xbd\x39\xe2\xfa\ -\xe8\xd8\x9b\x78\x88\x60\x10\xe5\x1d\x7b\x7b\x88\x13\x1b\xbb\x8c\ -\xdf\xab\xbd\xa9\xeb\x51\x50\xca\xbb\x63\x7b\x9f\x1f\xdd\xbd\xd6\ -\x66\xd0\x43\xa9\x83\xb5\xad\x4d\x91\xab\xb2\x00\x77\xbe\xa5\xe8\ -\xfe\x06\x72\xf9\xd7\xc8\xe4\xb5\xad\xf9\x7b\xb1\xb5\x43\xa6\x53\ -\xc6\xdf\x6a\x6b\x8f\xb8\xb6\xc7\x6d\xf7\x5e\x6d\x4d\x4c\xe7\x02\ -\x6b\x53\x64\xab\xbb\x57\xfe\x6a\x64\xbf\xbb\xba\x7d\x25\x6b\x3b\ -\xc4\xc3\xbe\xcb\xee\xd6\xda\x17\xd8\x9a\x21\x9f\xda\x3e\x75\x5f\ -\x8d\xec\xfe\x9a\x7d\xf7\xb6\xbe\xf3\x2c\xfe\xc6\x1c\x6e\xef\xac\ -\x6f\xbb\x3d\x39\xdc\x26\x6f\xb6\xf4\xe9\x72\x8b\x5b\x86\x12\x2b\ -\x91\xc9\x38\x6e\x0c\x55\x39\x46\xc7\x50\x0e\xf2\x98\x43\x09\xa6\ -\xf6\xe5\xf0\x37\x50\x1f\x21\x08\x37\xe2\xfe\x21\x82\x36\x46\xaa\ -\xad\x69\xe9\x59\x23\xc8\x3d\x1d\x16\xac\x5b\x05\x91\xca\x7f\xed\ -\x14\xa8\x9f\x11\xb0\x1d\xae\x07\xfd\x2d\x03\x6f\xf3\x6d\xda\x41\ -\xd0\x46\xae\x6f\x33\x9f\xed\x27\x68\xee\x72\xcb\x3c\xcc\x0a\x75\ -\x33\x6f\x46\x22\x03\x6d\xd5\x03\x15\xd3\x41\x2e\x71\xa0\xc9\x74\ -\xcf\x90\xdf\x6a\x79\xee\x7b\xae\xe3\xd8\x7b\x4b\x2d\xc2\xf2\xb9\ -\xcf\x52\x2d\xd0\xfa\xad\x40\x10\x67\x0e\xe3\xbe\xc3\x16\x9b\xcb\ -\x03\xe6\xd8\x0e\xea\x99\x88\x51\x67\x9b\x47\x8e\x88\xab\x0e\xcf\ -\x58\x19\x9c\x20\x7d\xee\x52\x03\x77\xcc\xa6\xf6\xce\x5c\x97\x1d\ -\x6b\x1f\xc9\x0c\x76\x52\xca\xdc\x8c\x96\xf9\x2a\x2c\x97\xb9\xe8\ -\xf8\xe7\x7b\xd2\xfa\x17\xa3\xae\xa7\x76\x4b\xed\x7f\x18\x1c\x02\ -\x52\x53\xfb\x74\xb6\xef\x5d\xe7\xfa\x5e\xd0\x7e\xac\x8b\x89\x6d\ -\xfc\xc5\x80\xb0\xf2\xd4\xe1\xf7\xe9\xdc\xe3\xe5\xf7\xaa\x73\xd3\ -\x2c\xbd\xa6\x73\x4f\x26\x78\x4d\xe7\x52\x6c\x9a\xdc\xbb\x99\xa7\ -\x81\x7e\x63\x01\x13\xe6\xa2\x10\xf9\x6a\x5f\x3a\x6a\x3c\x64\x56\ -\x9a\xfa\x1c\x50\xc9\xe7\x61\xfa\xa4\x29\x6b\x9d\xe8\x3a\xa4\x22\ -\xf9\x22\x02\x68\x08\x3d\x8d\x17\xf1\x01\x19\xa5\x7e\xf5\xf0\x37\ -\xc0\x7f\xdc\x89\x4d\xc3\x79\x92\x6e\x83\x02\xf2\x8f\x09\x2b\x26\ -\xd3\xa7\x54\x94\x2a\x03\x55\xcf\x4d\x03\x0c\x03\xd7\x32\x8f\x3b\ -\x84\x5d\x79\xa8\x4c\x71\x50\xc7\x2b\x43\xb5\xf3\x78\x6d\x25\xdc\ -\x79\x35\xa0\xb3\xb0\x87\x74\xcb\xe6\xf0\x4e\x16\x56\xa9\xd5\x87\ -\xb6\xbd\x03\xb2\x82\x8a\x79\x64\x0f\x72\x93\x35\x47\x03\x00\x3b\ -\x15\xdf\xc1\x0a\x8c\x70\x4a\xe8\x23\xb4\x07\x0e\x24\x67\xe7\xfb\ -\x63\x8b\xf4\xbd\x3c\xe9\x13\xd8\xbf\x40\x19\x96\xa0\x7b\xb6\x7f\ -\x06\xdb\x3c\x36\xce\xa5\xb2\x89\x82\x75\xb0\xe7\xea\xad\xaa\x01\ -\xcc\xa3\xa4\x45\xef\x55\xf6\x84\xba\x07\xf6\xae\x4c\x09\xcd\x1e\ -\xe1\xf6\x81\x21\x09\x82\xca\x7a\xc2\x94\x27\xe0\x1f\xbb\x43\x4b\ -\xef\x70\x0c\xbf\x00\xea\x87\x2b\xee\x1a\x02\x40\xd8\x23\xb6\xdf\ -\x71\x45\x86\x11\x71\xda\x77\x54\x6d\x4f\x34\xe9\x65\xbe\xf8\x16\ -\x4f\x32\x59\xd7\x97\x8e\x77\xdb\xbf\xdf\xaf\xec\x4a\xde\x87\x2b\ -\xf5\xb8\x12\x73\x11\xe3\x36\xf6\x3a\xbd\x25\xe7\xc8\xa6\x8e\x77\ -\xca\x95\xcc\x0b\x13\xdb\xdb\x9c\xa9\xf5\xc0\xf0\xc4\x8e\xfb\xf7\ -\xfc\x95\xdd\x89\x36\xee\x74\x91\x72\xa7\x15\x70\x30\x72\x3c\x1b\ -\xba\xd1\x1b\x69\xd0\x0b\x38\xb4\xf0\xe3\xff\xfc\xfb\x23\x52\xce\ -\x4d\xba\xff\xbb\xfe\x43\xa8\xe0\x9b\x86\xca\x79\x99\xf7\xe6\x55\ -\x1c\x7f\x38\xd4\xb9\xa9\xf7\x75\x87\xba\x71\xf6\x3d\x37\xff\xde\ -\xdc\xa9\xf8\x87\x53\x9d\x7b\x97\xf2\x4a\x6b\x68\xde\xb8\x3d\x34\ -\x5d\x93\x76\x7d\xea\xc4\xed\xc6\xad\x5b\xc4\xdf\x5f\xd3\x4f\x28\ -\xc0\x1d\xc4\x28\xa5\x8e\xff\xff\xad\xe9\x00\xf7\x47\x55\xbf\xa0\ -\xaa\xbf\xda\xff\xde\xba\x03\x36\xc9\x59\x85\xfd\xd6\x3d\x30\xf9\ -\xdd\xf1\x72\x42\x81\x77\xd2\x03\x9b\xce\x47\xbc\x5c\x52\x5f\x5e\ -\x8f\x17\x76\xe3\x78\x71\xce\x4b\xcf\x37\x8e\x17\xf7\xda\xf5\xe5\ -\xbd\xc4\x0b\xfe\x88\x97\x4b\x9a\xfc\xd7\xfb\xb1\x56\x62\xbc\x4d\ -\xc0\xf0\xae\xbf\x9d\x68\xf2\x6f\xdd\x90\xe1\x6b\x3f\x64\x79\x2f\ -\x0d\x19\x3b\x19\x30\x67\xbd\x5a\xaa\x5e\x77\x7f\xfd\x17\xa7\x84\ -\x21\xa6\x8f\x47\x6c\x44\x06\x6e\xbd\x48\x3c\x75\xbe\xea\x79\x99\ -\xca\x71\xeb\x85\xf6\x75\x5f\xb2\xdd\x0c\x09\xea\xa0\xdd\x37\xf9\ -\x6f\x46\xa2\x75\xf3\x73\xaf\x58\xf8\x48\x7d\x90\xf0\x76\xa7\x30\ -\x29\xbf\x77\x2c\x38\xbe\x02\x0a\xad\xc7\x84\xf7\x0a\x43\xf5\x91\ -\xca\x55\x7c\xc2\xbc\x7f\xaf\xa8\xbe\x7a\x72\xae\x03\x87\x79\xff\ -\xe9\xb3\x76\x0f\x0f\xb1\xdd\x47\x29\x1d\x5c\xec\x93\xe7\x27\x71\ -\x21\xf7\x0e\xc9\xfe\xb3\x0d\xb8\x1b\xa6\xea\x93\x3a\xda\xc6\xc4\ -\x3b\x71\x7a\x1a\x90\xfb\x2f\x2c\x76\xd5\x6d\xb0\x47\xe6\x20\xaa\ -\xcb\xed\x1b\x21\xb9\xfb\xc0\x81\x49\xf5\xd7\x96\x57\xf4\x92\xfb\ -\x07\x85\x21\x7a\x35\x0f\xf9\x06\x8a\x6f\xf3\xff\xa2\x57\x04\xc5\ -\xbb\x18\x96\xa1\x35\x1b\x3f\x0c\xd5\x7f\x89\x8e\x1f\xfe\x0b\x5f\ -\x2f\x09\x26\ -\x00\x00\x06\x59\ -\x00\ -\x00\x4e\xd5\x78\x9c\xe5\x9c\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ -\x54\xed\x25\x41\x4b\xbd\x6d\x3d\x62\x3b\x87\x06\x01\x02\xf4\xd4\ -\xa6\xe8\x31\x90\x25\xda\x16\x56\x12\x0d\x8a\x5e\xdb\xf9\xf5\x21\ -\xa9\x87\x2d\x5b\x0b\xa4\x25\x55\x68\x97\x0a\x82\x40\x33\x43\x8a\ -\xfc\x34\x43\x0e\x29\x3a\x8b\x8f\xa7\x22\xd7\x9e\x21\xae\x32\x54\ -\x2e\x75\xdb\xb0\x74\x0d\x96\x09\x4a\xb3\x72\xbb\xd4\xff\xfe\xfa\ -\x19\x04\xba\x56\x91\xb8\x4c\xe3\x1c\x95\x70\xa9\x97\x48\xff\xb8\ -\x7a\x58\xfc\x02\x80\xf6\x3b\x86\x31\x81\xa9\x76\xcc\xc8\x4e\xfb\ -\x52\x3e\x55\x49\xbc\x87\xda\xbb\x1d\x21\xfb\xc8\x34\x8f\xc7\xa3\ -\x91\x35\x42\x03\xe1\xad\xf9\x5e\x03\x60\xf5\xf0\xb0\xa8\x9e\xb7\ -\x0f\x9a\xa6\xd1\xe7\x96\x55\x94\x26\x4b\xbd\x29\xb0\x3f\xe0\x9c\ -\x1b\xa6\x89\x09\x73\x58\xc0\x92\x54\xa6\x6d\xd8\xa6\x7e\x31\x4f\ -\x2e\xe6\x09\x7b\x7a\xf6\x0c\x13\x54\x14\xa8\xac\x78\xc9\xb2\x7a\ -\xbc\x32\xc6\xe9\xa6\xb3\x66\xad\x39\xba\xdc\xc8\x0e\xc3\xd0\xb4\ -\x1c\xd3\x71\x00\xb5\x00\xd5\xb9\x24\xf1\x09\xf4\x8b\xd2\x36\x0e\ -\x15\x75\x2c\xcb\x32\xa9\xee\x62\xf9\x73\x56\x51\x45\x81\xee\xe9\ -\xdf\xce\xbc\x15\x18\x15\x3a\xe0\x04\x6e\x68\x39\x68\x94\x90\x98\ -\x9f\xbe\x7e\xea\x94\xc0\x32\x52\x92\x5e\x55\xd3\xf2\xec\x3d\xb5\ -\x07\xb9\x8c\x0b\x58\xed\xe3\x04\x56\x66\x2b\xe7\xe5\x8f\x59\x4a\ -\x76\x4b\xdd\xf5\x0c\xdb\xa5\xd7\x8c\x0b\x77\x30\xdb\xee\xc8\xad\ -\x34\x4b\x97\x3a\x6d\xbd\x13\x06\xf5\xfd\x95\x73\xd8\xb5\x41\x53\ -\x71\xd4\x69\x2c\x23\x74\x0c\x5b\xc3\xf6\xcc\xf5\x6b\x9b\xb6\x0b\ -\x51\x8a\x12\xd6\x26\x5a\x25\x2c\xb2\xf8\x40\x50\x41\xdf\x5a\x92\ -\xe4\x71\x55\x65\x9b\x2c\xa1\x37\xa8\xdc\xe7\x87\x6d\x56\x7e\xeb\ -\x0b\xbf\x41\x8c\x58\xed\x46\x4b\xb2\x7b\x2c\x3c\xed\x11\x26\xe0\ -\x94\xee\x29\xcf\xb9\x3f\xa8\x3c\xb7\xca\x15\xd5\x2e\x52\xb8\xa9\ -\x98\x55\xdd\x39\x76\x47\x7b\xe7\xeb\x9a\xc9\xb5\x5d\x5b\x59\x43\ -\xd3\xe7\x0c\x1e\x2f\xb6\xeb\xb8\xaa\x01\x6a\xda\x3e\xde\x52\x67\ -\xcb\x11\x5e\xea\x8f\x1b\x7e\x35\x8a\x35\xc2\x29\xc4\xad\x6a\xce\ -\xaf\x9e\x0a\xd1\x17\x92\x91\x73\x1d\x5e\x4d\xdd\x6d\x7b\x59\xad\ -\x9d\xde\x1a\xd6\x57\xbb\x38\x45\xc7\xa5\xee\xdc\x2a\xbf\x23\x54\ -\x2c\xf5\x99\x31\x0b\x83\xd0\xb2\x6f\xb5\xc9\x69\xa9\x03\xdf\x35\ -\x7c\xdf\x0d\x6c\xf7\x4e\x4b\x9f\xe7\xd0\x06\xb9\xbe\x17\xdc\x2b\ -\x0f\x18\xd3\xf8\x03\x79\x7c\x86\xb4\x53\xfc\x9f\xb6\xfe\x6a\x87\ -\x8e\x5b\xcc\xe0\x10\x7c\x80\xb7\x25\x99\x06\xac\xd7\xe8\x34\xac\ -\xa6\xee\x70\x60\x91\x0d\x0e\x65\x46\x68\xf4\xec\x4f\xd7\xb5\x1e\ -\xb2\x14\x56\xc3\x05\xab\x32\xde\x83\x6d\x8e\xd6\x71\x3e\x6c\x70\ -\xcc\x4a\x0a\x09\x34\x8e\x6e\xbb\xdd\x3b\xb8\xb5\x68\xbd\xde\xb7\ -\x82\x17\x2c\x68\xdb\xef\xde\x43\xa3\x3a\xbf\xac\x2a\xe2\x53\x56\ -\x64\xdf\x21\x05\x63\x73\xb7\xa3\xae\xd5\xc3\x52\x17\xd3\x34\x72\ -\x66\x11\x7c\x3a\x33\x99\xde\x0a\x19\x4f\x26\x70\xc2\xd0\xef\x84\ -\x08\x67\x34\x30\xae\x9a\xd3\x8a\xce\xd7\x22\x16\xef\x74\xb8\x3e\ -\x71\xff\xe2\xde\xe7\xdf\xea\xce\xd7\xba\xc6\xed\xcd\x7b\xbf\xe7\ -\xf2\x02\x92\x38\x8d\x49\x7c\x09\x82\x56\x42\xdb\x66\xb5\x3d\xa3\ -\x43\x67\xf4\xe7\xa7\xcf\xab\xe6\x41\x8b\x24\x89\xfe\x41\xf8\xa9\ -\x7d\xae\xa6\x31\x83\x78\x8d\x0e\x94\xb4\xbe\xea\xc4\x8b\x34\x89\ -\xe8\x60\x47\x07\x81\x55\x56\x50\xd7\x66\xe3\xe4\xaf\x74\x70\x5b\ -\x98\x17\x45\xcf\x98\xc1\xba\x54\x5a\x57\x8b\x61\x3d\x6a\x0e\x4e\ -\x1d\x69\x52\x64\xac\x90\xf9\x17\xc9\xf2\xfc\x0b\x7b\x48\xd3\xe3\ -\xab\x4a\x33\x92\xc3\x8b\x70\x61\x36\xad\x6f\xfa\x66\x5e\x75\x6e\ -\x61\xb6\xbd\xe7\x77\xdb\x0b\x95\x5e\x50\x74\x2f\x3a\x8f\xd7\x90\ -\x7a\xe8\x1f\x4c\xa9\xdd\x69\xb7\x18\x1d\xf6\x05\x4a\x61\x53\xbc\ -\xa3\x09\x13\xd2\xbd\x32\x72\xce\xa9\x7e\x43\x5b\x1f\x3d\xae\x5d\ -\xf6\xe7\x03\xbb\x01\xcd\x30\x11\xd9\xf5\x2d\x3e\xe4\x74\xb8\x7b\ -\x86\x25\x4a\xd3\x0f\x15\xc1\xe8\x09\x46\x8f\x16\xbf\x9a\xdb\x3a\ -\x18\x22\xcb\xf0\xdc\xd0\x63\xef\xbe\x95\x53\x42\x10\xe7\xd4\x5b\ -\x49\xe4\xb5\xb2\x34\xa6\xc3\x0c\xc6\xf1\x39\x2a\xe9\x44\xdf\x4a\ -\xbb\x67\xf6\x1c\x95\x35\x77\x16\xb8\x21\xb0\x41\x00\x2e\xaa\x26\ -\xf6\x66\x86\xeb\x5e\xa6\x13\x76\xb5\x21\xe7\x19\x21\xd7\x78\x9d\ -\x86\x39\xad\x65\xdc\x38\x2d\xf5\x56\x70\xef\xca\xb8\x17\x07\x98\ -\xbb\xf4\xdc\x63\xd7\xbc\x7b\xc1\x2f\x83\xb4\xac\xcd\x86\x82\x99\ -\x32\xc8\x70\x0c\x90\x36\x1d\xff\xfb\x96\x6f\x9e\xa3\x0d\x66\x63\ -\x90\x0c\x8c\x80\xf7\xc5\x51\x87\xa4\x3f\x06\x47\xc7\x35\xe6\xea\ -\x20\xa4\xce\x38\x8a\x37\xda\x81\xd1\xcb\x34\x45\x51\xbe\x82\x89\ -\x26\x1c\xc7\x1f\x5d\xd7\xf0\x64\xce\x34\xd3\x26\x29\x48\xd0\xea\ -\x91\x33\x02\xb5\x7c\xd0\x13\xa4\x77\x6f\x3e\x46\xaa\x33\x71\x8c\ -\x81\x4c\x17\x94\x9d\xde\x4c\x9c\x9d\x25\xec\x82\x3d\x7a\xb2\x53\ -\x9a\xa9\xd3\x73\x65\xc2\x93\x98\xc7\x4c\x9d\x9b\xf0\xc4\xdb\x8f\ -\x59\xe5\x52\x17\xf1\x45\xf2\xe0\xcc\xa1\x56\xe6\xc2\x06\x3f\x61\ -\x8e\xfd\x08\x0e\x8c\x19\x37\x51\x88\x9f\xdc\x09\x44\x45\x0f\x04\ -\x8e\x4c\x82\xaa\x65\x7f\x6c\x21\xe7\x89\xfa\xa0\x33\xbf\x9d\x41\ -\xf8\x6a\xc4\x77\x15\x8a\xe6\x7a\x73\x41\x74\x62\x1e\x24\x49\x7d\ -\x52\x91\x8c\xb0\xd9\xa1\x11\xde\x30\x1c\xc4\x18\xdc\x6e\x36\xbc\ -\x79\x94\x21\xf0\x85\x47\xc7\xe1\xd8\x76\xeb\x4a\x94\x71\x4b\x0f\ -\x38\xa2\xeb\x64\xc7\x36\x6e\x84\x72\x43\x7b\xe2\x9b\xaf\x01\x10\ -\x5d\xed\xd9\x3d\x17\xb4\x95\xd9\xb6\xe6\x59\x8e\x27\xea\x7e\xf6\ -\x98\x63\xe1\xd4\x09\xba\xe2\x5b\xd5\x3d\x7c\x8e\xe4\x3c\x7b\xe2\ -\xfc\x6c\x30\x17\x9f\x92\x87\x86\x3f\xc5\x38\x5a\x74\x3e\x96\x1b\ -\xc7\xb6\xe4\x25\xf3\xc4\x01\xb2\x89\x78\x0e\x5c\xd1\x5d\x87\x41\ -\x5f\x94\x8d\x72\xf2\x39\x0d\xdb\x06\x03\xa1\x35\x06\x4b\xc5\xf2\ -\xc3\x66\x27\x47\xfc\x9c\x83\xca\x49\x76\xb3\x99\x03\xc2\xb9\x54\ -\x8a\x6a\x2d\x9e\x3d\x4f\x78\xc1\x77\xe5\x6f\xca\xee\xe2\x00\x51\ -\x1f\xec\x43\x54\xcb\x07\x59\x28\x8b\x66\x39\x7d\x7e\x12\xd7\x7a\ -\xaf\x80\x1f\xdf\x00\x13\xfe\xb2\xd2\x27\xa8\xde\xde\x97\x4f\xa7\ -\x12\xd1\x45\x5f\x9f\xa1\xec\xc5\xca\x2b\x80\xc8\x4e\xcb\x01\x6b\ -\x2e\x79\x4e\x91\x97\x69\xf7\xb1\xbd\x0a\xa4\x7c\x4f\x56\x78\x2f\ -\x0c\xb8\xfe\x6d\x72\xf8\xaf\x33\xc6\x56\x4a\x70\x5c\x56\xec\xac\ -\xff\x52\xaf\x92\x38\x87\xef\x80\xfd\x9b\xfd\xfe\xcd\x38\x30\x4f\ -\x2c\x45\xbf\x70\xdd\x8c\x04\x81\x21\xef\xfc\x36\x67\xf2\xd3\x0c\ -\xeb\x5f\x3a\xfd\x9f\x0c\x45\xb3\xf1\xc1\x33\x9e\x92\x4f\x2a\x4e\ -\x9f\x62\xed\x89\x63\xb0\x94\x7d\x6a\x62\xea\x2c\x05\x19\x0e\x9f\ -\xdc\x51\xce\x1f\x45\xc3\x7a\x10\xa3\xfc\x1f\xb7\x4c\x1c\xa3\xf8\ -\x6a\x7b\x90\xa3\xfc\x9f\xb6\x4c\x9c\xa3\xe8\x72\x7b\x90\xa2\xd4\ -\x1f\xb6\x4c\x1c\xa0\x37\x0e\x42\xd9\x47\x43\x5f\x01\x47\xf1\x55\ -\xe3\xb0\x33\x2a\x36\x4b\xd7\xfb\x40\x82\x24\x07\xcf\x9e\x48\xfd\ -\xf0\x3f\x79\x88\xcd\x0a\x7c\x14\x90\xea\xb9\x64\xb3\x1c\x1c\x83\ -\xa6\x3a\x6b\x42\xb9\x47\x29\x64\x7f\x60\x98\x38\x3c\xf1\xe3\xca\ -\xc3\x1f\x5c\x55\xa3\x18\x88\x9f\x27\x1b\x3e\x05\xa0\xd0\xec\xc2\ -\x92\x9d\x51\x4e\x35\x4a\x3f\x5d\x36\x69\x90\xf5\x87\xeb\x40\xee\ -\xf1\x46\x75\xa6\x93\x26\xe9\x16\xde\xd8\x19\x3e\x60\xa6\x10\xc6\ -\x60\xac\xd3\xde\xff\xe5\xc3\xd7\xc2\xdc\xae\x1e\x16\xec\xbf\x13\ -\x5a\x3d\xfc\x00\x35\xeb\x83\x36\ -\x00\x00\x0e\x5b\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x73\ -\x65\x74\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\ -\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\ -\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ -\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\ -\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ -\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ -\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ -\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\ -\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x33\x37\ -\x2e\x38\x30\x34\x35\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x2e\x32\x33\x34\ -\x31\x36\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\ -\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\ -\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\ -\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\ -\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ -\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ -\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\ -\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ -\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\ -\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\ -\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\ -\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ -\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\ -\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\ -\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\ -\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ -\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ -\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\ -\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x37\x37\ -\x31\x63\x38\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ -\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x31\x2e\x30\x37\x31\x36\x32\x31\x37\x38\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ -\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\ -\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x38\x2e\x34\x32\x33\x33\x38\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x34\x2e\ -\x39\x35\x35\x38\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x35\x32\x2e\x30\x34\x36\x30\x38\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x3d\x22\x34\x34\x2e\x32\x34\x39\x31\x32\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\ -\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x79\x3d\x22\x32\x2e\x34\x39\x35\x36\x39\x38\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\ -\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x37\ -\x31\x38\x32\x31\x37\x33\x2c\x30\x2e\x34\x38\x39\x38\x32\x33\x33\ -\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\ -\x2c\x30\x2c\x2d\x30\x2e\x38\x32\x34\x33\x35\x32\x37\x31\x2c\x30\ -\x2e\x35\x36\x36\x30\x37\x36\x35\x2c\x30\x2c\x30\x29\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x36\x35\x39\x39\ -\x38\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\ -\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x32\x38\x2e\x34\x30\x32\x33\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x37\x2e\x30\x32\x39\x30\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x31\x35\x2e\x38\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x38\x2e\x34\x32\ -\x33\x33\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x32\ -\x31\x34\x34\x37\x38\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ -\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\ -\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x30\x2e\x39\x39\x36\x38\x33\x35\x38\x39\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ -\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x30\x30\x31\x31\x32\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x39\x34\x34\x38\x30\x31\x37\ -\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ -\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x38\x2e\x34\x32\x33\x33\ -\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x31\x36\x2e\x37\x39\x32\x33\x35\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x35\x2e\x34\x30\x33\x30\x32\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x35\x2e\ -\x31\x38\x30\x37\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x34\x37\x34\x39\ -\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\ -\x2c\x2d\x30\x2e\x37\x37\x36\x34\x37\x36\x37\x35\x2c\x30\x2e\x36\ -\x33\x30\x31\x34\x35\x39\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x35\x32\x39\x36\x30\ -\x32\x38\x2c\x30\x2e\x36\x35\x38\x30\x36\x35\x39\x36\x2c\x30\x2c\ -\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\ -\x2e\x39\x34\x38\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x2e\x36\x34\x31\x33\x38\x37\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x36\x2e\ -\x39\x36\x33\x35\x32\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x31\x37\x2e\x33\x31\x36\x38\x31\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x31\x38\x2e\x34\x32\x33\x33\x38\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x39\x32\x34\x35\x34\x31\ -\x37\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0b\xb0\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x63\x6b\x73\ -\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x32\ -\x31\x2e\x37\x33\x36\x36\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\x34\x2e\x32\ -\x35\x36\x35\x31\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ -\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ -\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ -\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\ -\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ -\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ -\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ -\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\ -\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ -\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\ -\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ -\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ -\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ -\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ -\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ -\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ -\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\ -\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ -\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ -\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ -\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ -\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\ -\x23\x62\x66\x61\x64\x61\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ -\x62\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x30\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x31\x33\x33\ -\x33\x33\x34\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\ -\x23\x36\x36\x36\x36\x36\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ -\x62\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x30\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x34\x35\x31\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x33\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x32\x2e\x38\x30\x30\ -\x30\x30\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\ -\x62\x66\x61\x64\x61\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x62\ -\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x30\x32\x2d\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x39\ -\x2e\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x32\x2e\x31\x33\x33\x33\x33\x36\x35\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x36\x36\x36\x36\x36\x36\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x66\x62\x66\x62\x66\x62\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x35\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x31\x39\x2d\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x2e\x33\x33\x33\x33\ -\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\ -\x2e\x33\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x10\x81\ -\x00\ -\x01\x72\x36\x78\x9c\xed\x9d\x4b\x93\xe3\xb6\x11\x80\xef\xfb\x2b\ -\x14\xed\xc5\xae\x2c\x21\x3c\xf8\x82\x76\x66\x7d\xb0\x2b\x15\x57\ -\x25\x97\xc4\x49\x8e\x2e\x8e\xc4\xd1\x28\x2b\x89\x13\x8a\x9a\x87\ -\x7f\x7d\x00\xbe\x44\x52\xe4\xec\x7a\x85\x26\x66\xe4\xd6\xd8\xb5\ -\x12\x41\x89\x24\x3e\x74\xa3\xbb\xd1\x00\xae\x7e\x78\xda\x6e\x26\ -\x0f\x71\xba\x5f\x27\xbb\xeb\x29\x23\x74\x3a\x89\x77\x8b\x64\xb9\ -\xde\xad\xae\xa7\xff\xfa\xe5\x2f\x4e\x38\x9d\xec\xb3\x68\xb7\x8c\ -\x36\xc9\x2e\xbe\x9e\xee\x92\xe9\x0f\x9f\xde\x5d\xfd\xc9\x71\x26\ -\x3f\xa6\x71\x94\xc5\xcb\xc9\xe3\x3a\xbb\x9b\xfc\xbc\xfb\xbc\x5f\ -\x44\xf7\xf1\xe4\xbb\xbb\x2c\xbb\x9f\xcf\x66\x8f\x8f\x8f\x64\x5d\ -\x1e\x24\x49\xba\x9a\x7d\x3f\x71\x9c\x4f\xef\xde\x5d\xed\x1f\x56\ -\xef\x26\x93\x89\xba\xee\x6e\x3f\x5f\x2e\xae\xa7\xe5\x17\xee\x0f\ -\xe9\x26\x3f\x71\xb9\x98\xc5\x9b\x78\x1b\xef\xb2\xfd\x8c\x11\x36\ -\x9b\x1e\x4f\x5f\x1c\x4f\x5f\xe8\xab\xaf\x1f\xe2\x45\xb2\xdd\x26\ -\xbb\x7d\xfe\xcd\xdd\xfe\x7d\xe3\xe4\x74\x79\x5b\x9f\xad\xef\xe6\ -\x51\xe4\x27\x31\x29\xe5\x8c\xf2\x19\xe7\x8e\x3a\xc3\xd9\x3f\xef\ -\xb2\xe8\xc9\x69\x7f\x55\xdd\x63\xdf\x57\x39\xa5\x74\xa6\xca\x8e\ -\x67\x7e\xdd\x59\xf3\xbd\xaa\xd0\x7b\xf5\x7f\x7d\x7a\x75\x80\xec\ -\x93\x43\xba\x88\x6f\xd5\xf7\x62\xb2\x8b\xb3\xd9\x4f\xbf\xfc\x54\ -\x17\x3a\x94\x2c\xb3\x65\xe3\x67\xaa\xfa\x6c\x5d\xb5\x55\xc9\xbb\ -\x68\x1b\xef\xef\xa3\x45\xbc\x9f\x55\xc7\xf3\xef\x3f\xae\x97\xd9\ -\xdd\xf5\x54\xb8\x84\x09\xf5\xf2\xf2\x83\x77\xf1\x7a\x75\x97\x75\ -\x8f\xae\x97\xd7\x53\x75\xf7\x5c\x86\xc5\xe7\x46\xe3\x60\xc5\x09\ -\xe5\x0f\xcf\xeb\x12\x4a\x24\x27\x6c\x92\x32\x4f\x04\xc5\x39\xd5\ -\x23\xcc\x97\xc9\x42\xdf\x93\xfa\xc9\x78\xbb\x8e\x0e\x59\xb2\x55\ -\xd4\x16\x8b\x4d\xb4\xdf\xaf\x6f\xd7\x0b\xf5\x21\xd9\xdd\x6f\x0e\ -\xab\xf5\xee\x57\xf5\xa3\x59\x16\xa7\xbf\x66\x49\xb2\x21\x55\xfd\ -\xd5\x17\x8b\x9f\xee\x93\x34\x73\x9e\x96\xf7\xaa\x16\xfd\xa0\xb7\ -\xf0\xb9\x2a\xfc\xa4\x4a\xaf\x96\xf1\xed\x5e\x9f\x55\x3c\x92\xfe\ -\xa4\x9e\x29\x98\x4e\x66\x79\x69\x7d\x87\xfa\xf6\x96\x0f\xeb\xf8\ -\xf1\x78\xee\x4d\xb4\x2f\xaa\x6d\x32\xb9\x8f\x56\xaa\x89\x6d\x92\ -\xf4\x7a\xfa\xfe\x36\x7f\x95\x05\x37\x49\xba\x8c\xd3\xaa\xc8\xcf\ -\x5f\xad\xa2\x44\x61\x58\x67\xcf\x85\x50\x95\xbf\x5d\xdd\xaf\xfe\ -\xd5\xba\x9c\xf6\x97\xef\xef\xa2\x65\xf2\x78\x3d\xe5\xdd\xc2\xdf\ -\x92\x64\xab\xa0\x11\xe9\x49\xca\xa9\xec\x16\x2f\x9e\xae\xa7\x8e\ -\x2b\x09\x0b\x28\x2b\x11\x36\x4b\xd5\x05\x43\x97\x78\x4c\x06\x9e\ -\x38\x29\x3c\xa4\xa9\x12\x3b\x67\x13\x3d\xc7\xea\xa9\xf2\x7f\x58\ -\x79\xd2\xfe\x2e\x79\x5c\xa5\xba\x76\xb2\xf4\x10\x77\xbf\xa9\x4b\ -\x9c\x9b\x9b\xe4\xa9\xbf\x58\xb5\x82\x83\x16\x68\xe7\xb0\x5b\x67\ -\x4a\x68\xee\x9f\x9a\xbf\x7a\x58\x2f\xe3\x7d\xff\x17\x1f\xd7\x3b\ -\x55\x09\x4e\xd9\x7c\x99\xa8\xeb\xb8\x7b\x46\xd5\x96\x03\x1a\x0e\ -\x9c\xa1\x6e\xed\xa4\x9e\xcb\xa2\xe7\xe1\xa2\x6d\xf4\xb4\xde\xae\ -\x7f\x8b\xd5\x73\xb3\xee\x29\xfb\x5d\x74\xef\xac\x36\xc9\x4d\xb4\ -\x29\xef\xfe\x53\x7e\xc6\x55\xab\x5a\x8a\x2f\x4d\x26\xd9\xb3\x16\ -\xdc\xa7\x67\x7d\x6c\x5a\x1d\xd4\xf5\xa9\x0f\x88\xc0\xf7\xea\x83\ -\x49\xba\x56\xf2\xd0\xb8\xdf\xea\xd0\x73\xf3\x90\x16\x73\xa5\xa5\ -\x9f\xf2\x06\x96\x37\xbf\xa0\x5b\xf6\xdc\x2c\x2b\xdb\xfd\xec\xb4\ -\xe1\xe7\xc7\xb7\x71\x16\x2d\xa3\x2c\x3a\x4a\x41\x75\x84\x4b\x49\ -\xab\x27\x53\x1a\x73\xfe\x8f\x9f\xfe\xf2\xa9\xbc\xd0\xd5\x62\x31\ -\xff\x4f\x92\x7e\xae\xae\x3b\x99\xe8\x13\xa2\x9b\xe4\xa0\x50\x4c\ -\x3f\xd5\x87\xaf\x96\x8b\xb9\xd2\x71\x4a\xf6\x3f\xad\xb7\xaa\x6d\ -\x6b\xf5\xf8\x67\xa5\xd3\xae\x66\xc7\x82\xd6\xc9\xba\xb2\x8e\x3f\ -\x5a\xfc\x6c\x1a\x17\xca\xb2\xb7\xc7\x58\x2e\xb6\x6b\xfd\xa5\xd9\ -\x3f\xb3\xf5\x66\xf3\xb3\xbe\x48\xf9\xc4\x8d\x1f\x5d\x67\x9b\xf8\ -\x78\xf0\x6a\x56\xde\x7d\xf9\x6c\xb3\xc6\xc3\x5d\xcd\xaa\xa7\xcf\ -\x3f\xad\x8e\xb5\xd2\x12\x8a\x1a\xf4\x26\xba\x89\x55\x23\xf8\x9b\ -\x2e\x9c\x9c\x94\xae\xd2\xe4\x70\xbf\x4d\x96\x71\xf9\xf5\xba\x36\ -\xe3\x45\x56\x23\xcb\x9e\x37\xaa\xfc\x56\xdd\xfd\xfc\xfd\x2d\xd5\ -\x7f\x1f\xf5\x07\xa7\xd4\x13\x73\x56\x7c\x4c\x0f\x1b\xa5\xef\x1e\ -\xe2\x5d\xb2\x5c\x7e\xdc\x67\x69\xf2\x39\x9e\xbf\xa7\xd4\x0d\x29\ -\x2d\x3f\x16\xd2\x32\xaf\x3f\x6e\xd6\xbb\x58\xdd\xc6\x7c\xff\xbf\ -\x43\x94\xc6\xcd\xa3\xff\x4d\xd6\xbb\xb9\xaa\xb7\x38\xad\x8e\xe6\ -\x1f\x36\xaa\xc5\x67\x73\xb7\x3a\xb6\x8c\x94\x2a\x4a\xd3\xe8\x79\ -\xbe\x53\x26\x40\xf3\x68\x72\x7b\xbb\x8f\xb3\xe3\x95\xaa\x5b\xa5\ -\x44\x94\xaf\x56\x43\xd7\x8f\x2b\xa4\x64\xf5\xc1\xde\x5e\x49\xbf\ -\xfa\x7b\x26\xfd\x6a\x49\x85\x6a\xdf\x92\xb8\x81\x90\x54\xf8\xb1\ -\xc3\xfc\xba\x20\x6d\x9d\x96\x3e\x6b\x75\x29\x54\xef\xe4\xcb\xb0\ -\x6e\x15\x57\xf7\x51\x76\xd7\x57\xfb\x8d\xa7\xd4\x35\x4b\x6f\x39\ -\x6f\xd7\x2c\x2f\x6e\x4a\xb8\x6e\xb7\x8a\x6f\x0e\x59\x66\xaa\x82\ -\x6b\xee\xf5\x73\xa8\x2a\xfc\xfb\x84\x7e\xa0\x93\x7f\x4f\xaa\x8a\ -\x69\x57\xb0\x7e\x22\x25\xad\xc7\x7a\x38\x6a\xf6\x64\xa7\xee\x30\ -\x4b\x52\x47\xe9\xf8\x87\x28\x3b\xa4\x71\x4b\x97\xd4\x3a\x41\x35\ -\x52\x2d\x46\x4a\x1d\x2f\x16\x6f\xbd\xaa\xea\x4a\xfa\x50\xbf\x9b\ -\xfc\x75\x42\xfb\xaa\x2c\x7c\x3d\x55\xc6\x88\x22\x48\xb9\x17\xde\ -\x3f\xfd\xfe\x3a\x1b\xa8\x89\xba\x17\xf8\xc0\x43\x12\x4e\x7e\x9c\ -\x08\xc2\x8b\xb7\x27\x6f\x4e\x6a\x47\x04\x01\x77\xe8\x57\xd7\x8f\ -\x91\x36\xc3\x02\xcf\x65\x9e\x67\xac\x06\xb6\x13\xaf\x52\x49\x1f\ -\x84\x47\xf8\x64\xa1\xe4\xc8\x71\x09\xcf\x2b\x65\xe8\xfd\x69\x55\ -\x84\xee\x9b\xaf\x08\x46\x49\xd9\x14\xce\xac\x08\xe7\xeb\x65\xe6\ -\x8b\x55\xf1\x7e\xc1\x97\xf4\xd6\xef\x76\x78\xa3\x57\x0e\x67\xc4\ -\x4c\x2b\x71\xe4\x5b\x6f\x27\xdc\x37\xd5\x4e\xde\xbc\xc8\x08\x7e\ -\x76\x1d\x88\xb7\x5e\x07\xcc\x3f\xbb\x0e\xbe\xde\x2c\xf9\xb2\xbe\ -\xd0\x8e\x78\x6d\xf0\x8e\xd5\x8f\x6e\x9b\xfd\xa8\x20\x6e\xf1\xdc\ -\x8b\x49\x65\xe4\x08\x65\x9a\x0d\xbc\x1f\xe8\x55\x1d\x7e\x49\x75\ -\xc2\xc2\xca\xca\x3a\xab\x4e\xd8\x88\xb2\x02\x6b\x6c\x31\x5e\x1b\ -\x5b\xf9\xdb\x93\x37\x43\x55\x30\xa6\xba\x80\x6d\x13\x41\x21\x26\ -\xe7\xca\x89\x7b\x31\x15\x52\x3f\xec\x79\x15\xf2\x0d\xf6\xc5\xaa\ -\x15\x74\x72\x79\x78\x6c\x7e\x2d\x3d\xe2\x7a\xfa\xaf\x63\x8b\xd5\ -\xa7\x66\x69\xb4\xdb\xeb\x90\x8d\x0e\x79\xa9\xb7\x9b\x28\x8b\xbf\ -\x73\x24\x91\x61\xa0\xfe\xdc\x0f\x9e\x20\x21\x0d\x5c\x1a\x7e\x5f\ -\xc7\x7f\x8e\x57\xae\xae\x4d\xe5\x11\xe8\x57\x5d\xbd\x11\xc8\x69\ -\x06\x4d\x1a\xdf\xce\x23\xb1\x39\x50\xf5\xfa\xb8\x5c\xef\xef\x37\ -\xca\x4b\x5c\xef\x34\xa6\x8f\xc9\x43\x9c\xde\x6e\x92\xc7\xf9\xc3\ -\x7a\xbf\xbe\xd9\xc4\x1f\xf3\x7f\xd7\x1b\xfd\xe3\xd5\xa1\x17\x2e\ -\xdf\x88\xbc\xa8\xd6\xf3\x5b\x9c\x26\xc7\x06\x14\xd0\xc0\xbb\xfd\ -\x42\xe4\xc5\xa4\xaf\xfb\x52\xdc\x85\x7d\xdc\x46\xe9\xe7\x38\x2d\ -\xbe\x10\xef\x22\xf5\x5c\xce\x4d\xb4\xf8\xac\x03\x50\xbb\xe5\x3c\ -\x5a\x2c\x0e\xdb\x83\x26\x36\x6d\xd6\x60\x1d\x9b\x09\x29\x77\xb8\ -\x68\x95\x55\x91\x57\xc2\x5b\x87\xab\x00\x0d\x25\x92\xa9\x96\xe4\ -\x05\xed\xe2\xa7\xeb\xa9\xea\x20\x03\xce\xd4\x5f\xab\xe0\xf9\x7a\ -\xea\x70\x49\x02\xa1\x4a\xc2\x76\x80\x0e\xb9\x82\x72\x75\x1b\x2a\ -\xe3\x3c\xb0\x3e\x61\x08\xf6\xf5\x80\xe5\x62\x88\x6c\x77\x54\xa0\ -\xc9\xb7\xbf\x54\xe1\x15\xca\x05\xd6\x78\xd9\x09\x5e\x55\xe2\xe6\ -\x9a\x1d\xf1\x8e\x2b\xb7\x0d\xcf\xc9\x00\x5f\xe5\xb8\xe8\x3a\x75\ -\x91\xef\xab\xe0\xeb\x3b\xa2\x11\x21\x31\xc0\xd7\x27\x7e\x5e\xa7\ -\xa7\x7c\x39\x71\x15\xde\xc0\x43\xbe\x23\xf2\x95\xc2\x09\x8d\xca\ -\x2f\xea\xe7\x57\xc5\xd7\x75\x84\x70\x38\x2a\xe8\x8b\x05\xcc\x95\ -\x82\xf6\x42\x93\x80\x39\x11\xb9\xb3\x7c\x0a\x58\x10\x4f\x13\x66\ -\x08\x78\x54\x09\xf6\x1d\xe6\x78\x26\x09\xbb\xc4\xd3\x3a\xba\x47\ -\x84\x91\xb0\x25\x17\xc9\x61\xe3\xe8\x68\x8f\xf8\xda\xc8\xe2\x08\ -\x78\x6c\x27\xc9\xac\x9b\xe4\x11\x4f\x2b\x69\xf9\x46\x09\x17\xd7\ -\xbb\x1c\xc2\xd2\xc9\x5d\x25\x93\x84\x83\x22\x40\x89\x66\xd6\xab\ -\x00\xec\x3a\xa1\x23\x99\xea\x88\x8d\x3a\xc3\xc3\x52\x8c\x90\xad\ -\x48\x31\x53\xff\x07\x26\x09\x0f\x87\x3b\xde\x84\xa9\x75\x69\x7a\ -\x5a\x8b\xb1\xef\x78\x66\x3d\xe2\x90\x68\x77\x09\xfd\xa5\xd7\x83\ -\x58\xe6\x7f\xae\x41\xc8\x5c\x12\x36\xe0\x15\xbf\x09\x55\x7d\x69\ -\x82\x9c\xc7\xa5\xcd\x9a\xd4\x83\x62\xec\x13\x6d\x50\x8b\xd7\x0d\ -\xf8\xf2\xc4\x58\x38\x81\x13\x78\x66\x23\x1f\x18\x9d\x7e\x55\x90\ -\x8b\xc8\x87\x49\x3d\xfd\xd6\x4d\xea\x4b\xd3\xd3\x45\xe8\xc3\xec\ -\x10\xd3\xdb\xf6\x8c\x2f\x8d\x70\xd1\x13\x9b\x0c\x5f\xba\x7a\xc2\ -\x76\xbf\x96\xc6\x31\x62\x6b\x32\xec\x99\x8c\x7c\x70\x3a\xe4\x17\ -\x2b\x43\x9b\x23\x62\x3b\x91\x0f\x66\x32\x80\xc9\xd9\x60\x86\x65\ -\x40\x18\xfa\xc5\x76\xf4\xb4\xc9\xc0\x07\x17\x24\xd4\xb5\xea\x9f\ -\xea\x69\x4a\x84\x26\x8c\x80\x47\x4f\xf5\x30\x9a\x6d\x89\x6a\xfa\ -\xb5\x21\xce\x73\x01\x8c\x5a\x5b\xc3\x7a\xfa\x6d\xd8\xd3\x97\xc6\ -\x58\xea\x84\x1e\x27\x34\xab\xa9\x87\xe5\x18\xfb\x62\x6b\x71\x0f\ -\xb3\xaa\x3a\x1c\x9a\xf7\x80\x4e\x93\xc5\x9c\x0f\xa3\xe3\xc5\x4a\ -\x58\xe9\x40\x5e\x0f\x32\xb6\x97\xf5\xe1\x98\x4c\xbf\xe4\xee\x50\ -\xf0\x03\x4d\x2e\xbb\x89\x1f\x66\xad\x2e\x9e\x8f\x36\xf5\x8c\x27\ -\x22\x66\x8b\xa9\x1f\x46\x53\xb8\x5e\xf0\x8f\xd1\xb2\xb6\x99\xfc\ -\x61\xb6\x53\xf6\x8a\xc9\xe5\x6f\x75\xc4\xe9\xd2\x28\x97\x99\x01\ -\x66\x67\x9d\x52\xc2\x07\xd2\xb8\x5c\xe2\x6b\xc6\x01\x32\x1e\x7b\ -\xd2\x8b\x34\x6b\x77\x61\xb8\xfa\x75\x21\x2e\x52\x03\xcc\x76\xc8\ -\x68\x74\xbd\x2a\xc6\x55\x72\x80\xd1\x3c\x2e\x74\xa0\x5e\x17\xe4\ -\x32\x3f\xc0\xac\xb2\x1e\x0e\x76\x9d\x8e\x3c\x5d\xcd\x56\xd5\x12\ -\xca\xd5\x9b\xee\x5a\x43\xec\xd8\xb1\xf7\x2e\x20\xa4\xba\x80\xa0\ -\x5c\x78\x91\x12\x99\xbf\x6b\xac\x1f\xd4\x6e\x40\x65\x97\xc1\x03\ -\x9f\x35\x4d\x10\xbd\xec\x39\x57\xf6\xa0\x7e\x35\x9b\xe6\x8b\x2b\ -\x9a\xf4\xae\x82\xd2\xf6\x5b\x1a\x05\x66\x1b\x2e\x8b\xd8\x8d\x1b\ -\x5d\x7e\xc3\x6d\x34\x94\xaf\x05\x49\xcd\xf1\x73\x5b\x72\x81\x04\ -\xcd\x13\xac\x56\x42\xec\xc8\xa2\xff\x82\x2c\xf6\xe9\x9d\x17\x14\ -\x56\x0b\xa8\x40\x9c\x36\x70\x96\x6b\x7b\xfa\xd2\x30\x4e\x65\x80\ -\xf6\xac\x05\x87\x44\xcd\x11\x65\xca\x2a\xeb\x0a\xa2\x26\x5a\x2d\ -\x89\xed\x19\x26\xda\x9e\xe0\x85\x40\x47\x03\x2a\x5a\xbd\xa0\x19\ -\xe1\x0c\x1d\xdf\x43\x9a\xa0\x0a\xd7\x23\xfe\x48\x92\xc9\x5b\x39\ -\x0f\xc8\x72\x0c\x96\x10\x42\xe9\xa3\x86\x05\xe6\x58\xee\x03\xe0\ -\x8e\x64\x04\xe9\x94\x24\x1f\x91\xda\x40\x5a\xef\x50\x03\xd0\x75\ -\xca\xd6\x38\x18\x42\x85\x88\x1e\x04\x63\xca\x29\x17\x48\xd4\x0e\ -\x51\x38\x31\x45\x21\xb5\x13\x51\xe8\x8b\xf1\x9d\xd7\x87\x72\x34\ -\x8b\xec\xc4\x86\x40\xfb\x50\x86\x4e\x8b\x1d\xcb\x08\x2a\x80\xeb\ -\x3b\x02\x35\xae\x0d\xa2\xa6\x35\xae\x5e\x41\x02\x83\x43\x63\x07\ -\x14\xfa\xb0\x98\xe9\x3f\x99\x23\x11\x27\x2c\xce\x90\x04\x52\xbf\ -\x60\x05\x53\x67\x04\xe0\xb8\x35\x2c\x49\x4e\xa4\xe4\x9e\xe4\x1d\ -\xe9\x74\x49\xe8\xea\xbf\xfe\xd0\xad\xa0\x22\x50\xff\xf5\x21\x2d\ -\xd2\x58\xbc\x61\x5d\x2b\x5b\xfb\x82\x21\x54\x98\x7e\xd3\x0f\xd5\ -\xab\x6b\xdf\x52\x92\x33\x0d\x06\x4c\xa1\x6f\xa7\x2a\xf3\xe9\xa6\ -\x68\x0d\xc1\x52\x75\x09\x97\x3e\x97\x5d\xaa\x8c\x48\xa1\xfe\x5c\ -\xd3\x50\x73\xed\xdb\x9a\xcb\x82\x50\xc7\x19\x69\x11\x39\x50\x01\ -\x20\xa4\xd8\x9f\x8e\xcf\x13\x4c\xeb\xea\xb0\x82\xa7\xae\x88\x8a\ -\x17\xdc\xda\xe5\xc5\xd4\x8d\x71\x14\x6f\x31\xb1\x9f\x3b\x98\x4f\ -\x64\x25\x0a\x58\x6f\xf5\x6a\xda\x31\x45\xe5\x6b\x89\x28\x54\x1e\ -\x4a\xbe\x90\x0e\x86\x1a\xc6\xee\x50\xa1\x02\xba\x7a\xb2\x18\x7a\ -\xa6\x63\xd3\x84\x4b\xc8\xf5\x3b\x93\x49\x90\xe7\x68\x63\x2e\x70\ -\x39\xb9\xf9\x9a\x47\x28\xa5\x56\xa8\xc2\x24\xe6\x4a\x4c\x5d\xb0\ -\x95\x8d\x02\x96\xa0\x2b\x3a\xbb\x2a\x20\xd3\xd1\x98\x42\x08\x69\ -\xbe\xac\x2f\xe2\xb4\xe1\xbb\xc0\x0d\x93\xea\x08\x2f\xa6\xa4\x58\ -\xe9\x48\xa1\x42\x0c\xdd\x35\xc6\x10\xe9\x68\x48\xa1\xe4\xb4\xd8\ -\xde\x04\xe5\x74\x64\xb7\xd4\x7c\x8e\x51\xb1\xa4\x14\x46\x00\xa1\ -\xd3\x19\xba\x82\x19\x12\x2f\x17\xd8\x10\x80\x68\xb1\x7d\x18\x32\ -\xbd\x94\x64\x23\x8a\x2c\xed\xa4\x1b\x41\x8f\x91\xaa\x2e\x14\xed\ -\x22\xe8\xec\x14\x3f\xf4\x02\xf6\x15\xb3\x23\xbe\x7d\x05\x14\x9c\ -\x5b\x08\x6d\xdb\xd2\x2e\x97\xc2\xb6\xed\x0b\x29\x7c\xeb\x42\x44\ -\x4e\x80\xd3\x5b\x60\x31\xfa\xc4\xd3\x64\x4e\x33\xae\x0d\x62\xe4\ -\xa8\x50\xc1\xbb\x4a\xad\x4f\x5d\x01\xa6\x50\xf3\xd9\xda\x68\xf0\ -\x40\x1b\xaf\x22\x47\x03\x46\x91\x0b\x8c\x0e\xc0\x47\x07\x74\x35\ -\x72\x38\x86\x9d\x65\x88\x11\xe2\x9b\x9f\x62\x5f\x85\x07\xd0\x64\ -\xbd\xb0\x79\xf6\x02\x7d\xc9\x4b\x83\x5a\x64\x95\xb8\x38\xd7\xc1\ -\x0a\x56\x88\x50\xbb\xd6\xbc\x1e\xea\x5e\x3b\xeb\xf7\x41\x45\xdc\ -\x05\x0a\xa8\x1d\xa0\x50\x09\xb7\x7a\xcd\x54\x4c\xfd\x02\x66\xea\ -\x96\xeb\x90\x8f\x94\x82\xd0\xdd\x1b\xc9\x32\xd2\xe2\x7a\x7f\x0c\ -\xa4\x70\xd3\x1c\xf4\xea\xa9\xaf\x29\x01\xec\x22\xa9\x06\x05\x87\ -\x70\x24\xe5\x9b\x47\xff\xd0\x93\xb1\x03\x15\x36\xea\x40\x31\xf7\ -\xd6\x8e\xa1\x04\xe7\xa0\x72\x4c\x02\xb3\x05\x15\x54\x56\x99\x8e\ -\xfd\x22\x57\x1b\x3a\x18\xca\x4d\xd5\xeb\xc2\x61\xbf\x6a\x87\x29\ -\x64\xd8\x17\xd7\x59\x80\x86\x1a\x92\x40\xe7\x86\x79\x27\x16\xb0\ -\x0c\x59\xc8\x82\x7e\x57\xf5\xec\xb5\xa8\x50\xff\x82\xcb\xaa\xcb\ -\xd5\xeb\x44\x54\x7d\x05\x35\xa4\x10\xcb\xdc\xe8\x4d\xb8\x91\xaa\ -\x15\x6b\x49\x16\x63\xe5\xd4\xb8\x09\x2c\x30\xd3\xda\x56\x60\x09\ -\x8a\x69\xb1\x7e\xc6\x6b\x8a\xea\x53\x7a\xcb\xf9\xa5\x51\x1d\xb0\ -\x95\xe0\x22\xc0\xc5\x1c\x7d\x34\x97\xec\x70\x85\x0c\x03\xe7\x73\ -\xf5\xb1\x6b\xbd\x94\x7d\xd1\xca\x49\xc0\xaf\x49\x03\xff\x91\x80\ -\x82\x4a\x2a\x53\x56\x70\x67\x5b\x74\x44\x3b\x9a\x12\x86\x32\x99\ -\xf2\x19\xde\x28\xaf\x76\x02\x11\x50\x2e\x6b\x63\x92\x1a\x6e\xfd\ -\x02\x8c\xd6\x27\x7a\x9b\x6e\x7a\xba\x48\x6b\xe1\xf9\xf4\x46\x0e\ -\xbf\x7d\xc2\x9a\x83\xfb\x3c\xc3\xcb\xaa\x27\xa9\xdb\x0a\x0e\x7e\ -\x29\x12\x7c\xd6\x7c\x19\x94\x50\x63\x40\xaf\x66\xab\xf2\xcd\xea\ -\x5d\xa3\xc2\x57\x2e\x6b\x60\xcb\xd2\x68\xb7\xbf\x4d\xd2\xed\xf5\ -\x34\x7f\xab\x7f\xe1\x3b\xc7\x0d\x49\xd1\x51\x7e\x70\x05\x09\xf3\ -\x89\x52\xdf\x4f\x5f\x68\x26\xc2\x25\x1a\x38\xed\x4c\x22\xf7\xca\ -\x9f\xe9\x1b\x03\xfa\xe6\x56\x02\x37\x4e\xeb\x2e\x7c\x7f\xc9\xfe\ -\x38\x0d\xa4\x1f\x25\x57\xfd\xa9\xe2\xcd\xc1\x51\x42\x5a\xcf\x88\ -\x52\xa3\xf4\x09\xd3\x60\x3a\x8e\x91\x27\x49\xa8\x51\xf6\xf9\x45\ -\x67\xf4\xc5\x70\x61\x0b\x84\xa9\x61\x2a\x77\xd6\xe3\x22\xe8\xaa\ -\x58\x59\x78\xb9\xc6\x63\x17\x28\x9b\x36\x70\xfa\xec\x74\x9d\x3a\ -\x53\x63\x01\x08\x14\x14\xa8\x62\x90\x1b\x4a\x1d\xa0\xb4\x48\x30\ -\x35\x1f\x5b\x44\x7d\x6b\x85\x27\x2f\xf3\x9a\x00\x82\x8a\x70\x29\ -\xe0\x48\x54\x13\x15\x84\x33\xe5\xcc\x86\xe3\xa8\x5c\x09\xba\xef\ -\x25\x12\x7d\x81\xa8\x20\x9e\x5e\xd1\x0c\x68\x4d\x3a\x64\x6a\xc3\ -\x30\x82\x64\xca\x00\x43\xfe\x08\x75\x58\x50\xa1\x9c\x17\x1f\x23\ -\x0b\xe0\xeb\xee\x48\x25\xa4\x27\x91\x05\xbf\x08\x0b\x83\x4c\x91\ -\x03\x4c\x78\x41\xa6\x5a\x46\x29\xa1\x5a\x46\x83\x71\x98\xe6\x89\ -\xa4\x48\xd4\x06\xd1\xb0\x9c\x72\x03\xe1\xc2\x60\x78\x1e\x3c\x3c\ -\xcf\xb4\xe6\xed\x86\xe7\x81\x7a\xd2\x2a\x2b\x0d\xa9\xda\xa0\x0a\ -\x18\x0d\x74\x02\xc0\x91\x56\x64\x3a\x7e\xc0\xbe\x64\x8a\x11\x07\ -\xe8\x2e\x95\x7b\x3e\x0d\xdd\x93\x2e\x55\xe6\x59\x48\x86\x53\x97\ -\x24\xe4\x86\x23\x08\x74\x18\xa8\xd2\xbc\xa1\x46\xd3\x6f\x23\x9d\ -\x93\x8b\x26\x20\x67\xc4\x21\xd2\x62\x41\x51\xea\x32\xde\xdd\xeb\ -\xe9\xe5\x91\x98\xf3\x66\xc4\xc1\x2d\x08\x81\x44\x5f\x20\x2a\x14\ -\x36\x49\xfb\x57\x0e\x38\x37\x5f\x14\xc3\xbc\xd0\x16\x6f\xe8\x0b\ -\x57\xb2\x71\x84\x94\xe3\x60\x8c\x2d\xa2\x50\x42\xaa\xe7\x21\x63\ -\x00\x09\x7a\x49\x51\xdf\x0d\xfd\xe0\x74\xc4\x14\xc4\x38\x2a\xa6\ -\x36\x62\xe6\x91\x1d\xa8\x2e\x09\x7c\xe1\x0f\xac\xed\x71\x5e\x6f\ -\xaa\x23\x48\x28\xaa\xd0\xd1\x06\x37\xa0\xa1\x1c\x49\x54\xf3\x2d\ -\x88\x51\x50\xad\x20\x05\x13\x54\x09\xba\x62\x21\x32\x7d\x21\xdc\ -\x00\xa9\x7c\x19\x1a\x4a\x96\xfa\x54\xa8\xb0\xa0\x8f\xde\x8c\xa5\ -\x90\x83\x17\x10\x57\x39\x33\x60\xfb\x28\x22\x54\x1b\x62\xea\x13\ -\xaa\x94\xef\xc0\x80\xf8\xd9\xfe\x0c\xda\x49\xe0\x1b\xf2\x09\xd7\ -\x95\x81\x18\x47\xf9\xd6\x43\xe2\x18\xc7\xb7\xc2\x15\x70\x68\x46\ -\x0f\xa0\x62\xe0\x17\x7c\x5e\x85\xe7\xc9\x20\x1c\x49\x07\x1f\xf7\ -\x11\x47\xcf\xe6\x92\x46\xc6\xab\x74\x07\x1c\x7a\xbb\xa8\x74\x7c\ -\x89\x8e\xcd\x65\xcd\x99\xd1\xae\x2a\x26\x0f\x5e\xd6\x54\xe2\xaa\ -\x47\x45\xfb\xf7\x92\x54\x6f\xdd\xa3\xa2\x01\x7c\x49\x06\xb0\x4e\ -\x21\x44\x49\xb5\x83\x14\xce\xf6\x85\xdd\x5c\x0a\xa1\xbe\x10\x56\ -\x82\x89\x00\xe7\x59\x84\x68\x29\xd9\x89\x28\x01\x25\x9d\x95\x89\ -\x84\xd8\xa1\x02\x6b\x5f\x97\x30\x3f\x60\xf2\x77\xad\xbc\x72\x76\ -\xe6\x19\x52\xb5\x33\xc5\x18\x6a\xa6\x45\x99\x7b\x86\x2a\xd8\x0a\ -\x56\xb8\xa0\x7e\x99\x7d\x86\xe2\x0a\xbe\xd6\x60\x10\xb8\x7e\x77\ -\x11\x76\x28\x71\x2d\xf2\xcf\xd0\xaf\xb1\x02\x15\x4e\x58\xf3\x0c\ -\x34\xa4\x6a\xc5\x5b\x05\x55\xc1\x79\x0e\x1a\x66\xa1\xd9\x5a\x95\ -\x05\x24\xb2\x94\x67\xa1\xe1\xf8\xdb\x45\xa5\x2c\x35\x92\x5b\x70\ -\x20\xee\xa2\x72\x46\xeb\xf4\x16\xf4\x70\x2e\x2a\xbe\x7f\x4c\x84\ -\xc0\x05\xb2\xc0\x47\xce\x85\x5e\x18\xbf\xb3\xb9\x09\xc0\x72\xea\ -\x5a\xff\x62\x74\x1f\x7a\x70\xb5\x6f\xd3\x30\x90\x1d\x2b\x18\x7a\ -\x34\x56\x60\xfa\xd5\x98\xb7\x39\x98\xc5\x4a\x84\x68\xf3\xc2\x5a\ -\x46\x2e\x51\x95\x2d\xbd\xee\xc8\x9b\x3f\xbc\x6e\xdd\x39\x7b\x48\ -\x21\x4c\x50\x98\x65\xf7\x78\xba\xac\xa4\x79\x98\x28\x99\xf0\x03\ -\xa8\x5c\x09\x26\xef\x26\xf9\x06\xc3\xa9\x66\x67\x48\x26\xe4\x66\ -\x60\x88\xb3\x70\x55\xfc\x3c\x62\x34\x02\x4e\x1c\x06\x87\x8f\xfe\ -\xd1\xbc\xdb\x1c\xc5\x3d\xc1\x50\xae\x15\x98\x40\x8a\x16\x3d\x14\ -\x4b\x1d\x27\xc4\x56\x6c\xb8\x66\xa4\x25\x93\x16\x26\x76\x80\xfe\ -\x89\x0d\x98\x60\xb1\x03\x8a\xb3\xc1\xa1\x87\x55\x58\xef\x18\x28\ -\x40\xec\x20\xc0\x31\xb2\x71\x46\xb4\x7b\x72\xb0\x8d\x9b\x41\x3e\ -\xce\x68\xb2\x23\x9b\x00\xaa\x36\x1f\x40\xc1\xe8\x81\x15\x4d\x0b\ -\xb1\x51\x74\xee\xa2\x04\x68\x0a\xd9\xd1\xb6\x10\x11\x04\x86\x9b\ -\x74\x59\xc2\xe9\x73\x90\x61\x14\x3d\x7d\x09\x15\xae\x8d\x2d\x69\ -\x95\x35\x74\x32\xfa\x69\x6e\x42\x30\x45\xa3\xc8\xce\x3e\x31\x80\ -\xbb\x74\xf9\x7a\xb1\x39\x1f\xc5\x15\x58\xff\xd2\xa1\x29\x11\x2f\ -\x80\x3d\x77\x06\x29\x0a\xab\x0d\xa6\xca\x85\x61\x81\x17\x78\xfd\ -\x6b\x32\x9c\x3f\x83\x14\xa9\xc2\x52\xe5\x84\x06\xa1\xa0\xdd\xcc\ -\x3e\x9f\x84\x8c\x33\x0e\x31\x2f\xb8\x4a\xb2\x46\x1b\xd8\x0a\x59\ -\x49\x02\x05\xd6\xfc\x32\xae\x55\x8e\x35\x8e\xc0\x58\xc1\x0a\xd4\ -\xb5\xd6\x13\xf9\x51\x11\x03\x73\x65\x44\x6a\xff\xf3\x34\x21\x25\ -\xd0\x7b\x26\xf6\xcd\x89\x38\x67\x98\x14\xc3\xf7\xc6\x70\x5e\xcd\ -\x56\xfa\x4d\xfe\xcf\xd5\x6c\xff\xa0\xfe\xf9\x3f\xa7\x5f\x0b\x56\ -\ -\x00\x00\x07\x5e\ -\x00\ -\x00\x55\x31\x78\x9c\xe5\x9c\xdd\x93\x9b\x36\x10\xc0\xdf\xef\xaf\ -\xa0\xe4\xa5\x9d\x46\x7c\x63\x30\xb1\x9d\x87\x64\x3a\xcd\x4c\xfb\ -\xd2\xa6\xed\x63\x46\x06\xd9\x47\x03\xc8\x23\xe4\xb3\x9d\xbf\xbe\ -\x12\x5f\x06\xc3\xb5\xc9\x48\xee\xe8\x6c\xcf\xdc\x04\xb4\x42\x48\ -\x3f\x76\xb5\xbb\x12\x61\xf1\xf6\x98\x67\xda\x13\x22\x65\x8a\x8b\ -\xa5\x6e\x1b\x96\xae\xa1\x22\xc6\x49\x5a\x6c\x97\xfa\x1f\x1f\x7f\ -\x02\xa1\xae\x95\x14\x16\x09\xcc\x70\x81\x96\x7a\x81\xf5\xb7\xab\ -\x87\xc5\x77\x00\x68\xef\x08\x82\x14\x25\xda\x21\xa5\x8f\xda\x87\ -\xe2\x73\x19\xc3\x1d\xd2\xbe\x7f\xa4\x74\x17\x99\xe6\xe1\x70\x30\ -\xd2\xa6\xd0\xc0\x64\x6b\xfe\xa0\x01\xb0\x7a\x78\x58\x94\x4f\xdb\ -\x07\x4d\xd3\xd8\x7d\x8b\x32\x4a\xe2\xa5\xde\x5c\xb0\xdb\x93\xac\ -\xaa\x98\xc4\x26\xca\x50\x8e\x0a\x5a\x9a\xb6\x61\x9b\xfa\xb9\x7a\ -\x7c\xae\x1e\xf3\xbb\xa7\x4f\x28\xc6\x79\x8e\x8b\xb2\xba\xb2\x28\ -\x5f\xf5\x2a\x93\x64\xd3\xd5\xe6\xbd\x39\xb8\x55\x25\x7b\x3e\x9f\ -\x9b\x96\x63\x3a\x0e\x60\x35\x40\x79\x2a\x28\x3c\x82\xe1\xa5\xac\ -\x8f\x53\x97\x3a\x96\x65\x99\x4c\x76\xae\xf9\x75\xb5\xa2\x92\x01\ -\xdd\xb1\xbf\xae\x7a\x5b\x60\x94\x78\x4f\x62\xb4\x61\xd7\x21\xa3\ -\x40\xd4\x7c\xff\xf1\x7d\x27\x04\x96\x91\xd0\xa4\xd7\x4c\xcb\x73\ -\x70\xd7\x01\xe4\x02\xe6\xa8\xdc\xc1\x18\x95\x66\x5b\x5e\x5d\x7f\ -\x48\x13\xfa\xb8\xd4\x5d\xcf\xb0\x5d\xf6\xf3\xab\xc2\x47\x94\x6e\ -\x1f\xe9\x65\x69\x9a\x2c\x75\xd6\x7b\x67\x1e\xd6\xe7\x3d\xe5\xb0\ -\xeb\x0a\x4d\xc3\x51\x27\xb1\x8c\xb9\x63\xd8\x1a\xb1\x7d\x37\xa8\ -\xeb\xb4\x43\x88\x12\x1c\xf3\x3e\xb1\x26\x51\x9e\xc2\x3d\xc5\x39\ -\x7b\x6a\x71\x9c\xc1\xb2\x4c\x37\x69\xcc\x4e\x70\xb1\xcb\xf6\xdb\ -\xb4\xf8\xc4\x1a\xa5\x14\x91\x4f\xe5\x23\x3e\x7c\x22\xb0\x64\xc7\ -\x46\x8b\xb1\xbb\x27\x3a\xee\x30\xa1\xe0\x98\xec\x18\xcc\x59\x30\ -\x29\x3c\xb5\xc2\x15\x93\x2e\x12\xb4\x29\x79\xad\x7a\x64\xfc\x8c\ -\x0d\x2d\xd0\x35\xb3\x92\x76\x1d\xe5\xbd\x4c\x9e\x52\x74\x38\xd7\ -\x5d\xc3\xb2\xa6\xa7\x69\x3b\xb8\x65\x9a\x96\x61\xb2\xd4\x5f\x6d\ -\xaa\x5f\x23\x58\x63\x92\x20\xd2\x8a\x66\xd5\x6f\x20\xc2\xec\x69\ -\xa4\xf4\x54\xdb\x56\xd3\x76\xdb\x5f\xde\x6a\x27\xb7\xa6\xe5\xe5\ -\x23\x4c\xf0\x61\xa9\x3b\x97\xc2\x2f\x18\xe7\x4b\xdd\x37\xfc\x79\ -\x38\xb7\xec\x4b\x69\x7c\x5c\xea\xc0\x0e\x0c\xd7\xf5\xac\xae\x47\ -\x67\x29\xef\x0f\x7b\x9e\x76\xe8\x05\xa3\x86\xe3\x3d\x21\xcc\xf8\ -\x40\x06\x4f\x88\x0d\xaa\xfa\xa7\x6d\x9f\x3f\x9b\x2d\xe1\x70\x28\ -\xd9\xa3\xcb\x2b\xb9\x04\xac\xd7\xf8\x38\x2d\x66\xba\xb0\xe7\x66\ -\x0d\xf6\x45\x4a\x99\xe9\xec\x8e\xfd\x56\xf7\x69\x82\xca\xe9\x0b\ -\x0f\x69\xc1\x18\x80\x46\x89\x6d\x77\x3c\xa0\xa6\x46\xab\xd1\x81\ -\x15\x3e\x53\x83\x75\x6d\x84\xb9\x11\x9d\x9e\x17\xe5\xf0\x98\xe6\ -\xe9\x17\xc4\xc6\x3d\x22\x5d\x16\x70\x07\xb6\x19\x5e\xc3\xac\xe9\ -\xfd\xaa\xaa\xb1\x18\x60\xa9\x2f\xd2\x34\x7a\xe2\xe6\x7b\x3c\xf1\ -\x32\xbd\x2d\xe4\x3c\x79\x81\x1b\xcc\xfc\xae\x10\x93\x94\x59\x45\ -\xaf\xbf\x6d\xd1\xa9\x5f\xc4\x8d\x9d\xcd\xd5\xc7\x4a\xbf\x2a\xed\ -\x0b\x2e\x65\xa7\xbe\xac\x51\x7b\x73\xac\xf7\x55\x79\x8e\x28\x4c\ -\x20\x85\x67\x23\x68\x4b\x9c\xf9\xdc\x6a\x47\xc6\xe6\xcd\xe8\xb7\ -\xf7\x3f\xad\x9a\x1b\x2d\xe2\x38\xfa\x0b\x93\xcf\xed\x7d\x35\x8d\ -\x57\x80\x6b\xbc\x67\x8f\x42\x5f\x75\xc5\x8b\x24\x8e\xd8\x4c\xc7\ -\x66\x80\x55\x9a\x33\xd5\xe6\x93\xe4\x8f\x6c\x66\x5b\x98\x67\xc1\ -\xa0\x32\x87\x75\x6e\xb4\x6e\x96\xa0\x7a\xca\x9c\xf4\x1b\x49\x9c\ -\xa7\xfc\x22\xf3\x77\x9a\x66\xd9\x07\x7e\x93\x66\xc4\xbd\x46\x53\ -\x9a\xa1\x73\xe1\xc2\x6c\x7a\xdf\x8c\xcd\xec\x0d\x6e\x61\xb6\xa3\ -\xaf\xce\xb6\x67\x2a\x03\xa3\xe8\x1e\x74\x06\xd7\x88\x29\xc1\x2f\ -\x5c\xa8\x8d\xa4\x5b\x82\xf7\xbb\x1c\x27\xa8\xb9\xbc\xa3\x89\x62\ -\xda\x3d\x32\x7a\xca\x98\x7c\xc3\x7a\x1f\xbd\xb2\xac\x38\xde\x6c\ -\xde\xf0\x13\xd0\x4c\x13\x91\x5d\x9f\x92\x7d\xc6\xa6\xbb\x27\x54\ -\xe0\x24\x79\x53\x52\x82\x3f\xa3\xa8\x99\x98\x9a\xd3\xda\x5a\x22\ -\xab\x3d\x65\x60\x10\xc9\x98\x16\xd3\xc8\x6b\xcb\x12\xc8\x66\x17\ -\x42\xe0\x29\x2a\x98\x73\x6f\x4b\xbb\x5b\x0d\xf4\x93\xf7\xd2\x0f\ -\xdd\x79\x57\xd8\x58\xa3\x67\x38\x95\x6a\x9d\x05\xad\x11\x8e\x25\ -\x03\x65\x3e\x4d\xd5\x20\x83\x2a\xa4\x52\x5d\xcf\xe1\x3f\xb7\x7b\ -\x90\xff\x06\x0c\xc2\xc4\x53\x0c\x18\xb0\x05\x91\x8d\x0b\xaf\x82\ -\xce\xf3\x7c\x5f\x39\x74\xc0\x12\x84\x67\x3b\x46\x78\x4d\x6e\x9b\ -\x8d\x03\x1d\xa8\x1c\x37\x57\x14\x5b\x50\x7b\x8c\x7b\x64\x07\x42\ -\xe0\x0b\xe2\x73\x7c\x63\x76\x8f\xe4\x2c\x20\xaa\x78\xce\xdc\x08\ -\x87\x51\xcc\xfd\xf8\x09\xe0\x5d\xc3\x53\x58\xd2\xa0\xb1\xe9\xc0\ -\x52\x0f\x5a\x28\xec\x60\x43\xc3\xe7\xe9\xaf\x1b\x5e\x07\x9b\xa2\ -\x8e\x15\x04\x82\xd8\x2e\x5d\xab\x2c\x62\x9b\xcd\x7c\xae\x20\x31\ -\x17\xcc\x44\x81\x4d\x39\xd5\x1b\xa7\x06\x02\xe0\x08\x62\x73\x6c\ -\xa3\x32\x4f\xef\x9e\xb0\xb1\x18\x04\x88\xe6\x5a\x97\x51\x88\xbc\ -\x29\x4d\xc1\xbc\x14\x84\x82\xb4\x06\x99\xe9\x60\x6e\xbb\xcd\x60\ -\x23\x14\x05\x36\x19\x6d\x48\x05\xa7\xaa\xe7\x14\x76\x04\x17\x9e\ -\x53\x22\xb4\xd0\xe2\x3f\xe5\xa0\xb9\xc2\x5e\x60\xd2\x79\xde\x3e\ -\x38\xe6\x3f\x85\x53\xaa\x29\xff\x79\x07\xe4\xb8\x0b\x15\x9d\xe3\ -\x2e\x5d\xe8\x1d\x60\x63\x39\xbc\x70\x6a\x30\x99\xc5\x4b\x75\x0d\ -\x2a\x46\x20\x96\x70\x02\x3f\x88\x41\xc6\x69\xe9\x6d\x06\x22\x9e\ -\xb0\x6f\x98\x8c\x44\xe4\xe3\x53\x76\xfd\x43\x78\xbd\x72\x72\x05\ -\x44\x3e\x40\x55\xe3\xb9\x40\x38\xd5\xba\x8c\xe8\x64\xb3\x4b\x3c\ -\x25\x9d\x85\x0b\x66\xd7\x09\xec\xee\x84\x1f\x5f\x1d\x11\x77\xb6\ -\x53\xf1\xdd\xbd\x00\xe4\xd1\x8a\x23\xbc\x02\x3c\x19\xaf\xc8\x46\ -\xc8\xdd\x87\x7a\x08\x2d\xd1\xf4\x62\x10\xb3\x8c\x75\xf1\x16\x99\ -\xd9\xc2\x2b\x00\x93\x11\xcb\xbd\xc0\x0b\x85\xa7\xbc\xc9\x78\x45\ -\x36\x3e\xcb\x62\x37\x50\x0f\x1f\x9b\xef\x84\x77\x6e\xa6\x5c\xae\ -\x7c\x7c\x9e\x07\x15\xdc\xa3\x0e\xc4\x77\xf7\xa7\x1c\xae\x6c\x7c\ -\x61\xc0\xb2\x35\xa4\x1e\xbe\x6a\x79\xe0\x2a\xbb\xfc\xb2\x09\xf2\ -\x6c\x43\xbd\xe9\x4f\x7c\xdf\x75\xb8\x51\x31\x32\xe5\x5b\x84\xd6\ -\x64\xb9\x57\x49\x73\xef\x85\x20\x4f\x73\x45\xd7\xa7\x46\x1b\x17\ -\x92\xd9\x29\xeb\x72\x67\xc2\x4e\x63\x7a\xff\x42\x32\x3f\x07\x06\ -\x1b\xf5\xd6\x45\x9b\xdd\x6c\xf1\x8d\x8c\xcb\xc5\x78\xc9\xf4\x54\ -\x76\xb9\x8e\xf0\x9b\xb0\xd3\x6b\xf2\x92\x11\xae\xe3\xc4\xf5\x55\ -\x54\x40\xf1\xb7\xc4\xa6\x53\xb6\x11\xd4\x1b\xe5\xc7\xcc\xf7\x3a\ -\x49\xdb\x9d\x00\xb4\x98\x0b\x91\xfd\xda\x80\x6c\x76\xca\x7a\x5f\ -\xe7\x3a\xde\x57\x3e\x3f\x55\x33\x5e\x57\x38\xf2\x9b\xce\x79\x25\ -\x03\x54\x39\x7c\x91\xff\x9f\x02\x64\xd3\x0b\x43\x08\xd5\x4b\x3c\ -\x2c\xe0\x09\xbb\xde\xe1\x12\x73\x1f\xe3\x2d\x12\xab\x76\xc4\x85\ -\xbd\xed\x74\xb8\x72\xfb\xec\xaa\xdd\x5c\xe1\x54\x63\xe4\x6a\xe5\ -\x81\x53\xd6\xcb\xce\x24\x24\x19\xd3\x7e\x56\x26\x3c\x55\x5d\x2c\ -\xb3\xd8\xeb\xec\xe4\x4a\xa4\xa7\xb2\x7f\xe5\x9e\x42\x38\xc5\xbd\ -\xf4\xb0\x12\xa7\x3b\xa5\xd7\x06\xec\xeb\xec\x80\x7f\x3b\xbf\x1d\ -\xa4\x8f\x53\xfc\x7a\x63\xe2\x46\x5c\xbd\x4b\x30\x60\xe3\xd4\x9f\ -\x20\x71\xbd\x0e\x48\x96\x16\x28\x86\xbb\x68\xbd\xa7\xb4\x5f\xf6\ -\x37\x4e\x8b\xa8\x22\x28\x03\x27\xa3\xf9\xab\x66\xbd\xb6\xb4\x3f\ -\xb5\xf6\x33\x28\xee\x80\x35\x1f\x91\x33\x9f\x9f\x39\x9c\xbf\x93\ -\x81\x0b\xd6\x43\x8a\x09\x88\xf7\xe4\x09\xd2\x3d\x41\x83\x2f\x33\ -\x74\x5f\x58\xc0\x09\xe2\x1f\x25\x28\x97\x7a\x1c\xbf\x74\x54\x1d\ -\xa4\xd7\xdd\x91\xf6\xb3\x66\x4d\x21\x0b\xd5\x41\x66\x1b\xec\x09\ -\x5a\x8e\x1f\xee\x8e\xdf\xce\xec\x19\x12\xdd\x37\x35\x5e\x3b\xa1\ -\x11\x6a\xef\x34\xd7\x70\xea\xc3\xd1\xc1\x88\x8e\x1b\x04\x7d\x5f\ -\xfb\x5f\x7c\xa4\xe8\x8c\x1d\xf8\x9e\xed\xfb\xd2\x08\xe4\x9a\x5f\ -\x7b\x2b\xae\x0b\xbe\xe1\x68\x31\xb3\x23\xd0\x4c\x2e\xc1\x73\xc7\ -\x63\x14\xa1\xf7\xe2\x41\xd8\x96\xd1\xa8\x82\x20\x08\xf0\xf5\x36\ -\xa3\x28\x8a\x36\x84\x11\xd6\x89\xde\x2b\x99\x2f\x15\xc5\x4c\x96\ -\x56\xbc\x78\x03\x71\x1d\x61\x06\xee\x4b\x67\x60\xcf\x84\x19\x7c\ -\x7d\x10\xa2\xa2\xcb\xcc\xfb\x2e\xd3\x35\xbc\x7a\xd0\xb1\xd6\xc6\ -\x33\x2e\x8b\xc2\x9e\x39\x7e\xc6\x81\xf6\xde\x3d\x7e\xe9\x40\xec\ -\xb0\x8d\xa6\x84\x80\xd8\x2f\x1a\x48\x3f\xa8\xe2\x2b\x30\x4d\x50\ -\x55\x1d\x8e\x0e\x9e\x43\xf0\x7f\x4e\x14\xd7\xd5\x89\xa0\xb6\x11\ -\x51\x23\xf1\x6e\x06\x48\x37\x58\x31\x20\xdf\x1a\x59\x2c\xcc\xed\ -\xea\x61\xc1\xbf\x56\xb7\x7a\xf8\x07\x3d\x1f\xd6\xd0\ -\x00\x00\x0d\xbb\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x65\x78\x70\x6f\x72\x74\x2e\ -\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ -\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\ -\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x63\x31\x30\x30\x30\x30\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x73\x74\x6f\x70\x35\x39\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\ -\x6f\x6c\x6f\x72\x3a\x23\x38\x30\x30\x30\x30\x30\x3b\x73\x74\x6f\ -\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\ -\x74\x6f\x70\x35\x39\x37\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\ -\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x32\x3d\x22\ -\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\x3d\x22\x32\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x31\x3d\x22\x31\x35\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\ -\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x2d\x30\x2e\x39\x32\x30\x37\x37\x33\x37\x35\x2c\x2d\x30\ -\x2e\x30\x30\x31\x34\x32\x36\x38\x36\x2c\x30\x2e\x30\x30\x31\x34\ -\x30\x36\x31\x39\x2c\x2d\x30\x2e\x39\x33\x34\x33\x31\x30\x31\x34\ -\x2c\x33\x32\x2e\x35\x30\x37\x34\x32\x32\x2c\x33\x31\x2e\x30\x39\ -\x37\x30\x31\x37\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\ -\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\ -\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x33\x30\x32\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x39\ -\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ -\x61\x79\x73\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ -\x3d\x22\x2d\x32\x39\x2e\x34\x37\x34\x37\x31\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ -\x31\x35\x2e\x35\x35\x38\x35\x39\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\ -\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ -\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ -\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ -\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ -\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ -\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ -\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ -\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ -\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ -\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x64\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\ -\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\ -\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\ -\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x30\x32\x38\x29\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x6d\x20\x32\x30\x2e\x36\x38\x30\x38\x38\x31\x2c\x33\x31\ -\x2e\x33\x31\x32\x32\x36\x37\x20\x63\x20\x30\x2e\x39\x34\x33\x31\ -\x37\x33\x2c\x30\x2e\x30\x30\x31\x34\x20\x31\x2e\x36\x39\x38\x38\ -\x33\x2c\x2d\x30\x2e\x37\x36\x32\x39\x36\x35\x20\x31\x2e\x37\x30\ -\x30\x32\x37\x31\x2c\x2d\x31\x2e\x37\x32\x30\x30\x30\x32\x20\x4c\ -\x20\x32\x32\x2e\x34\x2c\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x20\ -\x6c\x20\x36\x2e\x34\x34\x35\x34\x31\x37\x2c\x30\x2e\x30\x31\x30\ -\x30\x33\x20\x43\x20\x33\x30\x2e\x36\x38\x36\x39\x36\x36\x2c\x31\ -\x37\x2e\x30\x37\x39\x35\x30\x38\x20\x31\x38\x2e\x37\x33\x38\x2c\ -\x33\x2e\x30\x34\x36\x33\x30\x39\x31\x20\x31\x38\x2e\x37\x33\x38\ -\x2c\x33\x2e\x30\x34\x36\x33\x30\x39\x31\x20\x4c\x20\x31\x37\x2e\ -\x38\x31\x38\x36\x33\x31\x2c\x32\x2e\x31\x31\x30\x35\x37\x31\x37\ -\x20\x31\x36\x2e\x38\x39\x36\x34\x35\x32\x2c\x33\x2e\x30\x34\x33\ -\x34\x35\x35\x35\x20\x63\x20\x30\x2c\x30\x20\x2d\x31\x31\x2e\x39\ -\x39\x31\x31\x35\x31\x31\x2c\x31\x33\x2e\x39\x39\x36\x31\x30\x31\ -\x35\x20\x2d\x31\x30\x2e\x31\x34\x39\x36\x30\x31\x38\x2c\x31\x33\ -\x2e\x39\x39\x38\x39\x35\x35\x35\x20\x6c\x20\x36\x2e\x34\x34\x35\ -\x34\x31\x35\x38\x2c\x30\x2e\x30\x31\x30\x30\x33\x20\x2d\x30\x2e\ -\x30\x31\x38\x38\x35\x2c\x31\x32\x2e\x35\x32\x35\x35\x39\x37\x20\ -\x63\x20\x2d\x30\x2e\x30\x30\x31\x34\x2c\x30\x2e\x39\x35\x37\x30\ -\x33\x38\x20\x30\x2e\x37\x35\x31\x39\x31\x31\x2c\x31\x2e\x37\x32\ -\x33\x38\x30\x32\x20\x31\x2e\x36\x39\x35\x30\x38\x33\x2c\x31\x2e\ -\x37\x32\x35\x32\x36\x35\x20\x6c\x20\x35\x2e\x38\x31\x32\x33\x38\ -\x34\x2c\x30\x2e\x30\x30\x39\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ -\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x08\xf8\ -\x00\ -\x00\x56\xfd\x78\x9c\xe5\x5c\xcb\x8e\xeb\xb8\x11\xdd\xf7\x57\x28\ -\xbe\x9b\x04\x31\x65\x8a\x7a\x50\x52\xdb\x3d\x8b\xb9\x18\xcc\x00\ -\xc9\x26\x33\x49\x80\x6c\x06\xb4\x44\xdb\xc2\xd5\xc3\xa0\xe8\xb6\ -\x7d\xbf\x3e\x45\xbd\x6c\xd9\x9a\x20\x00\x65\x40\xb0\x05\x34\xba\ -\x55\x55\x24\x8b\x47\xc5\xe2\x11\xc5\xe6\xf2\x87\x53\x96\x1a\x9f\ -\x5c\x94\x49\x91\xaf\x66\x96\x89\x67\x06\xcf\xa3\x22\x4e\xf2\xed\ -\x6a\xf6\xcf\xdf\x7e\x42\xfe\xcc\x28\x25\xcb\x63\x96\x16\x39\x5f\ -\xcd\xf2\x62\xf6\xc3\xc7\xdb\xf2\x4f\x08\x19\x3f\x0a\xce\x24\x8f\ -\x8d\x63\x22\x77\xc6\x2f\xf9\xb7\x32\x62\x7b\x6e\xfc\x79\x27\xe5\ -\x3e\x5c\x2c\x8e\xc7\xa3\x99\x34\x42\xb3\x10\xdb\xc5\x5f\x0c\x84\ -\x3e\xde\xde\x96\xe5\xe7\xf6\xcd\x30\x0c\x68\x37\x2f\xc3\x38\x5a\ -\xcd\x9a\x02\xfb\x83\x48\x2b\xc3\x38\x5a\xf0\x94\x67\x3c\x97\xe5\ -\xc2\x32\xad\xc5\xec\x62\x1e\x5d\xcc\x23\xd5\x7a\xf2\xc9\xa3\x22\ -\xcb\x8a\xbc\xac\x4a\xe6\xe5\x97\x2b\x63\x11\x6f\x3a\x6b\xe5\xcd\ -\xd1\xae\x8c\xac\x20\x08\x16\x98\x2c\x08\x41\x60\x81\xca\x73\x2e\ -\xd9\x09\xf5\x8b\x82\x8f\x43\x45\x09\xc6\x78\x01\xba\x8b\xe5\xff\ -\x67\x15\x96\x00\xe8\x1e\x7e\x3a\xf3\x56\x60\x96\xc5\x41\x44\x7c\ -\x03\xe5\xb8\x99\x73\xb9\xf8\xfa\xdb\xd7\x4e\x89\xb0\x19\xcb\xf8\ -\xaa\x9a\x16\xcf\x5e\xab\x3d\x90\x73\x96\xf1\x72\xcf\x22\x5e\x2e\ -\x5a\x79\x55\xfe\x98\xc4\x72\xb7\x9a\xd9\x8e\x69\xd9\x70\xb9\x95\ -\x70\xc7\x93\xed\x4e\xde\x4a\x93\x78\x35\x03\xef\x49\xe0\xd7\xf7\ -\x57\xc1\x61\xd5\x06\x4d\xc5\x61\xa7\xc1\x66\x40\x4c\xcb\x10\x96\ -\x6b\xd3\xda\xa6\xed\x42\x18\x17\x91\xf2\x09\xaa\xe4\x59\xc2\x0e\ -\xb2\xc8\xe0\xa9\x45\x51\xca\xca\x32\xd9\x24\x11\xdc\x14\xf9\x3e\ -\x3d\x6c\x93\xfc\xf7\xbd\xe0\x9f\x09\x3f\xfe\x2e\x78\x5c\x98\x2d\ -\x7e\x5d\x63\xfc\xb4\x2f\x84\x44\xa7\x78\x0f\x28\x7a\x74\x50\x79\ -\x6e\x95\x1f\xa0\x5d\xc6\x7c\x53\x2a\xab\xba\x4b\xea\x0e\xfa\x44\ -\x67\xc6\xa2\xd2\x76\x1e\x2a\xf7\x62\xd5\xf0\xc5\x76\xcd\xca\x1a\ -\x36\xc3\xd8\xb3\x2d\x84\x58\x5a\x88\xd5\xec\xcb\xa6\xba\x1a\xc5\ -\xba\x10\x31\x17\xad\xca\xab\xae\x9e\xaa\x80\xc7\x90\xc8\x73\x3d\ -\xa8\x9a\xba\x5b\x7f\x55\xad\x9d\x1e\x0f\xeb\xcb\x1d\x8b\x8b\xe3\ -\x6a\x46\x6e\x95\xdf\x8b\x22\x5b\xcd\xa8\x19\x58\x3e\x76\x2c\x7a\ -\xab\x8e\x4e\xab\x19\xb2\x6d\x93\xd8\x98\xba\xf6\x9d\x56\x39\xe4\ -\x98\x36\xf5\x6d\x72\x57\x73\x74\x10\x02\x86\x1d\x4a\xd9\x99\x43\ -\xaf\xaa\x5f\x56\x63\x54\xee\x8a\xe3\x56\x28\x74\xa4\x38\xf0\xdb\ -\x92\x4a\x83\xd6\xeb\xe2\x34\xac\x86\x28\x38\xa8\x01\x8d\x0e\x79\ -\x22\x61\xd0\xec\x4f\xd7\xb5\x1e\x92\x98\x97\xc3\x05\xcb\x9c\xed\ -\xd1\x36\x2d\xd6\x2c\x1d\x36\x38\x26\x39\xa0\x84\x9a\xf8\xb6\xec\ -\xee\x21\xdc\x5a\xb4\xc1\x4e\xb1\xff\x07\x16\xe0\xfb\xdd\x83\x68\ -\x54\xe7\x3f\x56\x65\xec\x94\x64\xc9\x77\x0e\xc0\x58\x55\xdc\x41\ -\x6c\xf5\x60\xa9\x8b\x19\x86\x3c\xab\x81\x7b\x3a\x2b\xd9\xac\x15\ -\x2a\x3c\x95\x80\x04\x01\xed\x84\x85\x48\x60\x3c\x5c\xb9\xd3\x8a\ -\xce\xd7\x22\x35\xcc\x21\x4b\x9f\xaa\x00\xab\xc2\x8f\xde\xea\xce\ -\xd7\xba\x26\xee\x17\xf7\x81\x5f\xc9\x33\x2e\x59\xcc\x24\xbb\x8c\ -\x82\x56\x02\xbe\xe1\xb6\x67\x90\x31\xc3\x7f\x7c\xfd\xe9\xa3\x69\ -\x68\x19\x45\xe1\xbf\x0b\xf1\xad\x6d\xd7\x30\x94\x01\x5b\x17\x07\ -\x40\x7a\xf6\xd1\x89\x97\x71\x14\x42\x8e\x83\xb1\xff\x91\x64\x10\ -\xdb\x2a\x3d\xfe\x15\x72\xda\x72\x71\x51\xf4\x8c\x15\x58\x97\x4a\ -\xeb\x6a\x05\xaf\x93\xe5\xe0\x8c\x11\x47\x59\xa2\x0a\x2d\x7e\x95\ -\x49\x9a\xfe\xa2\x1a\x69\x7a\x7c\x55\x69\x22\x53\x7e\x11\x2e\x17\ -\x8d\xf7\x4d\xdf\x16\x57\x9d\x5b\x2e\xda\xde\x57\x77\xdb\x0b\x2a\ -\xbd\x41\xd1\x3d\xe8\x94\xad\x39\x44\xe8\xdf\x94\xd2\xb8\xd3\x6e\ -\x45\x71\xd8\x67\x45\xcc\x9b\xe2\x1d\x9a\x3c\x92\xdd\x23\x93\xe7\ -\x14\xf4\x1b\xf0\x3e\xfc\x82\x71\x14\x6d\x36\xef\xea\x06\x35\x79\ -\x22\xb4\xea\x5b\x71\x48\x21\xdf\x7d\xf2\xbc\x88\xe3\xf7\x52\x8a\ -\xe2\x1b\x0f\x9b\xcc\xd4\xdc\xd6\x83\x21\xc4\xed\x2d\x00\xc3\x45\ -\x0a\x41\x2a\x43\xa7\x95\xc5\x0c\xd2\x8b\x10\xec\x1c\xe6\x30\xad\ -\xb7\xd2\xae\xa9\x5e\x7c\x2a\x2f\x5d\xdf\x0e\x3a\x61\x33\xd8\x1c\ -\x93\x54\xa1\x75\x51\xb4\x63\xec\x5e\xd3\x0b\xe6\xf3\x90\x85\xe8\ -\x99\x88\x2a\x74\x1d\xa2\x2e\xbb\x7b\x90\xff\x0b\x30\xc6\x62\x67\ -\x62\x80\x21\x4b\x13\xb2\x7b\xe1\x43\xa0\xf3\x3c\x1f\x4f\x0e\x3a\ -\xe4\x6b\x82\xe7\x9b\xae\x22\x35\xb6\xff\x58\xf0\x1c\xc7\x75\xa7\ -\x07\x1e\xd6\x04\xcf\x22\xe6\x43\x71\xdb\x6c\x08\x23\x6c\x72\xb8\ -\xd9\xba\xb0\xd1\x7a\xba\x7d\x45\xec\x10\xd5\x04\x8f\x58\x66\x35\ -\x60\x9d\x57\x04\xcf\x47\xae\x2e\x7c\xae\xe9\xbd\x22\x72\x18\xe9\ -\x8e\x5a\x12\x98\x7e\x9f\x3f\xbf\x0e\x43\x41\x8e\x26\x78\x83\x1c\ -\x05\x8f\x06\xda\x44\xb9\x89\x36\xb5\x1b\x64\x27\xe3\xc1\x36\x51\ -\x56\xa2\x3d\x47\xdc\xf2\x92\xb1\x10\xdb\x6c\x82\x60\x82\x88\xd9\ -\xc8\xd3\x05\x6c\x88\x91\x3c\x39\x6a\x88\x22\xa2\x09\xdb\x20\x17\ -\x79\x76\xd8\x80\x83\x20\xdd\xb7\xfc\x5b\x16\x32\x5e\x4a\x9b\xe0\ -\x8a\x88\xf6\x3b\x6a\x6f\x4d\xa4\x97\xdb\x9e\x93\x6c\xf8\xba\x80\ -\x0d\xb2\x8d\x51\x81\x9b\x2a\xe1\xd0\x1d\x98\x83\x84\x63\x54\xe4\ -\xa6\xca\x39\xb4\xa7\xd0\x1b\xce\x31\x22\x68\x3e\x56\xd7\xe4\x40\ -\xb3\xb5\xe7\xcf\x41\xda\xf1\xfc\xc0\x01\xf3\xd0\x7e\x19\x1d\x62\ -\x1e\x2f\x80\x9c\x22\x1f\xba\xb3\xc3\x2d\xf9\x78\x01\xd8\x30\xb2\ -\xf5\x17\xde\x86\xd6\x3f\x46\x9d\x1a\xa6\xc8\xdd\xb0\xf6\xd2\x47\ -\x8f\xbd\xdd\xcf\xaf\xcf\x49\xe1\x1c\xed\xb9\x61\x90\xc3\x8d\x0f\ -\xdf\x54\x89\x9c\xa5\xbd\xd2\x3b\x48\xe5\xc6\x07\x70\xaa\x7c\x8e\ -\x6a\x73\xe1\x5b\x46\x37\x36\x76\xb1\x33\xc9\xc9\xc2\x46\xde\x63\ -\x88\xdd\x8b\xe0\xa7\xd6\x95\x1e\xf3\x95\xeb\x55\x00\xac\x56\x98\ -\xb4\x3f\x4e\xdf\xd2\xbc\x57\x41\x4f\x71\x3d\xa2\xfd\xe5\x61\x90\ -\xed\x8d\x0d\xa1\x9a\x7c\xa7\x07\x21\xd6\x7d\x39\xeb\x31\xbe\xfb\ -\x91\xfc\x8c\x98\x59\xda\xeb\x27\x83\x7c\xef\x55\xc0\xf3\xb5\x27\ -\x8c\x41\xb6\xf7\x2a\xf0\x61\xed\x35\x81\x5b\xae\x37\x36\x72\x18\ -\xc3\xa3\x99\x1e\x72\x30\x53\x68\x7f\x6b\x1d\xa2\x7a\xe3\xc3\xe7\ -\x38\x6c\x82\xbb\x4a\xa8\xfe\x7e\x9c\x21\xa2\x37\x36\x7c\x84\xd1\ -\xcd\xf4\x96\x56\x6a\xa2\xa7\xbd\x12\x7a\x43\xf3\xc6\xc6\xce\xa7\ -\x8c\xc5\x7c\x7a\xd8\x55\x4b\x7a\x0f\xd9\xd3\x34\x36\x82\x6a\x85\ -\x60\x7a\xb3\x86\xfe\x2e\x93\xfe\x67\xd9\xbb\x34\xf8\x8c\xa0\xa9\ -\x85\xbd\x87\x10\xbd\x57\x81\xaf\x5a\xd8\x7b\xc8\xca\xde\xab\x20\ -\xa8\x56\xf6\x74\x97\xe4\xef\xbe\xd5\x8e\x8c\xdd\x64\xd9\x9e\xa7\ -\xcd\x57\x86\x3f\xd9\x8e\x8e\xdf\x54\xe9\x1e\xd1\x4e\x7f\xc3\x5f\ -\x6e\x47\x06\x70\xca\x84\x2f\x18\x9d\xf2\x8d\x8d\xde\x94\x29\x1f\ -\xd1\x5f\x17\x1d\xfc\x8e\x3b\x32\x84\xeb\x28\xb6\xdd\x29\x06\xa0\ -\xfe\x9e\xec\xe1\x85\xaa\x3b\x50\x9f\x14\x3f\x18\xbe\x8f\x59\xaa\ -\x7a\x11\x00\x31\xcc\xc1\x63\x6f\x35\x1b\x1b\xbb\xc9\xd2\x17\xf2\ -\x18\xfa\x32\x3e\x7e\x53\xa5\x2f\xb6\x36\x75\x1e\x5e\xaf\x1a\x19\ -\xc0\x29\xd3\x97\xf1\xff\x05\x6f\x6c\xf4\x7c\x9f\xb1\xe9\xbd\xb9\ -\x61\xe4\x68\x4f\xbd\xfd\x0f\x6b\xd7\x30\x3e\x23\x62\xd5\x2e\x2a\ -\xed\xd9\x76\x98\xae\x3c\x3f\x76\xd5\x4a\x8b\x36\x59\x1e\xe6\x2a\ -\xcf\x8f\x5e\xb5\x7f\x4a\xfb\x45\xed\x8e\xa8\x8c\x07\xdc\x64\x39\ -\x8a\x37\xc2\x2b\xda\x30\x4b\x19\x13\xbc\xa9\x12\x14\xc8\x77\x8f\ -\xd9\x3b\x35\x22\x7a\x53\x66\x27\x6a\x9e\x1d\x7b\xe3\xd4\x98\xe9\ -\x6e\xd2\x2b\x2b\xd6\x63\x76\x4d\x8d\x87\xdf\x55\x9f\xd4\x20\xae\ -\xf6\x9f\xf5\xb0\x21\xa6\x45\x5d\x6c\x11\xdf\x1e\x13\x24\x12\x04\ -\x77\x7b\x69\x6d\x72\x87\xc8\x95\x68\xf0\xb8\xb1\xf3\x90\x50\xe1\ -\xe1\xc2\x78\xc5\xf6\xf5\x19\x0a\x60\x6a\x9b\x3e\x76\x7c\xea\xbb\ -\x17\x58\xf6\x4c\xee\x6e\x60\xa9\x4e\xd6\xeb\xb0\xd8\x14\xb9\x44\ -\x95\x06\x7a\x26\x32\x96\xd6\x92\x4f\x26\x12\x96\xcb\x9e\xec\x58\ -\x39\xdd\x13\x01\x0e\x5c\x46\xbb\xbe\x2c\xf9\xce\xc3\x8c\xc7\xc9\ -\x21\x7b\x4f\x93\x9c\x37\x07\xc4\xf5\x6c\x36\x2c\x4b\xd2\x73\xf8\ -\x2b\xcb\xcb\x77\xd4\x9e\xe6\x85\xea\xe2\x7b\x1e\x75\x07\x18\xd6\ -\x16\x92\x9f\x24\x58\xc5\x1c\x1c\xc2\xf5\x1d\x4b\x93\x6d\x1e\x96\ -\x92\x09\x59\x0b\x62\x1e\x15\xa2\x2e\x53\x3d\xa1\x1b\x21\x52\x9e\ -\xd4\x9a\x94\x4b\x78\xbe\xa8\x39\xc9\xad\x75\xeb\x58\x88\xf8\x56\ -\x56\xd5\x21\x05\xb8\xa0\x4e\x52\xab\x4b\x1f\x45\x22\xc1\x04\xa9\ -\x43\xc7\xc2\x54\x20\xb9\x7e\x8f\x13\xf5\xc4\x55\xcb\xa9\x14\xef\ -\xea\x88\xc3\xaa\xdb\xe5\x2e\xd9\xc8\xb0\xbd\x6d\xdc\xce\xa3\x1d\ -\x80\x5f\xfb\x1d\x27\xe5\x3e\x85\x88\x4a\xf2\xca\xa0\xf8\xe4\x62\ -\x93\x16\xc7\xf0\x33\x29\x93\x75\xca\xdf\xab\xdf\x49\xaa\x02\xac\ -\x15\xd5\x29\xa1\x19\xe2\x37\x29\xa1\x09\xf2\xeb\xf8\xac\x23\xdc\ -\x36\x9d\xea\x14\x4a\x87\xbc\x67\x4c\x7c\xe3\xa2\xb6\xe1\x39\x83\ -\x2a\xd1\x9a\x45\xdf\xd4\x31\x6a\x79\x1c\xb2\x28\x3a\x64\x87\x94\ -\x49\xde\x85\x15\x84\xf3\xdf\x0d\x7f\x1e\x98\x5e\x1d\x84\xc6\x8f\ -\x06\x44\x99\xe5\x60\x0b\xd3\xb9\xe5\x98\x3e\xf5\x68\xe0\x1a\x8e\ -\xe9\xd8\xc4\x0f\x40\x46\x88\xe9\x39\x0e\x0d\x1c\x23\x30\x9d\x39\ -\x69\x66\x65\x6a\xa8\xa3\x11\x3d\x6a\xe1\x60\x6e\xc3\xe8\xf5\x7d\ -\xd7\x31\x60\xd2\x09\x1c\x6a\x3b\xf6\xdc\xc6\x50\xa7\x1a\x83\x06\ -\xf1\xea\x13\x33\xc9\x5c\xa5\x00\x23\x82\x9a\x2d\xdf\x0d\x82\x39\ -\x72\x4d\x52\x9b\xd8\xa6\x0b\x15\x59\x73\x04\x54\x29\xa0\xbe\x45\ -\xa8\x81\xa0\x4a\xb8\xa7\xa6\x63\xa4\x86\x3d\x47\xa4\x4e\x29\xd0\ -\xec\xcf\x46\x4b\x0c\x3c\xe3\x5f\x86\x57\x1b\x98\x64\xde\x92\x54\ -\x83\x34\x3d\x9b\x23\xdb\xa4\xd0\x1e\x31\x6d\x1a\xd8\x98\xcc\xc1\ -\x8a\x52\x4a\x02\x30\xb7\xc0\x6f\xd7\x87\x32\x81\x8b\x21\x83\x19\ -\xb8\x2e\xec\xcc\xc1\x03\x52\xfd\x65\x40\x69\xec\x28\x4f\xa1\x1c\ -\xf5\x3d\x4c\x41\xe4\x9b\x84\x60\x6a\x79\x73\xc8\x7b\x56\x40\x09\ -\xb8\x69\x99\x34\x50\xd7\x1c\x46\x75\xdd\x3e\x14\x74\x69\x00\xd9\ -\xc7\x55\x1e\x58\xbe\x67\xfb\xd0\x1f\xa7\xae\xcd\x07\x21\xb4\x6a\ -\xd9\x01\x71\xa1\x74\xd5\x65\xf5\x08\xa0\x1e\xa2\x1a\xb7\xeb\xbf\ -\x3c\x33\x68\xba\x7b\xfd\xa4\xfe\xd3\x4b\x4a\x2a\x11\x90\xe0\xea\ -\xdf\x84\x2f\x67\x53\x16\x79\x0e\xf1\x5b\x08\x14\x1d\xc4\x27\x93\ -\x07\xc1\x7b\xa7\x21\x76\xa7\x1a\x42\xc4\xab\x83\x00\x4b\x48\x21\ -\x65\x19\x55\x97\xfa\xdd\x9d\x7f\xb8\xfd\x78\x5b\xaa\xf3\x07\x3f\ -\xde\xfe\x0b\xb7\x0d\x2e\x74\ -\x00\x00\x17\xc8\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x65\x61\x72\x63\x68\x5f\ -\x69\x6d\x61\x67\x65\x73\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x33\x37\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ -\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\ -\x30\x66\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ -\x6f\x70\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\ -\x30\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ -\x23\x62\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ -\x6f\x70\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\ -\x30\x33\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ -\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\ -\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\ -\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\ -\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x66\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\ -\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\ -\x31\x34\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\ -\x32\x34\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\ -\x38\x2c\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\ -\x35\x38\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ -\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ -\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ -\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\ -\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\ -\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\x36\x33\x36\x33\x36\x33\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x32\x3d\x22\x33\x2e\x31\x38\ -\x31\x38\x31\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\ -\x3d\x22\x31\x31\x2e\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\x32\x37\ -\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\ -\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\ -\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x36\ -\x34\x2c\x30\x2c\x30\x2c\x30\x2e\x36\x31\x33\x33\x33\x33\x33\x33\ -\x2c\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x2c\x32\x2e\x37\x32\x29\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\ -\x22\x61\x6c\x77\x61\x79\x73\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ -\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\ -\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\x66\x66\ -\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ -\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x3c\x2f\ -\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ -\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x78\x3d\x22\x2d\x31\x39\x2e\x35\x37\x35\x38\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x79\x3d\x22\x31\x39\x2e\x32\x38\x36\x34\x39\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ -\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ -\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\ -\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\ -\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\ -\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ -\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ -\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ -\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ -\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ -\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ -\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ -\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ -\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ -\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ -\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ -\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ -\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ -\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x69\x6c\x6c\x3a\x23\x62\x33\x66\x66\x38\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x38\x35\x38\x31\ -\x35\x32\x39\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\ -\x35\x2e\x32\x38\x34\x35\x30\x36\x2c\x31\x2e\x36\x38\x35\x37\x36\ -\x38\x32\x20\x33\x32\x2e\x34\x34\x37\x35\x36\x35\x2c\x31\x30\x2e\ -\x32\x36\x37\x32\x39\x38\x20\x32\x33\x2e\x38\x36\x36\x30\x33\x35\ -\x2c\x32\x37\x2e\x34\x33\x30\x33\x35\x37\x20\x36\x2e\x37\x30\x32\ -\x39\x37\x35\x34\x2c\x31\x38\x2e\x38\x34\x38\x38\x32\x38\x20\x5a\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ -\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x30\x30\x36\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ -\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x6d\x20\x32\x32\x2e\x37\x39\x33\x33\x34\x34\ -\x2c\x36\x2e\x31\x31\x30\x36\x31\x39\x36\x20\x2d\x33\x2e\x30\x39\ -\x34\x33\x30\x32\x2c\x33\x2e\x34\x36\x35\x36\x31\x37\x32\x20\x2d\ -\x31\x2e\x37\x33\x32\x38\x30\x38\x2c\x33\x2e\x33\x37\x32\x37\x38\ -\x39\x32\x20\x2d\x30\x2e\x38\x36\x36\x34\x30\x36\x2c\x33\x2e\x33\ -\x34\x31\x38\x34\x35\x20\x76\x20\x35\x2e\x30\x31\x32\x37\x36\x38\ -\x20\x32\x2e\x35\x30\x36\x33\x38\x36\x20\x4c\x20\x36\x2e\x37\x30\ -\x32\x39\x37\x35\x34\x2c\x31\x38\x2e\x37\x39\x37\x32\x35\x37\x20\ -\x31\x35\x2e\x33\x36\x37\x30\x32\x2c\x32\x2e\x30\x38\x38\x30\x32\ -\x37\x34\x20\x32\x30\x2e\x33\x37\x39\x37\x38\x39\x2c\x34\x2e\x35\ -\x30\x31\x35\x38\x32\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x30\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ -\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ -\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\ -\x69\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\x38\x34\x30\x39\ -\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x31\x39\ -\x2e\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\x35\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x34\x38\x34\ -\x34\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x31\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x35\x35\x32\x32\ -\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x30\x35\x31\ -\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\x2e\x32\x35\x37\ -\x38\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\ -\x31\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\x35\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x32\x30\ -\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\x39\ -\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x69\x76\x65\x6c\ -\x6c\x6f\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x61\x79\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\ -\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\ -\x31\x2e\x30\x32\x32\x33\x33\x34\x32\x2c\x30\x2c\x30\x2c\x30\x2e\ -\x39\x37\x36\x33\x34\x38\x33\x36\x2c\x2d\x31\x2e\x32\x30\x34\x35\ -\x35\x30\x32\x2c\x32\x31\x2e\x34\x30\x37\x32\x34\x32\x29\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x35\x39\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\ -\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\ -\x30\x32\x39\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\ -\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x30\x2e\x36\x32\x36\x35\x32\x34\x38\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x37\x2e\x37\ -\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x34\x30\ -\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x36\x2e\x31\x33\x33\x33\x33\x33\x32\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x31\x37\x39\x33\x39\x35\x38\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\ -\x3d\x22\x32\x37\x2e\x34\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x36\x2e\x34\x30\x30\x30\ -\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\ -\x3d\x22\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x35\x2e\x38\x36\x36\x36\ -\x36\x36\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\ -\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x32\ -\x36\x37\x34\x32\x37\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x63\x78\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x36\ -\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x33\x33\x33\x33\x33\x33\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x35\ -\x2e\x38\x36\x36\x36\x36\x36\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x30\x2e\x31\x38\x35\x34\x31\x33\x31\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x30\x30\x35\ -\x39\x34\x30\x32\x37\x2c\x30\x2e\x39\x39\x39\x39\x38\x32\x33\x36\ -\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x34\x30\x30\x31\x31\ -\x33\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\ -\x22\x2d\x32\x37\x2e\x38\x32\x38\x36\x39\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x34\x30\x30\x30\ -\x37\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x36\x2e\x32\x36\x36\x36\x32\x30\x36\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ -\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x18\xa1\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x35\x33\x32\x30\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\ -\x64\x5f\x69\x6d\x61\x67\x65\x5f\x70\x72\x65\x76\x69\x65\x77\x2e\ -\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x2e\x35\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x2e\ -\x35\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x35\x33\x32\x32\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ -\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\ -\x32\x33\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ -\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ -\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\x66\x66\ -\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ -\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ -\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\ -\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x22\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\ -\x6f\x72\x3a\x23\x30\x30\x30\x30\x38\x30\x3b\x73\x74\x6f\x70\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\ -\x70\x35\x39\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\ -\x3a\x23\x30\x30\x30\x30\x38\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\ -\x39\x37\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\ -\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\ -\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\ -\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ -\x69\x65\x6e\x74\x35\x39\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x78\x31\x3d\x22\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x31\x3d\x22\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x32\x3d\x22\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\ -\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\ -\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\ -\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\ -\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x35\x33\ -\x37\x37\x34\x31\x30\x35\x2c\x30\x2c\x30\x2c\x30\x2e\x35\x33\x37\ -\x37\x34\x31\x30\x35\x2c\x31\x36\x2e\x33\x39\x36\x37\x30\x34\x2c\ -\x31\x37\x2e\x32\x37\x36\x33\x30\x38\x29\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\ -\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\ -\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\x32\x37\x32\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\x3d\x22\x31\x31\x2e\ -\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x32\x3d\x22\x33\x2e\x31\x38\x31\x38\x31\x38\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\x36\x33\x36\x33\ -\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\ -\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\x70\ -\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x33\x32\x32\ -\x36\x34\x34\x36\x33\x2c\x30\x2c\x30\x2c\x30\x2e\x33\x30\x39\x32\ -\x30\x31\x31\x2c\x33\x31\x2e\x34\x35\x33\x34\x35\x33\x2c\x32\x39\ -\x2e\x34\x35\x32\x37\x38\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\ -\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\ -\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ -\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ -\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\ -\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x78\x3d\x22\x2d\x34\x32\x2e\x33\x31\x30\x35\x36\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x79\x3d\x22\x31\x39\x2e\x38\x33\x35\x36\x37\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\ -\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\ -\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ -\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\ -\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ -\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\ -\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x67\x72\x69\x64\x35\x33\x34\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x35\x33\x32\x35\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ -\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ -\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ -\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ -\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ -\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ -\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ -\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ -\x6c\x61\x79\x65\x72\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\ -\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x33\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ -\x62\x65\x6c\x3d\x22\x4c\x69\x76\x65\x6c\x6c\x6f\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ -\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ -\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ -\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x62\x33\ -\x62\x33\x62\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\ -\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x35\ -\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x32\x2e\x32\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ -\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\ -\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\ -\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ -\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x30\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x34\x34\x2e\x37\ -\x39\x39\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x33\x37\x2e\x33\x33\x33\x33\x33\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x36\x2e\x34\x30\ -\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ -\x22\x2d\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x79\x3d\x22\x39\x2e\x33\x37\x31\x30\x32\x30\ -\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x62\x33\x66\x66\x38\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\x33\x37\x37\x37\x37\x36\ -\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ -\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x31\x2e\x33\ -\x37\x37\x37\x37\x38\x2c\x30\x20\x33\x34\x2e\x31\x33\x33\x33\x33\ -\x33\x2c\x31\x31\x2e\x33\x37\x37\x37\x37\x38\x20\x32\x32\x2e\x37\ -\x35\x35\x35\x35\x35\x2c\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\ -\x30\x2c\x32\x32\x2e\x37\x35\x35\x35\x35\x35\x20\x5a\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\ -\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ -\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x67\x33\x30\x30\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ -\x28\x31\x2e\x32\x39\x33\x34\x34\x32\x33\x2c\x30\x2c\x30\x2c\x31\ -\x2e\x32\x37\x38\x31\x32\x39\x36\x2c\x2d\x37\x2e\x35\x32\x35\x37\ -\x36\x32\x35\x2c\x2d\x31\x30\x2e\x33\x37\x36\x37\x35\x31\x29\x22\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\x38\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x33\x2e\ -\x33\x30\x33\x33\x31\x34\x2c\x31\x37\x2e\x31\x34\x31\x38\x37\x33\ -\x20\x63\x20\x2d\x30\x2e\x35\x35\x30\x38\x32\x32\x2c\x30\x20\x2d\ -\x30\x2e\x39\x39\x31\x34\x36\x2c\x30\x2e\x34\x34\x30\x36\x33\x38\ -\x20\x2d\x30\x2e\x39\x39\x31\x34\x36\x2c\x30\x2e\x39\x39\x31\x34\ -\x36\x20\x76\x20\x37\x2e\x32\x30\x39\x30\x39\x32\x20\x68\x20\x2d\ -\x33\x2e\x37\x36\x34\x31\x38\x36\x20\x63\x20\x2d\x31\x2e\x30\x37\ -\x35\x34\x38\x33\x2c\x30\x20\x35\x2e\x39\x31\x35\x31\x35\x2c\x38\ -\x2e\x30\x36\x36\x31\x31\x35\x20\x35\x2e\x39\x31\x35\x31\x35\x2c\ -\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x6c\x20\x30\x2e\x35\x33\x37\ -\x37\x34\x31\x2c\x30\x2e\x35\x33\x37\x37\x34\x31\x20\x30\x2e\x35\ -\x33\x37\x37\x34\x32\x2c\x2d\x30\x2e\x35\x33\x37\x37\x34\x31\x20\ -\x63\x20\x30\x2c\x30\x20\x36\x2e\x39\x39\x30\x36\x33\x33\x2c\x2d\ -\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x35\x2e\x39\x31\x35\x31\x35\ -\x32\x2c\x2d\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x68\x20\x2d\x33\ -\x2e\x37\x36\x34\x31\x38\x38\x20\x76\x20\x2d\x37\x2e\x32\x30\x39\ -\x30\x39\x32\x20\x63\x20\x30\x2c\x2d\x30\x2e\x35\x35\x30\x38\x32\ -\x32\x20\x2d\x30\x2e\x34\x34\x30\x36\x33\x38\x2c\x2d\x30\x2e\x39\ -\x39\x31\x34\x36\x20\x2d\x30\x2e\x39\x39\x31\x34\x36\x2c\x2d\x30\ -\x2e\x39\x39\x31\x34\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\ -\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x35\x39\x37\x37\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\ -\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x35\x39\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x36\x30\x32\x39\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x31\x35\x38\x35\x31\x33\x36\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\ -\x32\x39\x2e\x38\x34\x30\x32\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x63\x79\x3d\x22\x33\x31\x2e\x33\x30\x37\x39\x38\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\ -\x33\x2e\x32\x32\x36\x34\x34\x36\x34\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x30\x39\x32\x30\x31\x31\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\ -\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x30\x2e\x30\x39\x30\x34\x33\x39\x32\x31\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x63\x78\x3d\x22\x32\x39\x2e\x37\x30\x35\x37\x39\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x33\x31\x2e\ -\x33\x30\x37\x39\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x78\x3d\x22\x31\x2e\x32\x30\x39\x39\x31\x37\x34\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x39\ -\x35\x37\x35\x37\x35\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x30\x2e\x31\x33\x34\x38\x31\x38\x38\x32\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x39\x2e\x38\x34\ -\x30\x32\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\ -\x79\x3d\x22\x33\x31\x2e\x33\x30\x37\x39\x38\x39\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x36\x38\x38\ -\x37\x30\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x79\x3d\x22\x32\x2e\x39\x35\x37\x35\x37\x35\x38\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x30\x2e\x30\x39\x33\x34\x37\x32\x37\x33\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\ -\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\ -\x2e\x30\x30\x35\x39\x34\x30\x32\x38\x2c\x30\x2e\x39\x39\x39\x39\ -\x38\x32\x33\x36\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x33\x31\x2e\ -\x33\x30\x38\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x2d\x32\x39\x2e\x37\x32\x31\x34\x38\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x32\ -\x30\x39\x39\x35\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x79\x3d\x22\x33\x2e\x31\x35\x39\x32\x30\x35\x34\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x36\x36\x66\x66\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ -\x20\x32\x31\x2e\x33\x33\x33\x33\x33\x33\x2c\x35\x2e\x38\x36\x36\ -\x36\x36\x36\x37\x20\x2d\x34\x2e\x31\x30\x32\x35\x36\x34\x2c\x34\ -\x2e\x35\x39\x34\x38\x37\x31\x33\x20\x2d\x32\x2e\x32\x39\x37\x34\ -\x33\x36\x2c\x34\x2e\x34\x37\x31\x37\x39\x35\x20\x2d\x31\x2e\x31\ -\x34\x38\x37\x31\x38\x2c\x34\x2e\x34\x33\x30\x37\x36\x39\x20\x76\ -\x20\x36\x2e\x36\x34\x36\x31\x35\x34\x20\x33\x2e\x33\x32\x33\x30\ -\x37\x37\x20\x4c\x20\x30\x2c\x32\x32\x2e\x36\x38\x37\x31\x38\x20\ -\x31\x31\x2e\x34\x38\x37\x31\x38\x2c\x30\x2e\x35\x33\x33\x33\x33\ -\x33\x33\x33\x20\x31\x38\x2e\x31\x33\x33\x33\x33\x33\x2c\x33\x2e\ -\x37\x33\x33\x33\x33\x33\x33\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x30\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\ -\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\ -\x00\x00\x04\x5e\ -\x00\ -\x00\x0f\x16\x78\x9c\xe5\x57\x4d\x6f\xe3\x36\x10\xbd\xe7\x57\xb0\ -\xca\xa5\x45\x2d\x4a\xa4\x64\xeb\x63\x6d\xef\xa1\xc1\x02\x0b\xb4\ -\x97\x76\x8b\x1e\x0b\x5a\xa2\x6d\x36\x12\x29\x50\x54\x6c\xef\xaf\ -\xef\x50\xdf\x76\xbc\x40\xdb\x43\x10\xa0\x02\x82\x84\xf3\xde\x90\ -\x33\x8f\x33\x23\x65\xfd\xf1\x5c\x16\xe8\x85\xeb\x5a\x28\xb9\x71\ -\x08\xf6\x1d\xc4\x65\xa6\x72\x21\x0f\x1b\xe7\xf7\x2f\x9f\xdc\xd8\ -\x41\xb5\x61\x32\x67\x85\x92\x7c\xe3\x48\xe5\x7c\xdc\x3e\xac\xbf\ -\x73\x5d\xf4\x93\xe6\xcc\xf0\x1c\x9d\x84\x39\xa2\xcf\xf2\xb9\xce\ -\x58\xc5\xd1\xf7\x47\x63\xaa\xd4\xf3\x4e\xa7\x13\x16\xbd\x11\x2b\ -\x7d\xf0\x7e\x40\xae\xbb\x7d\x78\x58\xd7\x2f\x87\x07\x84\x10\x9c\ -\x2b\xeb\x34\xcf\x36\x4e\xef\x50\x35\xba\x68\x89\x79\xe6\xf1\x82\ -\x97\x5c\x9a\xda\x23\x98\x78\xce\x44\xcf\x26\x7a\x66\x4f\x17\x2f\ -\x3c\x53\x65\xa9\x64\xdd\x7a\xca\xfa\x71\x46\xd6\xf9\x7e\x64\xdb\ -\x68\x4e\x41\x4b\x22\x49\x92\x78\x3e\xf5\x28\x75\x81\xe1\xd6\x17\ -\x69\xd8\xd9\xbd\x76\x85\x18\xef\xb9\x52\xdf\xf7\x3d\xc0\x26\xe6\ -\x3f\x63\xa5\x35\x08\x5a\xc1\xcf\x48\x1f\x0c\xb8\x56\x8d\xce\xf8\ -\x1e\xfc\x38\x96\xdc\x78\x4f\x5f\x9e\x46\xd0\xf5\x71\x6e\xf2\xd9\ -\x36\x83\x9e\x57\xa7\x5e\x89\x2c\x59\xc9\xeb\x8a\x65\xbc\xf6\x06\ -\x7b\xeb\x7f\x12\xb9\x39\x6e\x9c\x20\xc4\x24\x80\x67\xd9\x1a\x8f\ -\x5c\x1c\x8e\xe6\xd6\x2a\xf2\x8d\x03\xd1\xd3\x24\xee\xd6\xb3\xe2\ -\x20\x1d\xa1\xdf\x38\x1d\x11\x1f\x27\x14\x13\xa4\xc9\x32\x88\x3a\ -\xce\x90\x42\x9a\xab\xcc\xc6\x04\x5b\xf2\x52\xb0\xc6\xa8\x12\x6e\ -\x2d\xcb\x0a\x56\xd7\x62\x2f\x32\x58\x28\x59\x15\xcd\x41\xc8\x3f\ -\x75\x23\xf1\x20\xdb\x78\x06\x3f\x57\x4a\x1b\xf7\x9c\x57\x20\x1e\ -\x19\x42\xbc\x41\x2f\x23\xba\x05\x78\x9d\xf3\x7d\x6d\x69\x5d\x2e\ -\x76\x05\xc9\x44\x0e\xf2\x5a\x74\x0c\xcd\xc6\x95\xbf\x08\x7e\x9a\ -\xb8\x3b\x56\x77\x7a\x21\x54\xb1\x03\xd4\x56\xa1\xf4\xc6\x79\xdc\ -\xb7\x4f\x0f\xec\x94\xce\xb9\x1e\xa0\x55\xfb\x5c\x41\x0a\xf4\x17\ -\xe6\xd2\x75\x53\xbf\xf7\x10\xb0\xdd\x75\xc4\xfd\xfb\x78\x7d\x64\ -\xb9\x3a\x6d\x1c\x7a\x0b\x7e\x55\xaa\x84\xdb\xc2\xc9\x32\xf1\xa9\ -\x1f\xdd\xc2\xd9\x79\xe3\xb8\x94\xe0\x64\x15\x05\x49\xf0\x0a\xb5\ -\x01\x11\x1c\x93\x24\xf4\x93\x57\x60\xa3\x35\xf4\x9b\x5b\xb0\x0b\ -\x87\xac\xda\x5f\xa4\x27\xd5\x47\x75\x3a\x68\xab\x8e\xd1\x0d\xbf\ -\xf5\xb4\x88\xbb\xdb\xa9\xf3\x7d\x18\xae\xbf\xb1\x9d\xec\x36\x52\ -\x18\xe8\x96\xea\x3c\xdf\xb5\x11\x39\x07\xe3\x9e\x15\xf5\x2b\xcf\ -\x93\x90\xa0\x82\xdb\x17\x2e\x09\x46\x91\x6f\x19\x43\x15\x47\x7e\ -\xfc\x0d\x06\xc4\xf6\x4a\xe8\x1e\xba\x7c\x1b\x2a\xd9\x59\x94\xe2\ -\x2b\x87\xc4\xc9\x2d\xa5\x96\xac\x72\x0f\x85\xda\xb1\xa2\xcf\x7b\ -\xdb\x32\xd6\x57\xba\x74\x4e\x08\x99\x8b\x6d\xd9\xf3\xc5\xda\x9c\ -\xc1\x68\x05\xb5\x86\x20\x5a\x2d\x47\xa3\xd2\x02\x3a\x61\x16\xef\ -\x60\xba\xcc\x4d\xb6\xc1\x61\x3e\x9f\xdb\x0a\x6b\xeb\x2f\xba\xc5\ -\x2e\x73\xac\x2f\x7c\xef\x75\xe5\xb7\xf6\x92\x1b\x96\x33\xc3\xa6\ -\x36\x18\x2c\x34\x49\xfc\x21\x33\x98\x95\xe9\xaf\x4f\x9f\xb6\xfd\ -\x41\xeb\x2c\x4b\xff\x50\xfa\x79\x38\x17\x21\x4b\x60\x3b\xd5\xc0\ -\x55\x38\xdb\xd1\xbc\xce\xb3\x14\xa6\x1b\x74\xfd\x56\x94\x50\xdc\ -\x76\x30\xfe\x08\xd3\x6c\xed\x4d\xc0\x15\xd9\x8a\x35\x6d\xda\x6d\ -\xab\x79\x37\x26\xef\xbe\x2b\xf2\xac\x14\xd6\xc9\xfb\xcd\x88\xa2\ -\xf8\x6c\x0f\xe9\x33\x9e\x6d\x2a\x4c\xc1\x27\xe3\xda\xeb\xa3\xef\ -\x73\xf3\x66\xc9\xad\xbd\x21\xfb\x76\x75\x98\x54\xb9\xea\x8a\xf1\ -\xa2\x0b\xb6\xe3\x50\x04\x3f\x5b\x10\xbd\x42\x0f\x5a\x35\x55\xa9\ -\x72\xde\xbb\x0f\x6a\x56\xcc\x1c\xc7\x2b\x33\x97\x02\xf0\x3d\x44\ -\x9f\x4a\x78\xc9\x7e\xb0\x7f\xb9\xfd\x94\x48\xc9\x87\xda\x68\xf5\ -\xcc\xd3\x47\xbf\x7d\xfa\x65\xd7\x18\x29\x0c\x83\xd6\x3a\xb0\xdc\ -\x42\x48\x0e\x27\xa7\xbb\xc6\x98\xb9\xed\x2f\x25\x64\x0a\x42\x71\ -\x3d\x58\xdb\x45\x01\x25\x6e\xd2\x70\xb0\xe5\x0c\x86\x8f\xd6\xec\ -\xd2\x05\xd2\x5b\xc7\x50\xc6\x2a\x03\x35\x7e\x41\x2b\x1c\x24\xf6\ -\x59\x2e\x22\x1c\xb6\x95\x16\x21\x1a\xe1\xc8\xbe\x4a\x82\x05\xa5\ -\x38\xb4\x91\x51\xd4\xa3\x2b\xba\x08\x82\xae\x26\x93\xab\x2e\xb0\ -\x5a\xc4\x51\x3c\xd9\xc6\xa9\xa4\x24\x24\x63\x94\x76\x61\x3e\xbd\ -\x30\xd3\x68\x6e\xdb\x60\xb8\xc7\xff\x24\x22\x63\xef\x4d\xc4\x70\ -\xb1\xea\x94\xf2\x57\x73\xf9\x08\x6e\xff\x58\x8e\xf2\x2d\x02\x8a\ -\x5b\x1a\xbd\xa7\x9e\x1b\xbd\x8d\x7e\xef\xb5\x08\x93\xc5\xb2\x13\ -\x2c\x0c\xe7\x2a\xfa\x98\x5a\xed\xe2\x51\xc5\x64\x11\xc0\xd7\xca\ -\xf4\xb5\x73\x2b\x23\x7d\x1b\x19\xc3\xd0\x16\xe2\x7b\x92\xb1\x2b\ -\x41\xb2\x08\x3b\xc5\x22\x32\x93\x91\x24\x98\x5e\xf7\x32\x59\xd0\ -\x04\xc7\xad\xb4\xf7\x65\x5c\xfd\x5f\xcb\x31\x5c\x04\x98\xce\xb5\ -\x8b\xfb\x8f\xeb\xa9\x91\x69\x8c\xe3\x36\xc0\xbb\xd2\x91\xb7\x51\ -\x8e\x12\x98\xd7\xf1\x7b\x52\x6e\x68\x64\xda\x09\x16\x5e\x55\x60\ -\xd4\xbd\x39\xe6\x8d\x3c\xa0\xf7\x1b\xd9\xff\x97\x32\xae\xbd\x03\ -\xfc\x5f\x6b\x3f\x4f\xb6\x0f\x7f\x03\xf2\x9e\x89\xe5\ -\x00\x00\x0c\x02\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\ -\x6f\x61\x64\x5f\x6f\x70\x74\x69\x6f\x6e\x73\x2e\x73\x76\x67\x22\ -\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\ -\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\ -\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x66\x69\x6c\x74\x65\x72\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\ -\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x2d\ -\x69\x6e\x74\x65\x72\x70\x6f\x6c\x61\x74\x69\x6f\x6e\x2d\x66\x69\ -\x6c\x74\x65\x72\x73\x3a\x73\x52\x47\x42\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x66\x69\x6c\x74\x65\x72\x34\x35\x30\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x30\x2e\ -\x30\x32\x33\x37\x34\x38\x36\x32\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x2e\x30\x34\x37\x34\x39\ -\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x30\ -\x2e\x30\x32\x34\x32\x35\x36\x37\x35\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x2e\x30\x34\x38\ -\x35\x31\x33\x35\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x66\x65\ -\x47\x61\x75\x73\x73\x69\x61\x6e\x42\x6c\x75\x72\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x64\x44\x65\x76\x69\ -\x61\x74\x69\x6f\x6e\x3d\x22\x30\x2e\x32\x37\x39\x32\x33\x37\x32\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x66\x65\x47\x61\x75\x73\x73\x69\x61\x6e\x42\x6c\x75\x72\x34\x35\ -\x30\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x66\x69\x6c\ -\x74\x65\x72\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\ -\x35\x31\x2e\x31\x36\x39\x34\x34\x35\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x2d\x36\x2e\ -\x35\x33\x38\x34\x34\x37\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\ -\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\ -\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ -\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ -\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ -\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ -\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ -\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ -\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ -\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ -\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ -\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ -\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x33\x33\x33\x33\x33\x33\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x31\x2e\x30\x33\x31\x32\x35\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x72\x6f\x75\x6e\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x74\x65\x72\x3a\x75\x72\x6c\x28\x23\x66\x69\ -\x6c\x74\x65\x72\x34\x35\x30\x35\x29\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x30\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x37\ -\x2e\x35\x38\x37\x33\x31\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x38\x2e\x31\x37\x39\x33\x31\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x33\x30\ -\x2e\x30\x36\x39\x36\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x31\x2e\x39\x33\x30\x30\x32\x30\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\ -\x72\x6f\x74\x61\x74\x65\x28\x2d\x39\x30\x2e\x30\x38\x33\x30\x39\ -\x34\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x31\x32\x66\x66\x32\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x39\x39\x39\x39\x39\x39\x37\x36\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ -\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ -\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ -\x6d\x20\x34\x2e\x37\x39\x32\x32\x32\x36\x32\x2c\x31\x34\x2e\x31\ -\x39\x37\x30\x34\x33\x20\x63\x20\x30\x2c\x30\x20\x38\x2e\x36\x38\ -\x39\x38\x39\x33\x38\x2c\x31\x36\x2e\x33\x36\x33\x30\x30\x38\x20\ -\x39\x2e\x33\x37\x31\x38\x32\x38\x38\x2c\x31\x32\x2e\x35\x33\x36\ -\x38\x37\x33\x20\x43\x20\x31\x37\x2e\x39\x37\x32\x39\x38\x34\x2c\ -\x35\x2e\x33\x36\x33\x31\x37\x38\x33\x20\x32\x38\x2e\x38\x31\x32\ -\x39\x30\x33\x2c\x34\x2e\x30\x39\x38\x31\x35\x36\x32\x20\x32\x38\ -\x2e\x38\x31\x32\x39\x30\x33\x2c\x34\x2e\x30\x39\x38\x31\x35\x36\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x34\x35\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ -\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x73\x63\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x0b\xfc\ -\x00\ -\x00\x36\x02\x78\x9c\xed\x5a\x4b\x73\xe3\xc6\x11\xbe\xef\xaf\x40\ -\xb8\x17\xbb\x42\x80\xf3\x7e\x50\xd2\xfa\x60\x97\x2b\xae\x72\x2e\ -\xb1\x53\x39\xba\x20\x00\x94\x90\x25\x01\x06\x00\x45\x69\x7f\x7d\ -\xbe\xc6\x8b\xa0\x48\xd1\x5a\x3b\x2e\xa7\x6c\x51\xa5\x22\xd1\x3d\ -\x8f\x9e\xee\xaf\xbb\x67\x30\x7d\xfd\xd5\xe3\x66\x1d\x3c\x64\x55\ -\x9d\x97\xc5\xcd\x8c\x47\x6c\x16\x64\x45\x52\xa6\x79\x71\x77\x33\ -\xfb\xe7\x8f\xdf\x86\x6e\x16\xd4\x4d\x5c\xa4\xf1\xba\x2c\xb2\x9b\ -\x59\x51\xce\xbe\xfa\xf0\xee\xfa\x2f\x61\x18\x7c\x5d\x65\x71\x93\ -\xa5\xc1\x3e\x6f\xee\x83\xef\x8a\x8f\x75\x12\x6f\xb3\xe0\x8b\xfb\ -\xa6\xd9\x2e\x17\x8b\xfd\x7e\x1f\xe5\x3d\x31\x2a\xab\xbb\xc5\x97\ -\x41\x18\x7e\x78\xf7\xee\xba\x7e\xb8\x7b\x17\x04\x01\xe6\x2d\xea\ -\x65\x9a\xdc\xcc\xfa\x0e\xdb\x5d\xb5\x6e\x1b\xa6\xc9\x22\x5b\x67\ -\x9b\xac\x68\xea\x05\x8f\xf8\x62\x76\x68\x9e\x1c\x9a\x27\x34\x7b\ -\xfe\x90\x25\xe5\x66\x53\x16\x75\xdb\xb3\xa8\xdf\x4f\x1a\x57\xe9\ -\x6a\x6c\x4d\xd2\xec\x65\xdb\x88\x7b\xef\x17\x4c\x2c\x84\x08\xd1\ -\x22\xac\x9f\x8a\x26\x7e\x0c\x8f\xbb\x42\xc6\x73\x5d\x05\x63\x6c\ -\x01\xde\xa1\xe5\xeb\x5a\x2d\x6b\x28\x74\x8b\xff\xb1\xf9\x40\x88\ -\xea\x72\x57\x25\xd9\x0a\xfd\xb2\xa8\xc8\x9a\xc5\x37\x3f\x7e\x33\ -\x32\x43\x16\xa5\x4d\x3a\x19\x66\xd0\xe7\xd1\xac\x47\x4a\x2e\xe2\ -\x4d\x56\x6f\xe3\x24\xab\x17\x03\xbd\xed\xbf\xcf\xd3\xe6\xfe\x66\ -\x26\x55\xc4\x25\x3e\xba\x25\xde\x67\xf9\xdd\x7d\xf3\x9c\x9a\xa7\ -\x37\x33\x48\x2f\xbc\xeb\x9e\x27\xe0\xe0\x5d\x83\x7e\xe0\xe5\xc8\ -\x61\x91\x17\x11\x0f\x2a\xae\xa5\xed\xda\x0c\x4b\x58\xa6\x65\x42\ -\x32\x61\xc8\x6c\x93\xc7\xbb\xa6\xdc\xc0\x6a\x49\xb2\x8e\xeb\x3a\ -\x5f\xe5\x09\x1e\xca\x62\xbb\xde\xdd\xe5\xc5\x4f\xbb\x22\x2d\x7f\ -\x5a\x27\xf5\x4f\xcd\x7d\x95\xd5\xf7\xe5\x3a\x8d\x06\x2d\x8e\x53\ -\x66\x8f\xdb\xb2\x6a\xc2\xc7\x74\x0b\x5d\x1a\x7b\x96\xf9\x34\x30\ -\x3f\x80\x7b\x9d\x66\xab\x9a\x5a\x75\x0b\xa3\x27\xac\xcc\xce\x82\ -\x45\xcb\x1d\xe5\x24\x21\xd3\x87\x3c\xdb\x1f\xda\xde\xc6\x75\xa7\ -\xbc\x20\xd8\xc6\x77\x00\xda\xba\xac\x6e\x66\xef\x57\xed\xa7\x67\ -\xdc\x96\x55\x9a\x55\x03\xcb\xb4\x9f\x23\x56\x09\x63\xe4\xcd\x53\ -\xe7\x5a\xfd\xd8\x83\xbc\x34\xea\xc8\x67\xe7\xf9\xf5\x7d\x9c\x96\ -\xfb\x9b\x99\x78\xce\xfc\x54\x96\x1b\x8c\x0a\xa3\x78\xeb\xd8\x09\ -\x3b\x79\xbc\x99\x85\x82\x45\xc6\x4b\xd3\x1b\x72\xca\x25\x81\x4c\ -\xc4\x99\xf2\xce\x9f\x30\x77\x55\x05\xe7\x0b\xd7\xf1\x53\x86\x55\ -\xb5\x5f\xbc\x6f\x04\xb3\xec\xef\x2a\xd2\x4e\x53\xed\xb2\xe7\x3d\ -\x89\x13\xde\xde\x96\x8f\xe7\xd9\xc0\xc2\x8e\xdc\x3a\xdc\x15\x79\ -\x03\xd7\xd9\x3e\x4e\x47\xdd\xe5\x69\x56\x9f\xef\x58\x17\xf1\x36\ -\xbc\x5b\x97\xb7\xf1\xfa\x7c\x83\x7d\x0e\xec\xec\xc3\x1e\xe5\x5c\ -\x8e\x46\x78\xde\x62\x80\xbc\x65\xee\x85\x16\x90\xfd\xc4\x10\x3d\ -\xeb\xe9\x65\xd6\x26\x7e\xcc\x37\xf9\xa7\x0c\x8a\xe1\x2d\xee\x80\ -\xad\x23\xb5\x74\xdd\x82\xa0\x79\x22\xf7\x7d\x7c\x22\xda\x6c\x20\ -\x92\x3e\x89\x20\xbc\xb7\x23\xb1\xac\x72\x78\xc5\x44\x9c\x81\xf4\ -\x34\x25\x91\xb3\x23\x56\x3f\xb6\x00\x6b\xe1\x67\x9f\xf3\x9e\xa6\ -\xbc\x1e\xf7\x8b\x53\xe0\xb7\xf4\x4d\xd6\xc4\x69\xdc\xc4\x07\x2f\ -\x18\x28\x90\x8d\x0d\x2b\x43\xdc\x5c\xfe\xe3\x9b\x6f\x3f\xf4\x13\ -\x5d\x27\xc9\xf2\x5f\x65\xf5\x71\x98\x37\x08\xa8\x41\x7c\x5b\xee\ -\xa0\xe9\xd9\x87\x91\x7c\x9d\x26\x4b\x44\x3a\x44\x80\x0f\xf9\x06\ -\xd8\xa6\x20\xf9\x57\x44\xb6\xeb\xc5\x81\x71\xd4\x98\x94\x75\x18\ -\xb4\x1b\x16\xa1\xa1\x0d\x99\x67\xf3\x46\x9a\x6c\x72\xea\xb4\xf8\ -\xa1\xc9\xd7\xeb\xef\x68\x92\x7e\xc5\x93\x41\xf3\x66\x9d\x1d\x88\ -\xd7\x8b\x5e\xfa\x7e\x6d\x8b\xc9\xe2\xae\x17\xc3\xea\xdb\xa7\xbb\ -\x83\x56\x8e\x9c\x62\x34\xf4\x3a\xbe\xcd\x80\xd0\xef\x89\x19\x9c\ -\x70\xef\xaa\x72\xb7\xdd\x94\x69\xd6\x77\x1f\xb4\x79\x77\x04\x03\ -\xc9\xa4\x1e\x2d\xd8\x54\x71\x51\x93\x66\x08\xf6\xf8\xb9\x46\xc2\ -\xfd\x82\xc2\xb5\x36\x5a\xaa\xb9\xc4\x0f\x6b\x94\xb4\x5f\x8e\x5a\ -\xbe\xae\xb2\xa4\x99\x18\x02\xc6\x97\x91\x44\x60\x36\xde\xcd\x0e\ -\x74\x90\x43\x13\x09\xa3\x39\x93\x72\x42\xa7\xa8\x21\x89\x61\x3c\ -\xe7\x13\xfa\x98\x2a\x6c\x44\x99\x42\x8a\x09\x6f\xc8\x2d\x67\x58\ -\xb4\x22\x12\x48\x3a\xae\x27\xe4\xba\x79\x5a\x43\x0b\x6d\xd8\x5c\ -\xbe\x67\xed\xe7\x2a\xcd\xeb\x2d\xf4\x82\x24\xb7\xce\x8b\xec\xaa\ -\x44\x76\x59\xad\xcb\xfd\xf2\x21\xaf\xf3\xdb\x75\x76\xd5\x7e\xe7\ -\x6b\xd8\x77\x24\xad\x60\xe4\x65\x1f\x90\xdb\x87\xb0\x0f\xa7\x4b\ -\xde\x3d\x56\xbb\x75\xb6\x2c\xca\xe2\x13\x02\xf1\x55\xdd\x54\xe5\ -\xc7\x6c\xf9\x3e\xbd\x25\x57\xe8\x1f\xbb\x98\xb1\x1c\x1d\x44\x0c\ -\x74\x12\x02\x66\x5b\xde\xee\x9a\x66\x4a\xfb\x77\x99\x17\x4b\xa0\ -\x2c\xab\x06\x6a\xfb\xb0\x86\xfb\x37\x4b\x35\xd0\xd2\x18\x81\xbb\ -\xaa\xb0\x1c\xcc\x9e\x4d\xa9\xe5\x6a\x55\x67\xcd\x92\x0d\xb4\x83\ -\xc4\x9b\xb8\xfa\x98\x55\x5d\x87\xac\x88\xb1\xc0\xf0\x36\x4e\x3e\ -\x12\x6c\x8a\x74\x19\x27\x08\x9e\x3b\x02\xc0\x04\xd1\xd7\xdb\xb8\ -\xb9\x9f\xe8\x75\x74\x6a\xa0\x8c\xfc\x00\xf1\x34\xa6\x4f\x5d\xc7\ -\x53\xab\x8c\x91\xbe\x2c\xb0\xc8\xa6\xac\x42\xc4\xfc\x87\xb8\xd9\ -\x55\xd9\x34\xb6\x74\xf6\xa3\x29\xa4\x93\x3a\x9c\x32\x40\xff\x7b\ -\xa0\x23\x69\xbd\x40\x60\x98\x23\x0d\x79\x7c\x3b\x11\x7c\x1d\xf0\ -\x48\x30\xc5\x9d\xb1\x73\x6e\x01\x24\xa6\xb5\x0e\x42\x17\x69\x6e\ -\x85\x14\x73\xae\x22\x26\x99\x25\x1a\x7e\x7a\x6c\x3a\xac\xa5\xee\ -\xce\x38\xb0\x41\x74\x91\x64\xc2\x73\x39\xe7\x2c\xb2\x92\x10\x0a\ -\xa2\x8f\x9c\x87\x08\x72\xae\x23\xcb\x8c\x64\x44\x14\x32\x52\x80\ -\xbe\x70\x20\xe2\x5b\x29\x46\x44\x1b\x39\x67\x98\x05\x8d\x33\x4c\ -\x2d\x4c\x10\x4a\x0e\x39\xad\xea\xe6\x76\x10\x93\x68\x1a\x52\x32\ -\xce\x39\xcd\x6d\xbd\x0e\x12\xd0\x22\x63\xd0\xc9\xcd\x43\x6c\x66\ -\x3c\x17\x02\x32\x8a\xc8\x3b\x6e\xb8\x9f\x87\x1e\xcd\xa4\x53\x3e\ -\x40\xa2\x56\x46\xe8\x79\xc8\x05\x48\xde\x73\x2b\x03\x15\x29\xb8\ -\xa4\x02\x51\x45\xd0\x95\x53\x4e\x07\x60\x6b\x65\x8d\x94\x68\x09\ -\x74\x71\xe3\x6d\x80\xd5\x01\x64\x5a\xa9\x39\x46\x31\x56\x69\x13\ -\x70\x19\x59\x67\xb5\x32\x6a\x4e\x1d\x94\xb0\xa2\xa5\x19\xcf\x1c\ -\xb4\x00\xa9\x2c\x2d\x59\x4f\x3a\xbb\xbe\xb7\xd2\x32\x80\x12\x30\ -\x34\x37\xe8\x6c\xb9\x70\xc2\x39\x98\x05\xbe\x0b\x6d\xd9\xb9\x87\ -\x47\x5a\xc3\x8c\x42\x33\x2c\xbf\x93\xd7\xfb\xe0\xd3\xa9\x2f\x76\ -\xae\x24\xe2\xd5\x4a\xc4\xcf\x5d\x69\x70\x1c\x72\x53\x9e\x1c\x3b\ -\x0e\xfb\x2d\xfd\x65\x14\xe1\x77\x82\xfc\x73\xc0\x2b\x0a\x8c\x4a\ -\x48\x3d\x37\x11\xe2\xaf\xf3\x96\x03\xf0\x30\x06\xf0\x8a\x3d\x58\ -\x0f\x64\x58\x3d\x00\x5c\x00\x53\x06\x24\xcc\x61\x35\xa9\x8d\x65\ -\x0a\x38\x36\x84\x1d\x8c\x8c\xfe\xca\x4a\xae\xac\x6d\xc1\x0d\xf0\ -\x58\x60\x4c\x93\xb9\xb4\x71\x80\x1d\x10\x03\x70\x6a\x0f\x4b\x4b\ -\x0e\x28\x62\x7f\x0e\xaa\x8a\x74\x17\xf8\x09\x83\x10\xc3\x08\xf4\ -\x17\x2e\x82\xe7\x39\xb8\x11\xce\x0b\xc2\x03\x14\x1c\x7e\x24\x45\ -\xa4\x3c\x13\xc2\xd0\xfc\xce\x42\x40\x42\xbd\xc1\x68\x70\x2e\x8b\ -\xf9\x25\x41\x97\xe6\x92\x3e\xf2\x56\x7a\x20\x1a\xcb\x63\xce\x78\ -\x21\x5b\x62\x3b\x94\x25\x00\x4a\x8f\x3f\x6e\x83\x3e\x33\x20\x4a\ -\xce\x91\x3c\x14\x7c\xe6\x04\xf7\xfe\x1c\xec\xf9\x09\xee\x95\x1e\ -\x71\xef\xf8\x80\x7b\x75\x00\xfe\x01\xf7\x72\xec\x6b\xf4\xe0\x34\ -\xe2\x55\xa8\xb7\x23\xea\x5d\x9b\x60\xf8\x05\xd8\x27\x31\x13\xc9\ -\xcb\xb0\x57\xf2\xcf\x04\x7b\x19\xba\x63\xe0\x6f\x60\x79\x04\x47\ -\xc6\x04\x0c\xc8\x35\x8c\x80\x58\x0d\xeb\x8b\x48\x70\xed\x2c\xa7\ -\x80\x89\x43\x08\xf7\x2e\x30\xf4\x03\x34\xb2\x9f\x11\x30\x3e\x6c\ -\xcf\x22\xd3\x83\x06\xf6\x80\x9d\x8c\x47\x52\x80\x2d\x11\xda\x85\ -\xe3\x01\x90\xa6\x99\x67\x7c\xde\x42\x0e\x4e\x11\x74\x89\x01\x1f\ -\x07\xf0\x6a\xfa\xa1\xe0\x66\xe8\xcd\x38\xbc\x8f\x21\x35\x20\x18\ -\x4b\x85\x96\x98\x98\xc1\x0f\x3c\xac\x6e\x91\x81\xb8\xc5\xe6\x09\ -\x62\x99\xde\x4b\xdb\x66\xad\x97\x92\x3b\x3a\x83\x74\x45\x78\x50\ -\x92\x29\x26\x03\x87\xa4\x02\xf4\x02\xe3\xc2\x44\x56\x28\x2f\x2d\ -\x10\x63\xa5\x6c\xa5\x81\x03\xf1\xb6\x33\xa5\x06\x78\x06\x82\xbf\ -\x11\x68\x0b\x1f\x64\x92\x96\x4a\xf9\x4b\x6b\xf8\x3d\x14\xa0\x30\ -\xa5\x67\x5e\xb6\xf9\xab\x5b\x2d\x9f\x33\x88\x07\x7c\x6a\xe5\xb5\ -\x80\x8a\x74\xe4\xa4\x90\xae\x6d\xd4\xfa\x0d\xdc\x80\x46\x43\xee\ -\xd2\x6a\xd2\x91\xfa\x49\x52\x8e\xed\xbc\xcf\x33\x29\x3c\x79\x34\ -\xfc\xb0\xd3\x36\xb9\x18\x13\x9a\xf3\x80\xe1\xc1\x76\x5b\x17\x7b\ -\x09\xde\xce\xc7\xec\x52\x54\x67\xec\x4f\x04\xef\x53\x70\xb7\x9b\ -\x01\xa1\xe4\x1c\x71\x57\xfd\x2c\xb8\xdd\x19\x70\x9b\x5f\x05\x6e\ -\x90\x10\x3c\xb1\x93\xa2\x10\x0e\x53\x2a\xa1\x28\x9e\x59\xc0\xd8\ -\x76\x1b\x0d\x65\xbd\x33\x93\xe9\x80\x8c\xd1\xaf\x5a\xb9\x90\x22\ -\x14\xed\x20\x8c\xd7\x9a\x19\x90\xb0\x7d\xe1\x8a\x21\xfe\x81\xeb\ -\x11\xc2\x82\x61\x8b\x8b\xa0\x89\xf1\x0e\x98\x56\xbf\x0c\xd2\xfc\ -\x00\x69\x77\x19\xd1\xe6\x67\x10\x2d\x3e\x1f\xd1\x0c\x0d\xdc\x45\ -\x44\xe3\x40\xf0\x7f\x85\xe8\x5f\x00\x55\x6b\x45\xc8\x42\x71\x01\ -\xae\x9c\x52\x5d\x1f\xa3\x44\xf7\x0e\x4f\x42\xd9\x67\x7f\xbe\xa4\ -\x4a\x9e\x08\x25\xc4\x41\x77\x29\xfd\x1d\xeb\x4e\x62\x4f\x4d\x79\ -\xdf\xc9\x5f\xa7\xc4\x88\xb7\xdb\x4f\xc7\x7f\x3f\x6d\xf2\x4b\xda\ -\xc4\xf1\x80\xd1\x76\xe6\x4d\x9b\xaf\xd4\xe6\xa5\x50\x4a\xce\x8f\ -\x48\xca\xde\xb4\xf9\x5a\x6d\xaa\x0b\xda\x94\xbd\xa3\xf3\x37\x6d\ -\xbe\x52\x9b\xfe\x82\x36\x71\x32\x81\x70\x4a\x1a\xf9\xa6\xce\x9f\ -\xdf\x31\x29\x76\xaa\x4a\x36\xbc\xba\x91\x7c\x3c\x0e\x30\x3a\x05\ -\xb6\xe7\x43\xf3\xd2\xef\xd7\xea\xf2\xcc\x96\xf4\x8f\xa2\xcb\xd0\ -\x9c\x68\x93\xde\x64\xd1\x0b\xd7\x37\x65\x7e\xb6\x32\x4f\x77\x47\ -\xb6\xd5\x25\xf3\xfe\x4d\x9b\x9f\xad\x4d\x7b\xa2\xcd\xc3\x3b\xda\ -\x37\x6d\x7e\x76\x0e\xba\x74\xd0\x54\xdd\xf6\xe8\x2d\xff\xbc\xf6\ -\x18\x74\x6e\xb3\xd9\xde\x38\xb5\x17\x08\xa7\x07\x21\x75\x50\xe2\ -\xf1\xcf\x37\x68\xb6\x07\xa1\x73\x1b\xa4\x83\x3e\x4f\x8f\x42\x6f\ -\xfa\xbc\x7c\x14\x3a\x77\xb4\x1c\xf5\x79\xe6\x30\xf4\xa6\xcf\xcb\ -\x87\xa1\x73\xc7\xa1\x51\x9f\xfd\x71\xc8\xf1\x37\x7d\xbe\xf6\x38\ -\x74\x11\x9f\xc3\x81\x48\x8b\x37\x85\xbe\x36\x80\xea\x0b\xfa\x3c\ -\x4d\xef\x7f\x48\x6d\x5e\x2f\xee\x86\x8a\xa0\x49\xd5\xc9\xb3\x37\ -\xb5\x09\xf7\xcf\x6e\x94\x59\xa4\x85\xa6\xdb\xc9\x49\x91\x46\xf6\ -\x90\x15\x65\x9a\x8e\xeb\xe5\x2e\x35\xcf\xdf\xe1\x8a\x48\x28\xab\ -\xb9\x64\xe6\xdc\x2a\x5e\x2b\xfc\xb4\xda\x86\xc4\x16\x58\xfa\x48\ -\x1c\x6a\x59\x64\xff\xb2\x7c\x64\x8c\x05\x30\x27\x9c\xa3\x0a\xad\ -\xa3\xda\xac\x0a\x2c\x1d\x69\xe6\x98\x72\x87\x79\xbb\x92\x1c\xba\ -\x50\x65\xd6\x1f\x54\x39\x85\xe5\xd9\xfa\x98\x55\x59\x34\x61\xcb\ -\xc1\xc2\xaa\x4d\xbc\xee\x28\x0f\x71\x95\xc7\x45\x73\x44\xdb\xb7\ -\xc2\x1e\x91\xa0\x86\xac\x49\xee\x8f\x69\xf9\xa7\x6c\xb9\xc9\xd2\ -\x7c\xb7\xb9\x22\x94\xf4\xd5\x71\x47\x6d\x56\xf1\x26\x5f\x3f\x2d\ -\x7f\x88\x8b\xfa\x2a\x1c\x9c\x25\xec\xba\x6f\xb3\x64\xac\xe1\xec\ -\x5a\x34\xd9\x63\x83\x56\x69\x56\x50\x85\x4b\xfb\x14\xaf\xf3\xbb\ -\x62\x59\x37\x71\xd5\x74\x84\x34\x4b\xca\xaa\xeb\xd3\x1a\xe8\x19\ -\xb1\xc5\x6b\xc7\x59\x67\x0d\xcc\x1b\xf6\x65\x6c\x83\x58\xfb\xb2\ -\x4a\x9f\xd3\xda\x31\xc6\x62\xa9\xae\xf7\xbe\xca\x1b\x34\x09\xa9\ -\xe2\x6a\xb9\xae\xc2\xe6\xf6\x2a\xcd\xc9\xe0\x34\xf3\xba\xa9\xae\ -\xa8\xbe\xb3\x5d\x76\x7d\x9f\xaf\x9a\xe5\xf0\xd8\x8b\x5d\x24\xf7\ -\x50\x7e\x27\xf7\x2f\x2e\x4d\x1a\x4c\x77\xf6\x9e\x62\x0a\xcf\xc1\ -\xa1\x55\x17\x16\xc4\xeb\x8b\x81\x06\xcc\xb4\x05\x0a\x92\x45\x8a\ -\x19\xaf\x15\x55\x22\xe0\x9b\x33\x17\x7c\x1d\x08\x83\xdd\x9c\xe2\ -\xde\x51\xde\xe4\x8c\x59\xed\x02\xda\x31\x1b\xcf\xb5\xa3\x0b\x1b\ -\xe1\x8c\x65\xd3\x9b\xda\xf6\x10\xdd\x5e\xc1\x7c\x1f\xb4\xb7\x38\ -\x8c\x33\xec\x0a\x23\xaf\x38\x33\x42\xd1\xe5\x18\xf3\x9a\x59\x43\ -\xd7\xc1\x70\x64\xba\x38\x35\xc2\xd3\x9d\x3c\x5d\x38\x29\x6f\x8d\ -\xd4\x01\x5d\x3d\x09\xba\xaf\x9f\xb7\x57\x3a\x8e\x6a\x79\x38\x1a\ -\x72\xad\x4d\x5b\x33\xa4\xb9\xd2\xca\x21\x48\xea\xc8\x31\x2a\x48\ -\xa0\x44\x04\x61\x38\x43\x67\x2c\x00\xa7\x78\xd5\x96\xe3\x68\xcf\ -\x1d\x73\x8e\x2e\xcf\x70\x50\x15\xa6\xbb\xe9\xe2\x0e\x87\x4e\x30\ -\x85\x32\x1c\x47\x2a\xf4\x44\xc8\x74\x10\xc5\x7b\x41\x95\x17\x9c\ -\xae\x7f\xa5\x17\x68\xa3\x98\xe5\xc2\xb4\x43\x71\x2e\x27\x17\x4b\ -\x43\x54\x17\xde\xb9\xd0\x4e\xce\x6c\xaf\x4d\x0c\xe7\xae\x2a\x93\ -\xe1\xf3\xe6\xde\x7f\x78\xf7\x3e\xad\x3c\xfc\x4d\xdd\x9b\x79\xc1\ -\xa4\xa1\x1a\x17\xc7\x3c\x57\x54\x7f\x24\x74\x64\x9c\x07\xf8\xe7\ -\x0c\xc8\xd7\xce\xc1\x57\xc9\xbf\x99\x56\x42\x51\x75\x0d\x5d\x0d\ -\x5b\x2a\x35\x63\x91\xd4\xdc\x2a\xaa\x34\xe2\xf0\x1a\x2b\x44\xeb\ -\xdf\x20\x32\x4f\x05\x3b\xe0\x5b\xc9\xa5\x30\x3e\xe0\x91\xf3\x4a\ -\x7b\xba\x40\x96\x11\xc6\xd4\x70\x49\x8a\x1e\x0a\x81\x82\xd3\xf9\ -\x90\x3b\xa9\xa8\x62\xc7\xc0\x9f\x05\xd5\x24\x81\x66\xb5\x52\x14\ -\x5b\xd0\x90\x31\x03\xbf\xf7\xf4\xbe\x43\x6a\xc5\xcf\xf9\xb8\x3a\ -\x38\xb9\x1d\x9d\xdc\x9b\xd1\xc9\xe5\xe0\xe4\xd2\x0f\x5e\x2e\x4e\ -\xbc\x5c\x9e\x78\xb9\xed\xbd\xbc\x2d\xf4\x7b\xc9\xd1\x7f\x2b\x37\ -\x7f\x71\x1f\xb4\x5a\x9d\xcb\x04\x2f\xef\x7f\xfa\xa2\xd6\x23\xfc\ -\xf0\x88\x9f\x94\xa7\xd6\xff\xd9\xc5\x55\xf6\xfa\xbd\xde\xe5\x5d\ -\xd2\xc5\x02\xd5\x93\x9d\x93\x44\x56\x78\xbe\x73\x1a\xcb\x1b\x4e\ -\x76\x4e\xa7\x1c\x2a\x5a\x77\xfd\x7b\xae\xe9\x0e\x8a\xb7\xb0\x61\ -\xec\x78\xcf\x24\x22\xa7\xe8\xa3\x2f\x06\xd5\x56\xdb\x93\x25\x9d\ -\xd7\xa4\x8c\x90\xa9\xa8\x00\xcf\xfd\xba\x9d\xf3\xe7\xee\x39\x5b\ -\x2f\xc6\xf2\x8c\x68\xd3\x2c\x12\x73\x9f\x66\xff\x16\x48\xa4\x43\ -\x7b\xa4\x89\xc3\x81\xc3\x89\xff\x11\x5e\xc7\xf2\x7f\xec\xdb\xaf\ -\xa9\xfc\xfe\xc3\xbb\xff\x02\x4e\xaa\x5a\x58\ -\x00\x00\x0e\x9e\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x65\x6c\x65\x63\ -\x74\x5f\x61\x6c\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ -\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x78\x3d\x22\x32\x2e\x36\x34\x36\x39\x32\x38\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ -\x31\x36\x2e\x37\x30\x39\x34\x39\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ -\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ -\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ -\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\ -\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\ -\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\ -\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ -\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ -\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x64\x34\x30\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x33\x38\ -\x35\x31\x33\x39\x32\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\ -\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\ -\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\ -\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x32\x39\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x35\x2e\x33\ -\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x32\x2e\x32\x38\x32\x39\x32\x37\x33\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ -\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ -\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ -\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\ -\x30\x30\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\ -\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ -\x66\x64\x34\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x32\x2e\x33\x38\x35\x31\x33\x39\x32\x33\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ -\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\ -\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\ -\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ -\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x35\x2d\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x33\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x32\x38\x32\x39\x32\ -\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\ -\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\ -\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\ -\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\ -\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\ -\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x64\x34\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x33\x38\x35\x31\ -\x33\x39\x32\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\ -\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\ -\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\ -\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x32\x39\x39\x35\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x34\x2e\ -\x35\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x32\x2e\x32\x38\x32\x39\x32\x37\x33\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0a\x23\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x6d\x6f\x76\ -\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\ -\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ -\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ -\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\ -\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ -\x2d\x35\x38\x2e\x36\x33\x38\x31\x36\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x35\ -\x2e\x35\x33\x38\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ -\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\ -\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\ -\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\ -\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ -\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ -\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ -\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ -\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ -\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ -\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ -\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ -\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ -\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ -\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ -\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x64\ -\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ -\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x34\ -\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\ -\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\ -\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\x33\x38\ -\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x38\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x38\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\x31\x39\x31\x32\x39\x38\x39\ -\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ -\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x4d\x20\x35\x2e\x38\x36\x36\x36\x36\x36\x37\x2c\x31\x36\ -\x2e\x38\x36\x31\x32\x31\x31\x20\x48\x20\x32\x38\x2e\x32\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x33\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ -\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\ -\x3e\x0a\ -\x00\x00\x06\xb7\ -\x00\ -\x00\x26\x68\x78\x9c\xed\x59\x49\x8f\xe3\x44\x14\xbe\xf7\xaf\x28\ -\xdc\x17\x10\x71\xb9\x16\x6f\xe5\x4e\x32\x87\x19\x21\x90\xe0\x02\ -\x03\x1c\x47\x8e\x5d\x49\x4c\xdb\xae\x60\x3b\x9d\x84\x5f\xcf\x2b\ -\x6f\x71\x36\xe8\xa1\x33\x91\x90\xe2\x56\xab\xed\xf7\x5e\x6d\xdf\ -\xf7\x36\xbb\xc7\xef\xb6\x59\x8a\x5e\x64\x51\x26\x2a\x9f\x18\x14\ -\x13\x03\xc9\x3c\x52\x71\x92\x2f\x26\xc6\xaf\x1f\xbf\x33\x7d\x03\ -\x95\x55\x98\xc7\x61\xaa\x72\x39\x31\x72\x65\xbc\x9b\x3e\x8c\xbf\ -\x32\x4d\xf4\xbe\x90\x61\x25\x63\xb4\x49\xaa\x25\xfa\x21\x7f\x2e\ -\xa3\x70\x25\xd1\xd7\xcb\xaa\x5a\x05\x96\xb5\xd9\x6c\x70\xd2\x0a\ -\xb1\x2a\x16\xd6\x37\xc8\x34\xa7\x0f\x0f\xe3\xf2\x65\xf1\x80\x10\ -\x82\x75\xf3\x32\x88\xa3\x89\xd1\x0e\x58\xad\x8b\xb4\x36\x8c\x23\ -\x4b\xa6\x32\x93\x79\x55\x5a\x14\x53\xcb\xd8\x9b\x47\x7b\xf3\x48\ -\xaf\x9e\xbc\xc8\x48\x65\x99\xca\xcb\x7a\x64\x5e\x3e\x0e\x8c\x8b\ -\x78\xde\x5b\xeb\xdd\x6c\x78\x6d\x44\x85\x10\x16\x61\x16\x63\x26\ -\x58\x98\xe5\x2e\xaf\xc2\xad\x79\x38\x14\xf6\x78\x6e\x28\x23\x84\ -\x58\xa0\xdb\x5b\xbe\xce\x2a\x28\x01\xd0\x15\xfc\xf6\xe6\x9d\x00\ -\x97\x6a\x5d\x44\x72\x0e\xe3\x24\xce\x65\x65\x7d\xf8\xf8\xa1\x57\ -\x9a\x04\xc7\x55\x3c\x98\xa6\xc3\xf3\x60\xd5\x03\x90\xf3\x30\x93\ -\xe5\x2a\x8c\x64\x69\x75\xf2\x7a\xfc\x26\x89\xab\xe5\xc4\xe0\x36\ -\xa6\x1c\x2e\xa7\x16\x2e\x65\xb2\x58\x56\xc7\xd2\x24\x9e\x18\xb0\ -\x7b\x26\xfc\xe6\x79\xe0\x1c\xb4\x31\x68\x27\x0e\x7a\x0d\xc1\x82\ -\x61\x8a\x0a\xea\x70\xaf\xb1\xe9\x8e\x10\xc4\x2a\xd2\x7b\x82\x29\ -\x65\x96\x84\xeb\x4a\x65\xc0\x5a\x14\xa5\x61\x59\x26\xf3\x24\x82\ -\x07\x95\xaf\xd2\xf5\x22\xc9\x3f\x95\xc9\x22\xff\x54\x29\x95\xe2\ -\x0e\xbc\x7e\x25\xb9\x5d\xa9\xa2\x32\xb7\xf1\x0a\x20\x74\xbd\xb3\ -\xca\x5d\xa7\x9c\x82\x76\x1c\xcb\x79\xa9\xad\x9a\xf3\xe8\x27\x38\ -\x90\x67\x20\xab\xd6\xf6\xdb\xd3\x7b\x8b\x5f\x12\xb9\xd9\xdb\xce\ -\xc2\xb2\xc1\x0c\xa1\x55\xb8\x00\xff\x4a\x55\x31\x31\x1e\xe7\xf5\ -\xd5\x2a\x66\xaa\x88\x65\xd1\xa9\xdc\xfa\x3a\x50\x29\xe0\x20\xa9\ -\x76\x4d\x44\xb5\x73\x77\xfb\xd5\xb3\xf6\x7a\x72\x5e\x5f\x2e\xc3\ -\x58\x6d\x26\x06\x3b\x56\xfe\xa5\x54\x36\x31\x1c\xec\x08\x5f\x10\ -\x7a\xac\x8d\xb6\x13\xc3\x64\x2e\xa6\x94\xfb\xcc\x39\xd1\xc2\x7a\ -\x1c\x36\x24\x84\x2d\xfc\x13\xe5\xba\x28\x20\xe4\xcc\x34\xdc\x49\ -\x38\x54\xfd\xa7\x9b\xbf\x5c\xaa\xcd\xa2\xd0\xe0\x54\xc5\x5a\x1e\ -\x8f\xd4\x1a\x73\x36\x53\xdb\xf3\x6a\xf0\x80\xb5\x0e\x66\x73\x9d\ -\x27\x15\x04\xcc\x6a\x3b\x9c\x75\x9d\xc4\xb2\x3c\x3f\x70\x93\xe4\ -\x80\x81\xd9\xba\x2e\xe5\x3d\xc4\xc7\x16\x9d\x1f\x7b\xe4\xe4\x54\ -\xad\x05\x6c\xed\x04\xe6\x56\xb5\xbb\xac\xca\xc2\x6d\x92\x25\x7f\ -\x49\x38\xf7\x09\xd2\x65\x1e\xae\xcc\x45\xaa\x66\x61\xda\xee\x7e\ -\x5a\x5b\x8c\x0f\x60\x69\x06\x21\x54\xed\x74\xd0\x6e\x77\x5a\x66\ -\x74\x42\x8d\xa7\x16\x70\xcf\x75\x7a\xa1\x2a\x12\x88\x85\xc1\x7e\ -\x3b\xd1\x6e\x28\xd2\x21\x0e\x19\x7a\x5b\xfb\x57\xed\x7d\xde\xb1\ -\x6e\x37\xd4\xb5\x6e\x6f\x9d\xfa\x7d\x2d\xcf\x64\x15\xc6\x61\x15\ -\xee\x83\xa0\x93\x30\x21\x48\x77\x32\xc8\x96\xc1\xcf\x1f\xbe\x9b\ -\xb6\x0b\x8d\xa3\x28\xf8\x5d\x15\xcf\xdd\xba\x08\x69\x83\x70\xa6\ -\xd6\x40\x85\x31\xed\xc5\xe3\x38\x0a\x20\xbf\x41\xdc\x4f\x93\x0c\ -\x5c\x5b\xa7\xc6\x6f\x21\x9f\x8d\xad\xbd\xe2\xc0\x58\x83\xb5\x9f\ -\xb4\x99\xb6\x90\x4d\xa2\x3c\x5b\x2d\xe2\x28\x4b\xf4\x20\xeb\x97\ -\x2a\x49\xd3\x1f\xf4\x22\xed\x89\x07\x93\x26\x55\x2a\xf7\xc2\xb1\ -\xd5\xee\xbe\x3d\x9b\x35\x38\xdc\xd8\xea\x4e\x5f\x3f\x2d\xf6\xa8\ -\x1c\x04\x45\x4f\x74\x1a\xce\x24\x38\xc1\x8f\x5a\x89\x4e\xb4\x8b\ -\x42\xad\x57\x99\x8a\x65\x3b\xbc\x47\x53\x46\x55\x4f\x59\xb5\x4b\ -\x41\x3f\x87\xdd\x07\x8f\x73\xa2\x7f\x9e\xf4\x83\xd9\xa6\x89\x80\ -\x36\x8f\xc5\x3a\x85\x74\xf7\x22\x73\x15\xc7\x4f\x65\x55\xa8\x67\ -\x19\x3c\x12\x62\xfb\x84\xb4\x8f\x4d\xb4\x04\xfd\x63\x9a\xe4\x12\ -\xb6\x11\x94\x7f\xae\xc3\x42\x0e\xa5\x7f\xa8\x24\x0f\x00\x37\x59\ -\x74\xd2\xfa\x21\x05\x8f\xaf\x02\xbb\x93\xc5\x21\x64\xa2\xa2\x08\ -\x77\x41\x0e\xe5\x7f\x28\x55\xf3\x79\x29\xab\xfd\x4a\xdd\x56\x09\ -\xe6\xed\x75\xe0\xe8\xfa\xb8\x5c\x08\xda\x0b\xcf\x56\x24\x7d\x9d\ -\xaf\x4a\xfa\x3a\x88\x0a\xf0\x6f\x81\x6d\x8f\x0b\xc2\x5d\x69\x52\ -\xb7\x57\x14\x07\x66\x85\xce\x79\x98\x43\x65\x72\x21\xe7\x75\x0e\ -\x30\x5e\x85\xd5\xf2\x1c\xfa\x83\x53\x06\x8f\x94\x02\xb6\xd1\x21\ -\xb2\x0e\xf6\x9b\x98\x12\xc7\x10\xcf\xd6\x55\x75\x2d\x80\x7b\xde\ -\xfb\x73\xe8\x98\x44\xac\x41\x84\xf3\x51\x07\x0e\x47\x2e\xb6\x47\ -\x66\xa7\x40\x1c\xeb\xf6\x46\x08\x6f\x20\xab\x2d\x6c\xcc\xea\x6d\ -\x23\xa7\xe1\x07\x44\xed\x1d\x47\xad\xce\xed\xc7\xd8\x47\xb3\x2e\ -\x91\x8f\x9d\x5a\x71\xc0\xa9\x06\xd1\x26\x9e\x30\xb9\x39\x50\xf4\ -\x05\x45\xe5\x00\x4c\xa5\x0a\x13\x4a\xcb\x4b\x58\xad\x0b\xa9\x89\ -\xf9\x3c\x0a\x88\xcf\x63\x2f\x3e\xa4\x00\xf6\x66\x43\x35\x20\xc2\ -\xb9\x39\x05\x3f\x21\x0d\x8a\x70\x39\x25\x74\x04\xa5\xd4\x71\x1c\ -\x0a\x68\x71\x6c\xfb\x1e\x75\xa9\x18\x41\xed\xf5\x19\x75\xb9\x00\ -\x9c\x05\xe5\x9e\x4d\x47\x0c\xdc\xcf\x01\x80\x11\x25\xd8\x73\x5d\ -\x5f\x88\x11\x85\x23\x50\xdb\x23\x0e\xa2\xc0\x23\x15\xcc\x15\x23\ -\x1f\x7b\xc2\x25\x8c\x50\x44\x3d\x0c\x0b\xd8\x9e\x3f\xb2\xb1\x20\ -\x0e\x78\x2e\x47\x7a\x12\x6a\x0b\x67\x44\x30\xf5\x18\xb1\xa9\x80\ -\x55\xd9\xc8\xe4\x98\x5d\xa0\xe4\x0b\x11\x22\x49\x1c\xcd\x8f\x62\ -\xa2\xaf\x33\x6c\xb5\xfd\x7c\x4a\x2e\x00\x0d\x27\x1b\x78\xb9\xc0\ -\xee\x88\x33\x44\x19\xf6\x47\x4c\x34\x31\xe8\x21\x2a\xc0\x88\x39\ -\xd8\x45\xcc\x6e\x1c\x94\x8f\x18\xe9\x3c\x9d\xf9\x60\x4c\xfd\x3e\ -\x34\x1c\x30\xa6\xee\xde\x99\xf9\x59\xe4\xfe\xdf\xb8\x65\x08\x1a\ -\x4a\xdf\x13\xbe\x0b\xbe\xc2\xc0\x91\xc0\x8f\x3c\x0e\xce\xc8\x3c\ -\xc6\x6d\xe2\x3a\x75\x26\x00\x0b\xdb\x81\x6c\xc2\x5c\xdf\xf6\x1c\ -\x5f\xbb\x11\x25\x0e\xb8\xa8\x46\x11\x46\x52\x48\x05\x2e\x66\xd0\ -\x45\xb2\x3a\xa5\x40\xb6\x73\x3d\x2d\xf2\x6d\x5b\x50\x18\x0a\xe4\ -\xb8\xc2\x73\x6d\x3d\x12\x72\x30\x77\x1c\xaf\x5b\x83\xee\x57\x00\ -\xb0\x7d\x4c\x28\xe1\xa4\x4e\x2d\xc2\xa6\x60\x27\x2e\xe4\x10\xff\ -\x2a\xc0\xd7\x2d\xb9\xae\x89\xfa\x7a\x8a\x93\x72\x05\x45\x17\xde\ -\x9b\x34\x84\x4f\x0a\x5e\x58\xe6\xa9\xda\x04\x2f\x49\x99\xcc\x52\ -\xf9\x54\xff\x4d\x52\x8d\x62\x27\x3a\x93\x82\x08\x99\x33\x76\xc8\ -\x5c\x97\x19\x6d\xfb\x4b\xa6\xa0\x7f\x2a\xb3\xf4\x29\x0b\x8b\x67\ -\x59\x34\x03\x64\x1e\xc2\xe6\xcd\x59\x18\x3d\xeb\x7e\x23\x8f\x83\ -\x30\x82\xae\x7b\x9d\xc2\x0b\xfa\x61\x58\x91\x11\x41\xbf\xa1\x3e\ -\xb0\x4e\xb8\x80\x86\xcf\x7d\x35\x13\x3d\xf8\x7d\x5b\x09\x7d\x8e\ -\xee\xc4\xa0\xa3\x8f\xa2\x3b\x51\xff\x9d\xa8\x0c\xf5\xc9\x41\x17\ -\x10\xbb\xc9\x68\xd1\xa0\x03\x20\x97\xee\x4f\x28\xe5\x9e\xc7\x4c\ -\x62\xb2\x7b\x80\xdd\x96\xb7\x7d\xe9\x79\x13\x6f\xf4\xce\xdb\x2d\ -\x12\xe3\x80\x37\x68\x32\xd0\xfb\xba\x01\xa9\x6f\x4f\x6e\x2e\x31\ -\x75\x9d\x9e\xeb\xce\xd4\xab\x23\xcc\x6b\x12\xe3\x5b\x33\xe3\x75\ -\x5e\x5e\xee\xbc\xbd\xbe\xa2\x75\x9c\xbc\x8d\xb7\xeb\xf4\xea\x77\ -\xde\xfe\x25\x33\xf6\xcd\xe2\xe0\x7d\xec\x7b\x74\xca\x0a\xb4\x8e\ -\xaf\x6f\xe2\xef\xad\xe3\x97\x0b\xb4\xee\xc3\x0e\x10\x06\x2f\x65\ -\x10\x63\x64\xf0\xfd\xe7\xc2\xfd\x69\x8c\xf9\x36\xb9\xc7\xd7\x4d\ -\xf2\x22\xc1\x6d\x5e\x7c\x23\x5d\xf7\x77\xe8\xdb\x10\xc6\x28\xbe\ -\x4e\x7c\xdd\x2b\xd8\x8d\x08\x73\xaf\x15\x61\xf7\x94\x78\x13\xc2\ -\x38\x7b\x33\x53\xf7\x97\xb1\xdb\x14\x2f\xf7\xcd\x4c\xbd\xfe\x7b\ -\xe3\x9d\xa9\xab\x7c\xe0\xd0\xff\x18\x69\x3f\x70\xd4\xb7\x27\x37\ -\x17\x5e\xb8\x3e\x93\xa7\xb1\xb5\x98\x3e\x8c\xf5\xbf\xfb\xa7\x0f\ -\x7f\x03\xa5\x38\xeb\x75\ -\x00\x00\x12\x20\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x34\x20\x28\x35\x64\x61\ -\x36\x38\x39\x63\x33\x31\x33\x2c\x20\x32\x30\x31\x39\x2d\x30\x31\ -\x2d\x31\x34\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\ -\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\ -\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x75\x6e\x64\ -\x6f\x5f\x73\x61\x76\x65\x5f\x72\x6f\x69\x2e\x73\x76\x67\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ -\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ -\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ -\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ -\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ -\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ -\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x34\x2e\x35\x34\x38\x38\x30\ -\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x79\x3d\x22\x31\x36\x2e\x31\x30\x34\x39\x38\x39\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\ -\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\ -\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ -\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\ -\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ -\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x37\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ -\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ -\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ -\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ -\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ -\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ -\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ -\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ -\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ -\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ -\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ -\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ -\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x32\x34\ -\x37\x35\x31\x33\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x33\x32\x35\x36\x36\x65\x2d\ -\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x35\ -\x2e\x32\x31\x30\x36\x34\x36\x38\x65\x2d\x31\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\x34\ -\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ -\x2e\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\ -\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\ -\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\ -\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ -\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\ -\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\ -\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\ -\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\ -\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\ -\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\ -\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\ -\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\ -\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\ -\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\ -\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\ -\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\ -\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\ -\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\ -\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\ -\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\ -\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\ -\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\ -\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\ -\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\x32\ -\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\ -\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\ -\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x4d\x20\x33\x30\x2e\x34\x30\x36\x39\x35\x34\ -\x2c\x31\x31\x2e\x36\x39\x35\x31\x30\x38\x20\x43\x20\x32\x36\x2e\ -\x30\x30\x34\x31\x39\x38\x2c\x33\x2e\x33\x31\x30\x30\x37\x35\x38\ -\x20\x31\x39\x2e\x33\x36\x39\x31\x35\x38\x2c\x34\x2e\x35\x32\x38\ -\x36\x37\x30\x31\x20\x31\x30\x2e\x36\x36\x36\x36\x36\x37\x2c\x37\ -\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x4c\x20\x38\x2e\x36\x36\x36\ -\x30\x31\x30\x37\x2c\x31\x2e\x39\x34\x31\x30\x36\x32\x34\x20\x32\ -\x2e\x32\x30\x39\x35\x30\x37\x36\x2c\x31\x35\x2e\x39\x30\x32\x37\ -\x20\x33\x2e\x36\x32\x39\x36\x31\x36\x31\x2c\x31\x36\x2e\x34\x39\ -\x37\x36\x33\x35\x20\x31\x36\x2e\x39\x32\x37\x34\x35\x32\x2c\x31\ -\x37\x2e\x30\x36\x38\x36\x35\x31\x20\x31\x33\x2e\x36\x31\x35\x35\ -\x36\x39\x2c\x31\x31\x2e\x35\x31\x34\x35\x34\x38\x20\x63\x20\x35\ -\x2e\x38\x30\x33\x39\x39\x39\x2c\x2d\x31\x2e\x32\x38\x36\x31\x30\ -\x35\x20\x31\x31\x2e\x36\x30\x39\x39\x34\x38\x2c\x2d\x32\x2e\x35\ -\x39\x31\x38\x30\x38\x38\x20\x31\x34\x2e\x33\x38\x34\x32\x36\x34\ -\x2c\x32\x2e\x36\x39\x31\x38\x36\x36\x20\x32\x2e\x35\x32\x34\x36\ -\x31\x33\x2c\x32\x2e\x32\x38\x32\x34\x32\x38\x20\x33\x2e\x39\x39\ -\x32\x33\x38\x34\x2c\x31\x2e\x37\x33\x34\x33\x39\x32\x20\x32\x2e\ -\x34\x30\x37\x31\x32\x36\x2c\x2d\x32\x2e\x35\x31\x31\x33\x20\x7a\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x32\x39\x38\x38\x2d\x37\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ -\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ -\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\ -\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ -\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ -\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\ -\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\ -\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\ -\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\ -\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\ -\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\ -\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\ -\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\ -\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\ -\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\ -\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\ -\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\ -\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\ -\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\ -\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\ -\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\ -\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\ -\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\ -\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\ -\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\ -\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\ -\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\x32\x3b\ -\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\ -\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\ -\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x4d\x20\x33\x30\x2e\x30\x39\x32\x30\x33\x36\x2c\ -\x39\x2e\x33\x38\x30\x39\x31\x34\x31\x20\x43\x20\x32\x35\x2e\x36\ -\x38\x39\x32\x38\x32\x2c\x30\x2e\x39\x39\x35\x38\x38\x31\x30\x37\ -\x20\x31\x39\x2e\x30\x35\x34\x32\x34\x31\x2c\x32\x2e\x32\x31\x34\ -\x34\x37\x35\x36\x20\x31\x30\x2e\x33\x35\x31\x37\x34\x39\x2c\x35\ -\x2e\x31\x35\x32\x34\x37\x32\x32\x20\x4c\x20\x38\x2e\x33\x35\x31\ -\x30\x39\x33\x33\x2c\x2d\x30\x2e\x33\x37\x33\x31\x33\x32\x36\x39\ -\x20\x31\x2e\x38\x39\x34\x35\x39\x30\x32\x2c\x31\x33\x2e\x35\x38\ -\x38\x35\x30\x35\x20\x33\x2e\x33\x31\x34\x37\x30\x31\x31\x2c\x31\ -\x34\x2e\x31\x38\x33\x34\x34\x32\x20\x31\x36\x2e\x36\x31\x32\x35\ -\x33\x34\x2c\x31\x34\x2e\x37\x35\x34\x34\x35\x38\x20\x31\x33\x2e\ -\x33\x30\x30\x36\x35\x32\x2c\x39\x2e\x32\x30\x30\x33\x35\x34\x31\ -\x20\x63\x20\x35\x2e\x38\x30\x33\x39\x39\x39\x2c\x2d\x31\x2e\x32\ -\x38\x36\x31\x30\x34\x35\x20\x31\x31\x2e\x36\x30\x39\x39\x34\x37\ -\x2c\x2d\x32\x2e\x35\x39\x31\x38\x30\x39\x36\x20\x31\x34\x2e\x33\ -\x38\x34\x32\x36\x33\x2c\x32\x2e\x36\x39\x31\x38\x36\x33\x39\x20\ -\x32\x2e\x35\x32\x34\x36\x31\x32\x2c\x32\x2e\x32\x38\x32\x34\x32\ -\x38\x20\x33\x2e\x39\x39\x32\x33\x38\x33\x2c\x31\x2e\x37\x33\x34\ -\x33\x39\x32\x20\x32\x2e\x34\x30\x37\x31\x32\x37\x2c\x2d\x32\x2e\ -\x35\x31\x31\x32\x39\x39\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ -\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x31\x2e\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ -\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\ -\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x38\x2e\x31\x33\x33\x33\x33\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x39\x2e\ -\x32\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x79\x3d\x22\x32\x2e\x38\x34\x34\x34\x34\x34\x35\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x08\x11\ -\x00\ -\x00\x25\xb3\x78\x9c\xdd\x59\x5b\x6f\xdb\x38\x16\x7e\xcf\xaf\xd0\ -\x3a\x2f\x2d\xd6\x92\x29\x51\x77\x27\x99\x87\x29\x66\x67\x80\x2e\ -\x06\x98\xb6\xbb\xc0\xbc\x14\xb4\x44\xdb\x9c\x48\xa2\x97\xa2\x63\ -\xbb\xbf\x7e\x0f\x29\x89\x92\x7c\x29\xd2\x49\xd3\x49\x47\x40\x10\ -\xf2\x5c\x78\xf9\xce\x95\xc9\xcd\x0f\xfb\xb2\xb0\x1e\xa8\xa8\x19\ -\xaf\x6e\x27\xae\x83\x26\x16\xad\x32\x9e\xb3\x6a\x75\x3b\xf9\xf0\ -\xfe\x27\x3b\x9e\x58\xb5\x24\x55\x4e\x0a\x5e\xd1\xdb\x49\xc5\x27\ -\x3f\xdc\x5d\xdd\xfc\xc3\xb6\xad\x1f\x05\x25\x92\xe6\xd6\x8e\xc9\ -\xb5\xf5\x4b\x75\x5f\x67\x64\x43\xad\x57\x6b\x29\x37\xe9\x6c\xb6\ -\xdb\xed\x1c\xd6\x12\x1d\x2e\x56\xb3\xd7\x96\x6d\xdf\x5d\x5d\xdd\ -\xd4\x0f\xab\x2b\xcb\xb2\x60\xdf\xaa\x4e\xf3\xec\x76\xd2\x2a\x6c\ -\xb6\xa2\xd0\x82\x79\x36\xa3\x05\x2d\x69\x25\xeb\x99\xeb\xb8\xb3\ -\x49\x2f\x9e\xf5\xe2\x99\xda\x9d\x3d\xd0\x8c\x97\x25\xaf\x6a\xad\ -\x59\xd5\xd7\x03\x61\x91\x2f\x8d\xb4\x3a\xcd\x0e\x6b\x21\x37\x49\ -\x92\x19\xf2\x66\x9e\x67\x83\x84\x5d\x1f\x2a\x49\xf6\xf6\x58\x15\ -\xce\x78\x4e\xd5\x43\x08\xcd\x80\xd7\x4b\x3e\x4e\x2a\xdd\x17\x00\ -\xc5\xc5\xc3\x68\xee\x70\x77\x80\x7f\x03\x3f\x46\xa1\x23\x38\x35\ -\xdf\x8a\x8c\x2e\x41\x93\x3a\x15\x95\xb3\x37\xef\xdf\x18\xa6\x8d\ -\x9c\x5c\xe6\x83\x65\x3a\xf4\x47\xfb\x8e\x4c\x52\x91\x92\xd6\x1b\ -\x92\xd1\x7a\xd6\xd1\xb5\xfe\x8e\xe5\x72\x7d\x3b\xc1\xbe\xe3\x62\ -\xf8\x02\x4d\x5c\x53\xb6\x5a\xcb\x63\x2a\xcb\x6f\x27\x70\x57\x2f\ -\x89\x9b\xf9\xc0\x95\xdc\x46\xa0\x5d\x38\x35\x1c\xe4\x24\x9e\xe3\ -\x5a\xc2\x0d\x70\xd4\xc8\x74\x57\x48\x73\x9e\xa9\x33\xc1\x92\xb4\ -\x64\x64\x2b\x79\x09\x36\xce\xb2\x82\xd4\x35\x5b\xb2\x0c\x26\xbc\ -\xda\x14\xdb\x15\xab\x3e\x96\x14\x40\xf8\x58\xb3\x55\xf5\x51\x72\ -\x5e\x38\x1d\xe0\x66\x3f\xba\xdf\x70\x21\xed\x7d\xbe\x01\x20\xc3\ -\xe8\x2c\xf3\xd0\x31\xef\x80\x7b\x93\xd3\x65\xad\xa4\x9a\x5b\xa9\ -\x19\x5c\xab\xe1\x01\x17\x8c\x44\x89\xf8\x97\x20\x39\x03\xd7\x6c\ -\xe4\x1a\xc9\x31\x07\xc7\x6e\xd0\xea\x80\x56\x2d\xf9\xa6\x93\x85\ -\x8b\xca\x43\xa1\x6e\x07\x44\x3b\xe3\x05\x17\xe9\x75\x18\x2d\x97\ -\x61\x34\xd7\x24\x0e\xb6\x60\xf2\x90\xba\xf3\x49\xaf\xc3\x97\xcb\ -\x9a\x02\xee\x68\x40\xd3\xa8\x83\x06\xec\x15\x4d\xac\xd9\x85\xdd\ -\x7a\x29\x0f\x9f\x5b\xd0\x89\x62\x14\x7b\x6e\xe2\x4d\x3e\x7b\xc2\ -\x45\x06\x0e\x8d\xc6\x27\x44\x8e\x9f\xc4\x08\x27\x9e\x37\xbf\xbc\ -\xff\x99\xb5\x92\xb3\x6b\xc1\x3a\x6e\x10\xc6\xd1\xb9\x6b\xbb\xe7\ -\xaf\x9d\x98\x6d\x6f\x66\x63\xfc\x3f\x6f\xae\xce\x01\xe0\x3c\x05\ -\xcd\x60\x7d\x52\xec\xc8\xa1\x36\x9b\xe8\x58\x4c\xd7\x82\x42\xee\ -\xb8\x3e\x63\xd8\xcf\xd9\xdd\xeb\xcf\xba\x77\xe1\xe4\xc8\x41\xa1\ -\xd7\xab\x1c\x14\xad\x9f\xee\x3d\x98\x26\x4e\x82\xa3\x81\x88\x37\ -\x12\x59\xb5\x4b\x7f\xa8\x98\x84\x54\xb3\xad\xa9\x78\xa7\xc2\xf5\ -\xd7\xea\x43\x4d\x4f\xa4\xde\x0b\x52\xd5\x90\x1b\xca\xdb\x09\x84\ -\x8d\x60\xfb\x57\x90\x12\x90\x1f\x84\xbe\x8f\xfd\x29\x76\xa2\x10\ -\xbc\x39\xf4\xa7\xb6\xe7\x84\xd8\xf7\x23\x77\xaa\xf8\x21\x4a\x60\ -\x1c\x4d\x83\xd8\x89\xc3\x18\x27\xd1\xd4\xc6\x89\x13\x25\x38\x48\ -\xa2\xd7\x2d\xc8\x37\x33\x15\x0c\x7a\x64\x42\x55\xc5\x69\xfe\xc0\ -\xe8\xae\x8f\x98\x05\x31\xa7\xda\x90\x15\xd5\x26\x07\x14\x97\xfa\ -\x6b\x19\x0b\x2e\x72\x2a\x3a\x56\xa8\xbf\x11\xab\xf5\x8a\xa6\x16\ -\x5d\x8d\x8d\xa6\x56\x35\x7c\x74\x9e\x5f\xaf\x49\xce\x77\xb7\x13\ -\xef\x98\xf9\x89\x73\x40\x26\x70\x82\x24\x4e\x90\x7b\xcc\xcd\xf6\ -\xb7\x13\xdb\x47\x2a\xb5\x05\x01\x3e\xe1\x1e\x14\xd7\x41\x41\x88\ -\x11\x4a\x4e\xb8\x5b\x21\x00\x7f\xbb\x20\x07\x0a\xb7\xd2\xbf\xba\ -\x0d\xea\x35\xdf\xad\x84\x42\x47\x8a\x2d\x3d\xd6\x54\x1c\x7b\xb1\ -\xe0\xfb\xf3\x6c\x48\x87\x5b\x55\x07\xed\x6d\xe3\x00\x9b\xfd\x70\ -\xd5\x2d\xcb\x69\x7d\x5e\x71\xc7\x2a\x00\xc1\x6e\xf3\xb8\x8b\x0d\ -\xc6\xc7\x12\x5d\x52\x8f\x50\x7c\x41\x62\xdf\x67\x9e\x63\xd6\xe1\ -\x32\xab\x24\x7b\x56\xb2\x4f\x34\xef\x03\xd8\x88\xd4\x15\xd9\xd8\ -\xab\x82\x2f\x48\xd1\x9e\xbe\x0d\xd9\x11\x2c\x9d\x77\xcb\x83\xaa\ -\x60\xfb\x83\xa2\x8d\xa2\x4f\x11\x70\x14\xf6\xd1\xc2\x05\x83\xc2\ -\xb0\x1f\x66\xca\x86\x74\x18\x92\x54\xbd\x83\xe6\x66\xaf\x1d\x4c\ -\xbb\x5f\x74\xcc\x3b\x0c\x79\x5d\x04\x9c\x3a\xbe\xa6\x97\x54\x92\ -\x9c\x48\xd2\x47\x41\x47\xf1\x92\x04\x75\x37\x83\x46\x23\xfd\xed\ -\xcd\x4f\x26\x4f\x66\x59\xfa\x5f\x2e\xee\xfb\xcc\xa6\x04\xc8\x82\ -\x6f\xc1\x14\xa6\x76\xa8\x8a\x94\xa5\x2a\xa0\x89\xbc\x63\x25\xf8\ -\xb6\xea\x2a\xfe\x09\xc5\x1d\xe2\xd1\x30\x46\xc2\x0a\xac\x7e\xd1\ -\x66\x59\x41\x9b\xae\xe1\x6c\xa3\x95\x67\x25\x53\x4a\xb3\x77\x92\ -\x15\xc5\x2f\x6a\x93\x41\x3e\x6f\x17\x65\xb2\xa0\x83\x24\x3f\x6b\ -\x4f\xdf\xa5\xdf\xc1\xe5\x6e\x66\xdd\xed\xf5\x6c\xd5\xa3\x32\x0a\ -\x0a\x63\xe8\x82\x2c\x28\x38\xc1\x5b\xc5\xb4\x4e\xb8\x2b\xc1\xb7\ -\x9b\x92\xe7\xb4\x55\x37\x68\x42\xe2\x36\x26\x6b\x6a\xcc\x12\x4e\ -\x9f\xb6\x99\x66\xae\x26\x83\x5a\xaa\xa7\x62\x5b\x40\xd5\x7f\xa0\ -\x15\xcf\x73\x28\x3f\x82\xdf\xd3\xf4\x1a\x21\x3f\xd6\xd5\x48\x4d\ -\x9b\x68\x49\xcd\x54\x65\x77\x38\x46\x5a\xff\x6f\x4b\x04\x1d\x52\ -\xff\xe0\xac\x4a\x01\x37\x2a\x3a\xaa\x9e\x14\xe0\xf1\x32\xf5\x3b\ -\x5a\x4e\x20\x15\x09\x41\x0e\x69\x05\x9d\xf3\x90\xda\x94\xb6\x7e\ -\xa7\x41\x21\x6c\xbf\x91\xa3\xab\xeb\xe2\x24\xe9\x8b\xcb\xd9\xf6\ -\x4c\x7d\xe7\x5b\x34\xf5\x8d\xa2\x02\xfc\x3b\x71\xfc\x08\x27\x08\ -\x87\xd4\x76\x43\xc3\x10\x23\x31\x01\x72\xd8\xc1\xd0\xa6\x41\xe1\ -\xe8\xcb\xed\x86\xc8\xf5\x11\xfa\x6d\x71\x47\xfa\x9b\x2f\x39\x64\ -\x2c\xcd\x81\x9b\x83\x8f\x16\x0d\xe5\x81\x08\x46\x2a\x39\xa2\xed\ -\xf4\x81\x47\x24\xc0\x84\xca\x6c\x3d\xa6\x41\x26\x49\x21\xea\xd8\ -\xb6\x9c\x2b\x03\xb4\x69\x6b\x24\xb3\x24\x25\x2b\x0e\xe9\x3b\xa8\ -\x81\x73\xbb\x73\x21\xbb\x51\xdf\xd0\xcc\xb4\x8f\x8d\x84\xa4\x7b\ -\x09\x52\x39\x24\x57\xb0\x83\x9e\x91\x02\x7a\xc9\x14\xde\x3a\x42\ -\x36\x84\x1c\x2a\x98\x68\x74\xb4\x05\x8f\x88\xda\x15\x1a\x4e\x41\ -\x25\xd8\xdf\x6e\xd3\x47\x77\xac\x1d\xd4\xb3\x63\x9a\x5e\x43\x76\ -\x85\xba\xd1\xde\x09\x26\x41\xc4\x56\x9e\x9e\x16\xc2\x96\x8b\x79\ -\xce\x94\xd1\xd5\xce\x85\x14\x73\x55\x57\xf5\xb5\xeb\x35\x5b\xca\ -\xb4\x9b\xb6\xc7\xae\xb2\x35\x80\xdf\x9c\x3b\x67\xf5\x06\x42\x05\ -\x5a\x7f\x2d\xc0\xa1\xe7\x5e\x16\x7c\x97\x3e\xb0\x9a\x2d\x0a\x3a\ -\xd7\xbf\x59\xa1\x9c\xad\x23\xe9\xc8\x81\x8c\xf0\xea\xa4\xdb\xf1\ -\xdc\xd7\x97\x43\x09\x4e\xfe\x09\x8a\x75\x17\x4a\x43\x17\x6f\xe2\ -\x08\xba\x9f\xc0\xc3\x11\xc6\xae\x3f\x2f\x89\xb8\xa7\xa2\x11\xa2\ -\x15\x81\x6d\xed\x05\xc9\xee\x55\x7c\x57\x79\x4a\x32\xa8\x72\xdb\ -\x02\xde\x92\xc6\xf5\xc0\xeb\xff\x6d\xe1\xa8\x8d\x07\xd5\xb1\x60\ -\x3f\x8c\xa0\x79\xb1\xa0\xf1\x0c\x50\x84\x63\x45\xc5\x8e\x67\xa1\ -\x29\x38\x3b\xf2\xa2\x00\xbb\x16\x0e\x9d\x38\xf6\xa0\x6f\x51\xb4\ -\x38\x46\x51\xe0\x5b\xbf\x8f\x42\x49\xf9\x2e\x86\x96\xa8\x27\xf6\ -\xfd\x60\x05\xe1\x2e\xb9\xb0\xa1\x9a\x3f\x10\xb9\x15\x54\xc5\xc2\ -\xe7\xbc\x5e\x23\x37\xb8\xb8\x09\x80\x11\x0e\x5e\x13\x8a\xd0\x70\ -\x1d\x27\x96\xc5\x56\xca\xaf\x95\x56\x8c\x89\xc6\x10\xa2\x29\xb2\ -\xfe\x63\x75\xe9\x00\x9f\x60\x01\x35\x2a\x7c\x34\x16\xe6\xfa\xa6\ -\x12\x82\xc3\xaa\xe2\x01\x4d\x48\x96\x7d\xef\x50\x19\x90\xa6\x66\ -\x64\xfd\x6c\xa1\x73\x90\xc5\x2f\x07\x32\xd7\x01\x0b\x22\x2f\x88\ -\x37\xfb\x2f\xc7\xec\x02\x12\xa6\xf7\x99\x7a\xf0\x26\xb0\x7e\xb4\ -\x20\xce\x9a\xe1\xc9\xe0\x34\xb8\xa2\xc8\xb3\xd1\xb7\x0d\x2f\x17\ -\xe2\xdc\x0d\x82\xaf\x86\x40\x69\x05\x5d\x21\x9e\xe2\x00\x72\x4c\ -\x06\x71\x04\xdd\xbf\xa7\x41\xb9\x34\x3e\x85\x22\xf6\x9f\x0f\x88\ -\x98\x9e\x7a\x42\x6b\x35\xef\x59\x5c\xc1\xc5\xf0\x3c\xd4\x77\x6e\ -\x2f\xac\x68\x1e\xb8\x02\xe4\xf9\x76\x6a\x18\x96\x1b\x4e\x55\x6e\ -\x2e\x0c\x90\xd3\xc4\x09\xbb\x89\x3f\xed\xe2\xdc\x8a\x1c\x5f\x6b\ -\x4c\x0d\xa0\xb1\x13\x34\x32\xa0\x7f\x82\xa8\x8f\x70\xf4\x0d\x11\ -\x05\xd3\xeb\x53\x25\xf8\x5b\xa4\xa3\x33\xcd\xdf\x0b\x35\x81\x8d\ -\xbf\x38\xff\x19\x39\xd3\xfa\xd8\x19\xf4\x18\xd0\x33\xe9\x77\xd8\ -\x99\x1a\x74\x22\xa8\x5e\xe0\xc7\xaf\xb2\x17\x97\x38\x7a\x4b\x3c\ -\x31\x71\xd8\x8f\xaf\x31\x2f\x14\x0a\xcf\xed\x1c\xef\xa9\x50\x24\ -\xdf\x3d\x14\xe1\xd7\xf2\x8a\xef\xbe\xb2\x62\xef\xc9\x18\x3c\x3e\ -\xfb\xbc\x50\x0c\x54\x6a\x7e\x22\x06\x8f\x6f\xda\x5f\x62\x8b\x59\ -\x0e\x5b\x4c\xdc\x14\xa0\x08\xe0\xe8\x8a\x12\x86\x57\xcb\x85\xf1\ -\x85\x86\xd3\xf6\xfe\x36\x80\xb8\x71\x57\x9a\x9f\x04\x88\xfb\x5d\ -\x03\x32\x6a\x7b\x3c\xf3\x08\xd1\xc3\x93\xc1\x25\x08\xbe\x65\xa2\ -\x78\x5e\x9f\xe8\x9a\xb4\x27\x06\x89\xff\xb7\x01\xc4\x5c\xf6\x69\ -\x80\x3c\x57\x67\xb1\x5c\x22\xec\x2e\x5e\xde\x6b\x62\x08\x21\x46\ -\x4e\xd2\x40\xa8\xe2\xc8\xb4\xd6\xd6\xdb\x41\x13\x6b\x7a\x38\x55\ -\xb3\x3c\xd4\x95\xa7\xa3\x47\xc5\xdb\x61\x83\xa3\x9e\x1c\x7f\xea\ -\x4d\xf1\x05\x35\xed\x85\xbc\x2a\xc0\xca\x08\x91\x67\x7f\x85\xbf\ -\x64\xa3\x7d\xc5\x2a\x73\x4d\xc8\x20\x8b\x9c\x4f\x2a\xbe\x13\xb8\ -\x61\x14\x24\x7f\xc5\xdf\x07\x03\xdf\x01\x24\x92\xae\x5b\xf9\xd9\ -\x0a\x13\xe7\x28\xc2\xfa\xec\x12\x3f\xbe\x1f\x79\xd4\x9f\x08\x6f\ -\x66\xab\xbb\xab\x1b\xf5\xef\xbf\xbb\xab\xff\x03\xff\xe0\x07\xdf\ -\ -\x00\x00\x06\xfa\ -\x00\ -\x00\x20\xf8\x78\x9c\xdd\x59\x59\x8f\xdb\x36\x10\x7e\xdf\x5f\xa1\ -\x2a\x2f\x09\x6a\x49\x3c\x74\xc7\xde\x3e\x24\x48\x13\xa0\x45\x81\ -\x36\x69\x1f\x03\x5a\xe2\xda\x6a\x74\xb8\x94\xb4\xb6\xf3\xeb\x3b\ -\xd4\x41\x49\xb6\x0c\x6c\xe0\x6c\xba\xa9\x16\x0b\x93\x33\xc3\x63\ -\xbe\xb9\x48\x69\xf9\xd3\x21\x4b\xb5\x7b\x2e\xca\xa4\xc8\x57\x3a\ -\x36\x91\xae\xf1\x3c\x2a\xe2\x24\xdf\xac\xf4\x0f\xef\xdf\x18\xbe\ -\xae\x95\x15\xcb\x63\x96\x16\x39\x5f\xe9\x79\xa1\xff\x74\x7b\xb3\ -\xfc\xc1\x30\xb4\x57\x82\xb3\x8a\xc7\xda\x3e\xa9\xb6\xda\xbb\xfc\ -\x53\x19\xb1\x1d\xd7\x9e\x6f\xab\x6a\x17\x5a\xd6\x7e\xbf\x37\x93\ -\x8e\x68\x16\x62\x63\xbd\xd0\x0c\xe3\xf6\xe6\x66\x59\xde\x6f\x6e\ -\x34\x4d\x83\x75\xf3\x32\x8c\xa3\x95\xde\x0d\xd8\xd5\x22\x6d\x04\ -\xe3\xc8\xe2\x29\xcf\x78\x5e\x95\x16\x36\xb1\xa5\x0f\xe2\xd1\x20\ -\x1e\xc9\xd5\x93\x7b\x1e\x15\x59\x56\xe4\x65\x33\x32\x2f\x9f\x8d\ -\x84\x45\x7c\xa7\xa4\xe5\x6e\xf6\xb4\x11\xc2\x41\x10\x58\x88\x58\ -\x84\x18\x20\x61\x94\xc7\xbc\x62\x07\x63\x3a\x14\xf6\x38\x37\x94\ -\x20\x84\x2c\xe0\x0d\x92\x0f\x93\x0a\x0f\x29\x40\x71\x71\x33\x0d\ -\x77\xbc\x3a\xc0\xbf\x83\x7f\x35\xa0\x27\x98\x65\x51\x8b\x88\xdf\ -\xc1\x48\x6e\xe6\xbc\xb2\x5e\xbf\x7f\xad\x98\x06\x32\xe3\x2a\x1e\ -\x4d\xd3\xa3\x3f\x59\x77\x62\x92\x9c\x65\xbc\xdc\xb1\x88\x97\x56\ -\x4f\x6f\xc6\xef\x93\xb8\xda\xae\x74\x6a\x9b\x98\xc2\xe3\x34\xc4\ -\x2d\x4f\x36\xdb\xea\x94\x9a\xc4\x2b\x1d\x74\x25\x81\xdf\xf6\x47\ -\xae\x84\x5b\x81\x6e\xe2\x50\x71\x90\x19\x10\x13\x6b\x02\x3b\xd4\ -\x6b\x65\x7a\x15\xc2\xb8\x88\xe4\x9e\x60\x4a\x9e\x25\xac\xae\x8a\ -\x0c\x6c\x1c\x45\x29\x2b\xcb\xe4\x2e\x89\xa0\x53\xe4\xbb\xb4\xde\ -\x24\xf9\xc7\x24\xdb\x15\xa2\xfa\x58\xee\x78\x54\x09\x96\x7e\x4c\ -\x93\xb5\x60\xe2\x68\xf6\xc0\xab\x75\xf9\x41\x0a\x1a\x87\x78\x07\ -\x80\xba\xde\x2c\xf3\xd8\x33\x6f\x81\xbb\x8c\xf9\x5d\x29\xa5\x5a\ -\xed\x64\x0f\xd4\x6b\x79\xc0\x05\x63\x71\x26\x7e\x16\x2c\x4e\xc0\ -\x45\x5b\xb9\xd1\x8c\x51\x91\xa6\xb0\xa5\x95\xce\xd2\x3d\x3b\x96\ -\xba\x12\x80\xa9\xa6\x43\x9d\x00\xd4\xbf\xed\xf8\xcb\xb2\x2a\x76\ -\xbd\x2c\x20\x52\x1d\x53\x09\x03\x10\x0d\x98\xb1\x10\xe1\x33\xf0\ -\x2a\xe4\xa3\x97\x0d\xa9\x00\xa3\x25\xd5\x31\xc4\x2f\xf5\x61\x4c\ -\x71\x77\x57\x72\x58\x18\x8d\x68\x8d\x79\x60\x04\xac\x45\x75\xcd\ -\xba\x6e\x35\x34\xb7\x1a\x9e\x5f\xcd\x51\xab\x2d\xad\xa9\xda\xd7\ -\xc1\xd8\xc4\x4a\xb8\x15\x1c\x62\xfb\xd9\x0c\x9e\x97\xe1\xa6\x88\ -\x78\x8a\xbd\xe9\x88\x1f\xf2\xa4\x82\x20\xae\x4b\x2e\xfe\x90\x81\ -\xf0\x5b\xfe\xa1\xe4\x67\x52\xef\x05\xcb\x4b\x88\xba\x6c\xa5\x83\ -\x43\x8a\xe4\xf0\x1c\x7c\xd8\xa7\xbe\x83\x49\xb0\x40\xf2\x6f\xe8\ -\x62\xd3\xa3\x01\x26\xc4\x5b\x40\x40\xfa\x01\xc6\xc8\xc6\xf8\xc5\ -\xb0\x7f\x0c\x90\x39\xaa\x7b\x84\x2e\x21\x03\x97\xac\x74\x7b\x60\ -\x42\x8f\xa2\x0e\xc8\xa5\x25\x1d\xb1\x69\xa9\x70\x91\xb1\x12\xdf\ -\x27\x7c\x3f\x78\xeb\x9a\xa9\xfd\xef\xd8\x86\x37\xd6\x04\xa4\xee\ -\x9a\xa7\x63\xac\x0b\x11\x73\xd1\xb3\xdc\xe6\x99\xb0\x3a\x83\xb7\ -\xf5\xe0\x66\x6a\x18\x39\xab\xe2\xa3\x79\x7e\xb9\x65\x71\xb1\x07\ -\xcd\x4e\x99\x9f\x8b\x02\x30\x74\x4c\x27\xf0\x03\x84\x4f\xb9\xd1\ -\x61\xa5\x1b\x0e\x31\x1d\x3f\x70\x6d\xf7\x8c\x0b\xeb\x51\x62\x12\ -\x70\xcb\xe0\x9c\x59\x0b\x01\x86\x32\x52\x76\xe4\xa0\x54\xf3\xd3\ -\xcf\x5f\x6e\x8b\xfd\x46\x48\x70\x2a\x51\xf3\xd3\x91\x92\x63\xac\ -\xd7\xc5\x61\x9e\x0d\x19\xa9\x96\xa5\xc8\xa8\x5b\x4f\xd9\x1d\xc6\ -\xb3\xd6\x49\xcc\xcb\xf9\x81\xfb\x24\x07\x0c\x8c\x2e\x95\x62\xea\ -\x9e\xed\xb9\x93\xe8\xf3\xaa\x87\xfc\x0b\x12\x87\x21\xa6\x4f\x59\ -\xc7\xcb\xac\x8c\x1d\x92\x2c\xf9\xcc\xe3\x21\x46\x95\x48\x99\xb3\ -\x9d\xb1\x49\x8b\x35\x4b\xbb\xdd\x77\x51\x39\x81\xa5\xf7\xc3\xea\ -\x28\x8b\xc8\xe1\x28\x69\x93\x00\x93\x04\xea\xb9\x83\x3b\x17\x22\ -\x81\xdc\x7c\x18\xe7\xa0\x96\x74\x1c\x93\x64\xc9\x81\xf3\xc5\xa1\ -\xf1\xaf\xc6\xfb\xbc\x53\xde\x71\xcc\xeb\x03\xe0\xdc\xef\x1b\x7a\ -\xc6\x2b\x16\xb3\x8a\x0d\x41\xd0\x53\x48\x10\xa0\x5e\x33\xa8\xf5\ -\xe1\xef\xaf\xdf\xa8\x0c\x18\x45\xe1\x5f\x85\xf8\x34\x24\x2f\x29\ -\xc0\xd6\x45\x0d\xa6\x50\x59\x59\x16\x83\x28\x94\x91\xcf\xaa\xdb\ -\x24\x03\xd7\x96\x85\xfd\x47\xa8\xaf\x10\x8e\x8a\x31\x11\x96\x60\ -\x0d\x93\xb6\xd3\x0a\xde\x16\xee\xd9\xb3\x4e\x1c\x65\x89\x1c\x64\ -\xfd\x51\x25\x69\xfa\x4e\x2e\x32\xca\xd4\xdd\xa4\x49\x95\xf2\x51\ -\xfa\xb6\xba\xdd\xf7\x19\x76\xa4\xdc\xd2\xea\xb5\x6f\x7a\x9b\x01\ -\x95\x49\x50\x28\x43\xa7\x6c\xcd\xc1\x09\x7e\x91\x4c\xed\x8c\xbb\ -\x11\x45\xbd\xcb\x8a\x98\x77\xc3\x15\x9a\x90\x9b\x95\xc9\xda\xea\ -\x71\x07\xbb\x0f\xbb\x44\xf3\x52\x76\x46\x55\xaa\xe9\x8a\x3a\x85\ -\x82\x7b\xcf\xf3\x22\x8e\xa1\xb0\x88\xe2\x13\x97\x75\xc6\xf6\x11\ -\xea\xba\x6d\xb4\x84\xaa\x2b\x13\x38\x6c\x23\x2c\xff\xa9\x99\xe0\ -\x63\xea\xdf\x45\x92\x87\x80\x1b\x17\x3d\xb5\xe9\xa4\xe0\xf1\x55\ -\x68\xf7\xb4\x98\x41\x26\x12\x82\x1d\xc3\x1c\x0e\xaf\x63\x6a\x5b\ -\xbd\x86\x95\x54\x89\x33\x69\xf7\x4c\x1c\x5d\xaa\x4b\x83\x60\x28\ -\x2f\xb3\x27\x24\xf9\xcc\x9f\x92\xe4\x33\x89\x0a\xf0\xef\xc0\xb4\ -\xa1\x52\x20\xea\x72\x03\xbb\x8a\x21\x26\x62\x42\xe6\x3c\x93\xc2\ -\x49\xc9\x0d\xfc\xa1\xa2\xee\x58\xb5\x9d\x43\x7f\xa4\x65\x5b\xc1\ -\x4f\x91\x25\xed\xa6\xa8\x6d\x9f\x42\xbc\xae\xab\xea\x6b\x01\xac\ -\xec\xae\xf4\x00\x08\x7f\xd5\xa0\x4c\x6a\x7f\x6a\x3d\x30\x53\x80\ -\xa5\x46\x10\xad\x03\x0e\xa3\x83\x40\x0e\x3b\xac\x0a\x61\x40\x8e\ -\xbf\x67\x55\x2d\xf8\x24\x97\xa8\x9c\x00\x4e\x2a\xc3\x08\xd2\x71\ -\x14\x7d\xef\x50\x29\x90\x16\xaa\xa5\xbd\xd5\xd0\x1c\x64\xfe\xd3\ -\x81\x0c\x9b\x60\x41\x44\x1c\x7f\x77\xf8\x72\xcc\x2e\x20\xa1\xaa\ -\xc0\x82\xf8\xa6\xaf\xbd\xd2\xa8\x49\xda\xe6\x59\xe3\x0c\x1d\xea\ -\x79\xc4\x40\x0f\xc6\xe7\xab\xf8\x0c\xf6\x1c\x1b\x3b\xce\x57\x43\ -\x20\xd3\x9c\x3e\x25\x2d\xa8\x63\x12\x2d\x82\x38\x32\x6c\x93\x34\ -\xa0\x5c\x6a\x9f\x43\xe1\xdb\x8f\x07\x84\xcf\xcf\x3d\xa1\xb3\x1a\ -\x79\x14\x57\xc0\xd4\xf4\x5b\x9d\x3b\x85\x25\x8d\x80\x2b\x60\x64\ -\x76\x5d\xc5\xd0\xb0\xbb\x00\x0f\xd1\x52\x05\xe4\x22\x30\xdd\xbe\ -\x63\x2f\xfa\x38\xd7\x3c\xd3\x6e\x46\x2c\x14\xa0\xbe\xe9\xb4\x32\ -\x30\xfe\x0c\x51\x1b\x51\xef\x1b\x22\x0a\xa6\x6f\x76\x15\xd0\x6f\ -\x91\x8e\x66\xca\xe0\x13\x35\x81\x41\xbf\x38\xff\x29\xb9\xaa\xbf\ -\xd6\x19\x11\x9c\xf0\xb9\x30\x9a\x13\xe9\x4c\x0d\x3a\x13\x84\xb2\ -\x6c\x9c\x9e\x4f\x9f\x5c\xe2\x18\x2c\x71\x65\xe2\x30\x1e\x5e\x63\ -\x9e\x28\x14\x04\xf7\x8e\x77\x2d\x14\xc1\x77\x0f\x85\xfb\xb5\xbc\ -\xe2\xbb\xaf\xac\x94\x5c\x8d\xc1\xc3\xb3\xcf\x13\xc5\x40\xa6\xe6\ -\x2b\x31\x78\xf8\xa1\xfd\x29\x1e\x31\xb3\xf1\x11\x93\xb6\x05\xc8\ -\x03\x38\xfa\xa2\x44\xe1\xd6\x72\xa1\x7d\xe1\xc0\x69\x90\xff\x0d\ -\x20\xd8\xef\x4b\xf3\x55\x80\xe0\xef\x1a\x90\xc9\xb1\x87\xa8\x4b\ -\x48\xd3\x3c\x6b\x5c\x82\xe0\x5b\x26\x8a\xc7\xf5\x89\xfe\x90\x76\ -\x65\x90\xd8\xff\x1b\x40\x94\xb2\xd7\x01\xf2\x58\x27\x8b\xee\x8d\ -\xdc\x04\x10\xdb\x74\xb0\xeb\x39\xc1\x7f\xf1\x6e\x43\x46\xc9\x28\ -\xd3\xbe\xd5\x48\xd0\x5d\x25\x66\x90\xf1\x1f\x9e\x4b\xaf\x7d\xbd\ -\x51\x8b\xf4\xf9\xc9\x17\x25\xf9\xc9\xe8\xc5\x43\xdf\x65\x9e\x5d\ -\x7d\x4f\xfc\xc5\x36\x29\x54\x6f\x97\x2e\xe0\xe6\x80\xa9\x07\x52\ -\xb2\xea\xca\x6b\x04\xf2\x3c\xdf\x01\x27\x81\xb6\x8f\x69\xe0\xb9\ -\x0b\x64\xfa\xc8\xc5\x01\xc2\xce\x88\xd8\x35\x1c\xed\x4f\x6d\xb8\ -\x7d\xbd\x85\x6b\x94\xeb\xd9\x0e\xf1\xbc\x76\xb6\xc0\xf5\x3c\xd8\ -\x36\x4c\x07\xe7\x7f\x9f\x10\xea\x3a\x74\x01\x8b\x7b\x8e\xe7\xc9\ -\xab\xd8\x1c\x31\xd5\xba\x0f\x58\xa4\xff\x92\x45\x7a\x8a\xfc\x8a\ -\xd5\x51\xa2\xe6\x0d\x1e\x98\xcf\x0b\x10\x02\xbf\x37\xce\x67\xa5\ -\x63\x22\x58\x96\x98\x36\xec\x16\xee\x21\x9e\x1b\x20\xdf\x6f\x4f\ -\x19\x9d\xc6\xb6\x0f\xca\x75\x8a\xe2\x85\xa1\xb4\x53\xad\x11\xed\ -\xf3\xd9\xdb\x58\x87\xda\x5f\x7a\x2b\x59\x5a\x9b\xdb\x9b\xa5\x7c\ -\x81\x7f\x7b\xf3\x2f\x9c\x31\x79\xe2\ -\x00\x00\x16\x48\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x70\x72\x6f\x6a\x65\ -\x63\x74\x5f\x72\x61\x73\x74\x65\x72\x5f\x62\x61\x6e\x64\x73\x2e\ -\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ -\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\ -\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\ -\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\ -\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x6c\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\ -\x32\x37\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\x3d\ -\x22\x31\x31\x2e\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x32\x3d\x22\x33\x2e\x31\x38\x31\x38\x31\x38\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\ -\x36\x33\x36\x33\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ -\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ -\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\ -\x2e\x33\x39\x31\x32\x33\x39\x35\x35\x2c\x30\x2c\x30\x2c\x30\x2e\ -\x33\x37\x30\x34\x39\x39\x31\x32\x2c\x38\x2e\x35\x38\x36\x36\x32\ -\x34\x36\x2c\x37\x2e\x30\x34\x34\x31\x31\x32\x31\x29\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ -\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x36\x30\x32\x33\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ -\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\ -\x30\x66\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ -\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ -\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\ -\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ -\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ -\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ -\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ -\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x39\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x78\x3d\x22\x2d\x38\x33\x2e\x39\x38\x35\x39\x33\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ -\x22\x33\x31\x2e\x30\x39\x38\x32\x39\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ -\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ -\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ -\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ -\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ -\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ -\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ -\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\ -\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\ -\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\ -\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ -\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ -\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ -\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ -\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ -\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ -\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ -\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ -\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ -\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ -\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ -\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\ -\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\ -\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x34\x35\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ -\x22\x6d\x61\x74\x72\x69\x78\x28\x33\x2e\x38\x31\x37\x34\x31\x34\ -\x33\x2c\x30\x2c\x30\x2c\x34\x2e\x32\x36\x34\x37\x34\x30\x32\x2c\ -\x2d\x39\x2e\x36\x38\x32\x32\x32\x34\x33\x2c\x2d\x32\x33\x2e\x30\ -\x33\x32\x32\x36\x38\x29\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ -\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x35\x39\x38\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x29\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x38\x30\x37\ -\x32\x38\x31\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x63\x78\x3d\x22\x36\x2e\x36\x33\x30\x34\x32\x37\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x39\x2e\x32\x36\ -\x37\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x33\x2e\x39\x31\x32\x33\x39\x35\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x30\x34\ -\x39\x39\x31\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ -\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x30\x2e\x31\x30\x39\x30\x31\x35\x36\x38\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x34\x36\x37\x34\x31\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\ -\x39\x2e\x32\x36\x37\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x34\x36\x37\x31\x34\x38\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ -\x2e\x35\x34\x33\x39\x30\x34\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x30\x2e\x31\x36\x32\x35\x31\x30\x39\x39\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x36\ -\x33\x30\x34\x32\x37\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x63\x79\x3d\x22\x39\x2e\x32\x36\x37\x31\x30\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x33\x2e\x32\x36\ -\x30\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x33\x2e\x35\x34\x33\x39\x30\x34\x38\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x30\x2e\x31\x31\x32\x36\x37\x32\x33\x32\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\ -\x30\x30\x36\x30\x31\x31\x34\x35\x2c\x30\x2e\x39\x39\x39\x39\x38\ -\x31\x39\x33\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x39\x2e\x32\x36\ -\x37\x32\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\ -\x79\x3d\x22\x2d\x36\x2e\x36\x35\x36\x32\x35\x34\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x34\x34\ -\x39\x38\x32\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x33\x2e\x38\x33\x30\x38\x35\x38\x39\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x37\x37\x31\x63\x38\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x35\ -\x39\x34\x36\x39\x36\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ -\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x36\x2e\ -\x39\x38\x32\x39\x35\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x2e\x38\x31\x32\x38\x37\x33\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x31\x2e\ -\x34\x38\x38\x36\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x35\x33\x2e\x33\x30\x31\x39\x37\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x33\x30\x36\x38\x39\x37\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\x2e\ -\x31\x39\x34\x35\x35\x38\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x2d\x30\x2e\x32\x37\x38\x30\x37\x30\x32\x2c\x2d\x30\x2e\ -\x39\x36\x30\x35\x36\x30\x37\x36\x2c\x30\x2e\x36\x30\x36\x31\x35\ -\x31\x39\x37\x2c\x30\x2e\x37\x39\x35\x33\x34\x38\x38\x35\x2c\x30\ -\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\ -\x33\x36\x30\x36\x32\x37\x32\x36\x2c\x2d\x30\x2e\x39\x33\x32\x37\ -\x31\x30\x30\x32\x2c\x30\x2e\x37\x36\x38\x36\x36\x30\x37\x34\x2c\ -\x30\x2e\x36\x33\x39\x36\x35\x36\x36\x38\x2c\x30\x2c\x30\x29\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x30\x39\ -\x36\x36\x33\x32\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\ -\x3d\x22\x31\x2e\x39\x37\x30\x34\x38\x33\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x3d\x22\x32\x33\x2e\x38\x35\x35\x31\x31\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x2e\x34\ -\x36\x34\x39\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x38\x2e\x32\x39\x33\x37\x34\x33\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x31\x30\x2e\x35\x32\x38\x36\x30\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x32\x31\x34\x34\x37\x38\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x38\x36\x37\x30\x37\x39\ -\x36\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x31\x31\x32\x62\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x30\ -\x33\x34\x34\x37\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ -\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\ -\x2e\x37\x32\x36\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x2e\x38\x35\x39\x38\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\x39\x2e\x34\ -\x36\x32\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x37\x2e\x30\x33\x31\x36\x36\x35\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x39\ -\x38\x36\x34\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\ -\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\ -\x2d\x30\x2e\x33\x38\x33\x35\x32\x31\x35\x36\x2c\x2d\x30\x2e\x39\ -\x32\x33\x35\x33\x31\x39\x32\x2c\x30\x2e\x38\x33\x34\x30\x31\x39\ -\x39\x31\x2c\x30\x2e\x35\x35\x31\x37\x33\x34\x33\x35\x2c\x30\x2c\ -\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ -\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\x33\x38\x33\ -\x35\x32\x31\x35\x36\x2c\x2d\x30\x2e\x39\x32\x33\x35\x33\x31\x39\ -\x32\x2c\x30\x2e\x38\x35\x32\x37\x30\x37\x33\x31\x2c\x30\x2e\x35\ -\x32\x32\x33\x38\x38\x39\x37\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x39\x35\x33\x36\ -\x32\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ -\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x2d\x36\x2e\x31\x36\x31\x34\x39\x38\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x33\x31\x2e\x35\x35\ -\x31\x33\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ -\x67\x68\x74\x3d\x22\x31\x31\x2e\x31\x32\x37\x32\x34\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\ -\x2e\x37\x32\x36\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x30\x2e\x39\x37\x38\x37\x37\x39\x34\x39\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ -\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x06\x60\ -\x00\ -\x00\x4e\xb7\x78\x9c\xe5\x5c\x5b\x8f\xa3\x36\x14\x7e\x9f\x5f\x41\ -\x99\x97\x5d\xb5\x36\xd7\x24\xc0\x26\xd9\x87\x8e\x56\x5a\xa9\x4f\ -\xed\x56\x7d\x5c\x11\x70\x12\x34\x80\x11\x90\x49\xb2\xbf\xbe\xc7\ -\xe6\x92\x90\x30\x52\x2b\x1b\x89\x2c\x8c\x46\x33\xf8\x1c\x83\xfd\ -\xf9\x3b\xf6\xb9\x64\x66\xf9\xf9\x94\xc4\xca\x1b\xc9\x8b\x88\xa6\ -\x2b\xd5\xc0\xba\xaa\x90\x34\xa0\x61\x94\xee\x56\xea\xdf\xdf\xbe\ -\x20\x47\x55\x8a\xd2\x4f\x43\x3f\xa6\x29\x59\xa9\x29\x55\x3f\xaf\ -\x9f\x96\xbf\x20\xa4\xfc\x9e\x13\xbf\x24\xa1\x72\x8c\xca\xbd\xf2\ -\x35\x7d\x2d\x02\x3f\x23\xca\x87\x7d\x59\x66\x9e\xa6\x1d\x8f\x47\ -\x1c\xd5\x8d\x98\xe6\x3b\xed\xa3\x82\xd0\xfa\xe9\x69\x59\xbc\xed\ -\x9e\x14\x45\x81\xf7\xa6\x85\x17\x06\x2b\xb5\xee\x90\x1d\xf2\x98\ -\x2b\x86\x81\x46\x62\x92\x90\xb4\x2c\x34\x03\x1b\x9a\x7a\x51\x0f\ -\x2e\xea\x01\x7b\x7b\xf4\x46\x02\x9a\x24\x34\x2d\x78\xcf\xb4\x78\ -\xbe\x52\xce\xc3\x6d\xab\xcd\x46\x73\xb4\xb8\x92\xe1\xba\xae\xa6\ -\x9b\x9a\x69\x22\xd0\x40\xc5\x39\x2d\xfd\x13\xea\x76\x85\x31\xf6\ -\x75\x35\x75\x5d\xd7\x40\x76\xd1\xfc\x6f\x5a\x5e\x01\x80\x66\xf0\ -\xdd\xaa\x37\x0d\xb8\xa0\x87\x3c\x20\x5b\xe8\x47\x70\x4a\x4a\xed\ -\xe5\xdb\x4b\x2b\x44\x3a\x0e\xcb\xf0\xea\x31\x0d\x9e\x9d\xb7\x76\ -\x40\x4e\xfd\x84\x14\x99\x1f\x90\x42\x6b\xda\x79\xff\x63\x14\x96\ -\xfb\x95\x6a\xd9\xd8\xb0\xe0\x9a\xf1\xc6\x3d\x89\x76\xfb\xf2\xb6\ -\x35\x0a\x57\x2a\x8c\xde\x74\x9d\xea\xfe\x8a\x1c\x46\xa5\x50\x3f\ -\xd8\x6b\x25\x3a\x76\x4d\x6c\x2b\x1f\x66\xa1\x3f\x77\xdc\xc0\x32\ -\xac\xdf\x14\x53\x37\x5c\xa4\x1b\xc8\xb0\x3f\xf2\x5e\xcd\xa4\xbc\ -\x90\x06\x6c\x94\xf0\x12\x92\x44\xfe\xa1\xa4\x09\xac\x63\x10\xc4\ -\x7e\x51\x44\xdb\x28\x80\x1b\x9a\x66\xf1\x61\x17\xa5\xdf\x53\x36\ -\xc0\x0d\xcd\xbf\x67\xd1\x89\xc4\x05\x6e\x40\x6d\x47\x40\x4e\x19\ -\xcd\x4b\x74\x0a\x33\x80\x76\xbe\xe8\x15\x9e\x1b\xe1\x1a\xa4\xcb\ -\x90\x6c\x0b\xa6\x55\xcd\x93\xdd\xc1\x44\x17\xaa\xa2\x71\x69\x3b\ -\x48\x36\xc2\xf0\x2d\x22\xc7\x8b\xee\xc6\x2f\x2a\x2c\x15\x25\xf3\ -\x77\xc0\xbb\x98\xe6\x2b\xf5\x79\xcb\xaf\x5a\x00\x63\x0d\x49\xde\ -\x88\xe6\xfc\xea\x88\x28\xac\x4d\x54\x9e\x2b\x4b\xab\x9f\xdd\x8c\ -\x97\x3d\xb5\x95\xeb\xfd\xf2\x62\xef\x87\xf4\xb8\x52\xcd\x5b\xe1\ -\x0f\x4a\x93\x95\x3a\xc3\x33\xd7\x71\x75\xe3\x56\x1a\x9c\x56\x2a\ -\x2c\xb2\x6e\x3a\xa6\xeb\xde\x09\xd9\x70\x0c\xec\xd8\xf6\xdc\xb5\ -\xef\x84\x87\x3c\x07\x4b\x44\xb1\x7f\x26\x30\x27\xfe\xa3\x79\x7c\ -\xb1\xa7\xc7\x5d\xce\xb0\x29\xf3\x03\xb9\xed\xc9\x24\x68\xb3\xa1\ -\xa7\x7e\x31\xd0\xe0\xc0\x6c\x1c\x1d\xd2\xa8\x04\x3b\xca\x4e\xd7\ -\x4f\x3d\x44\x21\x29\xfa\x3b\x16\xa9\x9f\xa1\x5d\x4c\x37\x7e\xdc\ -\xaf\x70\x8c\x52\xc0\x08\xd5\x94\x37\xac\x76\x09\x6e\x35\x1a\xfe\ -\x2f\xf4\xc5\x3b\x1a\x30\xf6\xbb\x65\xa8\x45\xe7\xf7\x45\x89\x7f\ -\x8a\x92\xe8\x07\x01\x60\x0c\xce\x3a\x60\x56\x07\x96\xaa\x9b\xa2\ -\x94\x67\x66\xcb\xa7\x33\x6b\x53\x9b\x46\x86\x27\x6b\x80\x95\x5a\ -\xb4\x8d\x34\x8f\xc0\x20\xae\x86\xd3\x34\x9d\xaf\x9b\x98\xe5\xc3\ -\xc6\x7d\xe2\xf4\xe2\xe4\x5b\xdc\xca\xce\xd7\xb2\x9a\xf5\xda\x3d\ -\xed\x79\x7b\x42\x4a\x3f\xf4\x4b\xff\x62\x03\x4d\x0b\x8c\x4d\x6f\ -\x66\x06\x9b\xa8\xf7\xe7\xcb\x97\x75\xfd\xa2\x65\x10\x78\xff\xd0\ -\xfc\xb5\x79\xaf\xa2\x30\x05\x7f\x43\x0f\x80\xb4\xba\x6e\x9b\x97\ -\x61\xe0\xc1\xb6\x07\xc6\xbf\x8e\x12\x60\x36\xdb\x31\x7f\x85\x6d\ -\x6e\xa9\x5d\x04\x1d\x65\x06\xd6\xe5\xa1\xd5\x63\x73\x52\xed\x9f\ -\xbd\x87\x48\x18\x24\x11\xeb\xa4\xfd\x55\x46\x71\xfc\x95\xbd\xa4\ -\x9e\xf1\xd5\x43\xa3\x32\x26\x6b\xfe\xce\xea\xd7\x66\x16\x5a\x3d\ -\x8d\x7a\x92\xda\xd5\x2c\x97\x5a\x03\x03\xbf\xdb\x5d\xe0\xe9\x58\ -\x47\xbb\xe2\xb1\xbf\x21\x40\xd5\x3f\x98\x50\xb9\x93\xee\x72\x7a\ -\xc8\x12\x1a\x92\xba\x7b\x0b\x2b\x09\xca\x76\xed\xca\x73\x0c\xf2\ -\x2d\x4c\xc3\x7b\x76\x74\xf6\xf5\x89\xdd\xa0\x7a\xbb\xf0\x8c\xea\ -\x36\x3f\xc4\xb0\xed\xbd\x91\x94\x86\xe1\xa7\xa2\xcc\xe9\x2b\xf1\ -\x9e\x75\x7e\xd5\xb7\x95\x55\x78\x3a\xb6\x2d\xd7\x66\x24\x68\xda\ -\x01\x2a\x92\xc7\x40\xdb\xd2\xb3\x9b\xb6\xd0\x87\xed\x26\xcf\xfd\ -\xb3\x97\xc2\xd9\xdf\xb4\xb6\xef\xec\x30\x96\x0d\x77\xe6\x58\x2e\ -\x32\xc0\x63\x68\x04\xb5\x09\xce\xb0\x65\x5d\xce\x17\x76\x35\x96\ -\x67\x63\x97\x4b\xec\x56\xc2\xb8\xab\xe3\x1b\xee\x02\x69\x2d\xec\ -\x74\xb6\x53\x58\xff\x8e\x35\xe4\x9c\xd8\x73\x9b\x5d\xf3\x76\x99\ -\xdf\x47\x71\x63\xb1\xaf\x31\xa3\x88\x8c\x21\x70\x44\xf7\x3b\x83\ -\x18\x90\xd5\x90\x46\x0d\xa4\x3b\x04\x90\x86\x85\x17\x5d\xcd\x9f\ -\x1e\x47\x03\xcd\x86\x40\xd2\xc1\x0e\x9f\x8b\x39\x1d\x24\x17\x43\ -\xe0\x68\x5a\x58\xd6\xee\xf8\x00\x10\x02\x19\x07\x61\xa3\xe1\xe0\ -\xa9\x1d\x34\xee\x30\x7c\xb4\x2c\x6c\xcb\x3c\x69\xc6\xef\xf8\x30\ -\x52\x22\x7d\x10\xdb\x76\xf0\x8c\xab\x4e\x82\x95\x82\x08\xea\x1d\ -\x16\x4a\x76\x1c\xc7\xce\x42\x41\xec\xee\xd5\xa7\xe8\x7c\xdb\x43\ -\xa0\x28\xdd\xf5\x1e\x39\x8c\xa2\x71\x60\xc7\x8c\x65\xbb\xdb\x63\ -\x37\x63\xe4\x88\xc2\xd7\xcb\x41\xd9\x30\x8e\x9c\x82\xba\xb0\x25\ -\x77\x48\x28\x3b\x52\x19\x3d\x09\x6d\x64\x0e\xc1\x42\xd9\x38\x8e\ -\x9d\x85\x96\x4c\x12\x4a\x0c\xf3\x46\xcf\xbf\xf9\x10\xec\x93\x08\ -\xe0\xd8\x89\x27\x1c\xd8\x75\xcf\x60\xc9\xa1\xf1\xe8\xe9\x67\x0f\ -\x43\xc0\xe9\xa5\x18\xc4\x93\xd9\xfd\x71\x89\xe4\x0c\xc3\xc8\x81\ -\x04\x6f\x46\x18\xc7\xee\x51\x22\x39\xab\xf0\x00\x06\x6d\x0a\x6f\ -\x89\xfd\x67\xca\xa4\xf2\x33\x15\x13\xe5\xfa\xd6\x53\xb4\x65\x61\ -\xef\xba\x83\xa0\xf4\xfc\xc2\xe8\xcd\xd9\x41\xb6\x28\x07\xcd\xf9\ -\xed\x59\xcc\xf3\x5d\x0b\x6b\x42\xd6\x5c\x65\xae\x45\xf7\xc5\x5e\ -\x24\x81\x93\x93\x09\x96\x59\x21\x45\x34\xf9\xdf\x0b\xa2\x31\xa1\ -\x88\xaf\xaa\xa1\x88\x56\xf6\x7a\x61\x74\x6e\xeb\x2a\x3f\x3d\x94\ -\x0b\xe1\x03\xa6\x17\x48\x73\x92\x85\xbd\x19\xd2\x45\xa3\xc1\x7e\ -\xeb\x9e\x96\xeb\x58\x17\x9c\x87\x61\x26\x38\x91\x5c\x73\x42\x67\ -\x0e\x2f\x39\x0b\xbb\xe2\xfd\x76\xee\xe0\x89\x94\x5b\x84\x3f\xff\ -\x30\xa8\xfb\x38\x72\xf0\xc4\xc3\x18\xd3\xc0\x37\x8d\x53\x74\xc2\ -\x6d\x64\x8a\xd6\xfc\x7a\x81\x94\xe8\x83\xd7\x98\x8c\x15\x43\x07\ -\x89\x56\x5a\x8c\xa1\x1c\xef\x6a\x14\xa3\x45\x8e\xe7\x68\x45\xc1\ -\xeb\x65\xdf\x74\x30\xe4\x29\x1d\x5b\xf8\xd3\xef\x43\xc6\x2c\x23\ -\x47\xb0\x4a\xd0\x0e\xb2\x09\x4e\x0b\x48\xdd\x92\xec\xd2\xc8\x0e\ -\xf9\x46\x8e\x9f\x81\xe6\xe2\x39\x88\x3e\x1a\xca\xc6\x71\xe4\x07\ -\xb2\x0e\x81\x9e\xdc\x0d\x51\x76\xb4\x3c\x7a\x22\xda\x40\x45\x4b\ -\xb4\xea\xd7\x7f\x32\x4f\x2e\xf1\xc0\xa2\x65\x57\x38\x45\xdb\x1b\ -\xac\x4c\x2b\xf1\x50\x55\xaf\x1c\xb9\xde\xf6\x74\xd2\x0d\x75\x21\ -\x5a\xb8\x98\xdf\x7f\xc4\xc8\x83\x71\xe4\x16\x5d\x57\xa1\xc5\xff\ -\x2a\x6d\xd0\x1c\xe2\x43\x80\x68\x22\x57\x34\xb9\x6d\x0c\x55\xf8\ -\x1b\x39\x80\x55\x19\x5a\x38\x07\x76\xc5\xb7\x29\x26\xbf\x78\x05\ -\x5a\xf8\xe3\x76\x5d\x10\xa7\xc5\x41\x66\xca\xa2\xbe\x76\x17\x3f\ -\x89\xa9\x9b\x07\xc0\x8f\xd7\x9d\x85\x8f\xe4\x2e\x82\x92\xb3\x0e\ -\x0f\x80\xe2\x42\xc2\x27\xec\xba\x18\xca\x0e\x99\x1f\x00\xc4\xba\ -\xda\x2c\xf9\x4c\x99\x5e\xbc\x57\x15\x9a\x85\xf3\xda\x37\x47\xf3\ -\xb4\xfc\xc3\xab\x1a\xb3\x70\x95\xf9\xc6\xb0\xff\x5f\xa0\xb2\xd4\ -\x76\xeb\xa7\x25\xfb\x37\x41\xeb\xa7\x7f\x01\x0e\x6d\x5f\xf1\ -\x00\x00\x0a\xa6\ -\x00\ -\x00\x2c\xbd\x78\x9c\xed\x5a\xdb\x6e\xe3\x46\x12\x7d\xf7\x57\x70\ -\xe5\x97\x19\xac\x48\xf5\xfd\xa2\xb1\x9d\x87\x0d\x12\x04\x48\xb0\ -\xc0\x66\x06\xfb\x18\x50\x64\x4b\xe6\x0e\x45\x0a\x24\x65\x49\xf3\ -\xf5\x5b\xdd\x22\x29\x52\xa2\x6c\xd9\x56\x80\x9d\x60\xa5\x0c\x66\ -\xd8\xdd\xec\xcb\xa9\x53\x55\xa7\x5a\xb9\xfb\x61\xbb\x4c\xbd\x27\ -\x53\x94\x49\x9e\xdd\x8f\x70\x80\x46\x9e\xc9\xa2\x3c\x4e\xb2\xc5\ -\xfd\xe8\xcb\xe7\x9f\x7c\x35\xf2\xca\x2a\xcc\xe2\x30\xcd\x33\x73\ -\x3f\xca\xf2\xd1\x0f\x0f\x37\x77\x7f\xf3\x7d\xef\x1f\x85\x09\x2b\ -\x13\x7b\x9b\xa4\x7a\xf4\x7e\xc9\xbe\x96\x51\xb8\x32\xde\x87\xc7\ -\xaa\x5a\x4d\x27\x93\xcd\x66\x13\x24\x75\x63\x90\x17\x8b\xc9\x47\ -\xcf\xf7\x1f\x6e\x6e\xee\xca\xa7\xc5\x8d\xe7\x79\xb0\x6e\x56\x4e\ -\xf3\x72\x76\x3f\xea\xbc\x91\xaf\x4c\x56\x6e\xc2\x2a\x7a\x9c\xe5\ -\xf9\x57\xf7\xde\xba\x48\x26\x04\x21\x3d\x81\xb1\xa3\xc3\x9b\x71\ -\xd4\xbe\xb8\x5a\x17\xa9\x1b\x1a\x47\x13\x93\x9a\xa5\xc9\xaa\x72\ -\x82\x03\x3c\xe9\x0c\x8f\x0e\xc3\x23\xbb\xef\xe4\xc9\x44\xf9\x72\ -\x99\x67\xa5\x7b\x33\x2b\x6f\x3b\x83\x8b\x78\xde\xdb\xd5\x86\xba\ -\x41\x58\x6b\x3d\x41\x64\x42\x88\x0f\x23\xfc\x72\x97\x55\xe1\xd6\ -\xef\xbf\x0a\xa7\x1b\x7a\x15\x0e\x80\x26\xd0\x77\x18\x79\xd9\xa8\ -\xe9\x36\x05\x10\xcf\x6e\xc6\xf5\x76\x57\x07\xc3\xad\xe0\x4f\xfb\ -\x42\xd3\x10\x94\xf9\xba\x88\xcc\x1c\xde\x34\x41\x66\xaa\xc9\x8f\ -\x9f\x7f\x6c\x3b\x7d\x14\xc4\x55\xdc\x99\xa6\xb1\x5b\x6f\xdd\x9e\ -\x31\xb3\x70\x69\xca\x55\x18\x99\x72\xd2\xb4\xbb\xf7\x37\x49\x5c\ -\x3d\xde\x8f\x28\x0b\x30\x85\x0f\x77\x8d\x8f\x26\x59\x3c\x56\xc7\ -\xad\x49\x7c\x3f\x82\xb3\x12\xad\xa5\x7b\xee\x90\x10\xef\x07\xd4\ -\x13\x4f\xdb\x1e\x14\x68\x12\x60\xaf\xc0\x9c\xca\xfd\x98\xe6\x08\ -\xd3\x38\x8f\xec\x9e\x60\x4a\xb3\x4c\xc2\x75\x95\x2f\xc1\xc6\x51\ -\x94\x86\x65\x99\xcc\x93\x08\x1e\xf2\x6c\x95\xae\x17\x49\xf6\x47\ -\x0a\x6c\x2e\xc3\x4a\xfd\x51\xe5\x79\x1a\x34\x70\xb7\xab\x99\xed\ -\x2a\x2f\x2a\x7f\x1b\xaf\x00\x46\x21\x07\x3b\x77\x4d\xe7\x03\xf4\ -\xde\xb5\x9b\xb0\x3b\x88\x9f\x12\xb3\xb1\xef\xec\x4f\x38\x0b\xcb\ -\x3d\x32\x9e\xb7\x0a\x17\xc0\xb9\x34\x2f\xee\x47\xb7\x73\xf7\xa9\ -\x3b\x66\x79\x11\x9b\xa2\xe9\x12\xee\xd3\xeb\xca\x01\xe9\xa4\xda\ -\xed\xfd\xb3\x9e\xbb\xd9\x91\x9d\xb5\xed\x47\xc3\xfd\xe5\x63\x18\ -\xe7\x9b\xfb\x11\x39\xee\xfc\x96\xe7\xcb\xfb\x91\x0c\x34\x56\x88\ -\x61\x79\xdc\x1d\x6d\xef\x47\x3e\x56\x01\xc2\x0c\x73\x71\xd2\x0b\ -\x0b\x12\x19\x50\x84\x88\xa4\x27\x9d\xeb\xa2\x00\x3f\xf4\xd3\x70\ -\x67\xe0\x54\xee\x2f\x5c\x0f\x2a\x1f\xf3\xcd\xa2\xb0\xe8\x54\xc5\ -\xda\x1c\xbf\x69\x7b\xfc\xd9\x2c\xdf\x0e\x77\x83\xa1\xd7\xd6\xc3\ -\xfd\x75\x96\x54\xe0\x45\xab\x6d\x77\xd6\x75\x12\x9b\x72\xf8\xc5\ -\x32\x0b\x57\xfe\x22\xcd\x67\x61\x3a\x3c\x60\x93\x64\x80\x92\x5f\ -\x53\x18\x53\x71\x72\xe2\x7a\x44\xc3\x67\x89\xd4\x99\x11\xb0\xf7\ -\x13\x43\xd4\x5d\xbb\xf3\x5d\xcb\x70\x9b\x2c\x93\x6f\x06\x80\xc1\ -\x8e\x59\xc0\xad\x1e\x2c\xfb\xd7\xf6\xc4\xb2\xcf\x00\x3d\x1f\x35\ -\x8d\xd5\xce\x3a\xec\x76\x67\x3b\xda\xc6\xbc\x48\x80\xf2\x9d\xed\ -\x34\x4d\xbb\x6e\x93\xf5\x64\x08\xf8\x5b\x47\x30\x47\x3f\x79\xdc\ -\xb7\xeb\xf6\x79\x13\xc7\xfb\xc9\x29\xf1\x5d\x7b\x6c\xe6\xe5\xc1\ -\x03\xec\x13\x38\xb9\x6e\x4e\x04\x21\xcb\x84\xc5\xcf\x45\x18\x27\ -\x60\xc6\xee\x91\xfa\x3d\x02\x31\x51\xbf\x63\x7d\xac\xca\x57\xcd\ -\xd8\x3a\x76\x40\x0b\x8c\x51\xa3\x43\x73\x3e\x9f\x97\xa6\xea\x9e\ -\x0c\xf6\x5f\xed\x52\xb3\x1f\xed\x3b\x17\x9b\xde\x4a\x61\xbf\x9f\ -\x5c\x53\xed\x3a\x53\xfc\xa9\x3e\xd5\xb3\xab\x71\x34\xb0\x1a\x7e\ -\x7e\x35\x4a\x18\x17\xea\xec\x6a\x77\x93\xfe\xb1\x5f\x89\x12\x57\ -\x75\x14\x1a\xd8\xf7\xc0\x66\xe2\x38\xd6\xb1\x3e\xd9\xcc\xf3\x10\ -\x36\xe7\x87\xb5\xf4\x79\x94\x06\x56\x13\x91\xfd\x5e\xb0\x1a\x1e\ -\x5c\x0d\x62\xfc\xd5\x50\xe2\xfa\x15\x28\xe9\x28\x0c\x11\x7a\x3b\ -\x4a\xf8\x55\x28\x69\x4c\x63\x3c\x7b\x33\x4a\x82\x5e\x0f\x25\x72\ -\x58\x02\xd4\x16\xe4\x8e\x24\x83\x75\xcb\x3c\x85\x90\x72\xf9\x81\ -\xe6\x02\x74\xcc\x11\x7c\x28\x90\x4a\x11\xca\xe9\x2b\x70\x24\x57\ -\x3c\x19\xe6\x57\x39\xd9\x7c\x26\x67\xf2\xcd\xc4\xc0\xf2\x6a\x07\ -\x92\xf8\x6c\x70\x1c\xd8\x37\x47\x92\x28\xf6\xd6\x7d\x4b\xac\x5e\ -\x0e\x8e\x1c\x56\x78\x7d\x70\xc4\x33\x1b\x22\x8e\xa9\xc2\xb4\x42\ -\x54\x13\xf2\x4c\x4c\x1e\x0a\xb4\x52\xc5\x2a\x3e\x9a\xeb\x62\x3f\ -\x92\x04\xbd\xd1\x38\xad\xe4\xc9\xd3\xd4\x44\x30\x7f\x98\x6e\xc2\ -\x5d\xd9\x2e\xe2\x44\xfa\xf4\xb1\x30\x50\x54\xdc\x0e\x98\xf1\x39\ -\x2b\x13\x72\x98\x06\xdf\x8f\x54\x40\x88\x52\x02\xe9\xb6\x75\x07\ -\xad\x58\x07\x5a\x68\x79\xc8\xd9\x5b\x02\xca\x8c\x05\xe0\x6d\x36\ -\x16\xb5\x43\xc9\xc0\xd0\x45\xbd\xd4\x97\xbd\x9a\x5a\x97\xa6\xf8\ -\xdd\xea\xfa\x7f\x66\x5f\x5a\xe1\x6a\x45\x00\xd4\x4c\xf1\x6f\xa6\ -\x7a\xcc\x61\x93\xab\x30\x3e\x79\xff\x73\x11\x66\x25\x94\x17\x20\ -\x27\x01\x8d\xd4\x7c\x68\xd5\xc2\xc7\x03\xac\xc3\x00\x0e\x4c\x01\ -\xe2\xbd\x48\xb6\x30\x07\x96\x1c\x11\x8e\xc7\x3e\x09\x28\xc6\x8a\ -\x70\xe3\xab\x31\x0e\x38\xa3\x9a\xd1\xfa\x01\x4b\x8d\xb0\xa4\x30\ -\x46\x05\x42\x49\xaa\xf9\x18\x74\x30\x63\x94\x6a\x4a\x3e\x3e\x7f\ -\xfc\x33\x48\x0d\x82\x3a\x88\xff\xcb\xc8\x3c\x8f\xec\x90\xd1\x15\ -\xb9\x84\x3b\x4e\x1f\xbd\x48\xc2\x17\xb0\x7f\x17\x79\x6d\x52\x7d\ -\x56\x99\xf0\x1e\x78\x18\x07\x12\x33\xd1\x91\xac\x16\x67\x30\x15\ -\xe6\x18\x21\xa6\x45\xcf\x2a\x14\x07\x0a\x2a\x0b\x44\x7b\x06\x1c\ -\x1a\x7d\x19\xd0\xe7\x59\x06\xa9\x09\x49\x09\x7c\xb1\xbc\x91\x10\ -\x7a\x18\xd3\xc0\x26\x28\x36\x91\x26\x92\x11\x0d\xcd\x9c\x83\x64\ -\xc4\x5a\x8d\xd1\x18\x75\x08\x6d\xe7\x0c\xd3\xeb\x82\xda\xd1\xde\ -\x16\xd4\xfe\x12\x20\x8a\x0e\x80\xd8\xf2\xac\x13\x20\x6c\x3d\x06\ -\xc5\xda\x01\xde\x79\xbf\x7f\x7e\xdc\x5f\xd8\xd2\x0f\x69\xf7\xb9\ -\x08\x27\x85\x35\x92\x02\x49\x8b\x02\x80\x22\x18\xc1\xe0\xe0\x80\ -\x15\x13\x01\x46\xe0\x9e\xe0\x8e\x24\x10\x1c\x53\xc5\x3e\x5e\x68\ -\x9f\x97\x08\x3a\xa4\x52\xa4\x8f\xfc\xb3\x7a\xae\xa3\x1f\xb4\x2f\ -\xfd\x6e\xb0\xbf\xb0\x3e\x98\x87\x18\x0f\xc8\xbf\x97\x53\xa0\xa2\ -\x18\x76\xf6\x86\x34\x38\x17\xf3\xf9\x89\x62\x7a\xb1\x46\xf8\x33\ -\xd8\x57\x63\x7b\x9e\x81\x54\xf1\xd7\x66\x8f\xf3\x94\xf2\x69\x40\ -\xa8\xfb\x8e\x49\xc0\x30\x65\x42\x59\xc7\x53\x18\x09\x48\xff\xce\ -\x07\x19\x57\x48\x72\x3d\x96\x2c\x10\x10\x3b\x88\x18\xfb\x2a\x50\ -\x8c\x81\x23\x74\x38\x66\x5d\x01\xf3\x0e\xb7\x9d\x33\x48\x70\x67\ -\xa6\xb4\xec\x79\x44\x6f\xd8\x7c\x70\x58\xb1\x77\x14\x41\x78\x5b\ -\xea\xda\x2a\xd6\xfd\x6b\x69\xaa\x30\x0e\xab\xf0\xa6\xc5\xa7\x69\ -\xb1\x17\x21\x4d\x91\x5b\xc4\xf3\xe9\xbf\x7e\xfc\xa9\x25\x4c\x14\ -\x4d\xff\x9d\x17\x5f\x0f\x24\xb0\x03\xc2\x59\xbe\x06\xf3\xb4\x44\ -\xb6\xa5\x73\x34\xb5\x00\x85\xd5\x43\xb2\x0c\x17\xc6\x5e\x06\xfe\ -\x7d\xbb\x4c\x61\xfd\xb6\xa3\x37\xd8\x16\xfd\x87\x49\xf7\xd3\x16\ -\x66\x7f\xd9\x37\x78\x3f\x1a\x47\xcb\xc4\xbe\x34\xf9\xbd\x4a\xd2\ -\xf4\x17\xbb\x48\x87\xd8\xf5\xa4\x49\x95\x9a\x0e\xdb\x27\xf5\xee\ -\x1b\x32\x76\x0e\x77\x37\x69\x4e\xef\x9e\x16\x37\x7d\x0a\x2e\x8a\ -\x7c\xbd\x5a\xe6\xb1\xa9\x6f\x80\x8e\x2f\x3e\xd2\x70\x66\xd2\xfb\ -\xd1\xaf\xb6\xcf\x6b\x7c\xc4\xb9\xfc\xfe\xbe\xa8\x5e\xd1\xa4\x69\ -\xb2\x2a\xdb\x83\xd6\x0e\x34\x87\x03\x4c\xe1\x68\x1f\x6e\x4f\x19\ -\xfa\xf1\x93\xed\xed\x78\xaf\x7b\x2c\xd6\xa9\x99\x9a\x27\x93\xe5\ -\xb1\xd5\x89\x45\xfe\xd5\x4c\x6f\x11\xaa\xab\x15\xfb\xb8\xbf\xfd\ -\x99\xb6\x8f\x00\x96\x29\xd2\x04\xfe\x9a\xb2\xa6\x2d\x0e\xcb\xc7\ -\xb0\x28\xc2\xdd\x34\xcb\x33\xd3\xb4\xb6\x4b\xf5\x7c\x67\x15\x56\ -\x8f\x42\x50\xd2\x27\x2a\xda\xdf\x83\xd2\x3e\x5b\x21\x3d\xda\x46\ -\x76\xa0\xa1\x8d\xdf\x9d\x47\x7b\xdf\x06\x6e\xd2\x49\x3f\xe0\xde\ -\x67\x41\x39\x55\x15\xef\x05\x25\xc0\x58\x4a\x84\xb5\xb8\x16\x3a\ -\x76\xff\x8c\x70\xe4\x1f\x92\x79\x73\xfb\xa6\x6c\xf6\x67\xe8\x00\ -\x5c\x73\xe9\x06\x12\x0c\x8a\x48\x82\x0e\xb8\xd4\x97\x94\x1a\x62\ -\x02\x3d\xc4\xde\x9d\x93\x70\x4c\x10\xd6\x91\x53\x16\x42\x1a\x70\ -\x2a\x11\xc7\xb2\x87\x73\x2b\x35\x0f\xf7\x69\x03\x09\x50\x80\x20\ -\x61\x58\xb8\xc8\x04\x4a\x81\x09\x26\x31\x24\x42\x05\x71\x09\x24\ -\x29\xb3\x42\x41\x13\xf8\x72\xbe\x17\x0a\x27\x31\xb9\x9d\xd4\x8f\ -\xc0\x28\xa6\xf0\xdd\xe6\x21\x7b\x6a\x8a\x35\xbe\x60\x3c\x1c\xc0\ -\x07\x12\x28\x29\x04\xc8\xbf\xb7\x31\x81\x5c\x81\x09\xb5\xb8\xbf\ -\x36\x13\x4e\x78\x20\xf7\x65\x84\x3a\xe1\x81\x04\xdb\xf6\x6f\x2a\ -\xb7\x96\x1c\x90\x19\xa0\x4e\xc0\x3d\x1a\x48\x08\xe5\x52\x72\x7e\ -\x44\x03\x72\x44\x80\xe3\x9b\xcf\x0e\x01\x8a\xbc\x0a\x2b\xf3\xc1\ -\x22\x2f\x00\x79\x4d\x3a\x1a\xd0\xba\xf8\xa5\xd0\x83\x24\x7e\x37\ -\xf4\x48\x09\x8d\x81\x84\xcf\x41\x7f\x0a\xb2\xcd\x53\x5e\x83\xa6\ -\x1c\x43\x08\xda\x9f\xd6\xd3\x81\xe8\x3c\x45\x1e\xb0\x99\x42\xc1\ -\x2f\x80\xcb\x9a\x22\x82\xb9\x07\x49\x1a\x31\xa9\x81\xe9\x96\x77\ -\x18\x44\x8e\xe7\xb3\x00\x71\xb0\x8a\x18\xd3\x40\x60\x02\x99\xd2\ -\x4b\x3d\x5b\xa3\x41\xd1\x85\x39\xd4\x64\x50\x4d\x4b\x3b\x9b\x0f\ -\xb0\x22\x78\x49\x5a\x69\xcd\xec\x2d\x84\x9d\x0e\x34\x35\x93\xac\ -\x59\x81\xd9\xe9\x88\xdb\xc0\x18\x79\xbf\x7a\x22\x60\xee\xe0\x30\ -\x8f\xa8\xa7\x70\x9b\x83\xcc\x0f\x5e\xaa\x38\xfc\x77\x68\x04\x57\ -\x04\x4b\xc2\xda\xc6\x97\xe3\x76\x1e\x0f\xbc\xcf\xdb\x37\x91\x3a\ -\xd6\x52\xaf\xe9\x94\xee\x15\xb7\xc4\xa1\x71\xdc\xce\x88\x3d\x1e\ -\x30\x36\x6e\xf8\x20\xec\x7e\xc6\x87\x59\xbe\x0d\xf0\x96\xf1\x53\ -\xcf\x8d\xf2\x2c\x83\xce\xbc\xf0\xa3\x75\xf1\x14\x56\xeb\xc2\xf4\ -\xae\xdc\xdb\xab\x73\xc8\x8e\x36\x21\x83\x7c\x2a\xdd\x27\xfa\xd6\ -\xa9\xda\x5e\x97\xf9\x6c\x75\xf0\x7e\xd7\x56\x36\xc8\xc9\xab\x05\ -\x79\xeb\x1f\x54\x13\xea\xd3\x67\x42\xab\x0f\x61\xd4\x06\x55\x02\ -\xd4\x26\x84\x39\x6e\x70\xc1\x21\xa6\x8b\x7e\x24\x75\x3f\x49\x41\ -\xa1\x8f\x14\x50\xb3\x9f\x40\xa1\x8e\x87\xcc\xc0\x44\x3f\xb0\x73\ -\x9b\x55\x39\x3d\xca\xa3\x0c\xa2\x07\xb2\x96\x7f\xd9\x8f\x3b\x27\ -\x3c\x07\x19\xdd\xb3\x89\x34\xed\xd6\xeb\x81\x04\xd3\xd9\xba\xaa\ -\xba\x6d\xff\xc9\x93\x6c\xea\xf0\xbc\x06\xb8\x80\xed\x6f\x8e\x9c\ -\x8d\x72\xa0\x1e\x16\x63\xa7\x10\x8e\xf1\xe7\x4a\x0f\xde\x15\x0c\ -\x52\xf4\x3b\x47\x04\x33\x08\x2b\xf6\x33\x06\x09\x5f\x3b\xad\xa3\ -\x86\x6b\x03\x4d\x40\x06\xe1\xe9\xd0\xf3\x62\x80\xce\x65\xdd\x5b\ -\x23\xec\xf7\xdd\x9e\x08\x9a\x80\x6a\x75\x55\xb9\xc5\x35\x3e\x15\ -\x5b\x10\xeb\x88\x02\xcf\x3b\x49\xb2\x1c\xc2\x3c\xd2\xe8\x38\xc9\ -\x4a\x29\x85\xea\xdc\x19\x58\xe7\xd3\x30\x87\x50\xf8\x38\xa9\x52\ -\xa9\x04\x66\xf4\x28\xf5\x4a\xa5\x20\xcc\x3c\xaf\xb5\xb4\xd0\x4a\ -\x51\xc8\x02\x36\x2c\x30\xca\x25\x46\x6a\x6c\x23\x04\x78\x38\xc2\ -\xdc\x45\x08\xce\xb5\x46\xf4\xf8\x52\xe6\xcf\xb5\x0a\x24\x36\x50\ -\x13\xfa\xaa\xd2\xc7\x5a\xc5\x67\xc7\x76\xe1\x81\x86\xac\xcb\xd0\ -\xa9\x5d\x20\x7f\x61\xcd\x75\xe7\x2e\xc8\x82\x0d\xe9\x99\x33\xde\ -\x19\x6e\xc5\xa2\xfd\xe1\x05\x34\x2b\xee\xfc\x50\x6a\x2d\x63\xd3\ -\xb1\x16\x20\xb9\xfa\xaa\xc8\x56\xe1\x0c\x80\x7f\x41\x06\x33\x09\ -\x12\xdc\x65\x70\x29\x08\xc4\x6b\x7b\x43\x6b\xff\x0d\x64\xb1\xb5\ -\xba\x1d\x41\x81\x4f\x56\x11\x5f\x2c\x83\xe1\x7d\x49\x21\xe0\xcb\ -\x0b\x86\x3b\x12\x31\x86\xa0\x42\xd7\x7f\x01\xc3\x77\x2e\x5c\xde\ -\x66\x7a\x02\x88\x43\xb4\xa0\x3d\xdd\x6b\xd5\x12\xe6\x9c\xfd\xdf\ -\xee\xef\xb4\xbb\x90\x9a\xf0\xeb\x86\x61\x81\xd0\x89\xcd\x29\x54\ -\x55\x10\x2c\x3b\x1d\x8d\xcd\x49\x40\x88\xa0\xa0\x86\x7a\xee\x4e\ -\x6d\x05\x84\x74\xaf\xe4\xb5\x3a\x55\x6b\x90\xc5\x47\x46\xa7\x94\ -\x01\xd5\x70\xbf\x12\xb6\x85\xab\xa2\x9a\x76\x28\x32\x64\x75\x78\ -\x91\x53\xcd\xf7\x85\xae\x20\x52\x20\x67\x75\x6a\xef\xff\xb1\x92\ -\x4e\xc6\x53\x06\x16\x7c\x9d\xd5\xb5\x64\x04\x13\x36\x90\x76\x07\ -\x8b\x5e\xd8\x07\x48\x3e\x2a\x09\xfe\xee\x0d\xdf\xb9\x93\x7e\x9b\ -\xe9\x41\xe3\x61\x70\x6d\xd1\x2f\x73\x03\x4e\x94\x50\x9d\x1f\x85\ -\xfe\xc7\x4d\x4f\x2f\xbd\xef\x68\x4c\x8f\xe4\xf7\x6f\x7a\xf2\x5e\ -\xaf\x97\x01\xd6\x12\x75\x7e\x5a\x73\x5e\x0f\x36\x66\xac\xf3\x7f\ -\x6f\xfc\x65\x4d\x7f\x37\x59\x3c\xdc\xdc\xd9\x7b\xf1\x87\x9b\xff\ -\x02\x19\x39\x4d\x45\ -\x00\x00\x05\x90\ -\x00\ -\x00\x1b\xc7\x78\x9c\xed\x58\xdb\x8e\x9b\x48\x10\x7d\x9f\xaf\x60\ -\xc9\x4b\xa2\x1d\xa0\xaf\xd0\xed\xd8\x8e\xb4\x1b\x45\x8a\xb4\x4f\ -\xbb\x59\xed\x63\x84\xa1\x6d\xa3\x00\x6d\x01\x1e\xdb\xf9\xfa\xad\ -\xe6\x66\x98\x61\x2e\x89\x93\x87\x48\x46\x33\xca\x74\x55\x75\x77\ -\xf5\xa9\x73\xaa\x21\xf3\x77\xc7\x2c\xb5\xee\x54\x51\x26\x3a\x5f\ -\xd8\xd8\x45\xb6\xa5\xf2\x48\xc7\x49\xbe\x59\xd8\xff\x7e\xfa\xe0\ -\x08\xdb\x2a\xab\x30\x8f\xc3\x54\xe7\x6a\x61\xe7\xda\x7e\xb7\xbc\ -\x99\xff\xe6\x38\xd6\x9f\x85\x0a\x2b\x15\x5b\x87\xa4\xda\x5a\x1f\ -\xf3\x2f\x65\x14\xee\x94\xf5\x7a\x5b\x55\xbb\x99\xe7\x1d\x0e\x07\ -\x37\x69\x8d\xae\x2e\x36\xde\x1b\xcb\x71\x96\x37\x37\xf3\xf2\x6e\ -\x73\x63\x59\x16\xec\x9b\x97\xb3\x38\x5a\xd8\xed\x84\xdd\xbe\x48\ -\xeb\xc0\x38\xf2\x54\xaa\x32\x95\x57\xa5\x87\x5d\xec\xd9\xe7\xf0\ -\xe8\x1c\x1e\x99\xdd\x93\x3b\x15\xe9\x2c\xd3\x79\x59\xcf\xcc\xcb\ -\x57\x83\xe0\x22\x5e\xf7\xd1\x26\x9b\x03\xad\x83\xb0\x94\xd2\x43\ -\xc4\x23\xc4\x81\x08\xa7\x3c\xe5\x55\x78\x74\xc6\x53\x21\xc7\xa9\ -\xa9\x04\x21\xe4\x81\xef\x1c\xf9\xb2\xa8\x59\x09\x80\xee\xe0\xb7\ -\x0f\xef\x0c\x6e\xa9\xf7\x45\xa4\xd6\x30\x4f\xb9\xb9\xaa\xbc\xf7\ -\x9f\xde\xf7\x4e\x07\xb9\x71\x15\x0f\x96\xe9\xf0\x1c\xed\x3a\x02\ -\x39\x0f\x33\x55\xee\xc2\x48\x95\x5e\x67\xaf\xe7\x1f\x92\xb8\xda\ -\x2e\x6c\xca\x5c\x4c\xe1\xe1\xb5\x71\xab\x92\xcd\xb6\xba\x6f\x4d\ -\xe2\x85\x0d\xd9\x13\x29\x9a\xf1\x80\x1c\xb8\x09\x68\x17\x9e\xf5\ -\x1e\xe4\x4a\xe2\x62\xab\xc0\x9c\x06\x4d\x4c\x77\x84\x59\xac\x23\ -\x93\x13\x2c\xa9\xb2\x24\xdc\x57\x3a\x83\xaa\x45\x51\x1a\x96\x65\ -\xb2\x4e\x22\x18\xe8\x7c\x97\xee\x37\x49\xfe\x39\xd3\x65\x98\x44\ -\x9f\x2b\xad\x53\xb7\x83\xaf\xdf\x4b\x1d\x77\xba\xa8\x9c\x63\xbc\ -\x03\x10\xfd\x60\xd2\x79\x1a\x3a\xef\x12\x75\xf8\x43\x1f\x21\x39\ -\x0b\x59\x94\xc0\x8f\xbd\x04\xfb\x3c\x56\xeb\xd2\xf8\x9b\x83\x9a\ -\x11\x9c\x34\xb0\x2d\xaf\xf6\xf6\x79\x9b\xa4\x63\xb3\xc6\x39\x76\ -\x15\x96\x0d\x98\x96\xb5\x0b\x37\x40\xbc\x54\x17\x0b\xfb\xd5\xba\ -\x7e\x5a\xc7\x4a\x17\xb1\x2a\x3a\x97\x5f\x3f\x23\x97\x86\xe2\x24\ -\xd5\xa9\x91\x5a\xbb\x76\x77\x0c\xb3\x6a\xef\x47\xd3\xfe\x72\x1b\ -\xc6\xfa\xb0\xb0\xc9\x7d\xe7\x57\xad\x33\x58\x15\x8a\x24\x03\x81\ -\x1e\xb8\x23\x40\xc2\xc1\xc8\xc5\x08\xf9\x3e\x7b\xe0\x35\x09\xf9\ -\x6e\x40\x19\x97\xfc\x81\x73\x5f\x14\x20\x46\x27\x0d\x4f\x0a\x4e\ -\x55\xff\x83\xdb\xa0\x72\xab\x0f\x9b\xc2\xa0\x53\x15\x7b\x75\x7f\ -\xa6\xf1\x38\xab\x95\xa9\xc2\x94\x1b\xb8\xb1\x37\x32\x77\xf6\x79\ -\x52\x81\x94\x76\xc7\xe1\xaa\xfb\x24\x56\xe5\xf4\xc4\x32\x0f\x77\ -\xce\x26\xd5\xab\x30\x9d\x0e\x38\x24\x39\xa0\xe4\xb4\xac\xc7\xb4\ -\x2f\xc2\xfd\x88\x4e\x02\x01\x12\x8f\x44\x18\x06\x3d\xe2\x3a\x3d\ -\xee\xca\xc2\x63\x92\x25\x5f\x15\x00\x83\x1f\xa0\x62\x4e\x36\x84\ -\x65\x59\x07\xcc\x47\xb0\x35\x73\x2c\xab\x3a\x19\xb9\x1f\x4f\xc6\ -\x66\x77\x46\x83\xb7\x31\x10\x29\x83\xde\xa8\x8b\x04\x54\x34\x48\ -\xb7\x33\x9d\x86\x26\xd3\x1c\xa0\xb7\x1f\xcf\x79\xf5\x36\xc3\x81\ -\x4e\x07\xde\x43\x21\xd4\xf6\x4c\x55\x61\x1c\x56\xe1\x59\x15\x9d\ -\x05\x72\x41\xdd\x49\xa0\xaf\xce\xfe\x7e\xff\x61\xd9\x6e\x30\x8f\ -\xa2\xd9\x7f\xba\xf8\xd2\xed\x67\x59\x26\x20\x5c\xe9\x3d\x20\x6f\ -\x2f\x7b\xf3\x3c\x8e\x66\xd0\x09\xa1\x43\x2c\x93\x0c\xb8\x6e\x9a\ -\xe8\xef\xd0\xf9\xe6\xde\xd9\x31\x0a\x36\xe0\x9c\x17\x6d\x96\x2d\ -\x54\xd3\x52\x27\xef\x95\x38\xca\x12\x33\xc9\xfb\xa7\x4a\xd2\xf4\ -\xa3\xd9\xa4\x3d\xf1\x60\xd1\xa4\x4a\xd5\xd9\x38\xf7\xda\xec\xdb\ -\xb3\x79\x83\xc3\xcd\xbd\xee\xf4\xf5\x68\x73\x46\x65\x24\x92\xbe\ -\xb0\x69\xb8\x52\xc0\xd8\xbf\x8c\xd3\x7a\xc8\x8b\x42\xef\x77\x99\ -\x8e\x55\x3b\xbd\x47\x53\x45\x55\x5f\xaa\xea\x94\x82\x7f\x0d\xd9\ -\xcf\x5e\x21\xc4\x79\xcc\xde\x9a\x81\xd3\xf6\x8d\x19\x6e\x86\xc5\ -\x3e\x85\xb6\x78\xa7\x72\x1d\xc7\x6f\xcb\xaa\xd0\x5f\x94\x89\x37\ -\x4f\x3b\x6c\xc4\x31\x83\x7e\x41\x7c\xe9\x0b\xcc\x3b\x3b\x20\xa4\ -\x8a\x14\xd8\x5b\xcd\x58\x67\x8b\x43\xe8\x3b\x45\x11\x9e\x66\x39\ -\xbc\x05\x74\xd6\x7e\xcf\x11\x31\x4d\xba\x40\x06\xda\x1b\x3b\x15\ -\x42\xc7\x13\x34\x90\xa2\x77\x74\xe2\x93\x2e\xe6\x52\x62\x4c\x7a\ -\xcf\xb1\xbe\x94\x90\xa4\x18\x9f\x09\x0e\xfc\xe4\xd0\x15\xb9\x4f\ -\xb8\xec\x8d\x85\x61\xb2\x4b\x09\x46\x94\x9f\xf3\x28\xea\x06\x4b\ -\x05\x97\xe8\x6c\xac\x8a\x30\x2f\x0d\x8d\x80\xb4\x61\x55\x24\xc7\ -\xd7\xb0\x1a\x65\x02\x21\x2a\x6f\xe1\xae\x85\xf7\x02\x2a\x19\x11\ -\xb7\xc8\x65\xc2\x27\x84\x0b\x1f\xfe\x14\x01\x15\x94\xe2\xe0\x16\ -\xdd\xa2\x37\xe7\x83\x3e\x75\x2f\x4d\x05\xf4\x77\x53\xc7\xac\x51\ -\x59\xbf\x21\x35\xee\x43\x72\x70\x32\x93\x1a\xe1\x58\x30\x4c\xc6\ -\xa9\x35\x67\x67\x01\xa3\x98\x06\xcf\xe0\x04\xa1\x24\x70\x03\x22\ -\x98\xc4\x43\xf0\x31\x71\x05\x27\x80\xc1\x44\xad\x02\xc6\xc0\x13\ -\x3c\x5f\xde\x8e\x0c\x34\x18\xe0\x72\x8f\xc0\x61\x08\x84\xbc\x90\ -\xc0\x88\x63\x2a\x69\x70\x11\x81\x27\xab\xf2\x0b\x89\xcd\xb9\x54\ -\x6e\x98\xbb\x12\xc2\x7d\x3a\xe4\x06\x93\xf0\x62\x27\xc5\xb4\xda\ -\xae\x62\x7b\x91\xd8\xee\x69\x4d\x0a\x41\x30\x1b\x22\xef\x70\x60\ -\x30\x1c\x9b\xb3\x1f\x25\x36\xc7\xbf\xca\xed\x27\xcb\x8d\x5f\x28\ -\x37\x60\x02\x61\xe6\xbb\x63\xa8\x36\xec\x06\x82\x8b\xa1\xb2\xae\ -\x72\xbb\x48\x6e\x60\xe4\xe6\x19\x22\x2f\x00\x00\x22\xc8\xe0\xbe\ -\xbb\x54\x6d\xf4\xaa\xb6\x9f\x7d\xb9\x0d\x3a\xda\xf7\xe9\x4d\xba\ -\x94\x49\x8e\xe5\x58\x70\xc4\xc5\x82\xa2\x60\x52\x70\x4c\x5e\x15\ -\xf7\x12\xc5\x0d\x70\x6a\x24\x47\x18\xe7\xfe\xf8\x86\x93\x00\x01\ -\x16\x1c\xf9\x3f\x4c\x73\xbe\x43\x7e\x7d\xd5\xad\xd7\xf5\xde\x17\ -\xe5\x5a\x57\x93\xf8\x98\xfc\x48\xd1\x01\xc4\xf2\xe5\x82\xc3\xc0\ -\x70\x44\x08\x1b\x09\xce\x01\x6d\x31\xe0\x1c\x1b\x7d\x6c\x48\xd7\ -\x27\x82\x0a\xc9\x26\x7b\xf7\xfd\xef\x37\x0e\x62\xf1\x7d\xfe\x3d\ -\x92\xf3\x29\xc2\x18\x9b\xbf\x82\xc0\xe7\x88\x31\xda\xd0\xfa\x17\ -\x2f\x8a\xf3\x02\x9d\x3c\x5d\x16\x2c\xe1\xb3\x9a\x71\x46\xc7\x65\ -\xe1\x44\x42\x01\xfc\xc9\xb2\x5c\xab\xf2\x5c\x55\xbe\xe1\x6d\x70\ -\xba\x2a\xf0\x0d\x4e\x7d\x86\x25\x19\x56\x85\xba\x9c\x06\x02\x07\ -\xcf\xbc\xe8\x5c\xab\xf2\x98\x56\x9c\xcb\x9b\x18\x75\x7d\x11\xc0\ -\xe5\x35\xae\x0b\xa3\x82\xf9\x83\xd0\xa7\x5e\x1b\x7e\x5a\x61\xe6\ -\xde\x66\x79\x33\x37\xff\x47\xba\xbc\xf9\x1f\xda\xce\x98\x81\ -\x00\x00\x0c\x42\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6d\x6f\x76\x65\x5f\ -\x64\x6f\x77\x6e\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ -\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ -\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ -\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ -\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x78\x3d\x22\x2d\x32\x31\x2e\x30\x31\x36\x36\x38\x35\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ -\x22\x31\x37\x2e\x31\x32\x36\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ -\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ -\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ -\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x64\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\ -\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\ -\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ -\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\ -\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\ -\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\ -\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\ -\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\ -\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\ -\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\ -\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\ -\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\ -\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\ -\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\ -\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\ -\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\ -\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\ -\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\ -\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\ -\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\ -\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\ -\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\ -\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\ -\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\ -\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\ -\x6c\x3a\x23\x30\x30\x30\x30\x32\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x33\x2e\x36\x32\x36\x36\x36\x36\x37\x38\x3b\x6d\ -\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\ -\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ -\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x64\x3d\x22\x6d\x20\x31\x38\x2e\x36\x38\x36\x36\x31\x32\x2c\x2d\ -\x31\x39\x2e\x32\x30\x33\x37\x37\x36\x20\x2d\x32\x2e\x36\x33\x33\ -\x35\x31\x39\x2c\x30\x2e\x30\x35\x30\x31\x39\x20\x2d\x30\x2e\x38\ -\x30\x34\x30\x38\x2c\x2d\x30\x2e\x30\x34\x32\x33\x31\x20\x30\x2e\ -\x30\x32\x33\x32\x39\x2c\x33\x32\x2e\x36\x37\x39\x34\x38\x32\x20\ -\x2d\x34\x2e\x31\x32\x35\x31\x31\x39\x2c\x30\x2e\x30\x30\x39\x35\ -\x20\x35\x2e\x39\x31\x39\x34\x38\x37\x2c\x31\x35\x2e\x33\x30\x36\ -\x39\x32\x39\x20\x35\x2e\x37\x36\x38\x33\x35\x2c\x2d\x31\x35\x2e\ -\x33\x33\x33\x37\x33\x37\x20\x2d\x34\x2e\x31\x32\x35\x31\x31\x39\ -\x2c\x30\x2e\x30\x30\x39\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x31\x33\x2d\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ -\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x0f\xa5\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x67\x62\x5f\x74\ -\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ -\x22\x2d\x31\x31\x2e\x35\x31\x30\x33\x33\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x37\ -\x2e\x30\x35\x35\x33\x31\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ -\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\ -\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\ -\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\ -\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x67\x75\x69\x64\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\x22\x33\x32\x2e\ -\x30\x30\x30\x30\x30\x31\x2c\x2d\x32\x2e\x31\x33\x33\x33\x33\x33\ -\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x65\x6e\x74\ -\x61\x74\x69\x6f\x6e\x3d\x22\x30\x2c\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x67\x75\x69\x64\x65\x34\x34\x39\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x6f\x63\x6b\x65\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\ -\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\ -\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\ -\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\ -\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\ -\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ -\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\ -\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\ -\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\ -\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\ -\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\ -\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\ -\x64\x34\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x32\x2e\x31\x38\x33\x37\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\ -\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x34\x2e\x35\x37\x31\x35\ -\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x31\ -\x2e\x32\x36\x39\x31\x34\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\ -\x37\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\ -\x2e\x30\x33\x34\x31\x36\x31\x36\x38\x2c\x2d\x30\x2e\x39\x39\x39\ -\x34\x31\x36\x33\x32\x2c\x30\x2e\x35\x36\x35\x33\x35\x36\x39\x31\ -\x2c\x30\x2e\x38\x32\x34\x38\x34\x36\x33\x39\x2c\x30\x2c\x30\x29\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ -\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\x30\x33\x34\ -\x31\x36\x31\x36\x38\x2c\x2d\x30\x2e\x39\x39\x39\x34\x31\x36\x33\ -\x32\x2c\x30\x2e\x36\x34\x30\x35\x32\x31\x39\x35\x2c\x30\x2e\x37\ -\x36\x37\x39\x33\x39\x38\x36\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x39\x31\x37\x31\ -\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ -\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x31\x38\x2e\x37\x32\x31\x38\x34\x34\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x35\x2e\x31\x37\x36\x33\ -\x35\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\ -\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\x31\x37\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\ -\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ -\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\x39\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\ -\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ -\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\x39\x2e\x38\x34\ -\x30\x35\x35\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x2d\x30\x2e\x34\x36\x31\x32\x31\x35\x34\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ -\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x2d\x30\x2e\x30\x33\x34\x31\x36\x31\x36\x38\x2c\x2d\x30\ -\x2e\x39\x39\x39\x34\x31\x36\x33\x32\x2c\x30\x2e\x37\x30\x31\x34\ -\x36\x35\x32\x36\x2c\x30\x2e\x37\x31\x32\x37\x30\x33\x36\x35\x2c\ -\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\ -\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\ -\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\ -\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ -\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\ -\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\ -\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\ -\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\ -\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\ -\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\ -\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\ -\x73\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\ -\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\ -\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x30\x2e\x32\x31\x35\x35\x37\x30\x32\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x3d\x22\x32\x31\x2e\x34\x35\x36\x35\x32\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\ -\x74\x33\x37\x36\x31\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\ -\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x30\x2e\x32\x31\x35\x35\x37\x30\x32\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x31\x2e\x34\x35\x36\x35\x32\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\ -\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x33\ -\x2e\x38\x36\x36\x36\x36\x36\x37\x39\x70\x78\x3b\x6c\x69\x6e\x65\ -\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\x32\x35\x3b\x66\x6f\x6e\ -\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\ -\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\ -\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\ -\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\x64\x27\x3b\x66\x69\x6c\ -\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x32\x22\x3e\x52\x47\x42\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\ -\x74\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0a\ -\x00\x00\x0d\x9a\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x69\x6d\x70\x6f\x72\x74\x2e\ -\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ -\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\ -\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x2d\x32\ -\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x38\ -\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ -\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x39\x37\x33\x2d\x34\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ -\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x38\ -\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ -\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ -\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x39\x37\x35\x2d\x32\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\ -\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\ -\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x32\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x32\x3d\x22\x34\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x31\x3d\x22\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x31\x3d\x22\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ -\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x31\x39\x37\x32\ -\x37\x33\x2c\x30\x2c\x30\x2c\x30\x2e\x39\x31\x39\x37\x32\x37\x33\ -\x2c\x32\x2e\x38\x37\x33\x39\x39\x38\x39\x2c\x32\x2e\x38\x30\x30\ -\x38\x35\x31\x33\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\ -\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\ -\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x33\x30\x31\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\ -\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x35\x39\ -\x37\x31\x2d\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ -\x6c\x77\x61\x79\x73\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x64\x65\ -\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ -\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x78\x3d\x22\x2d\x34\x32\x2e\x38\x39\x35\x39\x37\x38\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ -\x22\x31\x32\x2e\x39\x37\x39\x35\x39\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ -\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ -\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\ -\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ -\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ -\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ -\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\ -\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ -\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ -\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ -\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ -\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ -\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ -\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ -\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ -\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ -\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ -\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\ -\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\ -\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\ -\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x64\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ -\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\ -\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ -\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\ -\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x30\x31\x32\x29\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\ -\x30\x36\x36\x36\x36\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x6d\x20\x31\x34\x2e\x36\x38\x36\x37\x34\x37\x2c\ -\x32\x2e\x35\x37\x30\x39\x31\x39\x35\x20\x63\x20\x2d\x30\x2e\x39\ -\x34\x32\x31\x30\x33\x2c\x30\x20\x2d\x31\x2e\x36\x39\x35\x37\x34\ -\x38\x2c\x30\x2e\x37\x35\x33\x36\x34\x36\x36\x20\x2d\x31\x2e\x36\ -\x39\x35\x37\x34\x38\x2c\x31\x2e\x36\x39\x35\x37\x34\x37\x32\x20\ -\x56\x20\x31\x36\x2e\x35\x39\x36\x37\x35\x39\x20\x48\x20\x36\x2e\ -\x35\x35\x32\x39\x30\x37\x39\x20\x63\x20\x2d\x31\x2e\x38\x33\x39\ -\x34\x35\x34\x38\x2c\x30\x20\x31\x30\x2e\x31\x31\x37\x30\x30\x30\ -\x31\x2c\x31\x33\x2e\x37\x39\x35\x39\x31\x31\x20\x31\x30\x2e\x31\ -\x31\x37\x30\x30\x30\x31\x2c\x31\x33\x2e\x37\x39\x35\x39\x31\x31\ -\x20\x6c\x20\x30\x2e\x39\x31\x39\x37\x32\x37\x2c\x30\x2e\x39\x31\ -\x39\x37\x32\x38\x20\x30\x2e\x39\x31\x39\x37\x32\x38\x2c\x2d\x30\ -\x2e\x39\x31\x39\x37\x32\x38\x20\x63\x20\x30\x2c\x30\x20\x31\x31\ -\x2e\x39\x35\x36\x34\x35\x36\x2c\x2d\x31\x33\x2e\x37\x39\x35\x39\ -\x31\x31\x20\x31\x30\x2e\x31\x31\x37\x2c\x2d\x31\x33\x2e\x37\x39\ -\x35\x39\x31\x31\x20\x48\x20\x32\x32\x2e\x31\x38\x38\x32\x37\x32\ -\x20\x56\x20\x34\x2e\x32\x36\x36\x36\x36\x36\x37\x20\x63\x20\x30\ -\x2c\x2d\x30\x2e\x39\x34\x32\x31\x30\x30\x36\x20\x2d\x30\x2e\x37\ -\x35\x33\x36\x34\x35\x2c\x2d\x31\x2e\x36\x39\x35\x37\x34\x37\x32\ -\x20\x2d\x31\x2e\x36\x39\x35\x37\x34\x38\x2c\x2d\x31\x2e\x36\x39\ -\x35\x37\x34\x37\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\x38\x2d\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ -\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x14\xeb\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x7a\x6f\x6f\x6d\x5f\x74\x6f\ -\x5f\x49\x6d\x61\x67\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ -\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x33\x37\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ -\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\ -\x30\x66\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ -\x6f\x70\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\ -\x30\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ -\x23\x62\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ -\x6f\x70\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\ -\x30\x33\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\ -\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ -\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\ -\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\ -\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\ -\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\ -\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x66\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\ -\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\ -\x31\x34\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\ -\x32\x34\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\ -\x38\x2c\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\ -\x35\x38\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ -\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ -\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ -\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\ -\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\ -\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x2e\ -\x37\x39\x39\x34\x35\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x35\x34\x2e\x37\ -\x33\x33\x32\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x30\x2e\x36\x36\x31\x37\ -\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ -\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ -\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\ -\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ -\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ -\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ -\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\ -\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ -\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ -\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\ -\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\ -\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\ -\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ -\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\ -\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\ -\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\ -\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ -\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ -\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\ -\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ -\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x2d\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ -\x72\x69\x78\x28\x30\x2e\x36\x33\x36\x33\x36\x33\x34\x2c\x30\x2c\ -\x30\x2c\x30\x2e\x35\x34\x32\x34\x35\x31\x33\x35\x2c\x38\x2e\x37\ -\x31\x34\x36\x36\x38\x37\x2c\x34\x2e\x39\x35\x35\x32\x35\x37\x32\ -\x29\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ -\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x34\x33\x36\x37\x38\x34\x38\ -\x2c\x30\x2e\x35\x33\x36\x38\x34\x38\x37\x39\x2c\x30\x2c\x30\x29\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\ -\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\ -\x2e\x34\x35\x31\x31\x34\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\ -\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x38\x33\x37\x30\x35\ -\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\ -\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x33\x37\x36\x37\x2d\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x35\x2e\x39\x38\ -\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x32\x37\x2e\x37\x39\x39\x37\x36\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\ -\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ -\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\ -\x38\x39\x33\x37\x32\x39\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\ -\x39\x38\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\x35\x30\ -\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\x30\x2c\ -\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\ -\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x78\x3d\x22\x32\x33\x2e\x33\x32\x30\x36\x32\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ -\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\ -\x39\x37\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\x63\ -\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x31\x2e\x39\x30\x37\x36\x32\x34\x39\x36\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ -\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\ -\x36\x39\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x31\x33\x2e\x38\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x34\x2e\x30\x34\x30\x31\x33\ -\x38\x34\x65\x2d\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x32\ -\x31\x31\x37\x36\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\ -\x35\x32\x2c\x30\x2e\x37\x30\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\ -\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\ -\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\ -\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ -\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\x38\x34\x30\x39\x33\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x31\x39\x2e\ -\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\ -\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x34\x38\x34\x34\ -\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\ -\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x35\x35\x32\x32\x30\ -\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ -\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\ -\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x30\x35\x31\x33\ -\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\x39\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\x2e\x32\x35\x37\x38\ -\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x31\ -\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\x35\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x32\x30\x33\ -\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\ -\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\x39\x2e\ -\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0b\xb1\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x65\x6e\x74\x65\x72\ -\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\ -\x36\x36\x2e\x32\x37\x39\x39\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\x35\x2e\ -\x39\x38\x32\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ -\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ -\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ -\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\ -\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ -\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ -\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ -\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\ -\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ -\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\ -\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ -\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ -\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ -\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ -\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ -\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ -\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ -\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ -\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\ -\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\ -\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x32\ -\x66\x32\x66\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x32\x65\x32\ -\x65\x32\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x33\x2e\x37\x31\x37\x38\x39\x30\x30\x32\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\ -\x33\x2e\x37\x30\x31\x39\x36\x30\x37\x20\x48\x20\x33\x32\x20\x56\ -\x20\x33\x31\x2e\x35\x38\x38\x36\x37\x32\x20\x48\x20\x30\x20\x5a\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x33\x30\x32\x38\x2d\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ -\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\ -\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\ -\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\ -\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\ -\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\ -\x6c\x3a\x23\x63\x37\x65\x39\x61\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x31\x35\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\ -\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\ -\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\ -\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\ -\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x72\x65\x63\x74\x33\x38\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x39\x31\ -\x35\x30\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x37\x2e\ -\x38\x38\x34\x39\x36\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x39\x2e\x33\x37\x31\x30\x32\x30\x33\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x37\x36\x30\x32\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\ -\x35\x36\x31\x30\x34\x35\x36\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x31\x2e\x30\x36\ -\x36\x36\x36\x37\x2c\x32\x35\x2e\x36\x36\x32\x37\x34\x36\x20\x32\ -\x36\x2e\x34\x2c\x31\x38\x2e\x36\x39\x31\x30\x36\x38\x20\x32\x31\ -\x2e\x30\x36\x36\x36\x36\x37\x2c\x31\x31\x2e\x37\x31\x39\x33\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ -\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\ -\x00\x00\x06\xae\ -\x00\ -\x00\x1d\x3d\x78\x9c\xed\x59\x5b\x73\xeb\xb6\x11\x7e\xf7\xaf\x60\ -\xe8\x97\x64\x2a\x82\xb8\x10\x24\x40\x4b\xce\x4c\x72\x26\x93\xcc\ -\xb4\x2f\x6d\xda\x3e\x66\x28\x12\x92\x19\x93\x84\x42\x82\x96\x94\ -\x5f\x9f\x05\xc5\x9b\x24\xab\x39\x6d\x7c\x92\x9c\x26\x94\x3d\x16\ -\x76\x17\xc0\xee\x87\x6f\x17\x00\xbd\xfc\xfc\x50\x16\xce\x8b\xaa\ -\x9b\x5c\x57\x2b\x97\x20\xec\x3a\xaa\x4a\x75\x96\x57\xdb\x95\xfb\ -\xcf\x6f\xbf\xf2\x84\xeb\x34\x26\xa9\xb2\xa4\xd0\x95\x5a\xb9\x95\ -\x76\x3f\x7f\xbc\x5b\x7e\xe2\x79\xce\x97\xb5\x4a\x8c\xca\x9c\x7d\ -\x6e\x9e\x9c\x6f\xaa\xe7\x26\x4d\x76\xca\xf9\xf4\xc9\x98\x5d\xec\ -\xfb\xfb\xfd\x1e\xe5\xbd\x10\xe9\x7a\xeb\x7f\xe6\x78\xde\xe3\xdd\ -\xdd\xb2\x79\xd9\xde\x39\x8e\x03\xf3\x56\x4d\x9c\xa5\x2b\xb7\xef\ -\xb0\x6b\xeb\xa2\x33\xcc\x52\x5f\x15\xaa\x54\x95\x69\x7c\x82\x88\ -\xef\x4e\xe6\xe9\x64\x9e\xda\xd9\xf3\x17\x95\xea\xb2\xd4\x55\xd3\ -\xf5\xac\x9a\xfb\x99\x71\x9d\x6d\x46\x6b\xeb\xcd\x9e\x75\x46\x44\ -\x4a\xe9\x63\xea\x53\xea\x81\x85\xd7\x1c\x2b\x93\x1c\xbc\xf3\xae\ -\xe0\xe3\x6b\x5d\x29\xc6\xd8\x07\xdd\x64\xf9\x7e\x56\x71\x03\x80\ -\xee\xe0\x77\x34\x1f\x04\xa8\xd1\x6d\x9d\xaa\x0d\xf4\x53\xa8\x52\ -\xc6\x7f\xf7\xed\xbb\x51\xe9\x61\x94\x99\x6c\x36\xcc\x80\xe7\xd9\ -\xac\x67\x20\x57\x49\xa9\x9a\x5d\x92\xaa\xc6\x1f\xe4\x5d\xff\x7d\ -\x9e\x99\xa7\x95\xcb\x02\x44\x18\x3c\xbc\x13\x3e\xa9\x7c\xfb\x64\ -\x2e\xa5\x79\xb6\x72\xc1\x7b\x2a\xc5\xa9\x3d\x23\x07\x39\x19\xf4\ -\x03\xc7\xa3\x06\x23\x49\x11\x71\x6a\xc2\x59\x74\xb2\x19\x42\x88\ -\x33\x9d\x5a\x9f\x60\x48\x55\xe6\x49\x6b\x74\x09\xab\x96\xa6\x45\ -\xd2\x34\xf9\x26\x4f\xa1\xa1\xab\x5d\xd1\x6e\xf3\xea\xbb\x5a\xe7\ -\xdf\x19\xad\x0b\x34\x60\x37\x4e\xa4\x0e\x3b\x5d\x1b\xef\x90\xed\ -\x00\xc1\x30\x7a\x55\x79\x9c\x2b\x5f\x72\xb5\xff\x42\x1f\xc0\x33\ -\x07\x3b\x8c\xc2\x8f\xfb\x08\xf2\x65\xa6\x36\x8d\xd5\x9f\xa2\xb4\ -\x2d\x08\x33\x72\x1d\xbf\xd3\x8e\x4e\x5b\x8f\x33\x3b\xc6\x64\xbb\ -\x4e\x9a\x13\x92\x8e\xb3\x4b\xb6\xc0\xba\x42\xd7\x2b\xf7\x7e\xd3\ -\x3d\xbd\x62\xad\xeb\x4c\xd5\x83\x2a\xec\x9e\x33\x95\x86\x95\xc9\ -\xcd\xf1\x94\x67\xfd\xd8\x43\x18\x76\xd4\x51\x8f\x5f\xd7\x37\x4f\ -\x49\xa6\xf7\x2b\x97\x5e\x2a\x7f\xd4\xba\x84\x75\x44\x92\x4b\x4c\ -\xb1\xbc\x54\xa7\x80\x84\xc7\x28\xa2\x42\x70\x46\xae\xb4\x30\x21\ -\x8f\x50\x24\x43\x22\xd8\x95\xb2\xad\x6b\xc8\x44\xaf\x48\x8e\x0a\ -\xa2\xea\xfe\x0c\x23\x34\x4f\x7a\xbf\xad\x2d\x3a\x9b\xa4\x18\xe1\ -\x19\xbb\x5a\x95\xb7\x5e\xdb\x65\x30\x75\x7b\xa5\x06\x66\xb4\x36\ -\xc9\xbd\xb6\xca\x0d\x24\xd2\xee\x30\x1f\xb6\xcd\x33\xd5\xdc\x18\ -\x78\x9f\x57\x00\x83\xd7\x73\x9a\xb0\x11\xe5\x4b\x8b\x81\xe0\x11\ -\x16\x37\x2c\x2c\x45\x6e\xa8\x8e\xb7\x55\x65\x72\xc8\xcb\xfc\x47\ -\x05\x91\x93\x8e\x58\x40\x9e\xb3\xb0\x4f\xdd\x1c\xc7\x1c\x6d\xb2\ -\x1e\x8e\x56\xe6\x0e\x42\x0b\x98\x15\xb0\x28\xe4\xa3\x50\xd7\x39\ -\xe4\xc0\xcc\x9d\x41\x74\x9c\x8b\x6c\x6a\x43\x65\x3e\xd8\x79\x2f\ -\x64\x96\x55\x03\x91\xfd\x6b\x26\x77\xf2\x52\x99\x24\x4b\x4c\x32\ -\xd1\x7a\x90\x50\x29\xf1\x10\x09\x54\xc5\xf8\xef\xef\xbe\x7a\xec\ -\x27\x58\xa6\x69\xfc\x6f\x5d\x3f\x0f\xf3\x39\x8e\x35\x48\xd6\xba\ -\x05\x64\xdd\xc7\x51\xbc\xcc\xd2\x18\xea\x18\xe4\xf7\x63\x5e\x02\ -\x59\x6d\x09\xfc\x0b\xd4\xad\xa5\x3f\x29\xce\x8c\x2d\x38\xd3\xa0\ -\xa7\x61\x6b\x75\x2a\x88\xaf\xee\x0a\x59\x5a\xe6\xb6\x93\xff\x0f\ -\x93\x17\xc5\x37\x76\x92\x3e\xe2\xd9\xa0\xb9\x29\xd4\x24\x5c\xfa\ -\xbd\xf7\x7d\x6c\xfe\x2c\xb8\xa5\x3f\x44\xdf\xb5\xb6\x13\x2a\x67\ -\x2c\x1f\x17\xb6\x48\xd6\xaa\x58\xb9\x7f\xb5\x4a\xe7\x4a\xbb\xad\ -\x75\xbb\x2b\x75\xa6\xfa\xee\x23\x9a\x2a\x35\xe3\x52\x99\x63\x01\ -\xfa\x0d\x78\x1f\xdf\x67\xeb\x4c\x29\xf6\x60\x1b\x5e\x9f\xf8\x31\ -\x39\x35\xeb\xb6\x80\xba\xf6\xa2\x2a\x9d\x65\x0f\x8d\xa9\xf5\xb3\ -\x8a\xef\x31\x0e\x04\xc6\x7d\xf3\x44\xfe\x78\x6c\x16\x79\xa5\xc0\ -\x8d\xb8\xf9\xa1\x4d\x6a\x35\x97\x7e\xaf\xf3\x2a\x06\xdc\x54\x3d\ -\x48\xbb\x46\x01\x04\x36\x71\x30\xc8\xb2\x04\x6a\x4b\x5d\x27\xc7\ -\xb8\x82\x6d\x7e\x2e\xd5\x9b\x4d\xa3\xcc\x34\xd3\xe0\x2a\x46\xac\ -\x7f\xce\x88\x6d\xc3\x65\x52\x4e\xf4\xec\xb3\x94\x72\x24\xed\x23\ -\x46\xc5\x90\x9c\x24\x44\x2c\x24\x38\x9c\xc6\x39\x74\xa5\x4c\xf0\ -\x28\x9a\xf2\xc3\xd2\x3b\x40\x14\x9e\x70\x1a\xa2\x3e\x74\xa5\x94\ -\x85\x78\x2a\x6b\x20\x3d\xce\xa5\x03\x17\x96\xbb\xc4\x3c\xbd\xb6\ -\x10\xb3\x80\xe3\x7b\xc2\xe8\x3a\x4c\xcf\x41\x26\x28\x60\xa1\x75\ -\xfd\x12\xec\x75\x6b\xcc\x5b\x41\x3d\x32\x60\x0c\x03\xc0\xfc\x9b\ -\xd3\xe3\xc0\xe4\x62\x8c\xde\xf9\x97\xc3\x30\xe2\xe2\x0a\x7a\x1b\ -\x20\xe4\x71\x38\x09\xc7\x22\xae\x2b\xf0\xd8\xe8\xda\x83\x72\xfe\ -\x92\x98\xb6\x56\x67\x55\x65\xac\x16\x40\x5f\x9b\x60\x50\x78\xd3\ -\xf4\xe7\x91\xbb\x17\x78\xcd\x36\x9b\x9f\x01\x4f\x72\x70\x0a\x36\ -\xa6\xdf\x00\x3d\x2a\x80\x5a\x38\x8a\xe8\x82\x4a\xc4\xe1\x5b\x18\ -\x39\x5f\x4f\x98\xbe\x86\x9e\xf8\x13\xbd\x13\x7a\xa5\x13\x20\xc6\ -\x85\x94\x01\x59\xd0\x10\x05\x92\x61\x40\x2f\x75\x08\xa2\x9c\x44\ -\x91\x94\x0b\x7c\xeb\xfb\x15\xae\x0c\x96\xc0\xc3\xef\x8d\xec\x7f\ -\x97\xb2\x70\xda\x96\x94\x5d\xe2\xc6\x19\xed\xea\xcd\x6f\xc0\x3a\ -\x8e\x28\x8b\x38\xc7\x6c\x41\x81\x6a\x70\x3a\xe1\x4e\x84\x08\xe1\ -\x94\x08\x6e\x45\x01\xe5\x0c\xd2\x98\x60\x24\x22\xcc\x79\xb0\x20\ -\x12\x6a\x29\x27\x98\x38\x04\x1a\x02\x09\xca\x04\x11\x4e\x01\x4c\ -\x25\x54\x06\x41\xb0\x08\x50\x88\x09\xe7\x83\x80\x2f\xa0\xbe\x51\ -\xca\xc3\xd0\x2e\x92\x20\x94\x8a\x05\x45\x38\xe0\x70\x8c\x87\xe9\ -\x31\x8e\x08\x61\x0b\x0b\x02\x13\xfc\x6a\x35\x02\xcc\xa2\xb7\x5b\ -\x8b\xdf\x3d\x8d\x25\x02\x64\x85\x20\xb6\x06\xc0\x89\x8b\x0a\x20\ -\x31\x5e\x78\x23\x5e\x37\xbe\x5f\x93\x58\x04\xd8\x7b\xff\xf2\xf0\ -\xf1\x03\x47\xf8\xa9\x7a\x06\x6f\x82\x9c\xfc\x03\x21\x47\x09\x0a\ -\x89\x84\xdb\xdf\x9b\x20\xc7\x3e\x50\xe1\xfc\x7d\x9d\x75\xec\x7e\ -\x13\x12\x12\x86\x14\x32\x15\x0e\x97\x3c\x0a\x43\x31\xdb\x6f\xf8\ -\x6c\x8f\xb9\xf8\x7e\x63\xbf\xf9\x03\x02\x07\x29\x4b\x83\x40\x30\ -\xfe\xcb\x80\xfb\x1f\x72\xf5\x95\x6b\x4e\xf7\x22\xa4\xdb\x9f\xe1\ -\x79\xc8\xf2\x66\x07\x17\xa3\x38\xaf\x2c\x0a\x0f\xfa\x45\xd5\x9b\ -\x42\xef\xe3\x97\xbc\xc9\xd7\x85\x7a\xe8\xfe\xe6\x85\x0d\x6f\x10\ -\x9d\x92\x9d\xa6\x3c\x49\xf0\xfb\xdf\x93\x14\xdf\xe0\xb1\x38\x0c\ -\xf7\x24\x14\xf2\x90\x93\x0f\x5a\x0b\xfe\xd3\x65\x89\x3c\x94\x49\ -\xfd\xac\xea\x53\x07\x55\x25\x10\x9e\xb7\x4e\xd2\x67\x7b\x6b\xac\ -\xb2\x38\x49\xd3\xb6\x6c\x8b\xc4\xa8\xb3\x25\xb1\xa0\xda\x22\xe6\ -\x71\xf8\x84\xde\x74\xb2\xef\x2f\x55\x12\xc2\x92\x38\x62\xd7\x97\ -\xaa\x6b\x0d\x5c\x95\x28\x12\x92\x8a\x30\x9a\xf2\xa2\x7b\xd5\x64\ -\xcf\x03\x94\x4e\x47\x82\xd3\xad\x2a\xc4\x42\x72\x42\x27\x69\x77\ -\xab\x22\x81\x08\x44\x34\x8d\x6a\xea\xa4\x6a\xec\xe5\x1e\x9c\xd5\ -\x06\xfc\xff\xd4\xc3\x88\x46\xf0\xe1\x9c\x7d\xf6\xab\xd0\x83\x04\ -\x41\x24\xde\x84\x1e\x42\x06\x1f\x39\x41\xbc\xe8\x06\x45\xa8\xbc\ -\x45\x91\x99\x06\xd6\x5d\xc0\x41\x95\x06\x4c\xd2\x0b\x8a\xd0\x28\ -\x94\x24\xf8\x48\x29\x42\x42\x9a\xf1\xb7\xa9\x20\xff\x07\x14\xe1\ -\xbf\x90\x22\x24\xb0\x97\x10\xc9\xa3\xcb\x2a\x12\x52\x38\xe9\xb0\ -\x8f\x94\x23\xd0\x79\x43\xe9\xdb\x70\x44\x7c\xd0\x43\xc0\xaf\xc2\ -\x91\xd9\xd9\xe9\x9c\x25\xe4\x26\x4b\xc8\x39\x4b\xa4\xfd\x87\x02\ -\xac\xde\x39\x4b\x58\x08\x07\x0f\x3a\x23\xd4\x1b\xb2\xe4\xea\xcc\ -\x32\xda\x7b\xa9\xaa\x00\x5e\xaf\xdb\x03\xe1\xf0\x13\x04\xe4\x95\ -\xb7\x64\x57\xe6\xe0\x84\x47\x90\x60\x4c\x82\x7f\xe3\xbb\xf5\xed\ -\xe3\xdd\xd2\xbe\xdb\x7e\xbc\xfb\x09\x54\x3a\xbf\x64\ -\x00\x00\x0a\x77\ -\x00\ -\x00\x28\xbf\x78\x9c\xdd\x59\x5b\x6f\xe3\xc6\x15\x7e\xdf\x5f\xc1\ -\xca\x2f\x59\x54\xa4\xe6\x7e\x51\xec\xcd\x43\x83\x16\x01\x12\x14\ -\x68\x12\xf4\x31\xa0\x49\xca\x66\x97\x22\x05\x92\x5a\x4b\xfb\xeb\ -\xfb\xcd\x48\xa4\x48\x49\xd6\xca\x5e\xa7\xc0\x56\x84\x61\x71\xce\ -\x5c\xcf\x77\x2e\xdf\x19\xdd\xfe\xb0\x59\x16\xc1\xa7\xac\x6e\xf2\ -\xaa\xbc\x9b\xd0\x88\x4c\x82\xac\x4c\xaa\x34\x2f\x1f\xee\x26\xbf\ -\xff\xf6\xf7\xd0\x4c\x82\xa6\x8d\xcb\x34\x2e\xaa\x32\xbb\x9b\x94\ -\xd5\xe4\x87\x0f\xef\x6e\xff\x12\x86\xc1\xdf\xea\x2c\x6e\xb3\x34\ -\x78\xca\xdb\xc7\xe0\xa7\xf2\x63\x93\xc4\xab\x2c\xf8\xee\xb1\x6d\ -\x57\xf3\xd9\xec\xe9\xe9\x29\xca\xf7\x8d\x51\x55\x3f\xcc\xde\x07\ -\x61\xf8\xe1\xdd\xbb\xdb\xe6\xd3\xc3\xbb\x20\x08\xb0\x6e\xd9\xcc\ -\xab\xe6\xfe\x6e\x32\x18\x51\xad\xb2\xb2\x79\x8a\xdb\xe4\xf1\xbe\ -\xaa\x3e\xfa\x71\xeb\x3a\x9f\x31\x42\xec\x0c\x7d\x27\x87\x91\x69\ -\xd2\x0f\x5c\xad\xeb\xc2\x77\x4d\x93\x59\x56\x64\xcb\xac\x6c\x9b\ -\x19\x8d\xe8\x6c\xd0\x3d\x39\x74\x4f\xdc\xbe\xf3\x4f\x59\x52\x2d\ -\x97\x55\xd9\xf8\x91\x65\x73\x33\xe8\x5c\xa7\x8b\xd1\xae\x9e\xb8\ -\xef\x44\xad\xb5\x33\xc2\x66\x8c\x85\xe8\x11\x36\xdb\xb2\x8d\x37\ -\xe1\x78\x28\x4e\x77\x6e\x28\x0e\x40\x66\x90\x1d\x7a\x5e\xd7\x6b\ -\xbe\x29\xa0\xc4\x67\x37\xe3\xa5\xc3\xd5\x01\xdc\x0a\x7f\xfd\x80\ -\xae\x21\x6a\xaa\x75\x9d\x64\x0b\x8c\xcc\xa2\x32\x6b\x67\x3f\xfe\ -\xf6\x63\x2f\x0c\x49\x94\xb6\xe9\x60\x9a\x0e\xb7\xd1\xba\x23\x30\ -\xcb\x78\x99\x35\xab\x38\xc9\x9a\x59\xd7\xee\xc7\x3f\xe5\x69\xfb\ -\x78\x37\xe1\x22\xa2\x1c\x1f\xe9\x1b\x1f\xb3\xfc\xe1\xb1\x3d\x6e\ -\xcd\xd3\xbb\x09\xce\xca\xac\xd5\xfe\x7d\x60\x84\x74\xd7\x61\x3f\ -\xf1\xbc\x97\x90\xc8\xb2\x88\x06\x35\x95\x5c\xef\xfa\x74\x47\x98\ -\xa7\x55\xe2\xf6\x84\x29\xb3\x65\x1e\xaf\xdb\x6a\x09\x8c\x93\xa4\ -\x88\x9b\x26\x5f\xe4\x09\x5e\xaa\x72\x55\xac\x1f\xf2\xf2\x8f\xb8\ -\x69\xb3\xfa\x8f\xb6\xaa\x8a\xa8\xd3\x75\xbf\x54\xb6\x59\x55\x75\ -\x1b\x6e\xd2\x15\x74\xa8\xf4\x59\xe1\xb6\x13\x7e\x80\xf4\xb6\xdf\ -\x81\x5b\x3e\xfd\x94\x67\x4f\x6e\xcc\xee\x78\xf7\x71\xb3\x53\x4b\ -\x10\xac\xe2\x07\x18\x5c\x51\xd5\x77\x93\x9b\x85\xff\xec\x05\xf7\ -\x55\x9d\x66\x75\x27\x52\xfe\x33\x12\x55\x50\x73\xde\x6e\x77\xce\ -\xb9\x9f\xbb\xdb\x91\x9b\xb5\x97\x93\xf3\xf2\xe6\x31\x4e\xab\xa7\ -\xbb\x09\x3b\x16\x7e\xae\xaa\xe5\xdd\x44\x47\x96\x1a\x22\xa8\x3e\ -\x16\x27\x9b\xbb\x49\x28\x58\x64\xa5\xa6\xf6\x64\x70\x82\x05\x99\ -\x8e\x38\x21\x4c\xf3\x13\xe1\xba\xae\xe1\x84\x61\x11\x6f\x33\x9c\ -\xca\xff\xa3\xfb\x4e\xcd\x63\xf5\xf4\x50\x3b\xed\xb4\xf5\x3a\x3b\ -\x1e\xe9\x24\xe1\xfd\x7d\xb5\x39\x2f\x06\xca\x6b\xe7\xde\xe1\xba\ -\xcc\x5b\xb8\xd0\x6a\x33\x9c\x75\x9d\xa7\x59\x73\x7e\x60\x53\xc6\ -\xab\xf0\xa1\xa8\xee\xe3\xe2\x7c\x87\xa7\xbc\x84\x96\xc2\xbd\xfd\ -\x52\xde\x83\x70\xdc\xa3\x33\x66\x4d\xcc\x33\x3d\xb0\xf7\x13\x20\ -\xf6\xa2\xed\xf3\xa2\x65\xbc\xc9\x97\xf9\xe7\x0c\x8a\xa1\xde\xb2\ -\x60\x5b\x23\xb5\xec\x86\xed\x0c\xcb\xbd\x43\xf5\x72\xd2\x35\xb6\ -\x5b\xe7\xad\x9b\xad\x13\xf4\x8d\x55\x9d\xc3\xde\x07\xdb\xe9\x9a\ -\xb6\xc3\x26\xe7\xc6\x88\xf6\x1b\x6f\x60\xde\xfc\xf4\xb1\x6c\x3b\ -\x94\x05\x33\x6f\xf7\xb3\x53\xc3\xf7\xed\x69\xb6\x68\x0e\x1e\xe0\ -\xde\xe0\xe1\xb6\x3b\x11\xe2\x55\x16\xd7\xff\xa8\xe3\x34\x07\x8c\ -\xc3\x23\x8d\x25\x8a\x08\xb5\x1f\xe3\x7c\xac\xad\x56\x5d\xdf\x7d\ -\xe0\x40\x0b\xfa\x98\xc9\xa1\xb9\x5a\x2c\x9a\xac\x1d\x9e\x0c\xfb\ -\x6f\xb7\x45\xb6\xeb\x1d\x7a\x17\x9b\xdf\x68\xe5\x9e\xef\x7d\xd3\ -\xde\x75\xe6\xf4\xfb\xfd\xa9\x2e\xae\x26\xc9\x99\xd5\xe8\xe5\xd5\ -\x38\x13\x52\x99\x67\x57\xbb\x9d\x8d\x8f\xfd\x42\x2d\x49\xb3\x8f\ -\x42\x67\xf6\x7d\x66\x33\x69\x9a\xda\xd4\x9e\x6c\xe6\xb2\x0a\xbb\ -\xf3\x63\x2d\xfb\xbc\x96\xce\xac\xa6\x12\xf7\x5c\xb1\x1a\x3d\xbb\ -\x1a\x02\xfc\x9b\x69\x49\xda\x17\x68\xc9\x26\x71\x4c\xc8\xeb\xb5\ -\x44\x5f\xa4\x25\x4b\x79\x4a\xef\x5f\xad\x25\xc5\xdf\x4e\x4b\xec\ -\xb0\x04\xa8\x16\x72\x47\x5e\x62\xdd\xa6\x2a\x10\x52\xae\x3f\xd0\ -\x42\x81\xc4\x1c\xa9\x8f\x44\xda\x18\xc6\x25\x7f\x81\x1e\xd9\x1b\ -\x9e\x8c\xca\x37\x39\xd9\xe2\x5e\xdf\xeb\x57\x1b\x06\xd5\xaf\x3b\ -\xd0\xc3\xfe\xfd\xb7\x3a\x2e\x1b\x10\x38\xe4\x6c\x70\x9b\x3a\xdf\ -\x7c\x07\xa2\xa4\x25\x61\x92\x4e\x43\x16\x29\x41\xa9\x55\x2a\x0b\ -\xcd\x14\xed\x8a\x13\xc6\xe9\xfe\x45\x5b\x42\x35\x9f\x86\x92\x46\ -\xca\x28\xc2\xd0\x1d\x99\x5b\x13\x6e\xe4\xfb\x7e\xab\x5b\x06\x1b\ -\xb3\x91\x55\x56\x1f\xe2\xff\x06\x8d\x4c\x44\x40\xce\xd9\x75\xdf\ -\x95\x9e\xeb\x8a\x46\x13\x31\x66\xb0\x82\x1d\x24\x10\x90\xed\xf4\ -\x97\xac\x7d\xac\xa0\x88\x55\x7c\x48\x4e\xdd\xb1\x7e\xdf\x65\xf2\ -\x75\x93\xd5\xbf\x3a\x42\xf9\xcf\xf2\xf7\x9e\x34\x9d\x45\x53\x1b\ -\x76\x58\xd4\xf1\xdf\xf9\x63\x9d\x81\xaf\xdf\x9c\xc9\x20\xfd\x34\ -\x3d\x33\xa9\x8a\x22\x4b\x80\x51\x5c\x3c\xc5\xdb\xe6\x80\xc8\x33\ -\xc6\xf4\xdc\xb8\x2b\x36\xe0\xc3\xce\xc5\xd8\x2d\x47\xca\xa3\x34\ -\xd2\x54\xa8\x41\x52\x77\x7a\x06\xa9\xa3\x92\x12\x22\xac\x1a\xa1\ -\xc2\x69\x64\xc0\xbd\x08\x1f\x01\x78\xae\xf7\x75\x8a\xbe\x64\x65\ -\x84\x70\x49\x94\x99\xa2\x4e\xe0\x8a\x4a\xab\xb8\x98\x92\x08\xac\ -\xd1\x1a\xb8\x35\x2c\x8c\x48\xd8\x9e\xd5\xd3\xd0\x44\x88\xdb\x42\ -\x52\x39\x85\xd5\x08\x2d\x88\xa5\xef\x0f\x3a\x76\x4b\xc4\xc5\xdb\ -\xea\x78\x40\x56\x9c\x8e\xc7\x4b\x20\x8b\x1c\xf4\xe3\xf8\x2c\x3b\ -\x98\x8e\x23\xb0\xd4\x44\x07\x6d\x2f\xc6\xf2\xc5\xb1\xbc\x76\x5c\ -\x99\x58\xff\xb9\x42\x6d\x24\x32\xd4\x12\xad\x88\x9e\x12\xf7\xc0\ -\x41\x19\x05\x7f\x82\x1f\x32\xe8\x91\x4b\x25\xe4\x94\xf2\x48\x52\ -\xcb\xe9\xfb\x2b\xd1\xfa\x92\xb9\x9e\x8b\xea\x3a\x24\xe1\xb3\xf9\ -\x6f\x10\x6f\x6d\xa8\x43\xfa\x85\x68\x76\x2e\x81\x71\x66\xd9\x2b\ -\xf8\x94\x34\x9c\x62\x67\xe7\x18\xdc\x17\x38\xd5\x42\x2d\x16\x27\ -\x19\xe6\x8b\x9c\xea\xcf\x30\xbe\xbd\x6e\x9f\x37\x40\x44\x58\xfd\ -\x66\x8e\x18\xf2\x88\x71\xff\x4c\x59\x24\x28\x17\x3b\x97\x34\x94\ -\x28\xcb\x98\xfb\x6a\x85\x34\x44\x4b\x3b\xd5\x22\x52\x88\x24\x4c\ -\x79\x97\x14\x02\x7e\x20\xde\x8f\x3c\x81\xca\x81\x69\x7b\x5f\xd0\ -\x91\xb6\xc2\x58\x3d\x72\x88\x51\xb7\xc5\xd9\x6e\xf5\xce\x4f\x14\ -\x93\x7d\x69\xe0\x58\xbf\xff\xb6\xcc\xda\x38\x8d\xdb\xf8\x50\x10\ -\x74\x2d\xae\x70\xec\x8a\x82\x3a\x5d\xcc\xff\xf5\xe3\xdf\x7b\x83\ -\x49\x92\xf9\xbf\xab\xfa\xe3\xc1\x08\x5c\x87\xf8\xbe\x5a\x03\x9e\ -\xde\x90\x5d\xa9\x91\xcc\x9d\x82\xe2\xf6\x43\xbe\x44\xa1\xeb\x6e\ -\x4e\xfe\xba\x59\x16\x58\xbf\x17\x8c\x3a\xbb\x22\xe9\x30\xe9\x6e\ -\xda\x3a\xdb\xdd\x8c\x9c\xbd\x4c\x4a\x93\x65\xee\x06\xcd\x7e\x6d\ -\xf3\xa2\xf8\xc9\x2d\x32\x30\xec\xfd\xa4\x79\x5b\x64\x03\x6b\x9f\ -\xed\x77\xdf\x19\xe3\xe0\x70\xb7\xb3\xee\xf4\xfe\xed\xe1\xa8\x10\ -\x7c\xa8\xab\xf5\x6a\x59\xa5\xd9\xbe\x62\x3e\x2e\x14\x8b\xf8\x3e\ -\x43\xf5\xfa\xb3\x93\x05\x9d\x8f\x78\x97\xdf\xd5\xd7\xfb\x15\xb3\ -\xa2\xc8\x57\x4d\x7f\xd0\xbd\x03\x2d\x70\x80\x39\x8e\xf6\xdd\xcd\ -\xa9\x85\xbe\xff\xde\x49\x07\xde\xeb\x5f\xeb\x75\x91\xcd\xb3\x4f\ -\x59\x59\xa5\x29\x9c\xad\xae\x3e\x66\xf3\x1b\x42\xf6\xec\xce\xbd\ -\xee\xaa\xe5\x79\xff\x0a\x65\x65\x75\x81\x2a\xb6\x9d\x8b\xae\x2d\ -\x8d\x9b\xc7\xb8\xae\xe3\xed\xbc\xac\xca\xac\x6b\xed\x97\x1a\xf9\ -\xce\x2a\x6e\x1f\x95\xe2\x6c\x6c\xa8\x64\x77\x69\xc4\xc7\xd6\x8a\ -\x64\xe9\x1a\xc5\xc1\x0c\x5d\xf8\x1e\xbc\xba\xfb\x09\xb8\xc9\x20\ -\xfb\xc0\xbd\x9f\x55\xca\x29\xc7\xf8\x5a\xa5\x44\x94\x6a\x4d\x40\ -\xc9\xde\x4a\x3b\x6e\xff\x82\x49\x12\x1e\x52\x7b\x77\x5b\x61\x1c\ -\x17\x10\xe4\xa0\xb8\xee\x92\x02\x84\x0c\xa4\x9b\x91\x83\x5e\xfc\ -\xa5\x0e\x45\xa4\xe0\xe2\xe0\xc2\xd0\x55\xa8\x23\x2b\x19\x13\x03\ -\xee\xe6\x54\x88\xfc\x04\xa2\x28\xa9\x1e\xe9\xb9\x27\x9e\x87\xfb\ -\x87\xd3\x68\x85\xc8\x04\x32\x82\x1a\x5d\xb9\xd0\x24\xad\x06\x5b\ -\x40\x40\xc2\x57\xb0\x06\x41\x2d\xf5\xc1\x8b\x18\x26\xc0\xf5\x5d\ -\x86\x3c\x04\xa8\xde\xe4\xfb\x69\xc3\x04\xb0\x64\x75\xe8\x73\x34\ -\x76\x6a\xf8\x20\x09\x3f\xdf\xdd\x1d\x8c\xaa\x88\x00\x09\x7d\x85\ -\x29\xdc\x64\xca\x3d\x5f\x8d\x3c\x47\x4e\xb7\xe6\x4d\x91\x97\x96\ -\x9e\xe2\x0e\xe6\xc5\x8c\xa5\xe2\x04\x77\x09\x4a\x46\x2c\x19\x90\ -\x23\x87\x3b\x05\x27\x63\x86\x2b\x31\x04\x1e\x93\x50\x29\x95\x62\ -\x47\x08\x73\x0d\xca\x2f\xf8\x91\x35\xa0\x8e\x03\xef\xbb\x84\xbb\ -\x77\x57\x06\xe2\xe3\xf1\xb5\x96\x12\x0c\x71\xb0\x5b\xab\x34\x70\ -\x73\x5f\x89\x21\x42\x72\x61\x77\xa8\xf7\xb0\x38\xff\xbf\xd6\x43\ -\xc1\x9e\xbf\xda\x43\x89\x51\x50\x1e\xd5\x97\x70\x3a\x45\x04\x80\ -\xfc\x12\xa0\x7e\x72\xf9\x15\xe5\x15\x8b\xa4\x96\xa8\x84\x02\xb0\ -\x3a\x03\x6f\x33\xc8\xbe\x91\xa2\x0c\x09\x4e\x07\x49\xe0\x5c\x45\ -\x30\xee\x7d\x40\x70\x66\x04\x91\x68\x83\x53\x69\x30\x41\x1e\x19\ -\xe7\x74\x8a\xa3\xc9\x38\x22\x28\xa6\x32\x42\x3a\x57\x4c\xf3\xa0\ -\x08\x50\x36\x33\x8b\xba\x11\xe9\xde\x60\x9f\xca\x62\x3e\x50\x47\ -\x7c\x95\x1a\xac\x9b\x51\x2a\x08\x0d\xdc\xc4\x60\x00\x7e\x3a\x89\ -\x55\x89\x09\x42\xac\x60\x28\xa3\x68\xb1\x8a\x19\x29\x82\x9f\x03\ -\xe3\xb8\x3b\xfa\x59\x4f\xcd\x25\xd6\x72\xdb\x43\x4f\xd4\x0a\xc4\ -\x7a\xbf\x94\x14\x89\x3d\x00\xcd\xe0\x4a\x0b\x21\xb8\xdb\x33\xb5\ -\x6e\x5f\xae\x71\x37\x93\x98\x76\x93\x07\x00\xcf\x8d\xc7\x0e\x05\ -\xd3\x9e\x7f\xa0\xd0\x84\x56\x5c\x23\xb7\xc4\x72\x02\x7e\x82\xf3\ -\x80\x7d\xe0\x84\x2e\x04\xb8\xba\x04\xb3\xba\x82\x12\x35\xb9\x0e\ -\x38\x4a\x0b\xe5\xb4\xe7\xda\x94\x44\x44\xd7\x81\xaf\x36\x99\xe0\ -\xdc\x8f\x95\xd8\x8a\x0e\x3e\x9f\x09\x84\x42\x9e\xfa\x7f\x52\x95\ -\x25\x84\x55\x1d\x26\xeb\xfa\x53\xdc\xae\xeb\x6c\x74\xd3\xd9\xdf\ -\x58\x22\xc9\xba\xbc\x0e\x16\xd6\xf8\x4f\xf2\x79\x50\x0a\xbe\x2c\ -\x81\xba\x1a\xe3\xeb\x73\x85\x41\x29\x27\xf4\x9b\x45\x0c\xe7\x49\ -\xdc\x32\x1e\xf2\xcb\x11\xda\xc5\x76\xe0\x4a\x9d\x7b\x32\x03\x62\ -\x47\xe0\x93\x70\x72\xec\xc5\x51\x4a\x14\x2d\x08\xf2\xb0\x40\x36\ -\x8e\xcf\xfe\xa7\x01\x06\x4b\x44\x54\x1f\x44\x1f\xff\x9b\x80\x04\ -\xf6\x88\x7e\x72\x14\x4e\xa4\xcb\xd6\x0e\xd6\x51\x38\x81\x1d\x2a\ -\xc2\xdc\xef\x1d\x5f\x0c\x01\x83\x23\x3f\xa7\x43\xce\x7c\x33\xeb\ -\xda\x5d\xc0\x80\x55\xcc\xef\xd7\x6d\x3b\x6c\xfb\x4f\x95\x97\x73\ -\xaf\xe0\xb7\xd0\xb6\x8f\x06\xb0\x59\x6b\x18\x85\x73\x20\x39\x19\ -\x6d\x28\xec\x18\x44\xd9\x28\x0e\x36\x3e\xa5\xee\x27\x16\x14\xc3\ -\x27\x08\x49\x63\xcf\x5e\x51\x9c\x35\xe2\x6f\x5e\x45\x48\xfb\xc2\ -\x22\xe6\xa3\xe6\xd5\x4a\x21\xaa\x04\xe0\x2d\x44\xc2\x2e\xe4\xd4\ -\x11\x18\xf0\x14\x76\x56\x45\x03\x23\xbe\x5a\x49\x7f\x72\x86\x07\ -\xa1\x40\x5c\xb2\x17\x33\xc7\x6b\x32\x7c\x28\x8e\x73\xbc\x44\xde\ -\x84\x8f\x91\xd3\x1c\x8f\x6a\x10\xc1\xd9\x0e\x6e\x38\x9c\x57\xa2\ -\x55\x09\x09\x03\x1c\xe5\x78\x1b\x39\x45\xf2\x91\x4f\xc2\xcf\x11\ -\x8e\xc1\x28\xe5\xc8\x29\x5d\x69\x29\x14\x82\xfa\xc5\x1c\x6f\x85\ -\x06\x87\x63\xda\xdf\x09\x51\x83\x14\x87\xfc\xe3\x73\x93\x64\x54\ -\xfa\x74\x2f\x2c\xc8\x2a\x7f\x09\xb3\x43\x48\xb1\x8e\x2d\x0c\xd8\ -\xe6\x45\x6a\x87\xdc\x83\x48\x43\xb5\xf9\x3f\xc0\x7d\x70\x8d\xf0\ -\x3a\xe4\x11\x4c\xad\xa0\x94\x1f\xe1\xce\xa4\x90\xe4\x5b\x01\x9e\ -\x9d\xf1\xf4\x0b\xc0\x1b\xf9\xbf\x03\x5e\x21\x21\xca\xb7\xa5\xf4\ -\x8a\x90\x13\xd0\x39\xe8\x1f\x78\xf7\x40\xd0\x81\xce\x22\x47\x14\ -\xa5\x1d\x97\x72\x14\x4c\x1f\x60\x9a\x11\xec\x0c\x04\xd4\xf9\xbb\ -\x38\x82\x1d\xe5\x32\x8c\x8d\xb2\x11\xec\xbe\x06\xe3\x96\x4b\x71\ -\x19\x77\x85\x6e\xca\x31\x35\x02\x9b\x22\xca\xd5\x0c\x8e\x2a\x70\ -\x81\x6a\x87\x7b\xaa\x00\xf6\x87\x74\x47\x5f\x80\x3b\xa6\x25\x20\ -\x17\x52\x5e\x89\x3b\x16\x41\xb9\x43\x60\x73\xdf\x3c\xf0\x83\xab\ -\xd6\x57\x42\xaf\x40\xfb\x05\x43\x11\x70\x04\xbd\xe3\x91\x86\x7d\ -\x23\xd0\x0b\x71\x65\x19\xbf\x87\xfe\xdb\xf7\xf8\x90\x7d\xb5\xcf\ -\x53\x1f\x79\xa9\x38\x02\xde\x28\xd4\x6c\xf6\x1b\x01\x5e\x0e\xae\ -\xee\xae\xf3\x79\xda\x5f\x2f\x3f\x7c\x78\x77\xeb\x2e\x7b\x3f\xbc\ -\xfb\x2f\xf4\x25\x33\x5f\ -\x00\x00\x12\xa8\ -\x00\ -\x01\xe6\x23\x78\x9c\xed\x5d\x4b\x73\xe3\xc6\x11\xbe\xef\xaf\x60\ -\xb8\x97\xa4\xb2\x18\x62\x06\x6f\xae\x24\x1f\xe2\x4a\xc5\x55\xc9\ -\x25\x71\x92\xa3\x8b\x22\x21\x89\x59\x92\x50\x81\xe0\x4a\xf2\xaf\ -\xcf\x0c\x9e\x24\xd8\xb2\x45\x37\xd0\x58\x19\xcd\xb5\x6b\x97\x00\ -\xf8\x9a\x0f\xfd\xfc\x7a\xba\xaf\xbe\x7b\xde\x6e\x26\x5f\xe3\x74\ -\xbf\x4e\x76\xd7\x53\x29\xec\xe9\x24\xde\x2d\x93\xd5\x7a\x77\x7f\ -\x3d\xfd\xf7\x8f\x7f\xb5\xc2\xe9\x64\x9f\x2d\x76\xab\xc5\x26\xd9\ -\xc5\xd7\xd3\x5d\x32\xfd\xee\xe6\xc3\xd5\x1f\x2c\x6b\xf2\x97\x34\ -\x5e\x64\xf1\x6a\xf2\xb4\xce\x1e\x26\x3f\xec\xbe\xec\x97\x8b\xc7\ -\x78\xf2\xc7\x87\x2c\x7b\x9c\xcf\x66\x4f\x4f\x4f\x62\x5d\x1e\x14\ -\x49\x7a\x3f\xfb\xd3\xc4\xb2\x6e\x3e\x7c\xb8\xda\x7f\xbd\xff\x30\ -\x99\x4c\xf4\xe7\xee\xf6\xf3\xd5\xf2\x7a\x5a\xbe\xe0\xf1\x90\x6e\ -\xf2\x0b\x57\xcb\x59\xbc\x89\xb7\xf1\x2e\xdb\xcf\xa4\x90\xb3\x69\ -\x73\xf9\xb2\xb9\x7c\x69\x3e\x7d\xfd\x35\x5e\x26\xdb\x6d\xb2\xdb\ -\xe7\xaf\xdc\xed\x3f\x1e\x5d\x9c\xae\xee\xea\xab\xcd\xb7\x79\x72\ -\xf2\x8b\x64\x14\x45\x33\x5b\xcd\x94\xb2\xf4\x15\xd6\xfe\x65\x97\ -\x2d\x9e\xad\xd3\x97\xea\xef\x08\xbd\x54\xd9\xb6\x3d\xd3\xe7\x9a\ -\x2b\xdf\x76\xd5\x7c\xaf\x17\xf4\x51\xff\x5f\x5f\x5e\x1d\x10\xfb\ -\xe4\x90\x2e\xe3\x3b\xfd\xba\x58\xec\xe2\x6c\xf6\xfd\x8f\xdf\xd7\ -\x27\x2d\x5b\xac\xb2\xd5\xd1\xdb\x54\xeb\x79\xf2\xa9\x27\x8b\xbc\ -\x5b\x6c\xe3\xfd\xe3\x62\x19\xef\x67\xd5\xf1\xfc\xf5\x4f\xeb\x55\ -\xf6\x70\x3d\x75\x5c\x21\x1d\xfd\xf0\xf2\x83\x0f\xf1\xfa\xfe\x21\ -\x6b\x1f\x5d\xaf\xae\xa7\xfa\xdb\x7b\x8e\xb2\xf3\xe7\x47\x37\x87\ -\x2c\x2e\x28\xdf\x78\x5e\x9f\xb1\x45\xa4\x84\x9c\xa4\xd2\x73\x82\ -\xe2\x9a\xea\x27\xcc\x57\xc9\xd2\x7c\x27\xfd\x96\xf1\x76\xbd\x38\ -\x64\xc9\x56\xa3\xb6\x5c\x6e\x16\xfb\xfd\xfa\x6e\xbd\xd4\x4f\x92\ -\xdd\xe3\xe6\x70\xbf\xde\xfd\xa4\xdf\x34\xcb\xe2\xf4\xa7\x74\xb1\ -\x37\x7f\xad\xd6\xfb\xc7\xcd\xe2\x45\x54\x2b\x59\x7f\x6c\xfc\xfc\ -\x98\xa4\x99\xf5\xbc\x7a\xd4\xeb\xe9\x07\xc2\x03\x4f\xbf\x34\xa7\ -\x6f\xf4\xf9\xab\x55\x7c\xb7\x37\xd7\x15\x3f\xd0\x3c\xd3\xbf\x50\ -\x4d\x27\xb3\xfc\x6c\xfd\x7d\xcd\x97\x5d\x7d\x5d\xc7\x4f\xcd\xb5\ -\xb7\x8b\x7d\xb1\x88\x93\xc9\xe3\xe2\x5e\xdf\x70\x9b\x24\xbd\x9e\ -\x7e\xbc\xcb\x1f\xe5\x89\xdb\x24\x5d\xc5\x69\x75\xca\xcf\x1f\x27\ -\xa7\x12\x0d\xca\x3a\x7b\x29\x44\xac\x7c\xef\xea\x1b\x9b\x77\xad\ -\xcf\xdb\xf0\xf9\xfd\xc3\x62\x95\x3c\x5d\x4f\x55\xfb\xe4\xcf\x49\ -\xb2\xbd\x9e\x06\x22\x92\xa1\xed\xca\xa0\x7d\x7a\xf9\x7c\x3d\xb5\ -\xa4\x14\xa1\x13\xb9\x5e\x74\x76\xd6\x7c\xa1\x48\x9f\xf4\xfc\x12\ -\xb8\xe3\x93\x87\x34\xd5\x42\x68\x69\x10\x62\xfd\xab\xf2\xbf\x9c\ -\xf2\xa2\xfd\x43\xf2\x74\x9f\x9a\xd5\xc9\xd2\x43\xdc\x7e\xa5\x39\ -\x63\xdd\xde\x26\xcf\xf0\x69\x7d\x4f\x1c\x8c\x78\x5b\x87\xdd\x3a\ -\xd3\x22\xf4\xf8\x7c\xfc\xae\x87\xf5\x2a\xde\xbf\xf2\xbe\xe6\xdc\ -\x2f\xbc\xf1\xd3\x7a\xa7\x17\xc9\x2a\x6f\x76\xe9\xd4\x18\xb4\xaf\ -\xa8\xee\xfc\xc0\x0e\x5f\xb9\x42\x7f\xc2\x19\x0e\xe5\xa9\x97\xd7\ -\x4f\x6d\x17\xcf\xeb\xed\xfa\xe7\x58\xaf\x8b\xcc\x6f\x3b\x7d\x6b\ -\x9d\xac\x4a\xf1\xb2\xc9\x24\x7b\x31\x52\xfc\xfc\x62\x8e\x4d\xab\ -\x83\x66\x39\xcd\x01\xcf\x71\xfd\xfa\x60\x92\xae\xb5\x70\x1c\x7d\ -\x9d\xea\xd0\xcb\xf1\x21\x23\xf3\x5a\x65\x3f\xe7\xf7\x57\x7e\xf7\ -\x05\xed\x73\x2f\xc7\xe7\xca\xdb\x7e\x76\x7e\xdf\xe7\xc7\xb7\x71\ -\xb6\x58\x2d\xb2\x45\x23\x04\xd5\x11\x2d\x34\x5e\xf5\xcb\xb4\xfa\ -\x9c\xff\xf3\xfb\xbf\xde\x94\x1f\x74\xb5\x5c\xce\xff\x9b\xa4\x5f\ -\xaa\xcf\x9d\x4c\xcc\x05\x8b\xdb\xe4\xa0\x57\x7a\x7a\x53\x1f\xbe\ -\x5a\x2d\xe7\x5a\xe1\x69\x45\x70\xb3\xde\xea\x5b\xdb\xe8\xca\x3f\ -\x6b\x05\x77\x35\x6b\x4e\x9c\x5c\x6c\x16\xab\x79\xd3\xe2\x6d\xd3\ -\xb8\xd0\x9c\xa0\xf9\x58\x2d\xb7\x6b\xf3\xa2\xd9\xbf\xb2\xf5\x66\ -\xf3\x83\xf9\x90\xf2\x17\x1f\xbd\xe9\x3a\xdb\xc4\xcd\xc1\xab\x59\ -\xf9\xed\xcb\xdf\x36\x3b\xfa\x71\x57\xb3\xea\xd7\xe7\xcf\xee\x9b\ -\x55\xc9\x65\xe2\x4c\x70\x36\x8b\xdb\x78\x73\x3d\xfd\xbb\x39\x39\ -\x39\x3b\x7b\x9f\x26\x87\xc7\x6d\xb2\x8a\xcb\x97\x57\x58\xdc\xff\ -\xda\x75\xad\x8f\x75\x5e\xfb\x58\x6d\x14\x37\x9b\xa4\x06\x29\x5e\ -\x66\xf5\x9d\x90\xbd\x6c\xf4\xdb\xe5\x6a\x6a\xfe\xd1\xce\x1f\x9f\ -\x4b\x3d\xab\x8d\xcb\x66\xbd\x8b\x3f\x27\x5a\xab\xdf\x6d\x92\xa7\ -\xf9\xd7\xf5\x7e\x7d\xbb\x89\x3f\xe7\x7f\xaf\x37\x7a\x41\xeb\x43\ -\x77\x7a\x55\xe7\x1f\x6f\x1d\xf3\x27\x7f\x62\x95\xea\x6b\x2e\x8b\ -\xa7\xe9\x61\x13\xcf\x77\xc9\xee\x67\xad\xf8\x3e\xef\xb3\x34\xf9\ -\x12\xcf\xb5\xc2\x0c\x3d\xfd\x79\xc5\xd3\x42\x48\xe7\x9e\x90\x91\ -\x74\x7d\x3f\x94\xd5\x71\xf3\x25\xf4\xcf\x99\xdf\x1e\xb2\xec\xf8\ -\xd8\xff\x92\xf5\x6e\xae\x61\x8d\xd3\xea\x68\xfe\x64\xa3\xe5\x2d\ -\x9b\xbb\xd5\xb1\xd5\x42\x2b\xca\x34\xd5\x3f\x47\x7f\x7a\x7c\x7c\ -\x34\xb9\xbb\xdb\xc7\xd9\x5c\x69\x65\xa7\x42\x5b\x7a\x61\x75\xb2\ -\xf9\xea\xdb\x45\xfa\x25\x4e\x8b\x57\xc6\xbb\x85\xfe\xa5\xd6\xed\ -\x62\xf9\xc5\x00\xb1\x5b\xcd\x17\x4b\xad\xb5\x0e\x1b\xed\xf2\x9c\ -\x08\xac\x59\x5f\xc7\xb6\x1b\x71\xab\x4c\xad\xaa\x8f\x54\xda\x46\ -\xf9\xe2\xc4\x32\x68\xb3\xae\x0f\x16\xb6\xd7\x71\xeb\x83\x2f\xd0\ -\xc1\x54\x1f\xd5\x2f\x8f\x1c\x2f\xf4\x9d\xfa\x66\xbe\x7a\x5c\x64\ -\x0f\x2d\x74\x73\x70\x8e\x7e\x7d\x0d\xf4\xc9\xc2\xd7\x9f\xe0\xf6\ -\xb9\xf0\xf5\xda\xd6\xbf\x43\xaf\xd8\x3f\x26\xb5\x1e\xfa\x64\xd5\ -\xff\x9c\xfc\x67\xe2\x38\xc5\x93\xe0\x64\x81\xcd\x4f\x54\x51\xd4\ -\x2c\x5a\x63\xa0\x92\x9d\xfe\xca\x59\x92\x5a\xda\x54\x7d\x5d\x64\ -\x87\x34\x3e\xd1\x89\xb5\x6e\xd3\x42\x64\xd4\x81\xb6\x2a\xcb\xe5\ -\x7b\x5f\x3b\xc7\x13\xea\x53\xbd\x52\x93\xbf\x4d\xce\x15\xfe\xd1\ -\xaa\x85\xdf\xce\xaa\x49\xa1\x41\xb4\x95\x17\x3e\x3e\x5f\xbe\x6c\ -\xe0\x62\x6c\x27\x15\x12\xce\x27\x15\x88\x20\xff\xd7\x64\x59\x1f\ -\x75\x3f\xd9\xaf\xfd\xfb\x6c\xad\x9c\x20\x50\x96\xfd\xe6\xd5\xea\ -\xe4\x26\x92\x81\xe7\x4a\xcf\xeb\x70\x3d\x7c\xe1\x7e\xaa\xbc\x79\ -\xb3\x12\xf6\x27\xcb\x15\x2a\xbf\x3d\x5e\xfb\xf7\xf9\x4a\x84\xee\ -\xbb\x5f\x07\xed\xf0\x16\x77\x43\x27\xab\x61\xbd\x5d\x8a\xbe\xd1\ -\xf5\x50\xaa\xa3\x1b\xc3\x8a\xde\xfd\x52\x04\x9d\xde\x1a\xef\x5e\ -\x54\x6a\x53\xd2\xcd\x7a\x38\xef\x7d\x3d\x64\xd0\xe9\x7a\xbc\xdd\ -\x6d\xf9\xd5\xf5\xc8\x33\x0e\xf5\x1a\x0c\x62\x64\xb5\x1a\x41\xd9\ -\x57\x4b\xfd\x9e\x96\xa3\xbe\x55\x70\x6b\x22\x09\x45\xa6\xe7\x05\ -\x91\x5d\x38\x61\xa4\x3a\xa4\xdf\x05\xf1\xb1\xf2\xe2\xfe\x6e\x96\ -\xa2\x09\xf4\x50\x0b\xf2\x1b\xfc\x8f\xfe\x32\x20\x46\xff\xe8\xd7\ -\xbf\x39\x03\x02\xad\xba\x7d\xf9\x5a\xff\xa6\xc4\x87\x7d\x86\x14\ -\x22\xdf\x11\xda\x8d\x22\xaf\xb2\xad\xe2\x3c\xe1\x61\x8b\x48\xba\ -\x2a\xf4\x82\xe6\x94\xc9\x50\x3a\xc2\x3d\xb5\x98\x26\x35\x59\xaa\ -\x0e\x8f\x71\xeb\x17\xb7\x23\x95\x72\x39\x72\x9e\x08\x4f\x53\x0d\ -\x8c\x1c\x21\x72\x11\x02\x39\x57\xf8\xe7\xc8\x79\xc2\x89\x6c\x37\ -\xf0\x19\xb9\xbe\x65\xee\x28\x85\x70\x39\x76\xa5\x9b\x19\x32\x76\ -\x43\x60\x87\xb1\x74\x90\xd4\x45\x22\xc7\xcd\x51\x8c\x5c\xef\x52\ -\xe7\x77\x2c\x75\x8c\x1d\x99\xad\x3b\x8a\x02\x3b\xf2\x53\x1c\xe1\ -\xf9\x32\xb2\xd9\x4f\x21\xb0\x76\x28\x5f\x25\x6c\x67\xd4\x18\x3d\ -\x4a\x7b\xd7\xb5\xe0\x85\xc2\x0e\x34\x74\x32\x62\xe8\x7a\x17\xbc\ -\xae\xc5\x8e\xb1\xa3\x33\x78\x08\x47\x53\xd9\xed\xca\x12\x0e\xcc\ -\xa9\x0d\x9e\xec\xda\xe2\x31\x7c\x44\xf0\x61\xa2\x04\x30\x97\xc9\ -\xbe\x0a\x99\xe0\x21\x9c\x15\x58\x69\x32\x76\x64\x06\x0f\xa3\x31\ -\xa3\x42\xee\x38\xb3\x32\x98\xc1\x43\x68\x4d\x25\x81\x30\x81\x14\ -\x3d\xf3\xea\x70\xac\xe8\x45\x80\xd2\x6c\xd7\x90\x56\x00\x9e\x9f\ -\x29\xf0\x3b\xaf\x59\x96\x76\x95\xec\x64\xfc\x7a\xb7\x7a\x68\x04\ -\x1d\x40\x7f\x32\x82\x74\xb6\x0f\xd0\x9e\x97\x01\xa8\xc4\xa9\xf4\ -\xb9\x22\xca\x65\x92\xb1\x23\xb0\x7d\x1e\x16\x3d\x57\x78\x05\x5a\ -\x0c\xe1\x10\x29\x4e\x28\x6c\x40\x89\x5f\x58\xe2\x19\x32\x76\xfd\ -\x93\x7a\x50\xe0\x80\x17\x3f\x86\x90\x90\xdb\xc3\x6b\x50\xd0\x81\ -\x51\x82\xd1\x23\x49\x76\x42\x44\xc3\x65\xf8\x79\xc2\x67\xe8\xc8\ -\xa9\x3d\x3c\x6e\x90\xdc\xf9\xc2\xcd\x97\x49\x32\x82\xfd\x33\x7c\ -\xf8\xd0\xa1\x25\x7a\x8c\x1e\x21\xc7\x87\x47\xaf\xdc\xbf\xc6\xb9\ -\x97\x01\xa9\x3e\xbc\x07\xda\x36\x7f\x0c\x20\x15\xd9\x87\x8f\xfd\ -\xc0\xec\x27\xfb\x2f\x24\x89\x4f\xeb\xac\xd1\x46\x27\xfa\x93\xd1\ -\x23\x21\xfc\xf0\xee\xe7\x59\x0b\x15\x8e\xdc\xa9\x79\x3f\x7c\xec\ -\x1e\x8a\x20\x32\x0f\x06\x71\x08\x10\xb1\xf6\xaf\xf1\x55\x8e\x35\ -\x68\x24\x14\x07\x11\x44\x46\x10\xd8\xc2\x77\x19\x82\xc6\xdc\x31\ -\x78\x83\xd8\x40\xac\xff\x52\x95\x05\x9e\xf6\x0b\xab\xb3\x32\x0c\ -\x20\x81\x05\xc4\x1a\x40\xe9\x00\xf5\x2f\x8c\x21\x1d\xfd\x07\x94\ -\x5a\xe3\x85\xb0\xd9\x31\xc6\x00\xf6\xcf\x01\xa2\xf5\x28\x24\x83\ -\x0c\x21\x25\x07\x88\x4d\x85\xb6\xdd\x98\x26\x31\xc3\xe8\x51\x70\ -\x80\x36\x16\xbf\xba\xe0\x85\x41\x1c\x86\x0d\x44\x23\xd8\x0e\x24\ -\xb8\x84\x89\x90\x08\xec\x45\xfe\x18\x42\x4a\x36\x10\xed\xc5\x80\ -\xbd\x41\x38\x9c\xa7\x65\x03\xd1\xe1\x04\x28\x88\x8c\x22\x1d\x25\ -\x88\x56\xa5\x50\x4e\x94\x5d\x19\x4a\x62\x10\x9d\x94\x81\x54\x29\ -\x43\x48\xca\x0e\xa2\x31\x3c\x2d\xaa\xe0\x68\x9e\x94\x17\x44\x2b\ -\xd1\xb0\xec\xff\xc9\x20\x0e\xb4\x29\x09\x5d\xd7\x04\x43\x48\xd2\ -\xa4\x6e\xd4\xd8\xe5\x9b\x92\xd0\x7e\xa8\xb2\xa1\x3e\x14\x8c\x1e\ -\x45\x32\xd4\x43\xd7\xc6\x34\x01\xc3\x31\x7a\x75\x9a\x9b\x41\x24\ -\xd9\x17\x81\x17\x42\xb0\xbc\x90\x61\xa4\x0b\x06\xf1\x92\x08\x66\ -\x65\x18\x42\xca\x32\x51\x7c\xa1\x28\xb8\xc3\x8c\x41\x24\xf4\x46\ -\xd1\x95\x6a\xbc\xc5\x6c\x20\x47\x14\x1d\xc8\x83\x71\x04\x03\x48\ -\xe7\xc6\xf4\xe3\x8d\xf2\x36\x17\x42\x37\x06\x9b\x8f\x01\xeb\xb4\ -\xbd\xc2\x3b\xa5\x69\x4b\x38\x6a\x08\x4b\x37\x06\x5d\x6d\xff\x0d\ -\x34\x6b\x32\xa3\xba\x46\x8a\x62\xe4\x40\xb3\x1f\x5c\xcf\xfc\xf1\ -\x00\x04\x1d\xdb\x09\xf4\x7f\xad\xb4\x4c\x64\x2e\x3f\xf5\x66\x3c\ -\x11\xf8\x2a\xf2\x89\x98\x89\x11\x23\x68\xda\x6d\x41\xb5\x6a\x97\ -\x61\xa8\x03\x07\x73\x3d\x63\x38\x58\x34\x01\xec\x9a\xb8\x0c\xc2\ -\x56\xcf\x1f\x23\x96\x81\x7e\x90\xf4\xc6\x1e\x35\x7a\x45\x50\x01\ -\x78\xa4\x97\xe1\xa7\x5d\x17\x3b\xb2\x23\xc5\x20\x0e\xd4\x74\x0b\ -\xe2\xe8\x51\x22\x28\x1d\x21\x3d\xfd\x60\x37\xa6\x7f\x11\xf4\x2d\ -\xb0\xed\x01\x5e\x04\x19\x44\x62\x9e\x09\x48\xab\x75\xe0\xcb\x84\ -\xc2\x5c\xe8\xb3\x22\xa5\xca\xd0\xa0\x85\xd1\xd7\xde\xa7\xe3\x3b\ -\x21\xc3\x38\x54\x33\x2e\x28\xc3\xdd\x81\x28\xda\xc2\x73\x43\xe9\ -\x12\x25\x4b\x47\x8c\x61\xde\x8e\x0b\x1f\xdf\x83\x82\xc8\x20\x12\ -\xb7\x74\xea\x49\xa1\x72\x8c\x4f\x98\xf2\x46\x07\x18\x60\xaa\x8d\ -\x6d\x22\xe5\xae\x26\xb4\x51\x94\x4a\x28\x19\xea\x3f\x27\x20\x46\ -\xc2\x0f\x5c\x3b\x20\x1a\x2f\x31\x62\x10\xf3\x3a\x52\x88\x7c\xba\ -\x0c\x44\x5f\x78\x1a\x43\x4e\xd6\x0c\x49\xe3\x43\x45\x34\x97\xa1\ -\x18\x09\x57\xc7\xfb\x92\x51\x1c\x30\xde\xc7\x2b\xd4\x50\x68\xf3\ -\xe7\xf8\x6c\x15\x07\x0d\xf8\xc1\xe6\xb1\x1d\xb8\x37\x6c\x19\x29\ -\x6b\x4b\xd1\x61\x86\x8e\x28\xa4\x0a\x54\x20\x59\x1a\x07\x2c\xcb\ -\xc0\xd3\x51\x60\xea\x86\x65\x91\xb2\xbe\x14\x0d\xa2\x74\x34\x5e\ -\x5a\x18\x87\xdc\x77\x38\x62\x10\xab\x6a\xd3\x5e\xa2\x0d\x86\x91\ -\xd6\x4f\x55\xe8\x0a\x0d\xd8\x32\xba\xfa\x4d\x22\xe5\x13\xf5\x51\ -\x18\x31\x8c\x75\xe9\x30\x3a\x23\x0e\x07\x1c\x0c\x24\x71\xe5\x29\ -\xbe\x64\xea\x1b\xa8\x5c\x1c\x71\x05\xb1\xa9\x3d\x45\xcf\x1b\xe1\ -\x81\x3f\x83\x17\x9f\xa2\xb7\x94\xf2\xc4\x9f\x81\xe0\xcb\x8b\xde\ -\x00\x6b\x88\x1f\x57\xe8\x96\x5b\xf5\x89\x02\xfe\x11\x63\x58\x94\ -\xbe\xa1\xb7\x61\x40\x93\x2b\x18\x44\xda\x10\x03\x2d\x89\x2d\x45\ -\xca\x43\x2b\xa8\x63\x0b\x34\x82\xd0\xf8\x1f\x86\x91\xb4\xe8\xad\ -\xeb\xe1\x69\xaa\xdc\x2b\xcc\x01\x45\xff\x52\x68\xd2\xa6\xbd\x8c\ -\x30\x64\x10\xe9\x4c\x61\x27\x53\xf0\x22\xa0\x7f\x3e\x07\x16\xe4\ -\x45\x8b\xe8\x4d\xde\x90\x30\x32\x8e\x94\x94\x70\x2f\x9d\x6a\xd8\ -\xa7\xa1\xcd\x96\xa2\x8d\x22\xa4\x4f\x19\x44\x3a\xa3\x28\x3b\x18\ -\xce\x05\x76\xcc\xe0\x20\x9f\xd2\x28\xfa\x1d\xf4\xc1\x74\xec\xa2\ -\x1f\xbb\x62\x18\x87\xe5\x11\xb1\x83\x0e\xc1\xde\x27\xec\xdc\x90\ -\x36\x21\x42\x5b\x46\x50\x1a\x9b\x2b\x19\x44\x22\x32\x18\x9d\x01\ -\x67\x26\x71\x60\x32\x18\x8d\x60\x2b\xf1\xc6\xed\xdc\x48\x69\x60\ -\xf4\xf0\x74\x28\xd4\x67\x0c\x49\xb9\x60\x34\x86\x10\x8d\xc8\x61\ -\x22\x2d\x17\x8c\x06\x11\x0a\x13\x19\x44\x5a\x2e\x18\x1d\x5b\x80\ -\xda\x94\x5b\xd4\xd2\xc5\x87\x68\x77\x06\x4a\xb9\x31\x82\x14\xa6\ -\x30\xa7\x81\x7b\x91\x40\x0e\x28\x88\x9b\x9f\xf4\x92\xf8\x66\x14\ -\x69\xd9\x60\x74\x8e\xe6\x34\x39\xc3\x31\x05\x35\x0d\x8c\xae\x8b\ -\x02\x6d\x21\xe3\x48\x98\x29\xed\xba\xca\x9b\x3d\x19\xb2\xec\x28\ -\xb6\x08\xa3\xa5\x3e\x19\x38\x0a\xbb\x67\x08\xdf\x5e\xb8\x09\x8e\ -\xe4\xc9\x09\x5f\x34\x8e\x4e\x79\x94\x71\x1c\x96\xf1\xed\x65\xbb\ -\x1a\xfb\x31\xb4\x8c\x2f\xb6\xc0\x1b\x94\x46\x1e\x3c\x43\xce\xf8\ -\xa2\xf3\xdc\xcc\x17\x0e\xe5\xdd\xe0\xd9\xc2\x48\xf8\xf9\x8a\x9c\ -\xe6\xb7\xeb\xa9\x5e\x04\x08\xde\xdd\xe5\xaf\x1f\x27\x82\x39\xe3\ -\x8b\x1e\xa3\x27\x21\x8e\x82\x12\xc3\x51\x4b\xa1\x61\x7c\xd1\x33\ -\x2c\x6b\x9d\x79\x0c\x21\x6d\x6b\x9a\x11\x43\x58\x10\xbe\xd8\xec\ -\x5a\x1e\xd1\x33\x7e\xc3\xed\xfb\x45\x4b\x21\xa4\x48\x9b\xea\x52\ -\x46\x91\x26\x3e\xc4\xe6\xd9\x9a\xf1\xcd\x0c\xe3\x50\xb4\x2f\x96\ -\xf5\x85\x7d\x1a\xb7\xc8\xc3\x39\x8c\x21\x09\xeb\x8b\x76\x4c\x21\ -\x41\x64\x10\x69\x49\x5f\x2c\xe1\x24\xdb\xad\x4b\x39\xac\x20\x1e\ -\x58\x82\xd6\xa5\xa0\x18\x32\x90\x84\xd9\x52\x6c\x68\x01\xa6\x69\ -\xd8\xa5\xa1\xcd\x95\x76\xab\x49\x19\x3d\x5a\x12\x18\x4b\x57\x34\ -\x7e\x0b\x87\xf8\x03\x92\xc0\xd8\x84\x77\x83\x18\xc3\x38\x28\x07\ -\x8c\x05\xb2\xe1\xed\x8f\x95\xaa\x5d\xee\xdf\x66\x20\x49\x38\xe0\ -\x7e\xa4\xb1\xf6\x57\x19\x44\x22\x0e\x18\xdb\x12\xe3\x5b\xc8\x9c\ -\x8e\xb8\x95\xb7\x69\x01\x8d\x1e\x1b\x34\x7c\x3b\x76\xa6\x82\x3b\ -\x18\x33\x0b\x36\x63\xe7\xa6\xfa\x84\x03\x67\x5c\x28\x52\x44\x0f\ -\xd4\xe3\xa1\x41\x94\x3e\xaa\x07\x7b\xa8\x97\x89\xa2\x12\xed\x92\ -\x0c\x46\x90\x6e\x13\x3e\x7e\x5c\x10\x24\x85\x52\x84\x9e\x0c\x3d\ -\x22\xf6\x62\xc4\x18\x16\x35\x19\xe0\x36\x7c\x9c\x14\x32\x82\xa4\ -\x55\x19\x11\xb8\xe7\xa9\x03\x9f\x86\x07\x77\x11\xe7\x6c\x3a\x90\ -\x45\x70\x1a\x22\x03\x49\x59\x99\xe1\xf4\x33\x5f\x36\x12\xca\xd5\ -\x0f\x8f\x51\xec\x5f\x1c\xf3\x1d\xf9\x78\x18\x21\x61\x64\x18\xe9\ -\xf9\x7d\xf4\xac\x60\x58\xad\x72\xcc\x4f\x98\x0a\xc7\x4f\xd1\x83\ -\xd3\x6f\x94\xb6\x71\xd4\xe9\xb7\x28\x0f\x37\x6c\x28\x13\xde\xc1\ -\xac\x60\x8e\xfc\x49\x73\x37\xca\x0a\xf0\xd3\x49\xa1\x61\xc1\x8c\ -\x23\x6d\xec\xd8\xc5\xf0\x6e\x70\x5c\x30\xc7\x1c\xc4\xc1\xa3\x82\ -\xeb\x89\x3b\x30\x91\xa1\x30\x17\x52\x75\x6c\x1f\x31\x94\xc6\xcf\ -\x31\x59\x00\x34\xd1\xa8\x84\x92\x5a\xb5\xb2\x44\x0e\x49\xfa\x1b\ -\x99\xec\x25\x2f\xc7\xf2\x48\xeb\xeb\x78\xda\x6b\x45\x3b\x3b\xa0\ -\xd7\x4a\x3b\xc2\x7b\xc4\x48\x16\xde\x4e\x2e\x9a\xbd\xe8\x56\x47\ -\x48\x4f\x3f\x88\x0a\xaa\x46\x0c\x64\x53\xde\x18\xf6\xe4\xb8\x32\ -\x94\xd4\xb5\x71\x2e\x9e\x48\xe6\xca\xaa\x41\x91\x04\x94\xaa\x3a\ -\x43\x4e\xfb\x32\xd2\x55\xa1\x17\xa8\x13\xe8\x5c\xa8\x31\x83\x12\ -\xbe\x1b\xf8\x92\xc4\xc5\x19\x37\x74\x56\x08\x24\xe4\xde\x0c\x1e\ -\x58\x5d\xcc\xe0\x91\x55\xe1\x00\x91\xe2\x9b\xb1\xf3\xe0\x56\xb5\ -\xa1\x8c\x6c\x92\xe6\x60\xa3\x86\xce\x14\xdf\x00\xfe\xcb\x9b\xc1\ -\x0b\xab\x6d\x18\x0c\xde\x30\xfb\xbe\x81\x80\xf0\xad\xe0\x29\x09\ -\x0f\x4c\x60\xad\x49\xc9\x0b\x63\xcc\x5e\x04\x75\xc7\x64\x00\x09\ -\xb7\x9b\x22\x0c\x9f\xb2\x81\xd9\x4f\xac\x3b\x49\xb7\x99\x02\x5c\ -\xfe\x9b\xe1\x73\x20\x9f\x93\xe1\x23\x72\x39\x31\x6a\x13\x0c\xf5\ -\x02\x11\x85\x76\xe4\xb2\xda\x24\x90\x3c\x4c\xb8\xf0\xca\xb6\x6e\ -\x06\x8f\xc8\xe6\x05\x18\xc9\x83\x62\x3d\xed\x86\xfa\x8e\x41\x8f\ -\xc1\x23\xb0\x79\x00\x15\x88\x0a\xf6\x18\x3d\xba\x2c\x0b\x22\xd6\ -\x83\xb3\x2c\xbe\x90\x9e\xa2\x19\x88\x30\x6a\xe8\x5c\x9c\xab\x09\ -\x67\x59\x18\x3c\x3a\xce\xd6\xc7\xe4\xc8\x40\x8f\x25\x12\x5a\x69\ -\x7a\x8a\x49\x21\x92\x34\x4b\xf7\x59\x16\xc6\x8f\x6e\x2f\x13\xc6\ -\x67\x01\x85\xcf\x15\x8e\xd6\x9c\x8c\x5d\xff\xb2\x07\x6e\xae\xc7\ -\x49\x1e\x83\x47\xc7\x2e\x00\x1b\x96\x70\xec\x02\x07\xea\xb4\xec\ -\x02\x26\xd3\x02\x4a\x1f\x03\x48\x56\x84\xdd\x79\x8a\x93\x7d\x16\ -\xc2\x92\xb2\xce\x89\x59\x46\x8f\x90\xd7\x43\xb8\x9c\x30\xaf\xc7\ -\xd1\x3a\x25\xaf\x67\x23\x2a\x01\x61\x62\x8f\xf1\xa3\xaa\xe1\x44\ -\xd9\x3d\x30\xcd\x19\x8a\x50\x2b\x4e\x87\x7d\x16\x02\xe1\x0b\xa0\ -\xcd\x7f\xb8\x44\x27\xc3\x47\x57\xc7\x89\x0a\xd7\x7f\xa9\xe3\x36\ -\xf3\x43\x14\x24\x03\x38\x71\x19\x1b\xf0\x31\x7e\x74\xd5\x9c\x18\ -\xe3\x07\x3b\x2e\xac\x3d\x89\xeb\x39\xbb\x8f\x1d\x18\x42\xca\x8a\ -\x4e\x68\x6b\x26\x36\xe9\xc9\x2a\x94\xb2\xa8\x13\xa5\x44\x5d\xc8\ -\x05\xa5\x44\xd0\xbc\x7a\xc4\x83\x0a\x8a\x7d\xb5\x80\x1b\x83\x1b\ -\xd1\xcb\xc3\x08\x49\xbb\x16\x7a\xe8\xd9\xae\x2d\x00\x9b\x29\x30\ -\x0c\x60\xff\x7e\x28\x58\xae\xd4\xc1\x14\x2d\x03\x2a\xe3\x47\xd4\ -\x6f\x12\x3d\x25\xbb\xad\x43\x19\x3d\x1a\xea\x08\xec\x69\xd7\x81\ -\xf4\xb1\x0d\xa4\x1d\x44\x88\x16\x40\x70\x9e\xab\x5d\x51\xbb\x8c\ -\x22\xcd\x24\x42\xb4\x2b\xd3\xde\xe1\xc7\xf8\x11\x4e\xae\xeb\x76\ -\x98\x6b\x50\xa4\x48\xa9\xd0\x1b\x75\x5b\x9e\x72\x2c\x08\xba\x51\ -\xaf\x12\x9e\x1d\xd9\xd1\x89\x10\x7a\x42\x85\x61\xc8\xad\xeb\x68\ -\xa2\xc1\x10\xdd\xf9\x5c\x9b\xc2\xc8\x77\x7c\xc7\x6b\x39\xa4\x7e\ -\x28\xdd\x90\xa8\x4b\xef\x88\x55\x69\x3e\xb3\x4e\xe1\xa7\x80\x72\ -\x50\x3f\xa8\x36\xf5\xf0\xc3\xb1\x21\x97\xd4\x17\x6e\xbe\x56\x44\ -\x13\x08\x46\x0c\x63\xd1\x3f\x12\xdc\xc5\x89\x0b\xed\xd9\x29\x25\ -\x4e\x70\x87\xf8\xb0\x02\x8c\xf1\x19\x48\xca\x19\x4b\xe0\xa4\xac\ -\x8b\x50\x6c\x06\x99\x1f\xa1\xe8\x15\xf3\x94\x1d\x92\x3e\x22\xa3\ -\x46\xb1\xf0\x4f\x7d\xbc\x30\x46\x42\x15\x26\x90\x61\x1c\x8c\xb3\ -\x00\x8b\xee\xf1\x63\xea\xd9\x4b\x25\xa7\x2e\x6c\xbc\xa3\x0a\x59\ -\x47\x46\x92\x96\xc6\xf0\xf1\x8e\x2a\x58\x53\xca\x4e\x0e\x29\x91\ -\x11\xe0\xa9\xc4\x13\xf7\x86\xe3\x45\x6a\x0a\x43\xe1\x1d\x9c\x50\ -\xc8\x33\x7d\xca\x40\xd2\x72\x19\x60\x79\xfe\x65\xe1\x46\x6b\x48\ -\xb6\x23\x38\x79\xda\xbb\x12\xcd\x67\x7e\x70\x31\xc6\xfb\x43\x2e\ -\x4f\x7b\x77\x50\x8c\xc8\xb5\x50\x43\x25\x69\x4c\xbe\x34\xc2\x87\ -\x85\x5c\x88\x31\x3c\x79\xd1\x81\x1c\x72\x21\xc6\x80\xac\x85\xdb\ -\x4f\x4c\xcf\x55\x6d\xd4\xd4\x85\x87\x17\xc4\x57\xba\x72\x31\x90\ -\x84\xd4\x05\x38\x83\x8e\x73\x6c\xef\x07\xc6\xb2\xb6\xc6\xef\x47\ -\x1c\x49\x71\x1c\xf5\xae\xb5\x82\xbc\xf0\xf1\x5e\x2a\xc4\x41\x71\ -\x98\x41\xc9\x5b\x80\xfb\xb7\x3b\x30\x8d\x0c\x22\x4d\x8a\x4d\x75\ -\x9f\xa7\xa1\xf4\x6a\x46\xad\x46\x0b\xca\xc9\xc6\x5b\x43\x50\x8d\ -\xb2\x73\x4a\x4a\x39\x75\x50\x91\x01\x11\x16\x1c\xf3\x93\x33\x4f\ -\x60\x1f\x4b\x7c\x89\x14\x23\x49\x4b\x3d\x49\xb4\x7b\x0a\xc2\x48\ -\xbc\x9f\x66\xc4\x30\xd6\x63\xae\x23\xe6\xa2\xde\x23\x7e\x0e\x3a\ -\x7d\xda\x44\xf4\x47\xd8\x29\xa7\x6a\xfa\xc5\x00\xf6\x2e\x80\xe0\ -\x84\xf9\xcb\x44\xcf\x06\x1a\x3b\x33\x86\x74\xce\x29\xbe\x16\x2a\ -\x12\x7e\xbe\x24\x27\x75\x18\x2a\x10\x81\x91\x4d\xee\x30\x44\xe2\ -\x98\x7a\x50\x97\xd2\xcb\x04\x51\x56\x80\x31\x8a\x43\x0d\x65\xc2\ -\x67\x4c\x41\x6d\xea\x09\x9f\xf1\x23\xe1\x12\x6d\x7c\x9b\xa1\x96\ -\x2b\xca\xe0\x11\x11\x16\x60\x9b\x4b\x3c\x7b\xc8\xae\x0c\x31\x67\ -\xa1\x3a\x6f\xb5\xc7\x10\x12\x66\x66\x6c\xb4\x0d\x84\xa3\x42\x56\ -\xa3\x34\x19\x99\x0e\xba\x0b\x81\x6a\x94\x0c\xbf\x11\xf7\x36\x89\ -\xf2\x5e\xb3\x80\xfa\xbc\xa8\xb3\x09\x98\x16\xd5\xf8\x29\x57\x3f\ -\x18\x44\x0a\x33\xe8\xc1\xb5\xa5\x97\xc1\xe8\x08\x19\x78\x81\xd7\ -\x56\xa3\x0c\x23\x59\x2d\x94\x6d\x62\x42\x24\x8c\x3a\x22\xb4\x43\ -\x37\x74\xdb\xf9\xb5\xc8\xb5\x03\x9a\x06\xec\xa3\x86\x31\xca\x2b\ -\xbd\x41\x0e\xff\x32\x18\x5d\xe1\x6a\x14\xc3\xb6\x51\x64\x69\x24\ -\x54\xaa\x26\x48\x44\x37\x6f\x0b\x84\xa3\xb5\x6a\xc0\xd6\x71\xc0\ -\x34\x4d\xd9\x5d\x01\x0b\x65\x28\x42\xa9\xa4\x52\xac\x5a\x07\xe4\ -\x7f\x2d\x70\x37\xd4\x65\xae\x8e\x14\x81\x32\x48\x0e\x08\xe4\x88\ -\xc3\xc6\xc8\x81\xa7\x6a\x5f\x14\x35\x36\x75\x17\x9c\xb9\x19\x6a\ -\x63\x29\xbe\x1b\x1f\x8c\x22\x93\x50\xb4\xdd\xf8\x1c\x74\x0e\x07\ -\xa6\x84\x39\x07\x47\xe7\xe0\x74\x50\x36\x0c\x12\xc2\x8c\x21\x0d\ -\x1d\xe5\xeb\xff\x7b\xe9\x6d\xca\x36\x91\x7c\x13\x4d\x17\x3b\x13\ -\x41\x61\x64\x28\x09\x4b\x86\xc1\x9e\xdf\x1d\x78\x37\xac\x51\xa9\ -\x62\x45\x85\xaf\xce\x00\x35\x2a\x23\x48\x16\xed\x7b\xa6\x09\xdf\ -\xfb\x76\x4e\x47\x9c\xb2\x29\x08\x46\x05\xd5\x2a\x76\x90\x44\xe5\ -\xcc\x1b\x31\xc5\xd8\x01\xc9\x08\x72\xc5\x0c\x24\x31\x3b\x15\x40\ -\x01\xff\x65\x12\x29\x85\xe7\x44\x4e\xc4\xb9\xf0\x81\xf9\x29\x70\ -\xc3\x7e\x07\x54\x23\x25\x94\xa3\xde\xf5\x1d\x59\x01\x6a\xe2\xba\ -\x76\x51\xc1\xb4\x4d\x64\xbb\x01\x89\x87\x33\x6a\xf4\x8c\x20\x2a\ -\xcc\xc0\x75\xe9\x03\xbb\xbc\x19\x3e\xca\x5d\x18\x11\x66\xdc\x3a\ -\x5c\xbd\xe8\x0a\x3b\xf0\x25\xcd\x78\xb6\x51\x03\x58\xa4\xbf\xc1\ -\x18\xf1\xcd\x08\x06\xc5\x94\x0b\x97\x11\x1c\x26\xd5\x06\x7a\xa3\ -\x6f\x46\x4f\x15\xe5\xdf\x8c\xde\x60\x69\x9a\x10\x8a\xef\xdf\x8c\ -\x5f\x04\xb9\x2f\x2d\xfc\xae\x66\xf7\x37\x1f\xae\x66\xfb\xaf\xfa\ -\xaf\xff\x03\xee\x2b\x64\x9e\ -\x00\x00\x0a\xad\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x70\x65\x6e\x5f\ -\x66\x69\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ -\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ -\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ -\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ -\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ -\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ -\x3d\x22\x2d\x38\x31\x2e\x31\x30\x30\x32\x37\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ -\x2d\x32\x2e\x36\x31\x31\x30\x33\x35\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ -\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ -\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\ -\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ -\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ -\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ -\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\ -\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ -\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ -\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ -\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ -\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ -\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ -\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ -\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ -\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ -\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ -\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\ -\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\ -\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\ -\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x38\x30\x38\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\x39\x32\x35\x36\x39\x36\x31\ -\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ -\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\x39\x2e\x32\ -\x34\x34\x34\x34\x34\x38\x20\x48\x20\x32\x36\x2e\x36\x36\x36\x36\ -\x36\x37\x20\x56\x20\x33\x35\x2e\x39\x31\x31\x31\x31\x31\x20\x48\ -\x20\x30\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x30\x32\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ -\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ -\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x33\x37\x63\x38\x37\x31\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ -\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x30\x2e\x36\ -\x36\x36\x36\x36\x37\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\ -\x48\x20\x33\x32\x20\x56\x20\x32\x38\x2e\x38\x20\x48\x20\x31\x30\ -\x2e\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x38\x2d\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ -\x35\x30\x32\x38\x33\x31\x35\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ -\x22\x4d\x20\x30\x2c\x39\x2e\x32\x34\x34\x34\x34\x34\x38\x20\x35\ -\x2e\x33\x33\x33\x33\x33\x33\x33\x2c\x31\x36\x2e\x33\x35\x35\x35\ -\x35\x36\x20\x56\x20\x34\x31\x2e\x32\x34\x34\x34\x34\x35\x20\x4c\ -\x20\x30\x2c\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x76\x20\x2d\ -\x32\x34\x2e\x38\x38\x38\x38\x38\x38\x32\x20\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ -\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x07\x31\ -\x00\ -\x00\x20\x5c\x78\x9c\xed\x59\xdd\x8f\xe3\xb8\x0d\x7f\x9f\xbf\xc2\ -\xf5\xbe\xec\xa2\x91\xac\x0f\xcb\x92\xbc\xc9\x1c\x8a\x2e\x0e\x38\ -\xa0\x7d\x69\xaf\xe8\xb3\x63\x2b\x19\x77\x1c\x3b\xb0\x9d\x49\xb2\ -\x7f\x7d\x29\xc7\x5f\x49\x9c\xd9\xd9\x36\x77\x0b\x1c\xc6\xc1\x20\ -\x23\x92\x92\x48\x8a\x3f\x92\x72\xe6\x3f\x1d\x36\x99\xf3\x62\xca\ -\x2a\x2d\xf2\x85\x4b\x31\x71\x1d\x93\xc7\x45\x92\xe6\xeb\x85\xfb\ -\xaf\x5f\x7f\x46\xca\x75\xaa\x3a\xca\x93\x28\x2b\x72\xb3\x70\xf3\ -\xc2\xfd\xe9\xf1\x61\xfe\x27\x84\x9c\xbf\x96\x26\xaa\x4d\xe2\xec\ -\xd3\xfa\xc9\xf9\x25\x7f\xae\xe2\x68\x6b\x9c\x8f\x4f\x75\xbd\x0d\ -\x3d\x6f\xbf\xdf\xe3\xb4\x25\xe2\xa2\x5c\x7b\x9f\x1c\x84\x1e\x1f\ -\x1e\xe6\xd5\xcb\xfa\xc1\x71\x1c\xd8\x37\xaf\xc2\x24\x5e\xb8\xed\ -\x84\xed\xae\xcc\x1a\xc1\x24\xf6\x4c\x66\x36\x26\xaf\x2b\x8f\x62\ -\xea\xb9\x83\x78\x3c\x88\xc7\x76\xf7\xf4\xc5\xc4\xc5\x66\x53\xe4\ -\x55\x33\x33\xaf\x3e\x8c\x84\xcb\x64\xd5\x4b\x5b\x6d\xf6\xbc\x11\ -\xa2\x5a\x6b\x8f\x30\x8f\x31\x04\x12\xa8\x3a\xe6\x75\x74\x40\xe7\ -\x53\x41\xc7\xa9\xa9\x8c\x10\xe2\x01\x6f\x90\x7c\x9b\x54\x58\x81\ -\x43\xb7\xf0\xd7\x8b\x77\x04\x5c\x15\xbb\x32\x36\x2b\x98\x67\x70\ -\x6e\x6a\xef\xcb\xaf\x5f\x7a\x26\x22\x38\xa9\x93\xd1\x32\x9d\x3f\ -\xcf\x76\x3d\x73\x72\x1e\x6d\x4c\xb5\x8d\x62\x53\x79\x1d\xbd\x99\ -\xbf\x4f\x93\xfa\x69\xe1\x72\x1f\x53\x0e\x8f\x68\x88\x4f\x26\x5d\ -\x3f\xd5\x97\xd4\x34\x59\xb8\xa0\x3d\xd3\xea\x34\x1e\x05\x07\x3d\ -\x09\xb4\x0b\x87\x3d\x87\x60\xcd\x30\x75\x4a\x2a\xb8\x3c\xc9\x74\ -\x26\x84\x49\x11\x5b\x9d\x40\x63\x93\x6d\x71\xe7\x95\x7e\x09\x73\ -\xd8\x16\x65\x8d\x0e\xc9\x16\x7c\x13\xc8\x49\xe6\xb1\x63\x3e\x02\ -\x77\x9e\x98\x55\x65\xa5\x4e\x8a\xda\x11\x68\x2a\x5d\xc7\x6b\xb8\ -\xfd\xbe\x76\xd3\xe4\x25\x35\xfb\x41\x76\x19\x55\x27\x67\x38\xce\ -\x36\x5a\x43\xe0\x64\x45\xb9\x70\x3f\xac\x9a\xa7\x65\x2c\x8b\x32\ -\x31\x65\xc7\x0a\x9a\xe7\x8c\x55\x80\x73\xd3\xfa\x78\x82\x4a\xbb\ -\x76\xa7\xaf\x5d\xb5\xe7\x93\x69\x7e\xf5\x14\x25\xc5\x7e\xe1\xb2\ -\x4b\xe6\xd7\xa2\xd8\xc0\x51\x60\x2d\x34\x61\x44\x5d\xb2\xe3\xc3\ -\xc2\x45\x8a\x60\x46\xa8\xef\x5f\x73\x61\x43\x0e\xa7\x20\x09\xa3\ -\xe2\x8a\xb9\x2b\x4b\x00\x13\xca\xa2\xa3\x01\xab\x9a\x2f\xda\x0a\ -\x55\x4f\xc5\x7e\x5d\x5a\xef\xd4\xe5\xce\x5c\xce\xb4\x1c\xb4\x5c\ -\x16\x87\x69\x36\x9c\xed\xce\xc2\x14\xed\xf2\xb4\x06\x28\x6c\x0f\ -\xe3\x55\x77\x69\x62\xaa\xe9\x89\xfb\x34\x07\x27\xa0\x36\x28\x29\ -\xef\x7d\x7c\x29\xd1\x45\xa8\xbc\x76\x48\x2b\x01\xaa\x5d\xf9\xb9\ -\x65\x1d\x6f\xb3\x36\xd1\x21\xdd\xa4\x5f\x0d\xd8\x4d\x2f\x45\xaa\ -\x3c\xda\xa2\x75\x56\x2c\xa3\xac\xd5\xfe\xb1\x91\x98\x9f\xb9\xe5\ -\x34\xc9\x71\xea\xa3\x85\xe3\xe1\x68\x69\x6e\x47\xb4\xfe\xb4\x04\ -\x2e\x03\xd1\x13\x8b\x32\x5d\xa7\xf9\x48\xdf\x8e\x74\x1c\x93\x2c\ -\x78\x21\xf7\x1e\x9a\x00\x6b\xc2\x4f\x5e\xf2\x8e\x63\x5e\x1b\xf7\ -\xde\x75\xe0\x37\xf4\x8d\xa9\xa3\x24\xaa\xa3\x01\x05\x1d\x85\x69\ -\x4d\x3a\xcb\x20\x0f\x86\xff\xf8\xf2\xf3\x63\xbb\xd1\x3c\x8e\xc3\ -\x7f\x17\xe5\x73\xb7\xaf\xe3\x58\x81\x68\x59\xec\xe0\x28\xdc\xc7\ -\x9e\x3c\x4f\xe2\x10\x32\xd7\x26\xaa\x1f\xd3\x0d\xc4\xb6\x4d\x7a\ -\x7f\x86\x4c\x35\xf7\x06\xc6\x99\xb0\x75\xd6\xb0\xe8\x69\xd9\xd2\ -\x9c\x52\xe0\x64\x1d\x48\xe2\x4d\x6a\x27\x79\xff\xac\xd3\x2c\xfb\ -\xc5\x6e\xd2\x5a\x3c\x5a\x34\xad\x33\x33\x10\xe7\x5e\xab\x7d\x6b\ -\x9b\x37\x32\x6e\xee\x75\xd6\x37\xa3\xf5\xe0\x95\x33\x50\xf4\x07\ -\x9d\x45\x4b\x03\x41\xf0\x37\xcb\x74\xae\xb8\xeb\xb2\xd8\x6d\x37\ -\x45\x62\xda\xe9\x9d\x37\xe3\xb4\x8c\xb3\xde\xce\xaa\x3e\x66\x20\ -\xd1\xa4\x94\xf0\x03\x69\x9e\xcf\x49\x5a\x6d\x61\x0e\x24\xf4\x2c\ -\xcd\xcd\xe7\x02\x32\xe9\x2a\x2b\xf6\xe1\x4b\x5a\xa5\xcb\xcc\x7c\ -\x6e\xbe\xd3\x0c\x6c\xef\x49\x2b\x70\x40\xf8\x61\x15\xd8\x4f\x33\ -\x40\x6d\xaa\x09\xe9\x69\x58\xee\x32\x13\xe6\x45\xfe\x15\x92\xd4\ -\xe7\xaa\x2e\x8b\x67\x63\xf7\x0b\x62\x9d\xb4\xc3\x13\xe0\x42\xd2\ -\x0d\xed\xde\x60\x49\xb8\xdc\xd5\xf5\x98\xf6\x9f\x22\xcd\x43\x70\ -\xbc\x29\x3b\x6a\x33\xc8\x00\x32\x75\xc8\xb1\xe8\xa8\x49\x04\xd9\ -\xac\x2c\xc1\x0e\xd8\xd6\x8c\xa9\xc5\x6a\x55\x99\x3a\x64\x58\x71\ -\xa6\x08\x15\xaa\x63\x0e\x3a\x6f\xa2\xf2\xd9\x94\xa7\x99\x26\x8f\ -\xc0\x44\xb4\x8c\xe2\x67\xeb\xd4\x3c\x09\xa3\x18\x52\xcb\x2e\x83\ -\xfe\xe2\x0c\x54\xdb\xa8\x7e\xe2\x4c\xe8\x9e\x68\xd3\x22\x95\x27\ -\x34\xa8\x81\x6a\x21\x12\xf4\xc3\xb2\x19\x75\x21\xd2\x1d\x7b\x0b\ -\x53\x4e\x28\x75\x2f\x0e\x6b\xf0\x1e\x59\x31\x76\xa5\x7b\x0f\x81\ -\xb9\xd5\x67\x08\xe8\x3e\x32\xea\x32\xca\x2b\x0b\x00\x14\x43\x7a\ -\x34\xa5\x4d\x45\x0c\x07\x4c\x69\xed\xbb\x6f\x91\xb7\xc9\x9e\x62\ -\x29\xb5\x1c\x1b\x3b\x2a\xab\xc5\xd6\xe4\x67\xb9\xf5\x8c\x6b\xf2\ -\xc4\x16\x20\x45\x85\x14\x5a\xa8\x29\x11\xe8\xe9\xca\x7a\x9c\x78\ -\x20\x95\x75\x5a\x2c\xdc\xb2\xa8\xc1\xf5\x1f\x03\x1f\xd6\x80\xf4\ -\x4c\x3f\x8d\xc4\x60\xe9\xbf\x3b\x5c\x60\x11\x28\x3a\x43\x0a\xfb\ -\x92\x2b\x46\x03\xe7\x2f\x0e\xe5\x58\x35\x59\x69\xd6\xfd\xa7\x1c\ -\x02\x1f\xea\x70\x0a\x85\xcb\xf7\xa5\x3f\xa3\xe0\x06\x5f\x30\x25\ -\xa7\x94\x2a\xed\xb9\x75\x53\x27\x05\x0e\x83\xc0\xe4\x0a\xf6\xe4\ -\x07\x9d\x26\x25\x60\x09\x06\xbe\x85\x3a\xca\xf9\xf8\x30\xba\xf0\ -\x82\x43\x47\x0c\x8d\xcf\xe9\xae\x10\x1e\x41\xe5\x32\xc0\x4e\xf0\ -\x14\x58\xfb\x52\x11\x2d\xff\x2f\x98\xfa\xdf\x01\x52\xad\x02\xc2\ -\x7d\x25\xef\x00\xd2\x91\xa3\x4f\x95\x31\x2a\xe3\x51\xc6\xbe\x00\ -\xcc\xef\x1c\xce\x08\x62\x19\x33\x9f\x11\x71\x15\xcf\x10\x33\x82\ -\x68\x2d\x69\x30\xd3\x98\x52\x48\x59\x82\x4e\x46\xb4\x6c\x23\x1a\ -\x51\x48\x6e\x92\x0b\xad\x66\x54\x43\x70\x2b\x41\xc4\xb7\x42\x7a\ -\x3a\xe6\xdf\x12\xd2\xbd\x4e\xb7\x22\x1a\x31\x86\xa1\xdb\x08\xb8\ -\xba\x1d\xd2\x14\xa9\xf7\xa0\xfe\xed\x83\xfa\xd5\x2a\x00\x57\x3a\ -\xa6\x89\x94\x94\xcb\x37\x17\x02\x06\x85\x00\x92\x95\xfc\x81\x85\ -\x00\xd0\x41\x7d\x50\x5b\x5f\x17\x02\xd0\x0e\x2a\xb2\x0c\x2c\x42\ -\x02\x00\x10\x7f\x15\x36\x4c\x61\x1e\x28\x2d\x66\x8c\x63\xa9\x85\ -\x3f\x9d\xe5\xef\x82\x99\x4e\x9f\x5b\x90\xa1\x0a\x16\x10\x9a\xbe\ -\x52\x03\x10\x7d\x07\xcc\x1f\xb0\x0a\x48\x86\x89\x20\x92\x5f\x57\ -\x01\x81\x39\x64\x51\xc5\xe4\x0c\x51\x1f\x73\x2d\x84\xd2\xaf\x36\ -\x36\x48\xdb\x4e\x82\x13\xa5\x66\xc8\x07\x68\x4b\xc6\xd5\x64\xdb\ -\x71\xa7\xd6\xa6\xd7\xea\x66\x21\x68\xaa\x91\xcf\xc5\xab\x75\xe0\ -\xbd\xbd\xf9\xf1\x95\x80\x61\xa1\x18\x3f\xef\x84\xbf\x75\x23\x20\ -\xd0\xd8\x4a\xfe\x03\x0b\x01\x12\x1c\xfb\x54\xfb\x94\x5d\x81\x87\ -\xc2\xf2\x70\x0f\x93\xd2\xe6\xf6\x00\x24\xd4\xeb\x1d\x54\x80\x7d\ -\x9f\x03\x0e\xc5\x8c\x43\x2d\xe0\x3a\xe0\x93\xdd\xcd\x7d\x8a\x41\ -\xaf\xd2\x4d\xdc\x70\xc8\x09\x5a\x6b\xc2\x5e\xad\x07\x88\xbd\x03\ -\xe7\x0f\x57\x11\x20\x2e\xb0\x60\x92\xca\x8b\x98\xde\x38\x14\x82\ -\x54\x0a\x4a\xf8\x0c\xd9\x86\xc5\x0f\xa0\x07\x77\xa2\xd7\xea\x01\ -\xe4\xe7\x80\x07\x0c\xda\x21\x82\x89\x56\x7c\xba\x65\xbf\x53\x35\ -\xe8\x75\xba\x79\xd1\xc5\x01\x51\x50\x0c\xf4\x37\xaa\x01\xd2\xef\ -\x61\x7d\xf7\xb0\x9e\x7b\xeb\xf6\x1f\x93\x65\xe9\xb6\xfa\x8d\x5e\ -\x09\x12\xc2\xb8\x1f\xbf\xfd\x95\xa0\x11\xf6\x73\x7e\x08\x14\xfa\ -\x1e\x21\x29\xf3\xf9\xef\x74\x0a\xe4\x0e\xce\xef\x02\x19\xee\xe0\ -\x0c\x0d\x6d\x7e\xd3\xdb\x07\x58\x69\xdf\x67\x23\x6a\xf3\x4a\x10\ -\x43\xbf\xcf\x46\xef\xe4\x2d\xcc\x24\xf6\x2d\xca\xc4\x20\x6b\xd1\ -\x19\xe0\xd3\x8f\x3f\x62\x38\xce\xe9\x53\xbc\x8e\xf2\x29\x07\xdb\ -\x1f\x6e\x18\xa1\x4a\xaa\xef\x77\xdb\xf0\xde\xf1\xd2\xf2\x00\x1a\ -\x3d\x14\x5c\x5a\x2e\x14\xe7\xa3\x77\x9a\xb7\x2d\x87\xab\x9b\xb6\ -\x8f\xb8\xb0\xdc\xb6\xc0\x94\xde\xb6\x7c\xb4\xbd\x40\xa3\x9f\x27\ -\xbe\xcf\x21\xf6\xc5\xab\xa0\x8a\xde\xc3\x21\xe3\x33\x7f\x8b\xe5\ -\x01\x66\xf6\xa1\xfe\x77\x5a\x3e\xaa\x1d\x9b\xa8\x2e\xd3\xc3\x47\ -\xc8\xf2\x24\xe0\x52\x28\x39\x23\xd8\x3a\x53\xea\xc0\xde\x1e\x66\ -\xc4\x7e\x3e\x4d\x1d\x99\x44\xe2\x7f\xf5\x19\x23\x0a\x6e\xcd\xec\ -\x8e\x2e\x03\xe7\x04\xa3\x9e\xe7\x74\xc9\x08\xb0\x75\xa4\x1f\x5c\ -\x44\x0b\xd4\x12\x39\xba\x79\x58\x97\x49\x0c\xa1\x46\x44\x40\xfb\ -\x1f\xa2\x20\xe7\xcd\xed\x0f\x41\x8f\x0f\xff\x05\xb6\x74\x74\x2d\ -\ -\x00\x00\x0a\x2a\ -\x00\ -\x00\x2f\xfb\x78\x9c\xed\x5a\x59\x8f\xdb\xc8\x11\x7e\x9f\x5f\xc1\ -\xc8\x2f\x36\xa2\xa6\xfa\x66\x37\x67\xc6\xfb\xb0\x8b\x0d\x16\xd8\ -\x20\x40\x6c\x23\x8f\x0b\x8a\x6c\x49\x8c\x29\x52\x20\xa9\x91\xe4\ -\x5f\x9f\x6a\x52\xbc\x24\xce\xa1\x19\x7b\xb2\x71\x2c\xc3\xb0\xba\ -\xaa\xfa\xaa\xaa\xaf\x8e\x96\x6f\x7e\xda\xaf\x13\xe7\xce\xe4\x45\ -\x9c\xa5\xb7\x13\xe2\xe2\x89\x63\xd2\x30\x8b\xe2\x74\x79\x3b\xf9\ -\xf4\xf1\x57\xa4\x26\x4e\x51\x06\x69\x14\x24\x59\x6a\x6e\x27\x69\ -\x36\xf9\xe9\xfd\xd5\xcd\x5f\x10\x72\x7e\xce\x4d\x50\x9a\xc8\xd9\ -\xc5\xe5\xca\xf9\x2d\xfd\x5c\x84\xc1\xc6\x38\x6f\x57\x65\xb9\xf1\ -\x67\xb3\xdd\x6e\xe7\xc6\x47\xa2\x9b\xe5\xcb\xd9\x3b\x07\xa1\xf7\ -\x57\x57\x37\xc5\xdd\xf2\xca\x71\x1c\xd8\x37\x2d\xfc\x28\xbc\x9d\ -\x1c\x27\x6c\xb6\x79\x52\x09\x46\xe1\xcc\x24\x66\x6d\xd2\xb2\x98\ -\x11\x97\xcc\x26\x9d\x78\xd8\x89\x87\x76\xf7\xf8\xce\x84\xd9\x7a\ -\x9d\xa5\x45\x35\x33\x2d\xde\xf4\x84\xf3\x68\xd1\x4a\xdb\xd3\xec\ -\x58\x25\x44\xb4\xd6\x33\x4c\x67\x94\x22\x90\x40\xc5\x21\x2d\x83\ -\x3d\x1a\x4e\x85\x33\x8e\x4d\xa5\x18\xe3\x19\xf0\x3a\xc9\xa7\x49\ -\xf9\xfb\x04\x54\x71\xef\x61\x2a\x6e\x7f\x77\x50\xff\x06\xfe\xb6\ -\x13\x1a\x82\x5b\x64\xdb\x3c\x34\x0b\x98\x69\xdc\xd4\x94\xb3\x5f\ -\x3e\xfe\xd2\x32\x11\x76\xa3\x32\xea\x2d\xd3\x68\x7f\xb0\xef\xc0\ -\x24\x69\xb0\x36\xc5\x26\x08\x4d\x31\x6b\xe8\xd5\xfc\x5d\x1c\x95\ -\xab\xdb\x09\xe3\x2e\x61\xf0\x11\x15\x71\x65\xe2\xe5\xaa\x3c\xa5\ -\xc6\xd1\xed\x04\xee\x4a\xb5\xaa\xc7\x3d\x57\x22\xb5\xc0\x71\x61\ -\xbf\xe5\x60\x57\x53\x97\x38\x39\x11\xcc\xab\x65\x9a\x2b\xf8\x51\ -\x16\xda\x33\xc1\x92\x66\x1d\x07\xdb\x32\x5b\x83\x8d\xc3\x30\x09\ -\x8a\x22\x5e\xc4\x21\x0c\xb2\x74\x93\x6c\x97\x71\xfa\x47\x98\xc4\ -\x9b\x3f\xca\x2c\x4b\xdc\x46\xd5\xed\x4e\x66\xbf\xc9\xf2\x12\xed\ -\xa3\x0d\xa8\x50\x7a\xa3\xcc\x43\xc3\x7c\x0f\xdc\x9b\xc8\x2c\x0a\ -\x2b\x55\xdf\xc7\x8e\xe0\x42\x35\x0f\xb8\x60\x1e\x13\xe4\x7f\xcb\ -\x83\x28\x06\xa7\xac\xe5\x7a\x2b\x86\x59\x92\x98\x10\x34\x13\x24\ -\xbb\xe0\x50\x4c\x5a\x01\x58\x6a\x38\x95\x63\x26\x8f\x8b\xc2\xb2\ -\x45\x99\x6d\x1a\x59\xd0\x41\x79\x48\xec\xc5\x81\x88\x60\xc5\x2c\ -\xf7\xdf\xe0\xea\x73\x5d\x91\x32\x30\x53\x5c\x1e\x7c\x72\x3d\xe9\ -\xe6\x64\x8b\x45\x61\x60\x63\xdc\xa3\x55\x06\x81\x19\xb0\x17\x40\ -\x77\xf6\xb2\xdd\xf0\xd8\x6e\x64\x74\x37\x8e\xdb\xdd\x6e\x66\xc3\ -\x6b\x7f\x7d\x35\x52\x75\x91\x1a\xf9\x5c\x93\xe7\xab\x11\x5f\xa8\ -\xc6\xf3\xdd\x2e\x50\x23\xa3\xcf\x54\xe3\x99\x96\x98\x52\xfa\xb5\ -\xb4\xc4\x94\x26\xf7\x6b\xa9\x27\xe5\x8d\x2d\xe8\xca\xda\xf7\xe8\ -\xe4\x39\x27\x7c\x35\xe3\xc0\xf1\xd9\x37\xf2\xf1\x2a\x03\xf8\xab\ -\xdc\x40\xc6\x7a\x33\x62\xc6\x87\xac\xac\x45\xb7\x0c\xb9\x9d\x50\ -\xd9\x0e\x0f\x30\x24\xdd\x70\x4f\x81\xdb\x09\x1f\x60\x48\x3a\x63\ -\x2e\x8f\x0b\x7e\x4a\xe3\x12\xd2\xda\xb6\x30\xf9\x07\x9b\x1a\xfe\ -\x91\x7e\x2a\xcc\x99\xd4\xc7\x3c\x48\x0b\xc8\x43\x6b\x50\x4d\x18\ -\x24\xe6\x2d\x54\x0e\xd2\x7e\xbc\x77\x9d\x8a\x2e\xf1\x54\x74\x59\ -\x60\x7c\xa1\xaf\x22\xfd\x34\x6f\x45\xe4\x7f\xdc\x5f\x7b\x17\xbd\ -\xc8\x63\x4f\x9c\xe3\xd4\x75\x4e\x1c\x6b\xe8\x76\x4f\xf3\xa4\x11\ -\x37\x80\x5a\xe8\xa9\x88\x40\xdd\x76\x8f\x82\x6b\xc4\x67\xa1\xac\ -\xc8\xe3\xfd\x5b\xec\x52\x25\x09\x15\x1e\x9b\x82\xff\x52\x4f\x78\ -\xdc\x9b\xa2\xee\x6b\x8f\x4f\x3d\x17\x2c\xce\x89\x9a\x22\xe1\x2a\ -\xc1\x24\xa6\xe2\x71\x57\x7f\x01\xee\xab\x24\xf7\x60\x29\xc1\x07\ -\x06\x60\xd2\x25\x12\x72\xbe\x1e\x58\x89\xc1\x0d\x3c\x4d\xc4\xc0\ -\x92\x8c\xb9\x4a\x32\xae\x87\xb1\x00\xee\x25\x19\x15\x98\x89\x97\ -\xc7\x84\x4e\xbf\xda\x83\x7b\x50\x50\xa5\xfd\xe3\x0a\xcc\xa9\x04\ -\xb7\x04\x75\x7b\x9e\x56\x58\x8a\x29\xd2\x2e\x25\x1a\x10\xf5\xad\ -\xd5\xc9\xe4\x83\xea\xe4\x74\xa8\x4e\xea\x32\x46\x29\x63\x03\x75\ -\x22\x42\x5c\xe1\x69\xfe\x7f\xa2\xcf\xf1\x0a\x16\xe1\xd7\xac\x61\ -\x91\x78\xdd\x2a\x16\x91\x57\xad\x63\x11\x7f\xcd\x4a\x16\xb1\xd7\ -\xad\x65\xd1\x33\x0b\xa6\x7b\xf0\x73\x0f\xd8\xc6\x81\x39\x0a\xe2\ -\xe7\xe6\x26\x8e\x25\x7b\x6a\x98\x41\x9d\xf6\x5f\x96\x9b\x46\xb1\ -\x4e\xa7\xd0\xe8\x2b\xce\x20\xff\x78\x6a\x0a\xd7\xe6\x9a\x33\xf6\ -\x28\xd6\x2f\xd6\xe8\x79\xe6\x18\x4d\x32\x2f\x50\xa8\x78\x9a\x42\ -\x2b\x8c\xfc\xd7\x14\x7a\x33\xb3\xaf\x01\xd5\xb7\xf6\x95\xc2\x3e\ -\x51\x44\x77\xb1\xd9\x5d\xb5\x97\x9b\x07\xed\x6d\x37\xc1\xd2\x54\ -\xf8\x81\xbb\x2c\xaa\xcf\x91\x31\xcf\xf2\xc8\xe4\x0d\xab\xaa\x96\ -\xe5\x80\x75\x84\x58\xfd\x0c\x77\x35\xbc\xaf\x5d\xb5\xe5\xe3\x71\ -\x7e\xb1\x0a\xa2\x6c\x07\xb5\xd8\x29\xf3\x4b\x96\x81\x1e\xe0\x6a\ -\x44\x7b\x0a\x9f\xb1\xc3\xbd\x05\x10\x73\x99\xf4\x08\x3b\x63\xc2\ -\x7e\x14\xc0\x45\x31\x21\xe4\x8c\xb9\xcd\x73\x50\x36\x4a\x82\x83\ -\x81\x4b\x55\xff\x34\x42\xc5\x2a\xdb\x2d\x73\xab\x9c\x32\xdf\x9a\ -\xd3\x99\x96\x83\xe6\xf3\x6c\x3f\xce\x8e\xb2\x70\x6b\x5f\x00\xd1\ -\xb6\xf6\xab\xcd\xbe\xbf\xea\x36\x8e\x4c\x31\x3e\xb1\x48\x83\x0d\ -\x5a\x26\xd9\x3c\x48\xc6\x05\x76\x71\x0a\x4a\x42\xc7\x27\x2e\xc2\ -\x5a\x1b\x9c\x4a\x34\xef\x5d\x1e\x56\xf7\x48\xec\xbb\x40\x7b\xca\ -\x3a\xdc\xcf\x5a\x07\xfb\x78\x1d\x7f\x31\x51\x17\x36\x3b\xad\xd8\ -\x9b\xf5\xd5\x72\xc4\xf4\x40\x6d\x8d\xab\x97\x07\xfb\xb6\xb7\x3f\ -\x58\xda\x00\x69\x96\x40\x75\xaf\xd7\xce\xf2\x78\x19\xa7\xfb\x7e\ -\x5e\xa8\x49\x87\x3e\xc9\xbe\x04\xc6\xe9\x72\x5f\xf9\x5f\xdd\xcc\ -\x9d\xf2\x0e\x7d\x5e\x03\x90\x73\x5c\x54\xf4\xb5\x29\x83\x28\x28\ -\x83\x0e\x24\x0d\x05\xce\xd6\x94\x10\x37\x79\xb4\xf0\xff\xf9\xcb\ -\xaf\x6d\x4e\x0a\x43\xff\x5f\x59\xfe\xb9\x4b\x27\x56\x20\x98\x67\ -\x5b\xb0\x44\x9b\x29\xed\x8b\x5d\xe8\x5b\x74\x07\xe5\xfb\x78\x0d\ -\xae\x6f\xdf\x5b\xff\xba\x5f\x27\x00\xd7\x96\x31\x10\xb6\xca\xea\ -\x16\xad\x97\xcd\x4d\xfd\x9e\x3a\xfa\x04\x1d\x85\xeb\xd8\x4e\x9a\ -\x7d\x28\xe3\x24\xf9\xcd\x6e\xd2\xcb\x9d\xc7\x45\xe3\x32\x31\xbd\ -\x84\x3a\x3b\x9e\xbe\xc9\x78\xbd\xcb\xdd\xcc\x9a\xdb\x57\xa3\x65\ -\xa7\x95\x01\x68\x5a\x43\x27\xc1\xdc\x80\x07\xff\x6e\x99\xce\xb9\ -\x9f\xe4\xd9\x76\xb3\xce\x22\x73\x9c\xde\x68\xd3\x24\x49\xbc\x29\ -\xda\x8b\x1e\x53\xfa\xb0\x34\x8a\xe2\x62\x03\x93\xfc\x38\xb5\x91\ -\xf6\x3a\xbb\x33\xf9\x22\xc9\x76\xfe\x5d\x5c\xc4\xf3\xc4\x5c\x57\ -\xff\xc6\x89\xcd\xf5\x0d\x69\x01\x1a\xf0\xd3\x0c\xa4\x8b\x32\xcf\ -\x3e\x1b\xff\x8d\x16\x86\x2d\x16\xc7\x61\x0d\x26\x9f\xba\x92\x08\ -\xca\x09\x16\x0d\xdd\x6e\x00\xe7\xf5\xe7\xdb\xb2\xec\xd3\xfe\x9d\ -\xc5\xa9\x0f\xea\x35\x79\x43\xad\x06\x09\xe0\xa2\xf4\x79\x43\x8b\ -\x02\x08\x68\x79\x0e\x47\xed\x6d\x5d\x51\xeb\xb2\xc3\xc7\x0d\xad\ -\xab\x85\xd6\x41\xfe\xd9\xe4\xf5\x04\x93\x06\x70\x78\x34\x0f\xc2\ -\xcf\x56\x5f\x69\xe4\x07\x21\x44\x95\x6d\x12\x94\xc3\xcc\xb4\x09\ -\xca\x15\xc3\x5c\x22\x81\xb8\x2d\x59\x5a\x80\x8d\xe4\x10\xad\xa4\ -\x82\x48\xc8\x20\x7f\x10\x49\x34\x93\xca\xa6\x0f\x88\xab\x94\x30\ -\x41\xa7\x56\x00\x4a\x00\x2c\xa4\x4d\x31\xef\xda\xa5\x6c\x88\xd5\ -\xae\xe4\x98\x68\xd1\xb5\x75\x36\xb6\x42\xdc\x05\xaa\xa4\x5d\x8e\ -\xcb\x41\x96\xbb\x0c\x4b\xdd\x95\x55\xf9\xc1\x66\x64\x48\x51\x12\ -\xb6\xe9\x72\xbd\x3d\xf9\x83\xc6\x5e\x64\x10\x43\x2b\x0e\xe8\x04\ -\x50\x91\xd4\x94\xbb\x20\x8f\x83\xb4\x1c\xd0\x76\x55\xbc\x1b\x90\ -\x40\xbd\xa6\x0c\x57\x43\x1a\x84\x2e\x1f\x70\x1e\x6f\xd7\xd7\xd6\ -\x96\xc7\x38\x39\x90\x59\x04\xeb\x38\x39\xf8\x1f\x40\x7d\xd7\xa8\ -\x71\x5a\x54\x4f\xdf\x98\xb0\x7d\xca\xaf\x25\x4a\xb3\x2f\x41\x2a\ -\x82\x70\x0f\x26\xad\x46\x41\x12\x2f\x53\xbf\x28\x83\xbc\xac\x09\ -\x11\xa4\xd4\xbc\x9e\x53\xd9\xf6\x84\x58\x79\x55\xcd\x49\x4c\x09\ -\xae\x84\x8e\x01\xab\x39\xd6\x0e\x12\xec\x29\xad\x5a\xa3\xb5\x71\ -\x3d\x7b\x97\xc7\x25\x88\x20\x8b\x2d\x3f\xc9\x51\x39\x07\xbc\xe4\ -\x50\x68\xd8\x9d\x93\x32\xbf\xb6\x89\xbe\xba\x76\xb1\x8a\x17\xa5\ -\xdf\x0c\x8f\xc7\x4e\xc3\x15\x28\xbf\x3e\xf7\x73\x71\xd6\x60\xcb\ -\x0e\x7a\x9e\x7d\x44\x5e\x1f\x0a\x35\xec\xc0\x7f\xa4\xe7\x31\x46\ -\xf8\xe5\xde\x0f\xce\xff\x77\x87\x81\xd3\xda\x1f\x74\xa0\x8b\xc4\ -\x6e\x1d\xdb\x9d\x9f\x1d\x42\xa7\xd6\x35\x2b\x86\x03\x8c\x2a\xea\ -\x7b\x96\xa6\x4f\x87\xbf\x5b\x82\x9c\x12\xcf\x65\xb5\x78\xe8\x80\ -\xf3\x3b\x84\xbb\x50\x5b\x51\x57\xd5\x44\x0a\x55\x56\x3d\x09\x41\ -\x6d\x59\xed\xe3\xd0\x66\x67\x04\x0d\xac\xc3\xad\xb4\x57\x1f\x00\ -\x40\x25\x2c\x87\x5b\x69\xee\x7c\x39\x07\xac\x92\x14\x75\x25\x64\ -\xaf\x30\x4c\x21\xe8\x94\x59\x8e\xa0\x38\xb9\x0b\xca\x6d\x6e\x06\ -\x49\xae\x4d\x56\x60\x61\x1b\xdf\xa1\x8e\x08\xed\xe7\x07\xa8\xbe\ -\x67\x50\x41\x62\x7f\x7b\xfa\x8c\xa8\xb5\x7e\xf7\x7a\x28\xa3\xbc\ -\x76\x68\x36\xa5\xb2\x87\x32\xe9\x7a\x0a\x30\x30\xd5\x90\x4e\x34\ -\x13\x0c\xc0\x25\x5c\x45\x09\x91\x6c\xea\x01\xfc\x28\x16\xdc\x1b\ -\xa5\x01\xea\x20\xe3\x0a\xe9\xd1\xa9\xb2\xc8\x52\x58\x37\xc8\x93\ -\xb0\x95\x12\x9c\x4f\x41\x42\x43\xc6\x81\x93\x3b\xca\xf5\x38\x87\ -\xee\x67\x4a\xb4\x4b\x21\x8f\x78\xd8\x03\xf8\x71\xca\x05\x87\x23\ -\x41\xed\xaf\x15\x51\x0e\x73\x3d\xa6\x28\x50\x98\x0b\xe5\x3e\x85\ -\x33\xc2\x17\x06\x1d\x34\xb1\x10\xe5\x54\x28\xc2\xee\x03\xa3\xf7\ -\x2d\xc0\x68\xdd\xe4\x04\x8c\x75\x94\xc4\x58\x88\x88\x9f\xda\xaf\ -\x1a\xe6\x5b\x40\xa6\xb9\x33\xb0\x6a\xd4\x56\x2c\xed\xc3\x50\xcf\ -\xa8\x04\x7a\x5c\xa6\x15\x97\xf2\xf2\x3a\xa4\xdd\x73\xa0\x0c\x7b\ -\x5c\x28\x6f\xbb\x1a\xa2\xe9\x33\xc0\x54\x58\x41\x91\xd0\x32\x9a\ -\xf6\x02\x42\x27\x17\x94\xf4\x1e\x73\x6f\x27\x12\xbc\x42\x50\xd1\ -\x7f\x71\xbf\x9d\x08\xb0\x84\x86\x76\x55\x0c\x0a\x05\xe8\xcc\x30\ -\xf5\x14\xf7\x06\xa5\x02\x50\x15\xe1\xbd\x27\xfa\xf3\x52\x86\x40\ -\x81\x62\x1b\x5f\xc1\x3c\x09\xa2\xb6\x1f\xa6\x10\xd4\x39\x78\xcd\ -\xa0\x72\x79\xf0\x57\xf5\x31\x81\xf6\x97\xf5\x87\x02\xea\x79\x45\ -\x39\x66\x1f\x48\x4c\x84\x60\x70\x78\xb6\xd9\x5f\x5e\x53\x9e\x5b\ -\xc8\xf6\x20\x0e\x34\xb3\xec\x08\x44\x0f\xbc\xbd\xca\x4d\x50\x9a\ -\x01\x06\xaa\xff\xd6\xc0\xcf\x9c\x9b\x63\x2d\x91\xba\xc0\xbd\x47\ -\x9d\xf7\x7e\x0b\x60\xe2\x81\x01\x95\xb5\x80\xf6\x24\xd4\x91\x27\ -\x16\xa8\x0d\x2a\xc1\x53\xb9\x7c\xcc\xf8\xb6\x4c\xd4\x2e\xd3\x44\ -\xf5\x7f\x4b\xa9\x9c\x07\xb6\x61\xbd\x47\xee\xd6\xff\x88\x4b\xa8\ -\x56\x8f\x3b\x6c\xe3\xde\xe0\x2f\xbd\xbe\x70\x08\xc9\x20\xb0\xe9\ -\xf1\x65\x90\x24\x15\x20\xf1\x8b\x20\xf9\xe7\x77\x3d\x9b\x4f\xaa\ -\x1c\xd0\x73\x3d\x76\x8f\xeb\xbd\xcc\xf1\x06\x26\x5a\x2c\xea\x0a\ -\xe6\x85\x26\x62\x5a\x08\x45\xbf\x66\xd0\x04\xaf\xd2\x17\x04\x4d\ -\xe2\x42\x24\x24\xbd\x58\x68\x7b\x26\x6a\xf3\xaa\x92\xb2\x8f\x06\ -\xaa\x5c\xaa\x25\xeb\x39\xf8\x43\x51\xd3\xd3\x9a\x42\x83\xf7\x78\ -\xd8\xf4\x04\x66\x0a\x00\x35\xb5\x15\x33\xc1\x98\xdb\xaf\x16\xb4\ -\xad\x09\xbe\x65\x2b\x3e\x52\xcd\xd8\x1f\xb0\xee\xab\x66\x46\xc5\ -\x19\x7f\xf7\xdd\xb5\xef\x0f\x76\xee\x10\x59\xa1\x66\xf0\x34\x98\ -\xcc\x53\x4c\x61\x08\xb6\x75\xf8\x15\x50\x0c\xc9\x2a\xfa\xda\xb7\ -\x71\xe5\x9d\x77\xee\xf6\x51\xd8\xfe\x90\xd0\x79\x96\xed\xdc\x11\ -\xd4\x71\x5a\x41\x29\xf5\xa3\x73\xff\xd1\x64\xdc\xd7\x64\x28\x2d\ -\x5e\xb1\xc9\x60\x4d\x03\x6f\x7f\xc7\x20\xb6\xbf\x20\xc7\x12\xc7\ -\x76\xea\xaa\xc9\x38\x6a\x0a\xbd\x39\x6b\x4a\x9f\xfe\x28\x71\x70\ -\xd3\xa6\x1c\x9b\x7f\x3e\xd6\xcd\xf3\x91\x6e\xde\x7b\x42\x37\xcf\ -\x1e\xea\xe6\xbf\x45\xfb\xf0\xea\x51\x58\xb2\x8b\xa2\xb0\x14\xdf\ -\x5f\x14\x46\xbd\x2a\xf3\x2b\x3f\xa1\x42\xa3\x4b\x30\xd3\xbd\x4a\ -\xa9\x7a\x42\xe5\x50\xdc\x42\x10\x17\x5f\x29\x10\xff\x29\x2a\x44\ -\xdb\xa6\x3f\x5e\x1c\x5e\x58\x1a\xde\xcc\x96\xef\xaf\x6e\xec\x8f\ -\x25\xef\xaf\xfe\x03\xc5\x8d\xf3\xce\ -\x00\x00\x0d\x9d\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ -\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ -\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ -\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ -\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ -\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ -\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ -\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ -\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ -\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ -\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ -\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ -\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\ -\x64\x5f\x73\x65\x61\x72\x63\x68\x2e\x73\x76\x67\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\ -\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\ -\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ -\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x30\x66\x65\x66\x66\x3b\x73\ -\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x73\x74\x6f\x70\x33\x37\x38\x33\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\ -\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\x30\x36\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\ -\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x62\x62\x66\x61\x66\x66\ -\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\ -\x34\x37\x30\x35\x38\x38\x32\x34\x3b\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x35\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\ -\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ -\x23\x38\x37\x66\x36\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x30\x33\x39\x32\x31\x36\x3b\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\ -\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\x68\x72\x65\ -\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ -\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\ -\x74\x33\x37\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\ -\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x63\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x66\x78\x3d\x22\x34\x2e\ -\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x3d\x22\x31\x34\x2e\x32\x31\x36\x38\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\ -\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ -\x72\x69\x78\x28\x31\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x32\x35\ -\x36\x33\x2c\x30\x2c\x2d\x30\x2e\x30\x37\x31\x30\x35\x30\x33\x35\ -\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\ -\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\x70\x61\ -\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\ -\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x78\x3d\x22\x2d\x39\x34\x2e\x32\x37\x36\x34\x33\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x79\x3d\x22\x31\x39\x2e\x31\x31\x38\x33\x31\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ -\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ -\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ -\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ -\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ -\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ -\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ -\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ -\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ -\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ -\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ -\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ -\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ -\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ -\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ -\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ -\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x65\ -\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x72\ -\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\ -\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ -\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\ -\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\ -\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x63\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x32\x31\x36\ -\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\ -\x33\x2e\x33\x39\x35\x34\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x30\x2e\x39\x35\x36\x34\x37\x39\x35\x37\x2c\x30\x2c\ -\x30\x2c\x30\x2e\x39\x34\x33\x37\x32\x36\x35\x31\x2c\x31\x34\x2e\ -\x30\x33\x32\x34\x34\x32\x2c\x38\x2e\x32\x36\x36\x32\x34\x35\x36\ -\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x37\x2e\x38\x36\x30\x36\ -\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x34\x2e\x31\x39\x37\x32\x35\x32\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x35\x2e\x35\x35\x34\x32\ -\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x39\ -\x2e\x39\x34\x38\x33\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x78\x3d\x22\x31\x2e\x30\x38\x33\x37\x38\x33\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x34\x38\x37\x38\ -\x31\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\ -\x39\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0f\x08\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x74\x61\x63\x6b\ -\x5f\x72\x61\x73\x74\x65\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x78\x3d\x22\x2d\x34\x33\x2e\x32\x35\x33\x31\x39\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x79\x3d\x22\x35\x2e\x31\x34\x39\x30\x32\x30\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ -\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ -\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ -\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ -\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ -\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ -\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ -\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ -\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ -\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ -\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ -\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ -\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x39\x2e\x38\x31\x33\x33\x33\x33\x35\x31\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ -\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ -\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ -\x6d\x20\x32\x2e\x32\x30\x35\x36\x34\x32\x37\x2c\x32\x33\x2e\x34\ -\x36\x36\x39\x31\x32\x20\x2d\x30\x2e\x30\x37\x32\x33\x30\x39\x2c\ -\x31\x30\x2e\x36\x36\x36\x34\x32\x31\x20\x33\x31\x2e\x39\x39\x39\ -\x32\x36\x34\x33\x2c\x30\x2e\x32\x31\x37\x30\x32\x34\x20\x30\x2e\ -\x30\x37\x32\x33\x31\x2c\x2d\x31\x30\x2e\x36\x36\x36\x34\x32\x31\ -\x20\x76\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x32\x39\x39\x32\x2d\x33\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ -\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ -\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x31\x31\x36\ -\x30\x36\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ -\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\ -\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x34\x33\x2e\x34\x37\x31\x32\x36\x34\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x33\x33\x37\x30\x37\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ -\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ -\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\ -\x30\x31\x2c\x30\x2e\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\ -\x2e\x38\x39\x37\x30\x34\x31\x32\x39\x2c\x30\x2e\x34\x34\x31\x39\ -\x34\x36\x37\x34\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ -\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\x30\x31\x2c\x30\x2e\ -\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\x2e\x38\x35\x31\x34\ -\x33\x35\x37\x33\x2c\x30\x2e\x35\x32\x34\x34\x35\x38\x39\x36\x2c\ -\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x36\x2e\x38\ -\x31\x37\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x32\x39\x2e\x38\x36\x35\x30\x37\x34\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\ -\x33\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x37\x32\x32\ -\x37\x33\x32\x33\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x35\x39\x33\x33\x33\x30\x33\ -\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ -\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\ -\x31\x33\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x39\x2e\x31\x35\x33\x36\x39\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x34\x2e\x32\x36\x39\x36\x30\x34\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ -\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ -\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\x30\x31\x2c\ -\x30\x2e\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\x2e\x38\x30\ -\x35\x34\x35\x35\x32\x33\x2c\x30\x2e\x35\x39\x32\x36\x35\x36\x36\ -\x32\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ -\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x39\x2e\x38\x31\x33\x33\x33\ -\x33\x35\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ -\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ -\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ -\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x4d\x20\x33\x34\x2e\x31\x33\x32\x30\x35\x33\x2c\ -\x31\x31\x2e\x37\x33\x37\x32\x38\x20\x33\x34\x2e\x31\x33\x33\x33\ -\x35\x33\x2c\x31\x2e\x30\x37\x30\x36\x31\x33\x33\x20\x32\x2e\x31\ -\x33\x33\x33\x35\x33\x33\x2c\x31\x2e\x30\x36\x36\x36\x36\x33\x33\ -\x20\x32\x2e\x31\x33\x32\x30\x34\x33\x33\x2c\x31\x31\x2e\x37\x33\ -\x33\x33\x33\x20\x76\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ -\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ -\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ -\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0d\x25\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x6f\x69\x5f\x72\ -\x65\x64\x6f\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ -\x3d\x22\x33\x2e\x36\x33\x30\x32\x37\x32\x34\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\ -\x38\x2e\x39\x37\x31\x31\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ -\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ -\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ -\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ -\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ -\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ -\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ -\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ -\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ -\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ -\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ -\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ -\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ -\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ -\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ -\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ -\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\x38\x33\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x39\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ -\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x33\x33\x30\ -\x33\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x33\x2e\x38\x30\x34\x38\x37\x38\x35\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\ -\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\ -\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ -\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\ -\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\ -\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ -\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\ -\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\ -\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\ -\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\ -\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\ -\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\ -\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ -\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\ -\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\ -\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\ -\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\ -\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\ -\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\ -\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\ -\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ -\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ -\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\ -\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\ -\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\ -\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x64\x3d\x22\x4d\x20\x38\x2c\x39\x2e\x36\x36\x36\x36\ -\x36\x36\x37\x20\x43\x20\x33\x2e\x38\x31\x34\x30\x31\x30\x37\x2c\ -\x31\x34\x2e\x38\x37\x36\x37\x39\x35\x20\x34\x2e\x34\x33\x32\x38\ -\x39\x30\x37\x2c\x32\x32\x2e\x36\x34\x34\x37\x39\x34\x20\x39\x2e\ -\x34\x2c\x32\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x31\x34\x2e\x33\ -\x36\x37\x31\x30\x39\x2c\x33\x31\x2e\x34\x38\x38\x35\x34\x20\x32\ -\x31\x2e\x39\x34\x37\x33\x34\x34\x2c\x33\x30\x2e\x38\x31\x30\x31\ -\x32\x38\x20\x32\x36\x2e\x31\x33\x33\x33\x33\x33\x2c\x32\x35\x2e\ -\x36\x20\x63\x20\x34\x2e\x31\x38\x35\x39\x39\x2c\x2d\x35\x2e\x32\ -\x31\x30\x31\x32\x38\x20\x33\x2e\x35\x36\x37\x31\x31\x2c\x2d\x31\ -\x32\x2e\x39\x37\x38\x31\x32\x37\x20\x2d\x31\x2e\x34\x2c\x2d\x31\ -\x37\x2e\x34\x20\x6c\x20\x33\x2c\x2d\x32\x2e\x38\x36\x36\x36\x36\ -\x36\x37\x20\x48\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x56\ -\x20\x36\x2e\x34\x20\x6c\x20\x33\x2e\x32\x2c\x38\x2e\x35\x33\x33\ -\x33\x33\x33\x20\x32\x2e\x36\x36\x36\x36\x36\x36\x2c\x2d\x33\x2e\ -\x37\x20\x63\x20\x32\x2e\x33\x37\x39\x33\x30\x32\x2c\x33\x2e\x32\ -\x37\x37\x37\x32\x39\x20\x33\x2e\x31\x37\x31\x30\x35\x38\x2c\x38\ -\x2e\x39\x35\x30\x32\x36\x36\x20\x30\x2e\x35\x33\x33\x33\x33\x34\ -\x2c\x31\x32\x2e\x32\x33\x33\x33\x33\x34\x20\x2d\x33\x2e\x30\x34\ -\x31\x38\x35\x38\x2c\x33\x2e\x37\x38\x36\x30\x37\x34\x20\x2d\x38\ -\x2e\x32\x32\x30\x37\x31\x37\x2c\x34\x2e\x32\x31\x39\x37\x32\x20\ -\x2d\x31\x31\x2e\x38\x2c\x31\x2e\x30\x33\x33\x33\x33\x33\x20\x2d\ -\x33\x2e\x35\x37\x39\x32\x38\x33\x35\x2c\x2d\x33\x2e\x31\x38\x36\ -\x33\x38\x37\x20\x2d\x34\x2e\x30\x34\x31\x38\x35\x38\x35\x2c\x2d\ -\x38\x2e\x39\x31\x33\x39\x32\x35\x20\x2d\x31\x2c\x2d\x31\x32\x2e\ -\x37\x20\x43\x20\x31\x31\x2e\x32\x2c\x31\x32\x2e\x33\x20\x31\x31\ -\x2e\x32\x2c\x36\x2e\x39\x36\x36\x36\x36\x36\x37\x20\x38\x2c\x39\ -\x2e\x36\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ -\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\ -\x65\x73\x3d\x22\x63\x73\x73\x63\x63\x63\x63\x63\x63\x73\x73\x63\ -\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0a\ -\x00\x00\x0a\xea\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x6f\x69\x5f\x73\ -\x69\x6e\x67\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ -\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x78\x3d\x22\x2d\x31\x34\x2e\x39\x31\x38\x38\x38\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ -\x3d\x22\x32\x31\x2e\x39\x38\x36\x31\x39\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ -\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ -\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ -\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ -\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\ -\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ -\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ -\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\ -\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\ -\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\ -\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\ -\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ -\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ -\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ -\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ -\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ -\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ -\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ -\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ -\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ -\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ -\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ -\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\ -\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\ -\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\ -\x38\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\ -\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\ -\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ -\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\ -\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\x37\x38\x35\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\ -\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ -\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x33\x2e\x32\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x6d\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\ -\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x63\x20\x30\x2c\x31\ -\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\x32\ -\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\x32\x30\x30\x30\ -\x30\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x33\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ -\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ -\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ -\x69\x6c\x6c\x3a\x23\x38\x30\x38\x30\x38\x30\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x35\x38\x39\x30\x39\x35\ -\x31\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\ -\x36\x36\x36\x36\x36\x37\x2c\x31\x36\x2e\x36\x30\x32\x32\x38\x39\ -\x20\x63\x20\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\ -\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\ -\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ -\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0a\xd8\ -\x00\ -\x00\x73\x2b\x78\x9c\xed\x5d\x5b\x93\xa3\xb8\x15\x7e\x9f\x5f\x41\ -\x3c\x2f\x33\x15\x4b\xd6\x8d\x8b\xdc\xee\xde\x87\xdd\xda\xda\xad\ -\xda\xbc\x64\x37\x95\xc7\x29\x1a\x64\x37\x19\x0c\x0e\xe0\xb6\x3d\ -\xbf\x3e\x47\xdc\x8c\x2f\x90\x4c\xb5\x71\xb6\xa0\x99\x9a\xea\xe6\ -\x1c\x49\x48\x9f\xbe\x73\x74\x24\xd4\x68\xf1\xc3\x7e\x1d\x1a\xaf\ -\x2a\x49\x83\x38\x7a\x9c\x50\x4c\x26\x86\x8a\xbc\xd8\x0f\xa2\xd5\ -\xe3\xe4\x1f\x7f\xfc\x8c\x9c\x89\x91\x66\x6e\xe4\xbb\x61\x1c\xa9\ -\xc7\x49\x14\x4f\x7e\x78\xfa\xb0\xf8\x0b\x42\xc6\x8f\x89\x72\x33\ -\xe5\x1b\xbb\x20\x7b\x31\x7e\x8d\xbe\xa6\x9e\xbb\x51\xc6\xa7\x97\ -\x2c\xdb\xcc\x67\xb3\xdd\x6e\x87\x83\x52\x88\xe3\x64\x35\xfb\x6c\ -\x20\xf4\xf4\xe1\xc3\x22\x7d\x5d\x7d\x30\x0c\x03\x9e\x1b\xa5\x73\ -\xdf\x7b\x9c\x94\x19\x36\xdb\x24\xcc\x13\xfa\xde\x4c\x85\x6a\xad\ -\xa2\x2c\x9d\x51\x4c\x67\x93\x63\x72\xef\x98\xdc\xd3\x4f\x0f\x5e\ -\x95\x17\xaf\xd7\x71\x94\xe6\x39\xa3\xf4\x63\x23\x71\xe2\x2f\xeb\ -\xd4\xba\x36\x3b\x9e\x27\xa2\x52\xca\x19\x61\x33\xc6\x10\xa4\x40\ -\xe9\x21\xca\xdc\x3d\x3a\xcd\x0a\x75\xbc\x96\x95\x11\x42\x66\xa0\ -\x3b\xa6\xfc\xdf\x52\xcd\x53\x00\x74\x03\xff\xeb\xe4\x95\x00\xa7\ -\xf1\x36\xf1\xd4\x12\xf2\x29\x1c\xa9\x6c\xf6\xd3\x1f\x3f\xd5\x4a\ -\x44\xb0\x9f\xf9\x8d\x62\x2a\x3c\x4f\x9e\x7a\x02\x72\xe4\xae\x55\ -\xba\x71\x3d\x95\xce\x2a\x79\x9e\x7f\x17\xf8\xd9\xcb\xe3\x84\x0b\ -\x4c\x39\x5c\x66\x2e\x7c\x51\xc1\xea\x25\x3b\x97\x06\xfe\xe3\x04\ -\x6a\xcf\xa4\x53\xdc\x37\xc8\x41\x8b\x04\x65\xc1\xf3\x5a\x43\xb0\ -\x64\x98\x1a\x09\x35\xb9\x5d\xa4\xa9\x9a\x30\xf7\x63\x4f\xd7\x09\ -\x8a\x54\xeb\xc0\xdd\x66\xf1\x1a\x7a\xcd\xf3\x42\x37\x4d\x83\x65\ -\xe0\xc1\x4d\x1c\x6d\xc2\xed\x2a\x88\xbe\x6c\x23\x3f\xfe\xa2\xfc\ -\x20\xfb\x92\xb8\x69\xa6\x12\x5c\x61\x58\x3f\x50\xed\x37\x71\x92\ -\xa1\xbd\xbf\x01\x24\x2d\xfb\xaa\xf2\x50\x29\x9f\x40\xbb\xf0\xd5\ -\x32\xd5\xa9\x8a\x66\xe9\x3b\x68\x97\x3d\x31\x66\xb9\xb6\xae\xa5\ -\xae\xa2\xff\x1a\xa8\xdd\x31\xed\xb3\x9b\x16\xd0\x19\xc6\xc6\x5d\ -\x01\xcd\xc2\x38\x79\x9c\x7c\x5c\xe6\x57\xa9\x78\x8e\x13\x5f\x25\ -\x95\xca\xca\xaf\x13\x55\x0c\x5d\x11\x64\x87\xc2\xb0\xca\xb2\xab\ -\xfa\xea\x52\x6b\x3d\xb9\xae\x4f\x5f\x5c\x3f\xde\x3d\x4e\xd8\xb9\ -\xf2\x5b\x1c\xaf\x1f\x27\x26\x36\xa5\x23\x09\x3d\xd7\x7a\xfb\xc7\ -\x09\x12\x12\xdb\x84\x3b\xf2\x42\x09\x8f\xb3\x31\xb3\xa5\x60\xa6\ -\x7d\xa1\xdc\x26\x09\x18\x1e\x0a\xdd\x83\x82\x36\xe5\x3f\xaa\xe2\ -\xd3\x97\x78\xb7\x4a\x34\x36\x59\xb2\x55\xe7\x39\xb5\x06\x3d\x3f\ -\xc7\xfb\xeb\x6a\xe0\xc1\x56\x9b\x34\xda\x46\x41\x06\x66\xb3\xd9\ -\x37\x4b\xdd\x06\xbe\x4a\xaf\x67\x4c\x23\x77\x83\x56\x61\xfc\xec\ -\x86\xd7\x13\xec\x02\xe0\xcd\x0e\x95\x0c\xa7\xbc\xee\x82\xf3\x14\ -\x15\xdd\x6d\xe2\xb4\xa4\x80\xba\x5f\x74\x43\xa9\x3a\xb4\xab\xd6\ -\xee\x3e\x58\x07\xdf\x14\x00\x43\x73\xd6\x01\xb3\x4e\x60\x29\xb2\ -\x19\x46\x76\xd0\xa6\xbb\x3f\x68\xd9\xa4\x12\x6a\x3c\xb5\x80\x49\ -\x69\xd7\xc2\x38\x09\xc0\x22\x1a\xd5\xa9\x44\x87\xa6\x48\x1b\x3a\ -\xf8\xe9\x7d\x4e\xaf\x9c\x7c\xf6\xb9\xee\xd0\xd4\x95\xac\x9f\x5d\ -\xd2\x3e\x97\xaf\x55\xe6\xfa\x6e\xe6\x1e\x6d\xa0\x92\x40\xdd\x48\ -\xd5\x32\xf0\x99\xf3\xbf\xff\xf4\xf3\x53\xf9\xa0\x85\xe7\xcd\xff\ -\x19\x27\x5f\xab\xe7\x1a\x86\x4e\xe0\x3e\xc7\x5b\x40\x7a\xf2\x54\ -\x8b\x17\xbe\x37\x07\x2f\x07\xd6\xff\x14\xac\x81\xd9\xda\x41\xfe\ -\x15\xbc\xda\x62\x76\x54\x9c\x24\xd6\x60\x1d\x0b\x2d\x8a\x4d\x54\ -\xe1\x2e\xaf\x8e\x19\xbe\xb7\x0e\x74\xa6\xd9\xef\x59\x10\x86\xbf\ -\xea\x87\x94\x2d\x6e\x14\x1a\x64\xa1\x3a\x0a\x17\xb3\xb2\xf6\x65\ -\xdb\x66\x8d\xc6\x2d\x66\x55\xeb\xf3\xbb\xd5\x11\x95\x13\xa3\xa8\ -\x3b\x3a\x74\x9f\x15\x30\xf4\x37\xad\x34\x2e\xb4\xab\x24\xde\x6e\ -\xd6\xb1\xaf\xca\xec\x15\x9a\xab\x13\x1a\x70\xca\x69\xdd\x83\x59\ -\xe2\x46\xa9\x46\x06\xfa\xc1\xcd\x92\x60\xff\x89\x62\x41\x84\x6d\ -\x51\x39\x25\xf0\x8f\x62\x2e\x1c\xf0\xb7\x53\x9b\x63\xa9\xe5\x02\ -\x44\xd2\x14\x8c\x11\xf6\xb9\x46\x7e\x91\x28\x2f\x6b\x74\x4e\x4e\ -\x08\x4b\xe8\xcb\x9a\x34\xe4\x27\x5c\x33\x0c\x48\x86\x2c\xec\x10\ -\x7d\xb1\x86\x5c\x3b\x16\x93\x63\x3d\x5a\xf0\xa6\xbc\xb2\x2d\x81\ -\x65\xae\x13\x0d\x5d\x69\x99\x66\x91\xab\x1c\x65\x8e\xad\xd6\x15\ -\x34\x1d\x2e\x11\x45\x4e\x43\x95\x66\x87\x10\xd0\x5a\x42\x5f\xce\ -\x3f\x12\xe2\xba\x8e\xf3\xa0\x6f\x50\xe9\x33\xe7\xb4\xb8\x4d\xb6\ -\x21\xf8\xfe\x57\x15\xc5\xbe\xff\x90\x66\x49\xfc\x55\xcd\xc1\x4b\ -\x5b\x2e\x21\xe5\x6d\xe1\x1a\xe6\x04\x73\x56\xb4\xa7\x92\x03\x5f\ -\x54\x12\x82\xed\x66\x73\x51\xc9\x7c\x17\x7c\x6e\x92\xb8\x87\x79\ -\x04\xf1\x4e\x25\xad\x9f\xd9\x60\xd4\x1b\x90\xa5\x14\xdb\xe7\x28\ -\xf5\x8c\x2c\xa2\xe3\xc0\x96\x97\xde\x8e\xde\x11\x5a\x39\x0e\x68\ -\x11\xc5\xce\xe9\x20\x73\x07\xd6\x22\x73\x1c\xe0\x52\x56\x22\x75\ -\x47\x70\xed\x71\x40\x6b\x63\x99\x5f\xe6\x7d\x79\x3b\x12\xe2\x32\ -\x56\x84\x09\x77\x75\xb8\x63\xa1\x2e\xb5\xff\x2f\x2e\x17\x91\x71\ -\xc0\xdb\x1a\xe2\x5a\xe2\xb6\xc0\xb6\xc3\xb9\x5c\x7a\xde\xe0\xe1\ -\x34\x1d\x9c\x07\x65\xce\xad\xe9\xda\x8e\xab\x2f\x5c\x77\x30\xb8\ -\xb6\xce\x17\xfa\xc2\x15\x89\x71\x20\xdb\x36\x5b\xb8\xb5\xfd\x77\ -\xcd\x6c\x87\xe4\x01\x5a\x67\x5f\xbd\x11\xd5\xe9\x40\x76\x48\x4c\ -\x6d\x9b\x7c\xdd\x9c\xa9\xa4\xcb\xf6\x87\xc4\xd5\xd6\xe9\x6c\x7f\ -\x4e\x15\xb1\x71\x90\xb5\x6d\x32\x7b\x7b\xb2\xf2\x71\x70\xb5\x75\ -\x75\xa0\x37\xae\x5a\xe3\x60\x6a\xdb\xda\x40\x0f\x6e\xb5\x63\xca\ -\x3a\x24\xaa\xb6\xae\xb6\xf4\xe8\x56\x47\x42\xd6\xd6\xa5\x96\x1e\ -\xa3\xab\xb1\xcc\xb1\xda\x56\x5a\xfa\x88\xaf\xba\x30\x1d\x92\x2b\ -\x68\x5d\xbd\xea\x33\xc2\xea\xf2\xb3\x43\x22\x6c\x9b\x33\xe8\x87\ -\xb0\xe3\x99\x14\xb4\x2c\xb5\xf4\x04\x6b\xc7\x84\x60\x50\xb0\x5a\ -\x57\x90\xd2\xb0\x72\xbb\xbf\x85\x6c\xd1\xc1\x59\x87\x58\xd6\x60\ -\xc0\xa5\x2d\x33\xd9\x3e\xc1\xa5\x5d\x7e\x76\x48\xe8\x96\x33\x2f\ -\x26\xef\x08\xae\xec\x7a\x01\x33\x24\x70\x11\xc3\x79\x45\xc8\xf9\ -\x6c\xa1\x5f\xea\x9a\x5d\xbb\x0a\x86\x84\x2f\x85\x20\xe1\x8e\xc8\ -\xda\x5d\xe3\xd9\x90\x70\x2d\x03\x5b\xeb\x7c\x3d\xa6\x67\xda\x9a\ -\x88\x74\x4c\x75\x87\x04\x30\x44\xb7\x17\x53\x84\xfe\xbd\xee\x68\ -\xf8\x0b\x33\xb3\xab\x51\x6e\xdf\x6e\xb7\xf3\xe5\xc2\x90\x00\x6e\ -\x0d\x78\xc5\xad\x27\xbd\x23\x09\xc3\xda\x01\xbd\xe2\x29\x6e\x43\ -\xd9\x0e\x5f\x60\x9a\x42\x0c\x06\xd9\xb6\xe9\x43\x7f\xc8\x0a\xc4\ -\x3a\x5e\xdb\x0e\x09\xdc\xb6\xd9\xc3\xcd\xdd\x80\x83\x3a\x5e\x85\ -\x0d\xc9\x11\xb4\x22\xda\x1b\x5b\x9d\x4e\x6c\x87\xc4\xd6\xd6\xe9\ -\xd8\xcd\xe9\x9a\xaf\x7e\x89\x0e\x27\x30\x24\xca\xb6\xc3\xda\xa7\ -\x87\xed\xda\x73\x34\x24\xd2\x5e\x99\xe3\xde\x9e\xae\x7c\x2c\x71\ -\xd6\x35\x34\x7b\x63\xa9\xd5\xb5\x0e\x33\x24\x8e\xb6\xad\x17\xf4\ -\xe0\x57\xed\x2e\xbb\x1f\x12\x53\x5b\x31\xed\xd1\xa9\x5a\x88\x77\ -\xbc\xbb\x1d\x12\x63\xdb\x16\x60\x7a\x0d\xb3\x28\x92\x1d\x0b\xdf\ -\x43\x82\xb7\x6d\x01\xa6\x9f\x40\x0b\x39\x23\x99\x1c\xb4\xc2\xda\ -\x6b\xa0\x65\x77\x6d\xe8\x18\x12\x6b\x5b\x9d\x42\x3f\xac\x15\x63\ -\x79\x4d\xd3\xbe\x04\xd3\x0f\xb0\x0c\xc9\x91\xbc\x47\x68\xdf\x78\ -\xd0\xcf\x8e\x83\xae\x45\xc3\x41\xfd\xe5\x5c\xeb\x9e\x83\x9e\x36\ -\x1b\x74\xed\xf1\x1c\x12\xb0\xad\xdb\x0d\x7a\xda\x67\x30\x9a\x6f\ -\x6e\xb4\xee\x34\xe8\x6d\x8b\xc1\x58\x3e\xb9\x71\x6d\x93\x41\x4f\ -\xbb\x0b\xc6\xf2\x77\xdf\xad\xfb\x0b\x7a\xdc\x58\x30\x96\xa1\xab\ -\x75\x6b\x41\x6f\x7b\x0a\xba\x5e\x1f\x0c\x09\xd9\xd6\x5d\x05\x3d\ -\x6e\x27\xe8\xda\x50\xf0\x27\xc4\x76\xd5\x52\x59\x78\xb8\x55\x3f\ -\x7c\x5e\x7e\x65\xf0\xb2\xa4\x63\xee\xc6\xd7\xc1\xf2\x5f\x43\x37\ -\x53\x9f\x10\x27\x25\xaa\x53\x24\x4b\x10\xf9\xe7\x33\x14\x57\x9c\ -\x51\xd9\xfc\x32\xdb\x69\x7f\x5f\xaf\xd8\x77\xa0\xd8\xac\x79\x85\ -\xa2\x63\x16\x1d\xfa\x16\x14\x9b\x55\xbc\x32\x36\x88\x93\x04\x1d\ -\x4c\xea\xa6\x60\xc1\xd8\x6b\xbb\xc0\x0b\x8a\x5f\x09\x7b\x2f\x6d\ -\xa1\xdd\x6a\xfe\xcb\xc7\x2c\xdb\x12\xd5\x1f\xb5\x3c\xf9\xa0\xdd\ -\x10\x3a\xae\x18\x7c\xee\xd2\x77\xd7\xa6\x82\xef\x7d\xf7\x86\xbe\ -\x93\x77\x33\x3b\x76\x55\xf1\xde\x75\x6f\x31\x3b\x18\x3d\xe5\x7d\ -\x7c\xa6\x85\xed\xfc\x4f\x42\xdf\x3b\xef\xed\x9d\x47\xf8\xc9\x8c\ -\xfd\xcd\xbd\x06\xd1\xf0\xfb\x20\xd7\xaf\xb5\x59\xc8\xba\xa9\x9d\ -\xd9\xc5\x47\x56\x9c\xf7\x6e\xeb\xd3\xce\xce\x36\x83\xf7\x62\x68\ -\xef\x11\xc9\x4d\x0d\x2d\x7f\x3f\x7f\x17\x53\x7b\xef\xb8\xdb\xc6\ -\x23\xf9\xab\xff\xbb\xf4\xdc\x7b\x24\x79\x53\x27\x29\xce\xbe\xda\ -\xdd\x4f\x3c\xf2\x1e\x40\xde\xd6\x4d\xea\x2d\x0b\xf6\x5d\xcc\xed\ -\xbd\xeb\x6e\x6e\x6e\xa2\x7f\x83\xfb\xf3\x38\xc9\xc5\x6c\x55\x9d\ -\xcd\x50\xfd\xb2\x71\xb3\x97\xaa\x94\xb2\x07\xf3\x13\x58\xf4\x8a\ -\xaf\xbe\x1e\x96\x71\x94\xa1\x5c\x03\x00\x27\x6b\x37\x2c\x24\xaf\ -\x6e\x12\xb8\x51\x76\x22\xdb\xe5\xf0\x9c\x88\xa0\x3b\x54\xe6\xbd\ -\x9c\xca\x82\x6f\x6a\xbe\x56\x7e\xb0\x5d\x3f\x84\x41\xa4\xca\xa3\ -\x44\x4e\xd2\x2c\xdd\x75\x10\x1e\xe6\xbf\xbb\x51\xfa\x80\xaa\x96\ -\xa1\x22\xfb\x46\x79\xf5\x61\x37\x45\x8a\x4c\xed\x33\x48\xe5\x2b\ -\xa8\x10\x29\xee\xdc\x30\x58\x45\xf3\x34\x73\x93\xac\x10\xf8\xca\ -\x8b\x93\x22\x4f\x4e\x94\x33\x21\xd2\x35\x29\x34\xa1\xca\x80\x66\ -\xa8\x3c\xf3\xa3\xaa\xd6\x2e\x4e\xfc\x73\x59\x5e\x46\xbd\x76\x5c\ -\xe4\xde\x25\x41\x06\x49\x90\x3e\x9e\x62\x1e\x26\x28\x7b\x7e\xf0\ -\x03\x4d\x3a\xfd\xe4\x30\x4b\x1e\xf4\x51\x38\x79\xb3\xd3\x97\x60\ -\x99\xcd\xab\xdb\xb2\xda\x91\xf7\x02\xe0\x17\xf5\xf6\x83\x74\x13\ -\x02\xb1\x83\x28\x4f\x10\xbf\xaa\x64\x19\xc6\xbb\xf9\x6b\x90\x06\ -\xcf\xa1\x7a\xc8\x7f\x06\xa1\xe6\x79\x25\xaa\x16\xeb\x8b\xae\x3b\ -\xb5\xbe\xd2\xd6\x9a\x66\x52\x18\x1a\xc7\x22\x3f\xb1\x48\xb0\x87\ -\xb5\x9b\x7c\x55\x49\x91\x46\x45\x2e\x14\x89\x9e\x5d\xef\xab\x3e\ -\x70\x23\xf2\xe7\xae\xe7\x6d\xd7\x5b\xbd\x38\x5e\x33\x0f\x2c\xea\ -\x6f\x06\x27\x58\x10\x4b\x9a\x62\x0a\xb3\x26\xf8\x49\x89\x63\xfc\ -\x68\x30\x0b\x13\x22\xa8\x74\xa6\x1c\x73\x4a\x88\x6d\x3a\x06\x95\ -\x98\x5b\x92\x9a\xce\x54\x60\x93\x39\x96\x4d\xa8\x41\x49\xf1\x0a\ -\xc9\x9e\xda\x58\x14\xbf\x19\xbf\x19\xf9\x57\x6d\x08\x25\xb6\x3e\ -\x87\x43\x50\x62\x31\x61\x30\xcc\x88\x34\x89\x6d\x4d\xa9\x89\x25\ -\x61\xb6\xc1\xb1\xc5\xa4\x45\x2d\x3a\x05\xdf\x28\xa4\x6d\x71\xd3\ -\x80\xdf\x24\xb3\x85\xc9\xa6\xb9\x23\x75\x2c\x13\x9e\x01\x09\xa9\ -\x69\x5a\x52\xd7\xd0\xa4\xc2\x14\x8e\xe1\x19\x26\x76\x08\x07\x77\ -\x3a\x45\x14\x43\x65\x28\x81\xcc\xd0\x00\x22\xa5\x70\xa6\x88\x61\ -\x53\x52\x87\x38\x50\x6b\x81\xb9\x23\x98\x25\xa6\x0c\x9a\x47\x61\ -\x5e\x08\x55\x31\x99\xb0\x28\x07\x09\x73\x98\x60\x0e\x54\x45\x4a\ -\x06\xc9\xa6\xda\xdc\x05\x97\x0c\xd2\x08\x62\x53\x66\xe5\x45\x51\ -\xca\x8d\x6f\x35\x6c\xda\x13\x69\xd3\x63\xd2\xd1\xcb\xed\x47\x47\ -\x70\x3c\x3b\x28\x8e\x22\x60\x4d\x9c\x20\x6f\x9b\xbc\xba\xd9\x36\ -\x51\x27\xa7\xd5\xd4\xa7\xce\x00\xcf\xf4\x41\x2d\x29\x18\x6e\x75\ -\xd5\x26\xff\x6e\xde\x43\x35\x6f\x18\x2c\xef\x69\xde\x44\x32\xc2\ -\xad\x29\x58\xaf\x43\x24\x15\x54\x9b\xb7\x89\x2d\x47\x02\xf9\xa7\ -\x04\x98\x6f\x3a\x0e\xd8\xaa\xb6\x6f\x62\x0a\x26\xa8\xb6\x0b\x2a\ -\x84\x6d\x5a\xda\xbe\xb9\x49\x6d\x21\xa7\x26\xa6\x60\x35\x36\x63\ -\xb9\x7d\x83\x90\x48\xfd\x72\x0d\xf4\x36\xa7\x9c\x59\xd2\xa0\xd8\ -\x91\xc2\x04\xd3\x9e\x82\xc5\x42\x99\x26\x98\xa4\xf6\x1e\x02\x1c\ -\x05\xd8\xb8\xc0\xd4\xe1\x42\x30\x6d\xe3\x16\x65\x26\x17\x5a\x66\ -\x9b\x42\x68\xdf\x02\x09\x09\xb1\xc0\xee\x25\xf8\x09\xc2\x4d\xa8\ -\xe6\x15\x1b\x17\x47\x23\xb7\x6b\x23\x97\x56\x6d\xe4\xbc\x32\x72\ -\x2e\x2b\x2b\x67\x17\x56\xce\x2f\xac\xdc\x2e\xad\x9c\x49\x28\xab\ -\xcd\xd0\xfb\x32\xf3\x66\x2c\x76\x16\x87\x5d\x1b\x09\xbe\x2f\x0e\ -\xa3\x98\xd6\x2f\x6c\x35\x53\xa1\xde\xf3\xf4\xdf\x5b\x37\x51\x4d\ -\xe9\xbf\xe2\x20\x9a\xe7\x01\xda\xf7\x47\x6b\x5a\x1a\x2f\x97\xa9\ -\xd2\xf6\xdd\x1a\xc1\x55\xd1\x1b\x87\x51\xa1\x16\x96\xf1\x1a\xad\ -\x42\xb2\x5a\x51\xc5\x6a\x97\x1a\x08\xbc\xa8\x53\x9c\xd1\x77\x14\ -\xea\xd8\x2b\xa7\x4d\xf3\x1b\x60\x49\xbe\x85\xcc\xc9\x23\x32\xb3\ -\xd3\xa9\xe6\x68\x37\x9a\x74\x1d\x49\x8e\x61\xa4\x02\xaa\x0b\xe7\ -\x1c\xcf\xe7\x6d\x96\xdd\x0a\xcd\x4b\xe4\x72\x2b\x86\xe6\x59\x2c\ -\x1f\x66\x61\x60\x2e\x87\xd9\x5f\x0c\x0e\xc3\xa1\x7d\x82\x44\xc5\ -\x58\x6e\x3b\xec\x46\x7c\xad\xcf\x4a\x83\xa8\x73\xa1\xcf\x2a\x7b\ -\xfa\xf0\x1f\xf2\x7c\xe6\x3d\ -\x00\x00\x0a\xd8\ -\x00\ -\x00\x73\x2b\x78\x9c\xed\x5d\x5b\x93\xa3\xb8\x15\x7e\x9f\x5f\x41\ -\x3c\x2f\x33\x15\x4b\xd6\x8d\x8b\xdc\xee\xde\x87\xdd\xda\xda\xad\ -\xda\xbc\x64\x37\x95\xc7\x29\x1a\x64\x37\x19\x0c\x0e\xe0\xb6\x3d\ -\xbf\x3e\x47\xdc\x8c\x2f\x90\x4c\xb5\x71\xb6\xa0\x99\x9a\xea\xe6\ -\x1c\x49\x48\x9f\xbe\x73\x74\x24\xd4\x68\xf1\xc3\x7e\x1d\x1a\xaf\ -\x2a\x49\x83\x38\x7a\x9c\x50\x4c\x26\x86\x8a\xbc\xd8\x0f\xa2\xd5\ -\xe3\xe4\x1f\x7f\xfc\x8c\x9c\x89\x91\x66\x6e\xe4\xbb\x61\x1c\xa9\ -\xc7\x49\x14\x4f\x7e\x78\xfa\xb0\xf8\x0b\x42\xc6\x8f\x89\x72\x33\ -\xe5\x1b\xbb\x20\x7b\x31\x7e\x8d\xbe\xa6\x9e\xbb\x51\xc6\xa7\x97\ -\x2c\xdb\xcc\x67\xb3\xdd\x6e\x87\x83\x52\x88\xe3\x64\x35\xfb\x6c\ -\x20\xf4\xf4\xe1\xc3\x22\x7d\x5d\x7d\x30\x0c\x03\x9e\x1b\xa5\x73\ -\xdf\x7b\x9c\x94\x19\x36\xdb\x24\xcc\x13\xfa\xde\x4c\x85\x6a\xad\ -\xa2\x2c\x9d\x51\x4c\x67\x93\x63\x72\xef\x98\xdc\xd3\x4f\x0f\x5e\ -\x95\x17\xaf\xd7\x71\x94\xe6\x39\xa3\xf4\x63\x23\x71\xe2\x2f\xeb\ -\xd4\xba\x36\x3b\x9e\x27\xa2\x52\xca\x19\x61\x33\xc6\x10\xa4\x40\ -\xe9\x21\xca\xdc\x3d\x3a\xcd\x0a\x75\xbc\x96\x95\x11\x42\x66\xa0\ -\x3b\xa6\xfc\xdf\x52\xcd\x53\x00\x74\x03\xff\xeb\xe4\x95\x00\xa7\ -\xf1\x36\xf1\xd4\x12\xf2\x29\x1c\xa9\x6c\xf6\xd3\x1f\x3f\xd5\x4a\ -\x44\xb0\x9f\xf9\x8d\x62\x2a\x3c\x4f\x9e\x7a\x02\x72\xe4\xae\x55\ -\xba\x71\x3d\x95\xce\x2a\x79\x9e\x7f\x17\xf8\xd9\xcb\xe3\x84\x0b\ -\x4c\x39\x5c\x66\x2e\x7c\x51\xc1\xea\x25\x3b\x97\x06\xfe\xe3\x04\ -\x6a\xcf\xa4\x53\xdc\x37\xc8\x41\x8b\x04\x65\xc1\xf3\x5a\x43\xb0\ -\x64\x98\x1a\x09\x35\xb9\x5d\xa4\xa9\x9a\x30\xf7\x63\x4f\xd7\x09\ -\x8a\x54\xeb\xc0\xdd\x66\xf1\x1a\x7a\xcd\xf3\x42\x37\x4d\x83\x65\ -\xe0\xc1\x4d\x1c\x6d\xc2\xed\x2a\x88\xbe\x6c\x23\x3f\xfe\xa2\xfc\ -\x20\xfb\x92\xb8\x69\xa6\x12\x5c\x61\x58\x3f\x50\xed\x37\x71\x92\ -\xa1\xbd\xbf\x01\x24\x2d\xfb\xaa\xf2\x50\x29\x9f\x40\xbb\xf0\xd5\ -\x32\xd5\xa9\x8a\x66\xe9\x3b\x68\x97\x3d\x31\x66\xb9\xb6\xae\xa5\ -\xae\xa2\xff\x1a\xa8\xdd\x31\xed\xb3\x9b\x16\xd0\x19\xc6\xc6\x5d\ -\x01\xcd\xc2\x38\x79\x9c\x7c\x5c\xe6\x57\xa9\x78\x8e\x13\x5f\x25\ -\x95\xca\xca\xaf\x13\x55\x0c\x5d\x11\x64\x87\xc2\xb0\xca\xb2\xab\ -\xfa\xea\x52\x6b\x3d\xb9\xae\x4f\x5f\x5c\x3f\xde\x3d\x4e\xd8\xb9\ -\xf2\x5b\x1c\xaf\x1f\x27\x26\x36\xa5\x23\x09\x3d\xd7\x7a\xfb\xc7\ -\x09\x12\x12\xdb\x84\x3b\xf2\x42\x09\x8f\xb3\x31\xb3\xa5\x60\xa6\ -\x7d\xa1\xdc\x26\x09\x18\x1e\x0a\xdd\x83\x82\x36\xe5\x3f\xaa\xe2\ -\xd3\x97\x78\xb7\x4a\x34\x36\x59\xb2\x55\xe7\x39\xb5\x06\x3d\x3f\ -\xc7\xfb\xeb\x6a\xe0\xc1\x56\x9b\x34\xda\x46\x41\x06\x66\xb3\xd9\ -\x37\x4b\xdd\x06\xbe\x4a\xaf\x67\x4c\x23\x77\x83\x56\x61\xfc\xec\ -\x86\xd7\x13\xec\x02\xe0\xcd\x0e\x95\x0c\xa7\xbc\xee\x82\xf3\x14\ -\x15\xdd\x6d\xe2\xb4\xa4\x80\xba\x5f\x74\x43\xa9\x3a\xb4\xab\xd6\ -\xee\x3e\x58\x07\xdf\x14\x00\x43\x73\xd6\x01\xb3\x4e\x60\x29\xb2\ -\x19\x46\x76\xd0\xa6\xbb\x3f\x68\xd9\xa4\x12\x6a\x3c\xb5\x80\x49\ -\x69\xd7\xc2\x38\x09\xc0\x22\x1a\xd5\xa9\x44\x87\xa6\x48\x1b\x3a\ -\xf8\xe9\x7d\x4e\xaf\x9c\x7c\xf6\xb9\xee\xd0\xd4\x95\xac\x9f\x5d\ -\xd2\x3e\x97\xaf\x55\xe6\xfa\x6e\xe6\x1e\x6d\xa0\x92\x40\xdd\x48\ -\xd5\x32\xf0\x99\xf3\xbf\xff\xf4\xf3\x53\xf9\xa0\x85\xe7\xcd\xff\ -\x19\x27\x5f\xab\xe7\x1a\x86\x4e\xe0\x3e\xc7\x5b\x40\x7a\xf2\x54\ -\x8b\x17\xbe\x37\x07\x2f\x07\xd6\xff\x14\xac\x81\xd9\xda\x41\xfe\ -\x15\xbc\xda\x62\x76\x54\x9c\x24\xd6\x60\x1d\x0b\x2d\x8a\x4d\x54\ -\xe1\x2e\xaf\x8e\x19\xbe\xb7\x0e\x74\xa6\xd9\xef\x59\x10\x86\xbf\ -\xea\x87\x94\x2d\x6e\x14\x1a\x64\xa1\x3a\x0a\x17\xb3\xb2\xf6\x65\ -\xdb\x66\x8d\xc6\x2d\x66\x55\xeb\xf3\xbb\xd5\x11\x95\x13\xa3\xa8\ -\x3b\x3a\x74\x9f\x15\x30\xf4\x37\xad\x34\x2e\xb4\xab\x24\xde\x6e\ -\xd6\xb1\xaf\xca\xec\x15\x9a\xab\x13\x1a\x70\xca\x69\xdd\x83\x59\ -\xe2\x46\xa9\x46\x06\xfa\xc1\xcd\x92\x60\xff\x89\x62\x41\x84\x6d\ -\x51\x39\x25\xf0\x8f\x62\x2e\x1c\xf0\xb7\x53\x9b\x63\xa9\xe5\x02\ -\x44\xd2\x14\x8c\x11\xf6\xb9\x46\x7e\x91\x28\x2f\x6b\x74\x4e\x4e\ -\x08\x4b\xe8\xcb\x9a\x34\xe4\x27\x5c\x33\x0c\x48\x86\x2c\xec\x10\ -\x7d\xb1\x86\x5c\x3b\x16\x93\x63\x3d\x5a\xf0\xa6\xbc\xb2\x2d\x81\ -\x65\xae\x13\x0d\x5d\x69\x99\x66\x91\xab\x1c\x65\x8e\xad\xd6\x15\ -\x34\x1d\x2e\x11\x45\x4e\x43\x95\x66\x87\x10\xd0\x5a\x42\x5f\xce\ -\x3f\x12\xe2\xba\x8e\xf3\xa0\x6f\x50\xe9\x33\xe7\xb4\xb8\x4d\xb6\ -\x21\xf8\xfe\x57\x15\xc5\xbe\xff\x90\x66\x49\xfc\x55\xcd\xc1\x4b\ -\x5b\x2e\x21\xe5\x6d\xe1\x1a\xe6\x04\x73\x56\xb4\xa7\x92\x03\x5f\ -\x54\x12\x82\xed\x66\x73\x51\xc9\x7c\x17\x7c\x6e\x92\xb8\x87\x79\ -\x04\xf1\x4e\x25\xad\x9f\xd9\x60\xd4\x1b\x90\xa5\x14\xdb\xe7\x28\ -\xf5\x8c\x2c\xa2\xe3\xc0\x96\x97\xde\x8e\xde\x11\x5a\x39\x0e\x68\ -\x11\xc5\xce\xe9\x20\x73\x07\xd6\x22\x73\x1c\xe0\x52\x56\x22\x75\ -\x47\x70\xed\x71\x40\x6b\x63\x99\x5f\xe6\x7d\x79\x3b\x12\xe2\x32\ -\x56\x84\x09\x77\x75\xb8\x63\xa1\x2e\xb5\xff\x2f\x2e\x17\x91\x71\ -\xc0\xdb\x1a\xe2\x5a\xe2\xb6\xc0\xb6\xc3\xb9\x5c\x7a\xde\xe0\xe1\ -\x34\x1d\x9c\x07\x65\xce\xad\xe9\xda\x8e\xab\x2f\x5c\x77\x30\xb8\ -\xb6\xce\x17\xfa\xc2\x15\x89\x71\x20\xdb\x36\x5b\xb8\xb5\xfd\x77\ -\xcd\x6c\x87\xe4\x01\x5a\x67\x5f\xbd\x11\xd5\xe9\x40\x76\x48\x4c\ -\x6d\x9b\x7c\xdd\x9c\xa9\xa4\xcb\xf6\x87\xc4\xd5\xd6\xe9\x6c\x7f\ -\x4e\x15\xb1\x71\x90\xb5\x6d\x32\x7b\x7b\xb2\xf2\x71\x70\xb5\x75\ -\x75\xa0\x37\xae\x5a\xe3\x60\x6a\xdb\xda\x40\x0f\x6e\xb5\x63\xca\ -\x3a\x24\xaa\xb6\xae\xb6\xf4\xe8\x56\x47\x42\xd6\xd6\xa5\x96\x1e\ -\xa3\xab\xb1\xcc\xb1\xda\x56\x5a\xfa\x88\xaf\xba\x30\x1d\x92\x2b\ -\x68\x5d\xbd\xea\x33\xc2\xea\xf2\xb3\x43\x22\x6c\x9b\x33\xe8\x87\ -\xb0\xe3\x99\x14\xb4\x2c\xb5\xf4\x04\x6b\xc7\x84\x60\x50\xb0\x5a\ -\x57\x90\xd2\xb0\x72\xbb\xbf\x85\x6c\xd1\xc1\x59\x87\x58\xd6\x60\ -\xc0\xa5\x2d\x33\xd9\x3e\xc1\xa5\x5d\x7e\x76\x48\xe8\x96\x33\x2f\ -\x26\xef\x08\xae\xec\x7a\x01\x33\x24\x70\x11\xc3\x79\x45\xc8\xf9\ -\x6c\xa1\x5f\xea\x9a\x5d\xbb\x0a\x86\x84\x2f\x85\x20\xe1\x8e\xc8\ -\xda\x5d\xe3\xd9\x90\x70\x2d\x03\x5b\xeb\x7c\x3d\xa6\x67\xda\x9a\ -\x88\x74\x4c\x75\x87\x04\x30\x44\xb7\x17\x53\x84\xfe\xbd\xee\x68\ -\xf8\x0b\x33\xb3\xab\x51\x6e\xdf\x6e\xb7\xf3\xe5\xc2\x90\x00\x6e\ -\x0d\x78\xc5\xad\x27\xbd\x23\x09\xc3\xda\x01\xbd\xe2\x29\x6e\x43\ -\xd9\x0e\x5f\x60\x9a\x42\x0c\x06\xd9\xb6\xe9\x43\x7f\xc8\x0a\xc4\ -\x3a\x5e\xdb\x0e\x09\xdc\xb6\xd9\xc3\xcd\xdd\x80\x83\x3a\x5e\x85\ -\x0d\xc9\x11\xb4\x22\xda\x1b\x5b\x9d\x4e\x6c\x87\xc4\xd6\xd6\xe9\ -\xd8\xcd\xe9\x9a\xaf\x7e\x89\x0e\x27\x30\x24\xca\xb6\xc3\xda\xa7\ -\x87\xed\xda\x73\x34\x24\xd2\x5e\x99\xe3\xde\x9e\xae\x7c\x2c\x71\ -\xd6\x35\x34\x7b\x63\xa9\xd5\xb5\x0e\x33\x24\x8e\xb6\xad\x17\xf4\ -\xe0\x57\xed\x2e\xbb\x1f\x12\x53\x5b\x31\xed\xd1\xa9\x5a\x88\x77\ -\xbc\xbb\x1d\x12\x63\xdb\x16\x60\x7a\x0d\xb3\x28\x92\x1d\x0b\xdf\ -\x43\x82\xb7\x6d\x01\xa6\x9f\x40\x0b\x39\x23\x99\x1c\xb4\xc2\xda\ -\x6b\xa0\x65\x77\x6d\xe8\x18\x12\x6b\x5b\x9d\x42\x3f\xac\x15\x63\ -\x79\x4d\xd3\xbe\x04\xd3\x0f\xb0\x0c\xc9\x91\xbc\x47\x68\xdf\x78\ -\xd0\xcf\x8e\x83\xae\x45\xc3\x41\xfd\xe5\x5c\xeb\x9e\x83\x9e\x36\ -\x1b\x74\xed\xf1\x1c\x12\xb0\xad\xdb\x0d\x7a\xda\x67\x30\x9a\x6f\ -\x6e\xb4\xee\x34\xe8\x6d\x8b\xc1\x58\x3e\xb9\x71\x6d\x93\x41\x4f\ -\xbb\x0b\xc6\xf2\x77\xdf\xad\xfb\x0b\x7a\xdc\x58\x30\x96\xa1\xab\ -\x75\x6b\x41\x6f\x7b\x0a\xba\x5e\x1f\x0c\x09\xd9\xd6\x5d\x05\x3d\ -\x6e\x27\xe8\xda\x50\xf0\x27\xc4\x76\xd5\x52\x59\x78\xb8\x55\x3f\ -\x7c\x5e\x7e\x65\xf0\xb2\xa4\x63\xee\xc6\xd7\xc1\xf2\x5f\x43\x37\ -\x53\x9f\x10\x27\x25\xaa\x53\x24\x4b\x10\xf9\xe7\x33\x14\x57\x9c\ -\x51\xd9\xfc\x32\xdb\x69\x7f\x5f\xaf\xd8\x77\xa0\xd8\xac\x79\x85\ -\xa2\x63\x16\x1d\xfa\x16\x14\x9b\x55\xbc\x32\x36\x88\x93\x04\x1d\ -\x4c\xea\xa6\x60\xc1\xd8\x6b\xbb\xc0\x0b\x8a\x5f\x09\x7b\x2f\x6d\ -\xa1\xdd\x6a\xfe\xcb\xc7\x2c\xdb\x12\xd5\x1f\xb5\x3c\xf9\xa0\xdd\ -\x10\x3a\xae\x18\x7c\xee\xd2\x77\xd7\xa6\x82\xef\x7d\xf7\x86\xbe\ -\x93\x77\x33\x3b\x76\x55\xf1\xde\x75\x6f\x31\x3b\x18\x3d\xe5\x7d\ -\x7c\xa6\x85\xed\xfc\x4f\x42\xdf\x3b\xef\xed\x9d\x47\xf8\xc9\x8c\ -\xfd\xcd\xbd\x06\xd1\xf0\xfb\x20\xd7\xaf\xb5\x59\xc8\xba\xa9\x9d\ -\xd9\xc5\x47\x56\x9c\xf7\x6e\xeb\xd3\xce\xce\x36\x83\xf7\x62\x68\ -\xef\x11\xc9\x4d\x0d\x2d\x7f\x3f\x7f\x17\x53\x7b\xef\xb8\xdb\xc6\ -\x23\xf9\xab\xff\xbb\xf4\xdc\x7b\x24\x79\x53\x27\x29\xce\xbe\xda\ -\xdd\x4f\x3c\xf2\x1e\x40\xde\xd6\x4d\xea\x2d\x0b\xf6\x5d\xcc\xed\ -\xbd\xeb\x6e\x6e\x6e\xa2\x7f\x83\xfb\xf3\x38\xc9\xc5\x6c\x55\x9d\ -\xcd\x50\xfd\xb2\x71\xb3\x97\xaa\x94\xb2\x07\xf3\x13\x58\xf4\x8a\ -\xaf\xbe\x1e\x96\x71\x94\xa1\x5c\x03\x00\x27\x6b\x37\x2c\x24\xaf\ -\x6e\x12\xb8\x51\x76\x22\xdb\xe5\xf0\x9c\x88\xa0\x3b\x54\xe6\xbd\ -\x9c\xca\x82\x6f\x6a\xbe\x56\x7e\xb0\x5d\x3f\x84\x41\xa4\xca\xa3\ -\x44\x4e\xd2\x2c\xdd\x75\x10\x1e\xe6\xbf\xbb\x51\xfa\x80\xaa\x96\ -\xa1\x22\xfb\x46\x79\xf5\x61\x37\x45\x8a\x4c\xed\x33\x48\xe5\x2b\ -\xa8\x10\x29\xee\xdc\x30\x58\x45\xf3\x34\x73\x93\xac\x10\xf8\xca\ -\x8b\x93\x22\x4f\x4e\x94\x33\x21\xd2\x35\x29\x34\xa1\xca\x80\x66\ -\xa8\x3c\xf3\xa3\xaa\xd6\x2e\x4e\xfc\x73\x59\x5e\x46\xbd\x76\x5c\ -\xe4\xde\x25\x41\x06\x49\x90\x3e\x9e\x62\x1e\x26\x28\x7b\x7e\xf0\ -\x03\x4d\x3a\xfd\xe4\x30\x4b\x1e\xf4\x51\x38\x79\xb3\xd3\x97\x60\ -\x99\xcd\xab\xdb\xb2\xda\x91\xf7\x02\xe0\x17\xf5\xf6\x83\x74\x13\ -\x02\xb1\x83\x28\x4f\x10\xbf\xaa\x64\x19\xc6\xbb\xf9\x6b\x90\x06\ -\xcf\xa1\x7a\xc8\x7f\x06\xa1\xe6\x79\x25\xaa\x16\xeb\x8b\xae\x3b\ -\xb5\xbe\xd2\xd6\x9a\x66\x52\x18\x1a\xc7\x22\x3f\xb1\x48\xb0\x87\ -\xb5\x9b\x7c\x55\x49\x91\x46\x45\x2e\x14\x89\x9e\x5d\xef\xab\x3e\ -\x70\x23\xf2\xe7\xae\xe7\x6d\xd7\x5b\xbd\x38\x5e\x33\x0f\x2c\xea\ -\x6f\x06\x27\x58\x10\x4b\x9a\x62\x0a\xb3\x26\xf8\x49\x89\x63\xfc\ -\x68\x30\x0b\x13\x22\xa8\x74\xa6\x1c\x73\x4a\x88\x6d\x3a\x06\x95\ -\x98\x5b\x92\x9a\xce\x54\x60\x93\x39\x96\x4d\xa8\x41\x49\xf1\x0a\ -\xc9\x9e\xda\x58\x14\xbf\x19\xbf\x19\xf9\x57\x6d\x08\x25\xb6\x3e\ -\x87\x43\x50\x62\x31\x61\x30\xcc\x88\x34\x89\x6d\x4d\xa9\x89\x25\ -\x61\xb6\xc1\xb1\xc5\xa4\x45\x2d\x3a\x05\xdf\x28\xa4\x6d\x71\xd3\ -\x80\xdf\x24\xb3\x85\xc9\xa6\xb9\x23\x75\x2c\x13\x9e\x01\x09\xa9\ -\x69\x5a\x52\xd7\xd0\xa4\xc2\x14\x8e\xe1\x19\x26\x76\x08\x07\x77\ -\x3a\x45\x14\x43\x65\x28\x81\xcc\xd0\x00\x22\xa5\x70\xa6\x88\x61\ -\x53\x52\x87\x38\x50\x6b\x81\xb9\x23\x98\x25\xa6\x0c\x9a\x47\x61\ -\x5e\x08\x55\x31\x99\xb0\x28\x07\x09\x73\x98\x60\x0e\x54\x45\x4a\ -\x06\xc9\xa6\xda\xdc\x05\x97\x0c\xd2\x08\x62\x53\x66\xe5\x45\x51\ -\xca\x8d\x6f\x35\x6c\xda\x13\x69\xd3\x63\xd2\xd1\xcb\xed\x47\x47\ -\x70\x3c\x3b\x28\x8e\x22\x60\x4d\x9c\x20\x6f\x9b\xbc\xba\xd9\x36\ -\x51\x27\xa7\xd5\xd4\xa7\xce\x00\xcf\xf4\x41\x2d\x29\x18\x6e\x75\ -\xd5\x26\xff\x6e\xde\x43\x35\x6f\x18\x2c\xef\x69\xde\x44\x32\xc2\ -\xad\x29\x58\xaf\x43\x24\x15\x54\x9b\xb7\x89\x2d\x47\x02\xf9\xa7\ -\x04\x98\x6f\x3a\x0e\xd8\xaa\xb6\x6f\x62\x0a\x26\xa8\xb6\x0b\x2a\ -\x84\x6d\x5a\xda\xbe\xb9\x49\x6d\x21\xa7\x26\xa6\x60\x35\x36\x63\ -\xb9\x7d\x83\x90\x48\xfd\x72\x0d\xf4\x36\xa7\x9c\x59\xd2\xa0\xd8\ -\x91\xc2\x04\xd3\x9e\x82\xc5\x42\x99\x26\x98\xa4\xf6\x1e\x02\x1c\ -\x05\xd8\xb8\xc0\xd4\xe1\x42\x30\x6d\xe3\x16\x65\x26\x17\x5a\x66\ -\x9b\x42\x68\xdf\x02\x09\x09\xb1\xc0\xee\x25\xf8\x09\xc2\x4d\xa8\ -\xe6\x15\x1b\x17\x47\x23\xb7\x6b\x23\x97\x56\x6d\xe4\xbc\x32\x72\ -\x2e\x2b\x2b\x67\x17\x56\xce\x2f\xac\xdc\x2e\xad\x9c\x49\x28\xab\ -\xcd\xd0\xfb\x32\xf3\x66\x2c\x76\x16\x87\x5d\x1b\x09\xbe\x2f\x0e\ -\xa3\x98\xd6\x2f\x6c\x35\x53\xa1\xde\xf3\xf4\xdf\x5b\x37\x51\x4d\ -\xe9\xbf\xe2\x20\x9a\xe7\x01\xda\xf7\x47\x6b\x5a\x1a\x2f\x97\xa9\ -\xd2\xf6\xdd\x1a\xc1\x55\xd1\x1b\x87\x51\xa1\x16\x96\xf1\x1a\xad\ -\x42\xb2\x5a\x51\xc5\x6a\x97\x1a\x08\xbc\xa8\x53\x9c\xd1\x77\x14\ -\xea\xd8\x2b\xa7\x4d\xf3\x1b\x60\x49\xbe\x85\xcc\xc9\x23\x32\xb3\ -\xd3\xa9\xe6\x68\x37\x9a\x74\x1d\x49\x8e\x61\xa4\x02\xaa\x0b\xe7\ -\x1c\xcf\xe7\x6d\x96\xdd\x0a\xcd\x4b\xe4\x72\x2b\x86\xe6\x59\x2c\ -\x1f\x66\x61\x60\x2e\x87\xd9\x5f\x0c\x0e\xc3\xa1\x7d\x82\x44\xc5\ -\x58\x6e\x3b\xec\x46\x7c\xad\xcf\x4a\x83\xa8\x73\xa1\xcf\x2a\x7b\ -\xfa\xf0\x1f\xf2\x7c\xe6\x3d\ -\x00\x00\x0a\x16\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6d\x69\x6e\x75\x73\ -\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x34\x34\x2e\x37\x39\x31\x32\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x31\ -\x37\x2e\x37\x39\x33\x31\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x35\x2e\x32\ -\x34\x32\x30\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ -\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ -\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ -\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\ -\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ -\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ -\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ -\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\ -\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ -\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ -\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\ -\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ -\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ -\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ -\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ -\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ -\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ -\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ -\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ -\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ -\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\ -\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\ -\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x64\ -\x30\x64\x30\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ -\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x37\x2e\x30\x30\x33\x36\x30\x39\x36\x36\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x33\ -\x33\x33\x33\x33\x33\x33\x2c\x31\x36\x2e\x38\x35\x32\x33\x33\x39\ -\x20\x48\x20\x32\x38\x2e\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x38\x32\x2d\x38\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\ -\x73\x3d\x22\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ -\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x64\x30\x64\x30\x64\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\x31\x39\x31\x32\ -\x39\x38\x39\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x38\x36\x36\x36\x36\x36\x37\ -\x2c\x31\x36\x2e\x38\x36\x31\x32\x31\x31\x20\x48\x20\x32\x38\x2e\ -\x32\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x38\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ -\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\ -\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\ -\x73\x76\x67\x3e\x0a\ -\x00\x00\x09\x8a\ -\x00\ -\x00\x63\x16\x78\x9c\xe5\x5c\x5b\x6f\xe3\xb8\x15\x7e\x9f\x5f\xa1\ -\x3a\x2f\x33\x68\x44\xf3\x26\x91\xf4\x38\xd9\x87\x0e\x16\x58\xa0\ -\xfb\xd2\x6e\xdb\xc7\x85\x2c\xd1\x8e\x3a\xb2\x64\x48\x72\xe2\xcc\ -\xaf\xef\xa1\x6c\xc9\xb2\x63\x1a\x33\xdd\x70\xb0\xe1\xd8\x08\x12\ -\x1d\x92\x12\xcf\xc7\x73\xf9\x78\xcc\x78\xfe\xd3\x6e\x5d\x04\x8f\ -\xba\x6e\xf2\xaa\xbc\x9b\x10\x84\x27\x81\x2e\xd3\x2a\xcb\xcb\xd5\ -\xdd\xe4\x5f\xbf\xfd\x1c\xca\x49\xd0\xb4\x49\x99\x25\x45\x55\xea\ -\xbb\x49\x59\x4d\x7e\xba\x7f\x37\xff\x4b\x18\x06\x7f\xab\x75\xd2\ -\xea\x2c\x78\xca\xdb\x87\xe0\x97\xf2\x73\x93\x26\x1b\x1d\xbc\x7f\ -\x68\xdb\xcd\x6c\x3a\x7d\x7a\x7a\x42\xf9\x41\x88\xaa\x7a\x35\xfd\ -\x10\x84\xe1\xfd\xbb\x77\xf3\xe6\x71\xf5\x2e\x08\x02\x78\x6e\xd9\ -\xcc\xb2\xf4\x6e\x72\x18\xb0\xd9\xd6\x45\xd7\x31\x4b\xa7\xba\xd0\ -\x6b\x5d\xb6\xcd\x94\x20\x32\x9d\x1c\xbb\xa7\xc7\xee\xa9\x79\x7a\ -\xfe\xa8\xd3\x6a\xbd\xae\xca\xa6\x1b\x59\x36\x37\xa3\xce\x75\xb6\ -\x1c\x7a\x9b\xd9\x3c\xb1\xae\x13\x51\x4a\x4d\x31\x9d\x52\x1a\x42\ -\x8f\xb0\x79\x2e\xdb\x64\x17\x9e\x0e\x85\x39\x5e\x1a\x4a\x31\xc6\ -\x53\x68\x3b\xf6\xfc\xba\x5e\xb3\x06\x00\xdd\xc0\xcf\xd0\xbd\x17\ -\xa0\xa6\xda\xd6\xa9\x5e\xc2\x38\x8d\x4a\xdd\x4e\x3f\xfd\xf6\x69\ -\x68\x0c\x31\xca\xda\x6c\x74\x9b\x1e\xcf\x93\xa7\x9e\x80\x5c\x26\ -\x6b\xdd\x6c\x92\x54\x37\xd3\x5e\xde\x8d\x7f\xca\xb3\xf6\xe1\x6e\ -\xc2\x38\x22\x0c\x5e\x51\x27\x7c\xd0\xf9\xea\xa1\x3d\x97\xe6\xd9\ -\xdd\x04\x66\x4f\x95\xdc\x5f\x8f\x8c\x83\xec\x3b\x1c\x6e\x3c\x1b\ -\x5a\x30\x52\x14\x91\xa0\x26\x11\x13\xfb\x3e\xbd\x0a\xb3\xac\x4a\ -\xcd\x9c\xe0\x96\x7a\x9d\x27\xdb\xb6\x5a\xc3\xaa\xa5\x69\x91\x34\ -\x4d\xbe\xcc\x53\xb8\xa8\xca\x4d\xb1\x5d\xe5\xe5\xef\xb5\x5e\x57\ -\x8f\xfa\xf7\x56\xaf\x37\xa8\x87\x6f\x78\x96\xde\x6d\xaa\xba\x0d\ -\x77\xd9\x06\x40\x8c\xc5\xc5\xc6\xe7\xbe\xf1\x1e\x5a\xe7\x99\x5e\ -\x36\xa6\xd7\x5e\x23\x73\x05\x2a\x89\x49\x30\xed\x5a\x87\x09\x9a\ -\xd9\x65\x8f\xb9\x7e\x3a\xf6\x5d\x24\xcd\x1e\xb5\x20\xd8\x24\x2b\ -\xb0\xb0\xa2\xaa\xef\x26\x37\xcb\xee\x75\x68\x58\x54\x75\xa6\xeb\ -\xbe\x29\xee\x5e\x27\x4d\x15\xac\x42\xde\x3e\xef\x7d\xea\x70\xef\ -\x7e\xbe\xe6\xae\x43\x3b\xbe\xdc\xde\x3c\x24\x59\xf5\x74\x37\xa1\ -\xe7\x8d\x5f\xaa\x6a\x7d\x37\x89\x50\xa4\xa4\xc2\x58\x9d\x37\xa7\ -\xbb\xbb\x49\xc8\x29\x8a\x98\x14\x07\x9c\xc6\xad\x66\x42\x02\x09\ -\xc1\x09\x7b\x71\xe7\x74\x5b\xd7\xe0\x75\x61\x91\x3c\x6b\xd0\xaa\ -\xfb\x45\x0e\x9d\x9a\x87\xea\x69\x55\x1b\x74\xda\x7a\xab\xcf\x47\ -\x9a\x96\x70\xb1\xa8\x76\x97\x9b\xc1\x08\xb6\xc6\x9f\xc3\x6d\x99\ -\xb7\xe0\x33\x9b\xdd\xf8\xae\xdb\x3c\xd3\x20\x5c\x26\x45\xf3\x62\ -\x64\x53\x26\x9b\x70\x55\x54\x8b\xa4\xb0\xf4\x78\xca\x4b\xc0\x29\ -\x3c\x18\x38\x61\xc3\x32\x9c\xf7\xe8\xad\x5d\x60\x69\xe9\x01\xb3\ -\x7f\xb1\x14\x87\xa6\x67\x7b\xd3\x3a\xd9\xe5\xeb\xfc\x8b\x06\x68\ -\x48\x67\x79\x60\x5d\x27\xc0\xec\x87\x05\x41\xfb\x6c\x3c\x77\xf7\ -\x6c\x64\x93\x5e\x68\x10\x35\x02\xaa\x94\x18\x84\x55\x9d\x83\x43\ -\x8c\xa6\xd3\x8b\x9e\xc7\x22\xe3\xe7\x10\xa6\x77\x9d\x89\x75\x06\ -\x28\xce\xdb\x9e\xc7\x6d\x07\xcb\x9f\xbe\x34\xfd\x4e\xbe\xd6\x6d\ -\x92\x25\x6d\x72\xf4\x83\x5e\x02\x73\xc3\xbd\x66\x10\x32\x67\xff\ -\xf8\xf4\xf3\xfd\xe1\x41\xf3\x34\x9d\xfd\xa7\xaa\x3f\xf7\xcf\x0d\ -\x02\xd3\x21\x59\x54\x5b\x40\x7a\x72\x3f\x88\xe7\x59\x3a\x83\x20\ -\x07\xce\x7f\x9f\xaf\xc1\xba\x4d\x7c\xfc\x2b\x04\xb5\xf9\xf4\xd8\ -\x70\xd2\xd9\x80\x75\xbc\xe9\xfe\xb6\xb5\xde\x47\xcb\x8b\x29\x23\ -\x4b\xd7\xb9\x19\x34\xfd\x67\x9b\x17\xc5\x2f\xe6\x21\x07\x8d\x47\ -\x37\xcd\xdb\x42\x1f\x85\xf3\xe9\x61\xf6\x07\xdd\xa6\x23\xe5\xe6\ -\xd3\x5e\xfb\xee\x6a\x75\x44\xe5\xc4\x2d\x86\x85\x2e\x92\x85\x06\ -\x13\xfd\xbb\x69\x0c\x5e\xb4\xae\xea\x6a\xbb\x59\x57\x99\x3e\x0c\ -\xef\xd1\xd4\x45\x91\x6f\x9a\x41\xd1\xa6\x7d\x2e\xa0\x4b\x17\x55\ -\x66\x37\xb8\x7b\x7d\xcc\xf2\x66\x03\x83\x20\xf8\x17\x79\xa9\x3f\ -\x42\x88\xac\x97\x45\xf5\x34\x7b\xcc\x9b\x7c\x51\xe8\x8f\xdd\xef\ -\xbc\x00\xe5\x07\xd1\x12\x10\x98\xdd\xf0\xcc\xbc\xbb\x8b\xf0\x10\ -\x6d\x66\x64\x7f\x59\x6f\x0b\x3d\x2b\xab\xf2\x0b\xc4\xa9\x8f\x4d\ -\x5b\x57\x9f\xf5\xec\x86\x4a\xca\xe0\x79\xfb\xcb\xbd\x43\xcd\x18\ -\x8a\x09\x26\x4c\x12\xd9\xcb\xcd\x24\x40\xa7\xd9\x62\xdb\xb6\x63\ -\xd9\x7f\xab\xbc\x9c\xc1\x12\xe8\xba\x97\x76\x17\x05\xf8\x46\x3b\ -\xe3\xbd\x2c\x4b\x20\xae\xd5\x35\xa8\x03\x4f\xd7\x63\x69\xb5\x5c\ -\x36\xba\x9d\x51\x24\x19\x95\x98\x44\xc3\x03\x8f\x53\x5f\x27\xf5\ -\x67\x5d\xef\x47\xea\x32\x01\x4d\xc3\x45\x92\x7e\x36\xe0\x96\xd9\ -\x2c\x49\x21\xc8\x6c\x0b\xa0\x24\x27\xce\xb5\x49\xda\x07\xa6\x44\ -\x3c\x08\x4d\x80\xa4\x0c\x11\x2e\x38\xa6\x47\x29\xb8\x0a\x8d\x51\ -\x8c\x25\xe6\x47\x37\xaa\x8d\x73\x49\x64\x28\x83\x3c\xde\xa1\x86\ -\xbe\x1c\xc9\x98\x63\xc6\xc5\x60\x64\xf3\x5a\xa7\xad\x9b\x95\x94\ -\xd8\xbc\xbf\x7a\x25\xc7\xd0\xee\x97\x91\x22\x2e\xa4\x62\xec\xff\ -\xc4\xd0\x68\xc6\x94\x3a\x22\x70\x88\xb6\x94\x23\x15\x09\x2a\xd4\ -\xd0\xd0\x07\x59\x2a\x10\x8e\xa8\xa2\xc7\x16\x40\x92\x21\x49\x30\ -\x15\x24\x1a\x84\x06\x74\x14\x03\xd3\x50\x94\x9f\x82\x6e\xd2\x9b\ -\x8c\xc9\x19\xe6\x9c\x47\x92\x4a\x7e\xc4\xdc\xa9\x03\xc5\x0b\xb9\ -\x88\xe5\x37\x38\x10\x31\xef\x73\xe4\x65\x2c\x24\x03\x98\xde\xba\ -\x03\x85\xe4\xc4\x85\x48\x84\x14\x16\x52\x46\x27\x2e\x14\x23\x46\ -\x24\xe3\xea\x6c\x35\x29\x12\xf1\x89\x5f\x75\xab\xc9\x84\x90\x82\ -\x46\xc7\xd5\x34\x8f\x3a\x5b\xca\x6e\x25\x46\xaa\x0e\xab\x7a\x82\ -\xf2\x90\xe4\xe8\x66\xf7\xed\x38\x0f\x00\x0d\xf3\x03\xb5\x7f\x0d\ -\x04\xa2\xb0\x6e\x24\xa6\xb7\xa0\x2b\x15\x94\x4b\x15\xfc\x3b\x00\ -\x9b\xe7\x44\x10\x7e\x01\x23\x25\x8f\xc2\x81\x53\x55\x25\x4c\xa3\ -\xad\xea\x10\xd8\xd5\x63\xd2\x6e\x6b\x6d\x72\xf8\x9f\x52\xe5\x75\ -\x40\x08\xa2\x10\xd5\x70\xa7\x72\x1c\x31\xd0\x3e\x80\x5d\x08\x51\ -\x38\x22\xfc\x56\xa1\x88\x46\xf1\xc8\xdb\x7b\xd5\x39\xcc\xee\x6d\ -\xab\xfe\x6b\x40\x62\x84\x31\x23\x9c\xdc\xc2\x5f\x9c\x44\x91\x08\ -\x00\x03\x49\x68\x4c\xc5\x2d\x84\x33\x2a\xb8\xe4\xd1\x25\xd5\xe9\ -\xdb\x56\x7d\x1d\x50\x02\xae\xac\xb0\x31\x74\x48\x6b\x8a\xf0\x98\ -\x04\x87\x45\x67\xb7\xe0\xa6\x90\xfd\x09\xbb\xa4\x39\x7f\x3d\xcd\ -\x3b\x6d\x25\x1e\x94\x5f\x08\xf3\xfe\x0e\xeb\xce\xc0\xcb\xa5\x60\ -\x58\x81\x79\xc3\xe6\x01\xec\x5b\x04\xb0\x1f\x56\x04\x76\x8b\xf2\ -\x96\x4a\x84\x59\x2c\xc7\x9e\x7d\x54\x3f\xfe\x76\xf5\x2f\x70\x84\ -\xbd\xfa\x5a\x25\x0b\x12\xdb\x73\x8d\x7e\xd4\x65\x95\x65\x03\x3e\ -\x44\x66\xf1\x72\x79\x8a\x0f\x46\x02\xac\x51\x0a\xcc\xbf\x3d\x83\ -\xbc\x44\xa7\x4f\xfc\xc0\xfe\x55\x18\x9d\xa7\x7e\x82\x11\x83\x40\ -\x31\x8a\x83\x7d\xea\x7f\xd9\x62\x08\x97\x44\x94\x44\xa3\x0d\x0a\ -\x24\x80\x90\x21\x45\x0d\xf8\xe4\x2c\xf5\x0b\x88\xb9\xe4\x2c\x5b\ -\x40\x60\xa2\x11\x8e\xd8\x51\xda\xd6\x49\xd9\x98\xad\x03\x4c\xb3\ -\x6a\x21\x6b\xbd\x87\x87\x70\x41\xb0\xa2\x1f\x8e\x80\xaf\x4e\x36\ -\x5a\x4c\x8d\x0c\x79\x74\x03\xd8\x7e\xd4\xf9\xee\x3d\x46\x11\x98\ -\x7a\x44\x14\xbb\x0d\x8d\x16\x24\x26\x82\xb3\xdb\x93\x3f\x87\x1e\ -\x1c\x61\xc9\xa4\xa2\xf1\x2d\xf8\x0f\x8b\x23\x8a\xd9\x87\x61\xc7\ -\x73\xb2\xd0\x7b\x0d\x30\x04\x13\x22\xc0\xc4\x8e\xc0\xec\x15\xc6\ -\xa3\x6b\xa3\x69\x6c\x60\xe1\x8a\x8c\xc4\x06\x16\xc8\x3b\x8a\x45\ -\x2c\x1a\x89\x07\xb6\x85\x38\x8b\xe8\x78\x40\x4f\xd0\x5e\x34\xf4\ -\xab\x1a\x01\x27\x19\x89\xcf\x5c\x31\x4d\xc1\xb6\xbe\xda\x16\xf7\ -\x85\x91\x33\x5b\xfc\x23\x26\x38\xda\xa2\xbd\x3e\x8e\x46\x2c\x05\ -\x7f\x45\x1c\x43\x62\x47\x32\x49\x32\xee\x2b\x92\x26\x60\x02\x43\ -\x7a\x55\x24\x43\x69\xc7\x32\x8e\xaf\x6d\x82\xde\x34\x96\x10\x42\ -\x84\x52\xe4\x64\xf4\x1f\xc7\x12\xdb\xb1\x84\x9d\x54\xe4\x2b\x96\ -\x1c\x52\x3a\x67\xe2\x55\xed\x92\xd9\xa0\x5c\x2e\x69\x42\x13\x5f\ -\xa1\x8c\x51\x1c\xab\x48\xbe\xae\x59\x8a\x1f\x13\x4b\x85\x08\xec\ -\x81\xd5\xeb\x62\x29\xc3\xe8\x87\x44\x93\x11\x14\x99\x6d\xe7\xeb\ -\x26\x1f\x1c\xfa\xee\xe7\xc0\x22\xa5\xa0\x92\x9d\xa2\xe9\x84\x14\ -\x85\xdc\x86\xa5\x27\xb4\xc8\x82\xa5\x1b\x5a\x74\x8d\x64\x7a\x41\ -\x8c\x2e\xa3\xe9\x88\x18\xd9\x73\x90\x27\xd4\xc8\x82\xa6\x13\x6a\ -\x14\xc6\xf6\xa0\xa9\x94\xbf\x60\xba\x21\x47\x21\xfd\x31\xd1\x74\ -\x45\x8f\x42\x6b\x9d\xc3\x0f\x3c\xbb\x08\x49\x15\xa1\xa7\x78\x3a\ -\xa8\x17\x5d\xdb\x9b\xfb\x50\x31\xb2\x21\xe9\x84\x1c\xc9\x2b\x60\ -\xfa\xc0\x8e\x6c\x60\x3a\x62\x47\x57\x8a\x99\x3e\xb0\x23\x0b\x9a\ -\xae\xd8\x91\x35\xa1\xfb\xc1\x8e\x6c\x68\xba\x61\x47\xd6\x7c\x2e\ -\xf7\x1f\xf0\x79\x0a\xa6\x23\x76\x64\xdd\xa0\xfb\x8d\xa6\x33\x76\ -\x64\x4d\x43\x5e\xe3\xe9\xac\x7c\x64\xdf\x58\xfa\x81\xa7\xc9\xdf\ -\x91\x10\xf8\x3b\xb0\x4d\x7c\xad\x80\xe4\x03\xdf\xb4\x61\xe9\xa6\ -\x18\x67\xcf\x43\x7e\x10\x4e\x1b\x9a\xae\xca\x71\xf6\xc2\xbb\x1f\ -\x94\xd3\x82\xa7\xb3\x82\xdc\x35\x0a\xef\x03\xe9\xb4\xe1\xe9\xa8\ -\x24\x67\x77\xf7\x8c\x7b\x9c\x88\x9c\x15\xe5\xec\x89\xdd\x6f\x3c\ -\xdd\x95\xe5\xec\xc7\x13\xbc\x46\xd4\x1d\xf5\xa4\xf6\xcf\x88\xfc\ -\x40\xb4\x73\x6e\xc6\xd8\xf7\x20\x9f\xd6\x7d\xa6\xc9\xed\xfe\x42\ -\xe9\x84\x7b\x5a\xcb\x49\x7e\x63\xe9\x88\x79\x5a\x13\x91\xd7\x68\ -\xba\xe2\x9d\xd6\xfa\x87\xdf\x68\x3a\x2a\x75\x5e\xf9\x58\x9d\xb1\ -\xb7\xbf\x27\xb2\xa1\xe9\x88\x74\x5e\xd9\x61\x72\x9e\xbc\xf9\xc3\ -\x48\x36\x34\x9d\x51\x4e\x6b\x4e\xa7\x89\x58\xbe\xfd\x7a\x92\x05\ -\x4f\x87\xb5\x4e\x7b\x31\x5e\x24\x49\xa6\xdf\x3c\xa0\x10\x25\xa9\ -\x24\x27\x30\x38\x2b\x76\x5a\x43\xa7\x29\x7e\x78\x90\x88\x2c\x58\ -\x3a\x2a\x76\x5a\x29\xa7\xdf\x68\xba\x2b\x76\x5a\x73\x91\xd7\x80\ -\xba\xab\x76\x5a\x3f\xdb\xf0\x1b\x4f\x57\xd5\xce\x2b\x54\xc9\x0b\ -\xe2\x69\x81\xd3\x59\xb5\xf3\xea\x09\x10\x0f\xa8\xa7\x05\x4f\x87\ -\xd5\x4e\xdf\xc9\xe7\x65\x44\x5d\x56\x3b\xad\xf5\x63\x3f\xd8\xa7\ -\x81\x8e\x41\xa8\xfc\x2e\x8c\x49\x5e\xf9\x07\x83\x45\x9a\xb1\xe8\ -\xcd\x1b\xa8\x0d\x4e\x57\x07\x12\xed\x84\xde\x6b\x3c\x9d\x1d\x49\ -\xb4\xa7\x24\xbf\xf1\x74\x54\xa9\xf3\x9d\x31\xd9\xe0\x74\x75\x2c\ -\xf1\xda\x61\x25\x1f\x18\x93\x0d\x4f\x77\x07\x13\xed\x16\xea\x09\ -\x63\x52\x08\x2b\x19\xf1\xef\x52\x5d\xe2\xf6\xf4\x2e\x65\x92\x78\ -\xb0\xe1\xb4\xa0\xe9\xea\x30\xdd\x95\x83\x9e\x5e\xe3\xe9\xae\xc2\ -\x74\x85\xcf\xfb\x8c\xa8\xc3\x03\x75\x57\x0e\xcb\x7b\x8d\xa8\xb3\ -\x23\x75\xd7\xbe\x51\xc5\x07\xd2\x64\x03\xd4\xdd\xa1\xba\xeb\xff\ -\x88\xfd\xf6\x69\x93\x0d\x51\x97\xc7\xea\xec\x56\xea\x35\x71\x72\ -\x7a\xb0\xee\x0a\x7d\xfa\x53\x17\x9b\x28\x22\x02\x72\x0b\x3b\x43\ -\x94\x21\xcc\x29\xa3\x27\x58\x3d\x77\x5f\xea\x8a\x55\x8c\x65\x74\ -\x8a\x2c\x88\x09\xa6\x10\xe0\x2e\x20\x4b\x24\xa2\x31\xc7\x82\xbe\ -\xc4\xf6\x52\xd3\xf8\x5b\x05\x2d\x88\x7e\xc5\x97\x60\x52\x4e\x18\ -\x70\x64\xf1\x1a\xb0\xcd\xa7\xab\xfd\x17\x7e\xc3\xaf\xb9\xf9\x5e\ -\xf2\xfb\x77\xff\x03\x89\x24\xec\x97\ -\x00\x00\x06\x59\ -\x00\ -\x00\x4e\xd5\x78\x9c\xe5\x9c\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ -\x54\xed\x25\x41\x4b\xbd\x6d\x3d\x62\x3b\x87\x06\x01\x02\xf4\xd4\ -\xa6\xe8\x31\x90\x25\xda\x26\x56\x12\x0d\x8a\x5e\xdb\xf9\xf5\x21\ -\xf5\xb2\x65\x6b\x81\xa6\xa4\x0a\xed\x52\x45\x90\x6a\x66\x48\x91\ -\x9f\x66\xc8\x21\x45\x67\xf1\xf1\x94\x67\xda\x33\x24\x25\xc2\xc5\ -\x52\xb7\x0d\x4b\xd7\x60\x91\xe0\x14\x15\xdb\xa5\xfe\xf7\xd7\xcf\ -\x20\xd0\xb5\x92\xc6\x45\x1a\x67\xb8\x80\x4b\xbd\xc0\xfa\xc7\xd5\ -\xc3\xe2\x17\x00\xb4\xdf\x09\x8c\x29\x4c\xb5\x23\xa2\x3b\xed\x4b\ -\xf1\x54\x26\xf1\x1e\x6a\xef\x76\x94\xee\x23\xd3\x3c\x1e\x8f\x06\ -\x6a\x84\x06\x26\x5b\xf3\xbd\x06\xc0\xea\xe1\x61\x51\x3e\x6f\x1f\ -\x34\x4d\x63\xcf\x2d\xca\x28\x4d\x96\x7a\x53\x60\x7f\x20\x59\x65\ -\x98\x26\x26\xcc\x60\x0e\x0b\x5a\x9a\xb6\x61\x9b\xfa\xc5\x3c\xb9\ -\x98\x27\xfc\xe9\xe8\x19\x26\x38\xcf\x71\x51\x56\x25\x8b\xf2\xf1\ -\xca\x98\xa4\x9b\xce\x9a\xb7\xe6\xe8\x56\x46\x76\x18\x86\xa6\xe5\ -\x98\x8e\x03\x98\x05\x28\xcf\x05\x8d\x4f\xa0\x5f\x94\xb5\x71\xa8\ -\xa8\x63\x59\x96\xc9\x74\x17\xcb\x7f\x67\x15\x95\x0c\xe8\x9e\xfd\ -\xe9\xcc\x5b\x81\x51\xe2\x03\x49\xe0\x86\x95\x83\x46\x01\xa9\xf9\ -\xe9\xeb\xa7\x4e\x09\x2c\x23\xa5\xe9\x55\x35\x2d\xcf\xde\x53\x7b\ -\x90\x8b\x38\x87\xe5\x3e\x4e\x60\x69\xb6\xf2\xaa\xfc\x11\xa5\x74\ -\xb7\xd4\x5d\xcf\xb0\x5d\x76\xcd\x2a\xe1\x0e\xa2\xed\x8e\xde\x4a\ -\x51\xba\xd4\x59\xeb\x9d\x30\xa8\xef\xaf\x9c\xc3\xae\x0d\x9a\x8a\ -\xa3\x4e\x63\x19\xa1\x63\xd8\x1a\xb1\x67\xae\x5f\xdb\xb4\x5d\x88\ -\x52\x9c\xf0\x36\xb1\x2a\x61\x8e\xe2\x03\xc5\x39\x7b\x6b\x49\x92\ -\xc5\x65\x89\x36\x28\x61\x37\xb8\xd8\x67\x87\x2d\x2a\xbe\xf5\x85\ -\xdf\x52\x94\x55\xff\x63\xb4\x28\xbb\xe7\xc2\xd3\x1e\x13\x0a\x4e\ -\xe9\x9e\x01\x9d\xfb\x83\xca\x73\xab\x5c\x31\xed\x22\x85\x9b\x92\ -\x5b\xd5\xbd\xe3\x77\xac\x7b\xbe\xae\x99\x95\xb6\x6b\x2c\x6f\x69\ -\xfa\x8c\xe0\xf1\x62\xbb\x8e\xcb\x9a\xa0\xa6\xed\xe3\x2d\xf3\xb6\ -\x0c\x93\xa5\xfe\xb8\xa9\xae\x46\xb1\xc6\x24\x85\xa4\x55\xcd\xab\ -\xab\xa7\xc2\xec\x8d\x20\x7a\xae\xe3\xab\xa9\xbb\x6d\x2f\xaf\xb5\ -\xd3\x5b\xc3\xfa\x72\x17\xa7\xf8\xb8\xd4\x9d\x5b\xe5\x77\x8c\x73\ -\x56\x2b\x7b\x33\xa1\x1f\x58\x77\xea\xe4\xb4\xd4\x81\x1d\x18\xee\ -\xcc\x9b\xdb\x77\x4a\xde\x1e\xdf\xb0\x9c\xd0\x0a\xef\x74\x07\x42\ -\x58\xfc\x81\x2c\x3e\x43\xd6\xa7\xea\xaf\xb6\x82\x72\x87\x8f\x5b\ -\xc2\xd9\x50\x72\x80\xb7\x25\xb9\x06\xac\xd7\xf8\x34\xac\x66\xee\ -\x70\xe0\x91\x0d\x0e\x05\xa2\x2c\x7a\xf6\xa7\xeb\x5a\x0f\x28\x85\ -\xe5\x70\xc1\xb2\x88\xf7\x60\x9b\xe1\x75\x9c\x0d\x1b\x1c\x51\xc1\ -\x18\x81\xc6\xd1\x6d\xb7\x7b\x05\xb7\x16\xad\xd7\xfb\x56\xf0\x82\ -\x05\x6b\xfb\xdd\x6b\x68\x54\xe7\x97\x55\x79\x7c\x42\x39\xfa\x0e\ -\x19\x18\xbb\xf2\x3a\xe6\x59\x3d\x2c\x75\x31\x4d\xa3\x67\x1e\xc1\ -\xa7\x33\x97\xe9\xad\x90\xf3\xe4\x02\x27\x0c\xfd\x4e\x88\x09\x62\ -\x81\x71\xd5\x9c\x56\x74\xbe\x16\xf1\x78\x67\xc3\xf5\xa9\x72\xaf\ -\xca\xf9\xfc\x5b\xdd\xf9\x5a\xd7\x78\xbd\x79\xef\xf6\x95\x3c\x87\ -\x34\x4e\x63\x1a\x5f\x62\xa0\x95\xb0\xb6\x59\x6d\xcf\xd8\xd0\x19\ -\xfd\xf9\xe9\xf3\xaa\x79\xd0\x22\x49\xa2\x7f\x30\x79\x6a\x9f\xab\ -\x69\xdc\x20\x5e\xe3\x03\x23\xad\xaf\x3a\xf1\x22\x4d\x22\x36\xd8\ -\xb1\x41\x60\x85\x72\xe6\xd9\x7c\x9c\xfc\x95\x0d\x6e\x0b\xf3\xa2\ -\xe8\x19\x73\x58\x97\x4a\xeb\x6a\x09\xac\x47\xcd\xc1\xa9\x23\x4d\ -\x72\xc4\x0b\x99\x7f\x51\x94\x65\x5f\xf8\x43\x9a\x1e\x5f\x55\x8a\ -\x68\x06\x2f\xc2\x85\xd9\xb4\xbe\xe9\x9b\x79\xd5\xb9\x85\xd9\xf6\ -\xbe\xba\xdb\x5e\xa8\xf4\x82\xa2\x7b\xd1\x59\xbc\x86\xcc\x43\xff\ -\xe0\x4a\xed\x4e\xbb\x25\xf8\xb0\xcf\x71\x0a\x9b\xe2\x1d\x4d\x98\ -\xd0\xee\x95\xd1\x73\xc6\xf4\x1b\xd6\xfa\xe8\x71\xed\xf2\xff\x3e\ -\xf0\x1b\xd0\x8c\x12\x91\x5d\xdf\x92\x43\xc6\x46\xbb\x67\x58\xe0\ -\x34\xfd\x50\x52\x82\x9f\x60\xf4\x68\x55\x57\x73\x5b\x07\x43\x64\ -\x19\x9e\x1b\x7a\xfc\xdd\xb7\x72\x46\x08\x92\x8c\x79\x2b\x8d\xbc\ -\x56\x96\xc6\x6c\x94\x21\x24\x3e\x47\x05\x9b\xe8\x5b\x69\xf7\xcc\ -\x9e\xa3\xf2\xe6\xce\x02\x37\x04\x36\x08\xc0\x45\xd5\xc4\xde\xcc\ -\x70\xdd\xcb\x74\xc2\xaf\x36\xe4\x3c\x23\xac\x34\x5e\xa7\xe1\x4e\ -\x6b\x19\x37\x4e\x7b\xe6\xa3\xd6\x9d\x2b\x93\x5e\x1c\x90\xca\xa5\ -\xe7\x1e\xbf\xe6\xdd\x0b\x7e\x19\xa4\x65\xcd\x66\x0c\xcc\x94\x41\ -\x86\x63\x80\xb4\x5d\xc3\xef\x5b\xbe\x79\x8e\x36\x98\x8d\x41\x32\ -\x30\x82\xaa\x2f\x8e\x3a\x24\xfd\x31\x38\x3a\xae\x31\x57\x07\x21\ -\x73\xc6\x51\xbc\x91\x65\x75\xbd\x44\x53\x14\xe5\x2b\x98\x68\xc2\ -\x71\xfc\xd1\x75\x0d\x4f\xe6\x4c\x33\x6d\x92\x82\x04\xad\x1e\x39\ -\x23\x50\xcb\x07\x3d\x41\x7a\xf7\xe6\x63\xa4\x3a\x13\xc7\x18\xc8\ -\x74\x41\xd9\xe9\xcd\xc4\xd9\x59\xc2\x2e\xd8\xa3\x27\x3b\xa5\x99\ -\x3a\x3d\x57\x26\x3c\x89\x79\xcc\xd4\xb9\x09\x4f\xbc\xfd\x98\x55\ -\x2e\x75\x11\x5f\x24\x0f\xce\x1c\x6a\x65\x2e\x7c\xf0\x13\xe6\xd8\ -\x8f\xe0\xc0\x98\x55\x26\x0a\xf1\x93\x3b\x81\xa8\xe8\x81\xc0\x91\ -\x49\x50\xb5\xec\x8f\x2f\xe4\x3c\x51\x1f\x74\xe6\xb7\x33\x48\xb5\ -\x1a\xf1\x5d\x85\xa2\xb9\xde\x5c\x10\x9d\x98\x07\x49\x32\x9f\x54\ -\x24\x23\x6c\x76\x68\x84\x37\x0c\x07\x31\x06\xb7\x9b\x0d\x6f\x1e\ -\x65\x08\x7c\xe1\xd1\x71\x38\xb6\xdd\xba\x12\x65\xdc\xd2\x03\x8e\ -\xe8\x3a\xd9\xb1\x8d\x1b\xa1\xdc\xd0\x9e\xf8\xe6\x6b\x00\x44\x57\ -\x7b\x76\xcf\x05\x6d\x65\xb6\xad\xab\x2c\xc7\x13\x75\x3f\x7b\xcc\ -\xb1\x70\xea\x04\x5d\xf1\xad\xea\x1e\x3e\x47\x72\x9e\x3d\x71\x7e\ -\x36\x98\x8b\x4f\xc9\x43\xc3\x9f\x62\x1c\x2d\x36\x1f\xcb\x8d\x63\ -\x5b\xf2\x92\x79\xe2\x00\xf9\x44\x3c\x07\xae\xe8\xae\xc3\xa0\x2f\ -\xca\x46\x39\xf9\x9c\x86\x6f\x83\x81\xd0\x1a\x83\xa5\x62\xf9\x61\ -\xb3\x93\x23\x7e\xce\x41\xe5\x24\xbb\xd9\xcc\x01\xe1\x5c\x2a\x45\ -\xb5\x16\xcf\x9e\x27\xbc\xe0\xbb\xf2\x37\x65\x77\x71\x80\xa8\x0f\ -\xf6\x21\xaa\xe5\x83\x3c\x94\x45\xb3\x9c\x3e\x3f\x89\x6b\xbd\x57\ -\xc0\xaf\xda\x00\x13\xfe\xb2\xd2\x27\xa8\xde\xde\x97\xcf\xa6\x12\ -\xd1\x45\x5f\x9f\xa1\xec\xc5\xca\x2b\x80\xc8\x4f\xcb\x01\x6b\x2e\ -\x79\x4e\x91\x97\x69\xf7\xb1\xbd\x0a\xa4\xd5\x9e\xac\xf0\x5e\x18\ -\x70\xfd\xdb\xe4\xf0\xa7\x33\xc6\x56\x4a\x49\x5c\x94\xfc\xac\xff\ -\x52\x2f\x93\x38\x83\xef\x80\xfd\x9b\xfd\xfe\xcd\x38\x70\x95\x58\ -\x8a\x7e\xe1\xba\x19\x09\x02\x43\xde\xf9\xed\xcd\xe6\x67\x16\xdc\ -\xf5\x0f\x9d\xfe\x4f\x86\xa2\xd9\xf8\xe0\x19\x4f\xc9\x27\x15\xa7\ -\x4f\xb1\xf6\xc4\x31\x58\xca\x3e\x35\x31\x75\x96\x82\x0c\x87\x4f\ -\xee\x28\xe7\x8f\xa2\x61\x3d\x88\x51\xfe\x8f\x5b\x26\x8e\x51\x7c\ -\xb5\x3d\xc8\x51\xfe\x4f\x5b\x26\xce\x51\x74\xb9\x3d\x48\x51\xea\ -\x0f\x5b\x26\x0e\xd0\x1b\x07\xa1\xec\xa3\xa1\xaf\x80\xa3\xf8\xaa\ -\x71\xd8\x19\x15\x9b\xa5\xeb\x7d\x20\x41\x92\x83\x67\x4f\xa4\x7e\ -\xf8\x9f\x3c\xc4\x66\x05\x3e\x0a\x48\xf5\x5c\xb2\x59\x0e\x8e\x41\ -\x53\x9d\x35\xa1\xdc\xa3\x14\xb2\x3f\x30\x4c\x1c\x9e\xf8\x71\xe5\ -\xe1\x0f\xae\xaa\x51\x0c\xc4\xcf\x93\x0d\x9f\x02\x50\x68\x76\xe1\ -\xc9\xce\x28\xa7\x1a\xa5\x9f\x2e\x9b\x34\xc8\xfa\xc3\x75\x20\xf7\ -\x78\xa3\x3a\xd3\x49\x93\x74\x0b\x6f\xec\x0c\x1f\x30\x53\x08\x63\ -\x30\xd6\x69\xef\xff\xf2\xe1\x6b\x61\x6e\x57\x0f\x0b\xfe\xcf\x09\ -\xad\x1e\x7e\x00\x7b\xad\x87\x0c\ -\x00\x00\x0c\xd5\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x70\x6f\x69\x6e\x74\ -\x65\x72\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ -\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x78\x3d\x22\x2d\x33\x36\x2e\x32\x32\x31\x31\x30\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x79\x3d\x22\x31\x30\x2e\x38\x33\x32\x31\x39\x39\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ -\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ -\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ -\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\ -\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\ -\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ -\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ -\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ -\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ -\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ -\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ -\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ -\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ -\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\ -\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\ -\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\ -\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\ -\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ -\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\ -\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\ -\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\ -\x38\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x33\x35\x2e\x32\x30\x30\x30\x30\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x31\x33\x33\x33\x33\x33\ -\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ -\x38\x34\x31\x37\x34\x35\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x62\x30\x35\x37\ -\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\ -\x36\x34\x37\x30\x35\x38\x38\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x66\x66\x35\x65\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x32\x2e\x32\x34\x37\x34\x36\x36\x38\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x33\ -\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\x34\x38\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ -\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ -\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x39\x39\x39\x39\x39\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x39\x33\x30\x30\x30\x30\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x32\ -\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ -\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ -\x6d\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x2c\x37\x2e\x39\x33\ -\x31\x30\x34\x34\x33\x20\x63\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\ -\x39\x39\x39\x37\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\x39\x39\x39\ -\x37\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\x39\x39\x39\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ -\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ -\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x39\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x39\ -\x33\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x33\x2e\x35\x38\x39\x30\x39\x35\x31\x32\x70\x78\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ -\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ -\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\x36\x36\x36\x36\x36\ -\x37\x2c\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x63\x20\x31\x39\ -\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\ -\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\x30\x30\x30\ -\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ -\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ -\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0a\ -\x00\x00\x07\x3b\ -\x00\ -\x00\x21\x2e\x78\x9c\xdd\x59\x5b\x8f\xdb\xb8\x15\x7e\x9f\x5f\xc1\ -\x3a\x2f\x09\x6a\x49\xbc\xe8\x46\xc5\x9e\x7d\xd8\x60\xbb\x0b\xb4\ -\x28\xd0\x4d\xda\xc7\x40\x96\x38\xb6\x1a\x5d\x5c\x4a\x1a\xdb\xf9\ -\xf5\x3d\xa4\x24\x4a\xf2\xa5\x98\x60\x92\x74\xb2\x02\x06\x43\x9e\ -\x73\x78\x39\x1f\xcf\x8d\xe6\xea\xa7\x63\x91\xa3\x47\x21\xeb\xac\ -\x2a\xd7\x0b\x62\xe3\x05\x12\x65\x52\xa5\x59\xb9\x5d\x2f\x3e\xbc\ -\xff\xc5\x0a\x17\xa8\x6e\xe2\x32\x8d\xf3\xaa\x14\xeb\x45\x59\x2d\ -\x7e\xba\xbf\x5b\xfd\xc9\xb2\xd0\xcf\x52\xc4\x8d\x48\xd1\x21\x6b\ -\x76\xe8\xb7\xf2\x53\x9d\xc4\x7b\x81\x5e\xef\x9a\x66\x1f\x39\xce\ -\xe1\x70\xb0\xb3\x9e\x68\x57\x72\xeb\xbc\x41\x96\x75\x7f\x77\xb7\ -\xaa\x1f\xb7\x77\x08\x21\x58\xb7\xac\xa3\x34\x59\x2f\xfa\x01\xfb\ -\x56\xe6\x5a\x30\x4d\x1c\x91\x8b\x42\x94\x4d\xed\x10\x9b\x38\x8b\ -\x51\x3c\x19\xc5\x13\xb5\x7a\xf6\x28\x92\xaa\x28\xaa\xb2\xd6\x23\ -\xcb\xfa\xd5\x44\x58\xa6\x0f\x46\x5a\xed\xe6\xc0\xb4\x10\xe1\x9c\ -\x3b\x98\x3a\x94\x5a\x20\x61\xd5\xa7\xb2\x89\x8f\xd6\x7c\x28\xec\ -\xf1\xda\x50\x8a\x31\x76\x80\x37\x4a\x3e\x4d\x2a\x3a\xe6\x00\xc5\ -\xcd\xcd\x68\xee\x74\x75\x80\x7f\x0f\x7f\x66\xc0\x40\xb0\xeb\xaa\ -\x95\x89\x78\x80\x91\xc2\x2e\x45\xe3\xbc\x7b\xff\xce\x30\x2d\x6c\ -\xa7\x4d\x3a\x99\x66\x40\x7f\xb6\xee\xec\x48\xca\xb8\x10\xf5\x3e\ -\x4e\x44\xed\x0c\x74\x3d\xfe\x90\xa5\xcd\x6e\xbd\x60\xae\x4d\x18\ -\x7c\x9e\x26\xee\x44\xb6\xdd\x35\xe7\xd4\x2c\x5d\x2f\x40\x57\xca\ -\xc3\xae\x3f\x31\x25\xd2\x09\xf4\x13\x47\x86\x83\x6d\x4e\x6d\x82\ -\x24\xf1\x58\xd0\xc9\x0c\x2a\x44\x69\x95\xa8\x3d\xc1\x94\xa2\xc8\ -\xe2\xb6\xa9\x0a\x38\xe3\x24\xc9\xe3\xba\xce\x1e\xb2\x04\x3a\x55\ -\xb9\xcf\xdb\x6d\x56\x7e\x14\xc7\x7d\x25\x9b\x8f\xf5\x5e\x24\x8d\ -\x8c\xf3\x8f\x79\xb6\x91\xb1\x3c\xd9\x03\xf0\x66\xdd\x4e\xd0\x3a\ -\xa6\x7b\x00\xd4\x0f\xae\x32\x4f\x03\xf3\x1e\xb8\xab\x54\x3c\xd4\ -\x4a\xaa\xd3\x4e\xf5\x40\xbd\x8e\x07\x5c\x38\x2c\x11\xcb\xbf\xc8\ -\x38\xcd\xc0\x44\x3b\xb9\x4e\x72\xce\xf1\x38\x68\x77\xdf\xf3\x57\ -\x75\x53\xed\x07\x59\x50\xb8\x39\xe5\x4a\x4b\x20\x5a\x49\x95\x57\ -\x32\x7a\x95\x10\x30\x1b\xfc\x56\x93\x2a\x38\x93\xac\x39\x45\xe4\ -\xed\x62\x1c\x53\x3d\x3c\xd4\x02\xf0\xc7\x13\x9a\x46\x1f\x46\xc0\ -\x5a\x6c\x81\x9c\xa7\xaf\x16\xe2\xcb\xd5\xf0\xb5\xd5\xc8\xf5\xd5\ -\x3c\xb3\xda\xca\x99\xab\xfd\xbf\x51\x1a\x70\x87\x6d\xe4\x70\x70\ -\xeb\x45\x9c\x1f\xe2\x53\x6d\x16\xd1\xae\x10\xed\xa4\x00\xd7\x7d\ -\x75\x05\xcf\xdb\x70\x33\x4c\x03\xc3\xde\xf6\xc4\x0f\x65\xd6\x80\ -\x8f\xb6\xb5\x90\xbf\x2b\x3b\xff\x7b\xf9\xa1\x16\x17\x52\xef\x65\ -\x5c\xd6\xe0\x54\xc5\x7a\x01\xf6\x26\xb3\xe3\x6b\xf0\x25\x1e\xb2\ -\xd0\xc3\xc4\x5d\x42\x1b\x63\xe2\x61\xea\xd1\xe5\xa4\x39\x15\x61\ -\xcc\x06\x47\xf6\x30\x5f\x52\x6e\xb3\xd0\x67\x94\xbe\x19\x55\x22\ -\x80\xa2\x67\xba\x27\xe8\x52\x3a\x72\xe9\x7a\xe1\x8e\x4c\xe8\x31\ -\xdc\x63\xbb\x72\x94\xe9\xe9\x96\x71\x10\xe5\x1d\xe9\x63\x26\x0e\ -\xa3\x7d\x6e\x62\xa3\xd2\x3e\xde\x0a\x7d\xc0\x00\xde\x83\xfe\x7a\ -\xc6\xa6\x92\xa9\x90\x03\xcb\xd7\xdf\x8c\xd5\xdb\x40\x97\x01\xee\ -\xe6\x67\xa5\x66\x35\x7c\x7c\x9d\x5f\xef\xe2\xb4\x3a\x80\x66\xe7\ -\xcc\xcf\x55\x55\x28\xfd\xed\x90\xf9\x38\x64\xe7\xec\xe4\xb8\x5e\ -\x58\xbe\x4d\x3d\x9f\x53\xc2\x2f\xb8\x6a\x43\xbe\x1d\x50\x46\x82\ -\x0b\x5e\x2b\x25\x9c\x9d\x95\xc7\x27\x01\x4a\xe9\x7f\x83\x7d\xd4\ -\xbb\xea\xb0\x95\x0a\x9c\x46\xb6\xe2\x7c\xa4\xe2\x58\x9b\x4d\x75\ -\xbc\xce\x86\x18\xd4\xaa\xe4\x63\xb5\x9d\xf1\xec\x8f\xd3\x59\xdb\ -\x2c\x15\xf5\xf5\x81\x87\xac\x04\x0c\xac\x3e\x78\x12\x66\x20\x3e\ -\x97\x18\x22\x69\x80\xc3\x1b\x12\xc7\xd1\xcd\xcf\x59\xa7\xdb\xac\ -\x22\x3e\x66\x45\xf6\x59\xa4\xa3\xdb\x1a\x91\xba\x8c\xf7\xd6\x36\ -\xaf\x36\x71\xde\xef\xbe\x77\xd4\x19\x2c\x83\x1d\x36\x27\x95\x36\ -\x8e\x27\x45\x9b\xf9\x9c\x22\xb0\xc0\x1f\xcd\xb9\x92\x19\x44\xe3\ -\xe3\x34\x2c\x75\xa4\xd3\x94\xa4\x92\x0c\x54\x14\x47\x6d\x5f\xda\ -\xfa\x82\x73\xde\x69\xca\x1b\x1c\xe0\xd2\xee\x35\xbd\x10\x4d\x9c\ -\xc6\x4d\x3c\x3a\xc1\x40\xa1\x9c\xe3\x41\x33\xc8\xee\xd1\x3f\xde\ -\xfd\x62\x82\x62\x92\x44\xff\xaa\xe4\xa7\x31\x9e\x29\x81\x78\x53\ -\xb5\x70\x14\x26\x50\xab\xf0\x9f\x44\x2a\x18\xc4\xcd\x7d\x56\x80\ -\x69\xab\x54\xfe\x67\xc8\xa8\xe0\x8e\x86\x31\x13\x56\x60\x8d\x93\ -\x76\xd3\x4a\xd1\xa5\xea\xab\xd5\x4d\x9a\x14\x99\x1a\xe4\xfc\xde\ -\x64\x79\xfe\x9b\x5a\x64\x12\xbc\xfb\x49\xb3\x26\x17\x93\x88\xee\ -\xf4\xbb\x1f\x82\xee\x44\xb9\x95\x33\x68\xaf\x7b\xdb\x11\x95\x99\ -\x53\x98\x83\xce\xe3\x8d\x00\x23\xf8\xab\x62\xa2\x0b\xee\x56\x56\ -\xed\xbe\xa8\x52\xd1\x0f\x37\x68\x42\xb8\x36\x47\xd6\x25\x94\x07\ -\xd8\x7d\xd4\x07\x9a\xb7\xaa\x33\x49\x5c\xba\x2b\xdb\x1c\x52\xec\ -\xa3\x28\xab\x34\x85\x5c\x23\xab\x4f\x22\x7a\x85\xb1\x1b\xea\xd4\ -\xa3\xba\x9d\xb7\x44\xa6\xab\x62\x3a\x6c\x23\xaa\xff\xd3\xc6\x52\ -\x4c\xa9\xff\xae\xb2\x32\x02\xdc\x84\x1c\xa8\xba\x93\x83\xc5\x37\ -\x91\x3b\xd0\xd2\x18\x22\x91\x94\xf1\x29\x2a\xa1\x5c\x9d\x52\xbb\ -\x84\x36\xae\x64\xb2\x9e\xcd\xfa\x6f\x66\xe8\x4a\x5d\xc6\xf9\x98\ -\x71\xae\xd6\x44\xea\xbb\x5e\x17\xa9\x6f\xe6\x15\x60\xdf\xdc\x76\ -\x03\xc6\x31\xf3\x85\x45\x7c\xc3\x90\x33\x31\x09\x72\xcc\x66\x50\ -\x1b\xf9\x3c\x1c\x93\xec\x3e\x6e\x76\xd7\xd0\x9f\x68\xa9\x90\xed\ -\x93\xfa\x04\x59\xda\x6d\x8a\xb9\xee\x39\xc4\x9b\xb6\x69\xbe\x16\ -\xc0\xe6\xdc\x8d\x1e\x00\xe1\xdf\x10\x5e\x62\xf4\x4f\x34\x00\x33\ -\x07\x58\x69\x04\xde\x3a\xe2\x30\xa9\x0d\x4a\xd8\x61\x53\x49\x0b\ -\x62\xfc\x63\xdc\xb4\x52\xcc\x62\x89\x89\x09\x60\xa4\xca\x8d\x20\ -\x1c\x27\xc9\x8f\x0e\x95\x01\x69\x69\x5a\xe8\x57\x84\xaf\x41\x16\ -\xbe\x1c\xc8\x88\x0d\x27\x08\xe5\x50\xb8\x3f\x7e\x39\x66\x37\x90\ -\x30\x59\x60\x49\x43\x3b\x44\x3f\x23\x66\xd3\xae\x79\xd1\xb8\x40\ -\x87\x05\x01\xb5\xf0\x93\xf1\xf9\x2a\x36\x43\x02\xcf\x25\x9e\xf7\ -\xd5\x10\x28\x90\x37\x84\xa4\x25\xf3\x6c\x8a\x12\xf0\x23\xcb\xb5\ -\xa9\x06\xe5\x56\xfb\x12\x8a\xd0\xfd\x76\x40\x84\xe2\xd2\x12\xfa\ -\x53\xa3\xdf\xc4\x14\x08\xb3\xc3\x4e\xe7\x5e\x61\x45\xa3\x60\x0a\ -\x04\xdb\x7d\xd7\x30\x10\xf1\x97\x60\x21\x28\x37\x40\x2e\xb9\xed\ -\x0f\x1d\x77\x39\xf8\x39\x0a\x6c\x57\x8f\x58\x1a\x40\x43\xdb\xeb\ -\x64\x60\xfc\x05\xa2\x2e\x66\xc1\x77\x44\x14\x8e\x5e\xef\x8a\xb3\ -\xef\x11\x8e\xae\xa4\xc1\x17\x7a\x04\x16\xfb\xe2\xf8\x67\xe4\x9a\ -\xe1\xa6\x67\x25\x50\xe1\x0b\x69\xe9\x8a\xf4\x4a\x0e\xba\x10\x84\ -\xb4\x6c\x9d\xd7\xa7\x2f\x2e\x70\x8c\x27\xf1\xcc\xc0\x61\x3d\x3d\ -\xc7\xbc\x50\x28\x28\x19\x0c\xef\xb9\x50\xf0\x1f\x1e\x0a\xff\x6b\ -\x59\xc5\x0f\x9f\x59\x19\x7d\x36\x06\x4f\x8f\x3e\x2f\x14\x03\x15\ -\x9a\x9f\x89\xc1\xd3\x8b\xf6\x97\x58\x62\x16\xd3\x12\x93\x75\x09\ -\x28\x00\x38\x86\xa4\xc4\xe0\xd6\x72\xa3\x7d\xa3\xe0\xb4\xe8\x1f\ -\x06\x10\x12\x0e\xa9\xf9\x59\x80\x90\x1f\x1a\x90\x59\xd9\x43\xcd\ -\x25\x44\x37\x2f\x1a\xb7\x20\xf8\x9e\x81\xe2\xdb\xda\xc4\x50\xa4\ -\x3d\xd3\x49\xdc\x3f\x0c\x20\x46\xd9\xe7\x01\xf2\xad\x2a\x8b\xfe\ -\x17\xb9\x19\x20\xae\xed\x11\x3f\xf0\xf8\xff\xe3\xb7\x0d\xe5\x25\ -\x93\x48\xfb\x2b\xa2\xbc\xbf\x4a\x5c\x41\x26\x7c\x7a\x2c\x7d\xee\ -\xcf\x1b\xad\xcc\x5f\x9f\x3d\x32\xa9\x57\xa4\x37\x4f\xfd\x2d\xf3\ -\xe2\xea\x7b\x56\x77\x61\xdb\xf3\x69\x88\x03\xf5\x2a\xe4\x13\xca\ -\x43\x1f\xec\x05\xa4\x71\x10\x84\x5e\xff\x96\x04\xfd\x90\x78\x14\ -\xfb\xea\x41\x29\xc4\xcc\x25\x5c\x93\xfc\xc0\x05\x92\x6a\x11\x8a\ -\x19\x5c\xa4\x40\x9c\xea\xe7\x28\xb8\x87\x91\x90\x07\x2e\x45\xbe\ -\x1d\x86\x3e\xf7\x88\x9a\x8a\x60\xaf\x9b\x9d\xfb\x41\x80\x5d\x3d\ -\x3b\x43\x16\xdc\x08\x02\xce\x61\x12\x18\xe7\xda\x41\xe0\x32\xaa\ -\x04\x6f\xd1\x73\xa4\x9f\xb5\x28\x73\x79\xf7\xc0\xe5\x31\x8f\x61\ -\x17\x0d\x6d\xb5\x94\x66\x87\xba\x7c\xc0\x30\x11\x9c\x2d\xa1\x1e\ -\xc7\x10\x0c\x61\x22\x16\x52\x12\x74\xf3\x87\xae\x1b\x86\x01\xd7\ -\x64\x97\x50\xb8\xcc\xc2\xf4\xdd\x96\x5d\xce\xcd\x9e\xad\x41\xb1\ -\x41\x2f\xe5\x54\xfd\x9b\xdb\xb2\x07\xcb\x45\x1d\x36\xb0\x46\x87\ -\x16\x43\x03\x32\xcb\x1e\x2c\x57\x4f\x4e\x61\x4a\xaf\x53\x9e\x7b\ -\xe8\xf3\xc5\x2f\xba\x1e\xec\xfc\x0b\x9d\x6e\xe5\x6c\xef\xef\x56\ -\xea\x11\xe0\xfe\xee\xbf\x97\xfe\x80\x42\ -\x00\x00\x0c\xc4\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x70\x6c\x75\x73\x2e\ -\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ -\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ -\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\ -\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ -\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\ -\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\ -\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\ -\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ -\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\ -\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\ -\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\ -\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x2e\ -\x34\x32\x37\x36\x31\x38\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x32\x2e\x33\x39\ -\x35\x38\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\ -\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\ -\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\ -\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\ -\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\ -\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\ -\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\ -\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ -\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ -\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ -\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\ -\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\ -\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\ -\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ -\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\ -\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\ -\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\ -\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ -\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ -\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\ -\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x64\x30\ -\x64\x30\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ -\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x37\ -\x2e\x30\x30\x33\x36\x30\x39\x36\x36\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ -\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x36\x2e\x39\ -\x34\x34\x39\x37\x35\x2c\x35\x2e\x31\x31\x39\x36\x33\x36\x39\x20\ -\x31\x37\x2e\x31\x38\x38\x33\x35\x38\x2c\x32\x38\x2e\x35\x38\x35\ -\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x33\x37\x38\x32\x2d\x38\x2d\x30\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ -\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ -\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\ -\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\ -\x22\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\ -\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x30\x64\x30\x64\x30\x64\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x37\x2e\x30\x30\x33\x36\x30\x39\ -\x36\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ -\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x64\x3d\x22\x4d\x20\x35\x2e\x33\x33\x33\x33\x33\x33\x33\x2c\x31\ -\x36\x2e\x38\x35\x32\x33\x33\x39\x20\x48\x20\x32\x38\x2e\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ -\x33\x37\x38\x32\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ -\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x30\x64\x30\x64\x30\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ -\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x35\x2e\x31\x39\x31\x32\x39\x38\x39\x36\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ -\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ -\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\ -\x2e\x38\x36\x36\x36\x36\x36\x37\x2c\x31\x36\x2e\x38\x36\x31\x32\ -\x31\x31\x20\x48\x20\x32\x38\x2e\x32\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ -\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ -\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\ -\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x64\x30\ -\x64\x30\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\ -\x2e\x31\x39\x31\x32\x39\x38\x39\x36\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ -\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x36\x2e\x39\ -\x34\x31\x36\x33\x35\x2c\x35\x2e\x36\x35\x33\x30\x33\x33\x36\x20\ -\x30\x2e\x32\x33\x32\x33\x32\x2c\x32\x32\x2e\x33\x39\x38\x37\x39\ -\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ -\x61\x74\x68\x33\x37\x38\x32\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ -\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0a\ -\x00\x00\x0b\xbd\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x63\ -\x61\x6c\x63\x5f\x65\x78\x70\x72\x65\x73\x73\x69\x6f\x6e\x2e\x73\ -\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ -\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\ -\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ -\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ -\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x2e\x39\x37\x39\x35\x31\x30\x35\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x78\x3d\x22\x2d\x32\x33\x35\x2e\x37\x30\x38\x33\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ -\x3d\x22\x2d\x31\x36\x2e\x38\x33\x32\x37\x35\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ -\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ -\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\ -\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\ -\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ -\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ -\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ -\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ -\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ -\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ -\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ -\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ -\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ -\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ -\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ -\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ -\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ -\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ -\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ -\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x39\x39\x39\x39\x39\ -\x39\x3b\x66\x69\x6c\x6c\x3a\x23\x38\x30\x62\x33\x66\x66\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x64\x33\x64\x33\x64\x33\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\x32\x37\ -\x37\x35\x35\x39\x32\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ -\x63\x74\x33\x37\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ -\x69\x64\x74\x68\x3d\x22\x34\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x78\x3d\x22\x2d\x33\x2e\x37\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x79\x3d\x22\x31\x32\x2e\x31\x39\x30\x34\x37\x38\x22\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\ -\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\ -\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ -\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x73\x69\x7a\x65\x3a\x31\x37\x2e\x31\x36\x32\x33\x32\x36\ -\x38\x31\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ -\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ -\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x6c\x65\x74\x74\x65\ -\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\ -\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x39\x39\x39\x39\x39\ -\x39\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x34\x33\x30\x31\x39\x33\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x2e\x32\x30\ -\x34\x38\x38\x31\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ -\x22\x32\x31\x2e\x30\x39\x35\x33\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\x39\x31\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x73\x63\x61\x6c\x65\x28\x30\x2e\x39\x35\x33\x34\x36\x32\ -\x36\x33\x2c\x31\x2e\x30\x34\x38\x38\x30\x38\x38\x29\x22\x3e\x3c\ -\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\x69\ -\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x74\x73\x70\x61\x6e\x33\x39\x31\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x2e\x32\x30\x34\x38\x38\x31\ -\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\ -\x31\x2e\x30\x39\x35\x33\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\ -\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\ -\x69\x7a\x65\x3a\x31\x34\x2e\x33\x30\x31\x39\x33\x39\x30\x31\x70\ -\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\ -\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\ -\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\ -\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\ -\x64\x27\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x31\x2e\x34\x33\x30\x31\x39\x33\x39\x22\x3e\x31\x2a\x32\x3c\x2f\ -\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0f\xa4\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x61\x76\x65\x5f\ -\x72\x6f\x69\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ -\x3d\x22\x2d\x31\x32\x2e\x33\x36\x33\x34\x35\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ -\x31\x31\x2e\x38\x35\x32\x34\x35\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ -\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ -\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\ -\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ -\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\ -\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\ -\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\ -\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\ -\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\ -\x6c\x3a\x23\x61\x61\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x37\x38\x39\x33\x33\x31\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ -\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\ -\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\ -\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\ -\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x38\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ -\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x37\x35\ -\x37\x30\x38\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ -\x3d\x22\x31\x2e\x39\x30\x32\x34\x33\x39\x32\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\ -\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\ -\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\ -\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x30\x2e\x39\x34\x32\x35\x30\x35\x35\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ -\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ -\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x2e\x38\ -\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x31\x33\x2e\x38\x36\x36\x36\x36\x37\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x39\x2e\x32\x30\ -\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x31\x39\x2e\x32\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x30\x39\x38\x32\x36\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\x2e\x36\x34\ -\x38\x37\x38\x30\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\ -\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\ -\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\ -\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x62\x33\x62\x33\x62\x33\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x37\ -\x31\x39\x37\x32\x32\x37\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ -\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ -\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\ -\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\ -\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\ -\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\ -\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ -\x65\x63\x74\x33\x37\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x33\x2e\x38\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x33\x2e\x30\x36\x33\x34\ -\x33\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x32\x2e\x30\x36\x30\x39\x37\x35\x38\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ -\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\ -\x20\x36\x2e\x37\x39\x34\x36\x33\x34\x37\x2c\x34\x2e\x32\x31\x35\ -\x33\x37\x34\x39\x20\x32\x37\x2e\x37\x33\x33\x33\x33\x33\x2c\x34\ -\x2e\x32\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x35\x38\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ -\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ -\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x36\x2e\x37\ -\x39\x34\x36\x33\x34\x37\x2c\x37\x2e\x34\x31\x35\x33\x37\x34\x39\ -\x20\x32\x37\x2e\x37\x33\x33\x33\x33\x33\x2c\x37\x2e\x34\x36\x36\ -\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x70\x61\x74\x68\x33\x37\x35\x38\x2d\x33\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ -\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ -\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\ -\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\ -\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ -\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ -\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x36\x2e\x37\x39\x34\ -\x36\x33\x34\x37\x2c\x31\x30\x2e\x36\x31\x35\x33\x37\x35\x20\x32\ -\x30\x2e\x39\x33\x38\x36\x39\x38\x33\x2c\x30\x2e\x30\x35\x31\x32\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ -\x74\x68\x33\x37\x35\x38\x2d\x39\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ -\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ -\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0a\ -\x00\x00\x07\x68\ -\x00\ -\x00\x1f\xe4\x78\x9c\xed\x59\xdb\x6e\xe3\x46\x12\x7d\xf7\x57\x70\ -\x39\x58\x24\x41\x44\xb2\xef\x17\x8e\xac\x00\xc9\x20\x40\x80\xcd\ -\xcb\x26\x8b\x7d\x0c\x28\xb2\x25\x33\x43\x91\x02\xd9\xb2\xa4\xf9\ -\xfa\xad\xe6\x55\xb2\xa4\xc0\x1b\x4c\x3c\x36\x10\xc1\x03\x9b\xa7\ -\xaa\x2f\xe7\xd4\x61\xa9\xc9\x99\x7f\x77\xd8\x14\xde\xa3\xa9\x9b\ -\xbc\x2a\xef\x7d\x1c\x22\xdf\x33\x65\x5a\x65\x79\xb9\xbe\xf7\xff\ -\xf3\xeb\x8f\x81\xf2\xbd\xc6\x26\x65\x96\x14\x55\x69\xee\xfd\xb2\ -\xf2\xbf\x5b\xdc\xcd\xff\x11\x04\xde\x0f\xb5\x49\xac\xc9\xbc\x7d\ -\x6e\x1f\xbc\x9f\xca\x8f\x4d\x9a\x6c\x8d\xf7\xf5\x83\xb5\xdb\x38\ -\x8a\xf6\xfb\x7d\x98\xf7\x60\x58\xd5\xeb\xe8\x1b\x2f\x08\x16\x77\ -\x77\xf3\xe6\x71\x7d\xe7\x79\x1e\xac\x5b\x36\x71\x96\xde\xfb\xfd\ -\x80\xed\xae\x2e\xda\xc4\x2c\x8d\x4c\x61\x36\xa6\xb4\x4d\x84\x43\ -\x1c\xf9\x53\x7a\x3a\xa5\xa7\x6e\xf5\xfc\xd1\xa4\xd5\x66\x53\x95\ -\x4d\x3b\xb2\x6c\xde\x9d\x24\xd7\xd9\x6a\xcc\x76\xbb\xd9\xd3\x36\ -\x09\x6b\xad\x23\x44\x22\x42\x02\xc8\x08\x9a\x63\x69\x93\x43\x70\ -\x3e\x14\xf6\x78\x6d\x28\x41\x08\x45\x10\x9b\x32\x9f\x97\x15\x37\ -\x20\xe8\x16\xfe\x8d\xe9\x03\x10\x36\xd5\xae\x4e\xcd\x0a\xc6\x99\ -\xb0\x34\x36\xfa\xf0\xeb\x87\x31\x18\xa0\x30\xb3\xd9\xc9\x34\x83\ -\x9e\x67\xab\x9e\x89\x5c\x26\x1b\xd3\x6c\x93\xd4\x34\xd1\x80\xb7\ -\xe3\xf7\x79\x66\x1f\xee\x7d\xca\x42\x4c\xe1\xc3\x5b\xf0\xc1\xe4\ -\xeb\x07\xfb\x14\xcd\xb3\x7b\x1f\x76\x4f\xb4\xea\xae\x4f\xcc\x81\ -\xbb\x84\x7e\xe2\x78\x8c\xa0\x50\x93\x10\x7b\x35\xe6\x54\x76\x39\ -\x03\x85\x38\xab\x52\xb7\x27\x98\xd2\x6c\xf2\x64\x67\xab\x0d\x54\ -\x2d\x4d\x8b\xa4\x69\xf2\x55\x9e\xc2\x45\x55\x6e\x8b\xdd\x3a\x2f\ -\x7f\x5b\x82\xcb\xd2\xa4\x48\x7f\xab\x77\x85\x69\xc2\x41\xc1\x71\ -\x39\x73\xd8\x56\xb5\x0d\x0e\xd9\x16\x74\x14\xf2\x6a\xf0\x78\x1a\ -\x7c\xcc\xcd\xfe\xfb\xea\x00\xfb\xf3\x90\x47\x09\xfc\xf8\x0b\xc0\ -\xe7\x99\x59\x35\x2e\xde\x71\x75\x57\x40\x56\xfa\x5e\xd4\x46\xc7\ -\xad\xbb\x7d\x67\x6e\x8e\x29\x77\x99\x34\x9d\x9e\x9e\xb7\x4d\xd6\ -\xe0\xbd\xa2\xaa\xef\xfd\x77\xab\xf6\xd3\x07\x96\x55\x9d\x99\x7a\ -\x08\x89\xf6\x73\x16\xaa\xa0\x3e\xb9\x3d\x76\x77\x5b\x3f\xf7\x40\ -\xc3\xcd\x3a\xc6\xd1\xf5\x78\xf3\x90\x64\xd5\xfe\xde\x27\x4f\x83\ -\x9f\xaa\x6a\x73\xef\xf3\x90\x6b\xa5\x11\x7e\x1a\x4d\x41\x88\x80\ -\x41\x11\x25\xa1\xe3\x8e\xa6\x28\xac\x47\x42\x8a\xb4\x26\x9c\x5e\ -\x04\x77\x75\x0d\xb7\x63\x50\x24\x47\x03\xa4\xda\x5f\xc3\xfc\xcd\ -\x43\xb5\x5f\xd7\x4e\x9c\x55\x52\x8c\xea\x8c\x43\x5d\x28\x58\x2e\ -\x5d\x15\x6c\xbd\xbb\x08\x83\x3d\x76\xee\x4e\x0f\x76\x65\x6e\xe1\ -\x6e\xda\x1e\x4e\xa7\xdd\xe5\x99\x69\xae\x0f\xdc\xe7\x25\x88\x10\ -\xf4\xbe\xc6\x57\x18\xf5\x19\x83\xc9\x25\x52\x37\x32\x9c\x41\x6e\ -\x84\x8e\xb7\x43\x9b\xe4\x90\x6f\xf2\x4f\x06\x88\x5f\x48\xdd\x94\ -\xc9\x36\x58\x17\xd5\x32\x29\xfa\xdd\x2f\xda\x8c\xf9\x99\x2c\xdd\ -\x20\xcf\xb3\x47\x77\x47\x1f\x8e\x0e\xf3\x07\xd0\x09\xea\x00\x2a\ -\x05\x1f\xc1\xaa\xce\xe1\x46\x39\xd9\xef\x00\x1d\x4f\x21\x77\xff\ -\x43\xfb\x3e\x4c\x1b\x1b\x31\x67\xba\xc1\xe7\xd1\xa5\xd1\x5b\x7c\ -\x63\x6c\x92\x25\x36\x99\x5c\x3f\x20\x44\x6b\x34\x30\x81\xd6\x19\ -\xff\xfb\xc3\x8f\x8b\x7e\x81\x79\x9a\xc6\xff\xad\xea\x8f\xc3\x7a\ -\x9e\xe7\x12\x92\x65\xb5\x03\xe9\xfd\xc5\x08\xcf\xb3\x34\x86\x66\ -\x07\x4d\x60\x91\x6f\xc0\xcb\xae\x4f\x7e\x0b\xcd\x6d\x1e\x4d\x81\ -\xb3\x64\x27\xce\x34\x69\x37\x6d\x6d\xba\xae\x79\xf5\xab\x23\x4b\ -\x37\xb9\x1b\x14\xfd\x62\xf3\xa2\xf8\xc9\x2d\xd2\x33\x3e\x99\x34\ -\xb7\x85\x99\xc0\x79\xd4\xef\xbe\xe7\x16\x9d\x90\x9b\x47\x03\xfb\ -\xf6\x6a\x3d\xa9\x72\x76\x17\x8c\x85\x2d\x92\xa5\x81\xa2\xff\xcb\ -\x05\xbd\x8b\xe8\xba\xae\x76\xdb\x4d\x95\x99\x7e\xf8\xa0\xe6\x36\ -\xb1\x0f\x63\xa9\xec\xb1\x80\xf8\x0a\x76\x1f\x97\xf0\x9d\xfb\xbe\ -\xb1\x75\xf5\xd1\xc4\xef\x0c\x5a\xad\x10\xea\x2f\x3b\xe7\xc7\x98\ -\x84\x42\x49\x24\x08\x11\x43\xa0\xc8\x4b\x03\x8b\xc5\xcb\x9d\xb5\ -\xa7\xd8\xef\x55\x5e\xc6\xa0\x8d\xa9\x07\xb4\xbd\x28\xc0\xc5\x36\ -\x66\x03\x96\x25\xd0\x5e\xea\x3a\x39\x9e\xae\x1d\xf4\x2d\x29\x9e\ -\x0c\x05\x02\xfc\xec\x05\x38\xd4\x0c\x13\x84\xf5\x4c\x85\x84\x30\ -\x21\x89\xeb\xb2\x21\xc1\x8a\x4a\x80\x38\x62\x8c\x4a\x7a\x66\x6a\ -\x47\x95\x4a\xad\x27\x70\xec\x32\x55\x09\x3b\xb7\x55\x1d\x40\xbf\ -\x79\x4c\xec\xae\x36\xce\xd6\x43\x9d\x9e\x27\x12\x6a\x3f\xe7\x22\ -\xa1\x50\x50\x46\x39\xc5\x5f\x46\x22\x41\x31\xe6\x8c\xce\x40\x17\ -\x28\x94\x68\x15\xe2\x44\x31\x2c\x00\x62\x4a\x20\xc6\xf5\xa5\x44\ -\x0a\xbf\xac\x44\x9a\x4a\x06\x27\x23\xb6\x3d\xfc\xff\x2a\x5d\xe5\ -\xbe\xf1\x30\x0f\x29\xc7\x04\x93\x59\x20\x41\x05\xce\x19\x63\x5e\ -\xea\xc1\xd7\x1a\x91\x12\xcf\x90\xd3\x83\x32\xac\x1d\x22\x31\x63\ -\x80\x30\x0c\x5a\x29\x07\x28\xea\x32\x04\xd6\x88\x50\xe9\x00\xcc\ -\x10\x75\x63\x38\x92\xce\x66\x70\x38\x42\x88\x11\x40\x38\x64\xe0\ -\x1e\x10\x0e\x90\x9c\x32\x89\x70\x87\xb4\x0b\x29\xc1\x91\x16\x5d\ -\x0e\x66\x30\x33\x0e\x25\x05\xdb\x22\xd5\x42\x04\x33\x0e\xb5\xe0\ -\x1a\xca\x22\x78\x97\xa5\x15\x03\x88\x3a\x49\xba\x71\x54\x0b\x35\ -\x63\x21\x58\x57\xa9\x2e\x07\xf2\xf1\x4c\x86\x70\xa0\x54\x44\xf6\ -\xeb\xbb\xe5\x09\xe7\x82\x75\xcb\x63\x08\xc2\x62\x8c\x63\x0c\x15\ -\xef\x20\x05\xf3\x62\x29\x84\xc6\xa2\x1b\x04\x08\xf0\x22\x94\xc0\ -\xf2\x1d\x02\x77\x0f\x68\xc1\x60\xd7\xa4\x1b\x84\x38\x77\x6a\x08\ -\x2d\xdb\x1c\xd8\x86\x09\x9c\x5e\x80\x83\x51\xbc\x40\x43\xac\x43\ -\x40\x40\x31\x0c\xc2\x2d\x20\x24\xa3\x9a\xb4\x83\xf0\xd9\x28\xc7\ -\x9c\xb4\x8a\x11\x2c\x15\x61\xf4\xe9\x28\xd5\x91\xe0\x98\xcb\x19\ -\xfc\x81\x91\x82\x4d\x76\x5b\xe4\x42\x29\x87\x01\x00\xce\xe9\x14\ -\x52\x9c\x12\x87\x51\xa6\x19\x0c\xba\xf0\xb4\x62\x6f\xdc\xd2\x3f\ -\x7b\x12\xea\x04\x93\x82\x13\xe1\x2f\x2d\x15\x26\xdc\x23\x1c\x40\ -\xe8\xc2\x02\x30\xa8\x99\x00\x13\x5e\x52\xe7\xf4\x6d\x53\xdf\x00\ -\x75\x2c\xe0\x1e\x02\x23\x62\xe6\xb8\x73\x49\x9d\x83\xb8\x54\x60\ -\x0e\x11\xc2\x6a\x12\x5a\xd9\x15\xe6\xf2\xad\x33\x87\x02\x03\x75\ -\x04\x7d\x0c\x98\x43\x85\xa9\x90\x3d\x73\x31\x31\xbf\x6c\xe1\x4a\ -\xe0\x17\x65\xae\x34\x55\x12\x63\xfa\x19\x99\x53\x47\x5c\x0a\xa2\ -\xda\x9a\x0b\x06\x5d\xd4\xd3\x8e\xb0\xe0\xca\xf5\x0d\x68\x08\xe3\ -\xc1\xfb\x94\xf8\xcb\x9a\xfd\x2f\x20\x8e\xb5\x63\x4e\xe0\x2b\x1a\ -\x88\x43\xe7\x97\x72\xe4\xfd\x07\xb4\xf9\x5b\x77\xfa\xb5\x7a\x07\ -\xbd\xd5\xd9\xac\xb7\xfa\x15\xe2\x5f\xe2\x16\x57\xea\x73\xd6\xbb\ -\x65\xce\x08\x6e\xeb\xcd\x24\x96\x78\x20\x2e\x07\xde\x57\xba\xba\ -\x90\xc1\x97\xe8\xeb\x9f\x97\xfa\xa5\xd5\x87\x92\xff\x51\xc5\x03\ -\xf1\xd6\x89\x13\x47\x5c\x29\xc9\xda\xb6\x2e\x35\xa3\xf4\x79\xcc\ -\xff\x84\xdb\xad\x39\xd8\x61\x10\x3c\xee\xc6\xed\x3b\x3a\x98\x11\ -\x1e\x65\x4d\xfd\x68\xfc\xa7\xaa\x54\xa5\x0d\xda\xbf\x41\x1b\x78\ -\x28\x2e\xde\xb7\xc8\xbe\x7d\x97\x71\x06\x35\xf9\x27\x13\x63\x1c\ -\x12\xd7\x0a\x34\xe2\xa0\x8f\x13\xa1\x7f\xed\x11\xa3\x7f\x76\x69\ -\xab\x64\x93\x17\xc7\xb8\x49\xca\x26\x80\x15\xf3\xd5\xfb\xc2\x58\ -\x90\x28\xe8\x5f\x0c\xc4\x08\x06\xee\xab\x3a\x3b\x03\xda\xe2\x0c\ -\x05\x71\x17\x93\x94\x43\xb9\x4e\x1f\x81\xfa\x47\xd2\x90\xb9\xa3\ -\x35\x9d\xbe\x10\xdd\x0b\x0b\xf7\x24\x20\xb0\xa4\xd3\x01\xc1\xbd\ -\x70\x82\x63\x2b\x87\xc3\xf3\xf9\x51\xd1\x69\x45\x35\x9e\x5e\x68\ -\xd8\x1a\xb6\xed\x5e\x0e\x40\xd5\x12\x5b\xe7\x87\xaf\xc1\x0f\x70\ -\xc6\xa7\xa8\x7d\x22\x80\x33\xbe\x52\x18\xfa\x53\x7b\x7a\x55\x70\ -\x48\x56\xee\x80\x8f\x98\x92\x12\xe2\x33\xf4\x8d\xbf\x98\x5b\xe0\ -\x55\x4e\x2f\x12\xc6\x77\x1f\x75\xe5\xf4\x76\x92\xf9\x53\xb4\xdd\ -\x85\x1b\x00\xdb\x20\x27\xf8\x75\x22\x37\xa8\x9c\x17\xb3\x2f\xdd\ -\xb2\x2a\xb2\x67\x15\x0e\x02\xfc\x56\xe9\x82\xc1\x76\x41\x37\xd3\ -\xd6\xa4\xe3\xbb\xd4\xf8\xab\x5f\x20\xd1\xfb\x1e\xd6\xf9\xea\x56\ -\x5d\x16\x78\x1e\xb5\xf4\x16\xf0\x1b\xc4\x7e\x31\x8f\xbe\x56\x77\ -\x6a\x57\x05\xaa\x10\xbe\x30\x27\xd2\x94\x5c\x35\x67\xc0\x5f\x89\ -\x3d\x4f\xbe\x80\x6e\x70\xb9\xc1\xe6\xb9\xfe\x7c\x51\x67\x92\xbf\ -\x9d\x79\xe6\x4c\x2c\x43\x4a\xe1\x19\xfd\xcc\x99\x14\x8c\xc4\x30\ -\x96\xb7\x9c\x29\x5e\x8b\x35\x9f\xf4\xce\x4b\x32\x37\xe8\xbc\x4a\ -\x6b\xd2\xbf\xad\x79\x66\x4d\x22\xe0\xf8\x44\x30\x51\x4f\x9a\xa6\ -\xc2\x1c\x11\x7d\xdd\x9a\xfa\xb5\x38\x13\x9f\x3b\xf3\x92\xcb\x0d\ -\x36\xaf\xd2\x99\xec\xd2\x99\xf3\x68\xbd\xb8\x9b\xbb\xff\x5d\x59\ -\xdc\xfd\x0f\x21\xad\x40\x64\ -\x00\x00\x05\xe6\ -\x00\ -\x00\x1e\xf2\x78\x9c\xdd\x59\xdd\x93\x9b\x36\x10\x7f\xbf\xbf\x42\ -\x25\x2f\xed\xd4\x7c\x7f\x13\xdb\x79\x48\xa6\x93\xcc\xb4\x2f\x6d\ -\xda\x3e\x66\x30\xc8\x36\x0d\x20\x57\x88\xb3\x9d\xbf\xbe\x2b\x40\ -\x02\x0c\x9e\xb9\xd4\x97\xe4\x2e\xcc\xdc\x1c\xda\x5d\x49\xbb\x3f\ -\xed\xae\x96\xf5\xf2\xd5\xa9\xc8\xd1\x3d\xa6\x55\x46\xca\x95\x62\ -\x6a\x86\x82\x70\x99\x90\x34\x2b\x77\x2b\xe5\xcf\xf7\xbf\xa8\x81\ -\x82\x2a\x16\x97\x69\x9c\x93\x12\xaf\x94\x92\x28\xaf\xd6\x77\xcb\ -\x1f\x54\x15\xbd\xa6\x38\x66\x38\x45\xc7\x8c\xed\xd1\xbb\xf2\x63\ -\x95\xc4\x07\x8c\x7e\xdc\x33\x76\x88\x74\xfd\x78\x3c\x6a\x59\x47\ -\xd4\x08\xdd\xe9\x3f\x21\x55\x5d\xdf\xdd\x2d\xab\xfb\xdd\x1d\x42\ -\x08\xf6\x2d\xab\x28\x4d\x56\x4a\x37\xe1\x50\xd3\xbc\x11\x4c\x13\ -\x1d\xe7\xb8\xc0\x25\xab\x74\x53\x33\x75\xa5\x17\x4f\x7a\xf1\x84\ -\xef\x9e\xdd\xe3\x84\x14\x05\x29\xab\x66\x66\x59\xbd\x18\x08\xd3\ -\x74\x2b\xa5\xb9\x36\x47\xbb\x11\x32\xc3\x30\xd4\x0d\x4b\xb7\x2c\ -\x15\x24\xd4\xea\x5c\xb2\xf8\xa4\x8e\xa7\x82\x8e\x73\x53\x2d\xc3\ -\x30\x74\xe0\xf5\x92\x0f\x93\x8a\x2a\x00\xf4\x00\x7f\x52\x5c\x10\ -\xb4\x8a\xd4\x34\xc1\x5b\x98\x87\xb5\x12\x33\xfd\xcd\xfb\x37\x92\ -\xa9\x1a\x5a\xca\xd2\xc1\x32\x02\xcf\xd1\xae\x23\x90\xcb\xb8\xc0\ -\xd5\x21\x4e\x70\xa5\x0b\x7a\x33\xff\x98\xa5\x6c\xbf\x52\x6c\x47\ -\x33\x6d\x78\xdc\x86\xb8\xc7\xd9\x6e\xcf\x2e\xa9\x59\xba\x52\x40\ -\x7b\x2b\x0c\xda\xf1\xc0\x39\xcc\x56\xa0\x5b\x38\x92\x1c\x43\x0b\ -\x2d\xcd\x44\xd4\x74\x6d\xbf\x95\x11\x26\x44\x29\x49\xb8\x4e\xb0\ -\x24\x2e\xb2\xb8\x66\xa4\x80\x53\x4b\x92\x3c\xae\xaa\x6c\x9b\x25\ -\x30\x20\xe5\x21\xaf\x77\x59\xf9\x21\x4e\xd3\x0f\x55\xb6\x2b\x3f\ -\x30\x42\x72\x4d\x00\x28\x77\xc3\xa7\x03\xa1\x4c\x3d\xa5\x07\x80\ -\xd1\xf3\x67\x99\x67\xc1\x5c\x03\x77\x99\xe2\x6d\xc5\xa5\x5a\x9b\ -\xf8\x08\x8c\xf2\x15\xa4\x37\x5c\xa9\x22\xd7\x2f\xbd\xcf\xf0\xb1\ -\x97\xdd\xc4\x55\x8b\x1b\x42\x87\x78\x07\x3e\x96\x13\xba\x52\x5e\ -\x6c\x9b\xa7\x63\x6c\x08\x4d\x31\x15\x2c\xaf\x79\x46\x2c\x02\xe7\ -\x90\xb1\x73\x1b\x55\xdd\xda\x42\x5f\xbe\xaa\xe4\x1b\xf3\xfc\x6a\ -\x1f\xa7\xe4\xb8\x52\xac\x4b\xe6\x27\x42\x0a\x58\x15\xce\x23\xf4\ -\x03\x63\xc2\x4e\x4e\x2b\xc5\xd1\x02\x2b\x70\x5d\xc7\x99\x30\x61\ -\x3f\xcb\xd6\x3c\xcf\x70\x4d\x6f\xc2\xac\x29\x85\xb0\x53\xf3\xf8\ -\x8c\xc1\xa8\xe6\x9f\xd9\x09\x55\x7b\x72\xdc\x51\x0e\x0e\xa3\x35\ -\xbe\x9c\xc9\x39\xea\x66\x43\x4e\xf3\x6c\xf0\x82\x9a\x07\xb4\x5a\ -\x97\x19\x83\xa0\x39\x9c\x86\xab\xd6\x59\x8a\xab\xf9\x89\xc7\xac\ -\x04\x0c\xd4\xce\x7d\x4d\xdb\x9b\xe8\xdc\x49\x08\x5f\xf6\x8d\xe0\ -\x8a\x04\xa8\x36\x81\xb9\x63\x9d\xaf\xb3\x8a\xf8\x94\x15\xd9\x27\ -\x0c\x76\x9b\x97\x22\x55\x19\x1f\xd4\x5d\x4e\x36\x71\xde\x69\xbf\ -\x6e\x24\x96\x23\x58\xda\x49\x08\xb1\x33\x0f\xdc\xd3\x99\xd3\x14\ -\x41\xe4\x78\x72\x82\xed\x7b\xae\x24\x12\x9a\x41\x3c\x0c\xf4\x15\ -\xa4\xf3\x90\xc4\xc3\x1c\xb2\xf4\xa9\xf1\xaf\xc6\xfb\xfc\x4b\xde\ -\x79\xc8\xeb\xdc\x5e\x9f\xfa\x7d\x43\x2f\x30\x8b\xd3\x98\xc5\x7d\ -\x10\x08\x8a\x15\x86\x86\xb0\x0c\x32\x66\xf4\xfb\x9b\x5f\xd6\xdd\ -\x46\xcb\x24\x89\xfe\x26\xf4\xa3\xd8\x17\x21\x2e\x10\x6f\x48\x0d\ -\x47\xa1\xac\x25\x79\x99\x26\x11\xe4\x38\x88\xfd\x75\x56\x80\x6b\ -\xf3\xf4\xf8\x33\xe4\xb4\xa5\xde\x33\x46\xc2\x1c\xac\x7e\xd1\x76\ -\x59\x8a\xdb\x64\x39\x7b\x63\xa4\x49\x91\xf1\x49\xfa\x1f\x2c\xcb\ -\xf3\x77\x7c\x93\xce\xe2\xc1\xa2\x19\xcb\x71\x4f\x5c\xea\x9d\xf6\ -\x9d\x6d\xfa\xc0\xb8\xa5\x2e\xac\x6f\x46\xbb\x1e\x95\x51\x50\xc8\ -\x83\xce\xe3\x0d\x06\x27\xf8\x95\x33\xd1\x84\xbb\xa3\xa4\x3e\x14\ -\x24\xc5\xdd\x74\x89\x26\x4e\x98\x3c\x32\x76\xce\x81\xbf\x05\xed\ -\xa3\x2e\xd1\xbc\xe4\x03\xb5\x4b\x13\x91\xd9\x0e\x69\x9d\x43\xba\ -\xbb\xc7\x25\x49\xd3\x97\x15\xa3\xe4\x23\x8e\x5e\x18\x86\x13\x18\ -\x46\x37\x6c\xa3\x25\x92\xc3\x3c\x2b\x31\xa8\x11\x55\xff\xd6\x31\ -\xc5\x43\xea\x3f\x24\x2b\x23\xc0\x0d\x53\x41\x6d\x06\x39\x78\x3c\ -\x8b\x1c\x41\x4b\x63\xc8\x44\x94\xc6\xe7\xa8\x84\x12\x60\x48\x25\ -\xdb\x6d\x85\x59\xbf\x93\x50\xd5\xd0\xec\xee\x19\x39\x3a\x37\xd7\ -\x0e\x43\x53\x12\x67\x6f\x25\xfe\xcc\xdf\x4c\xfc\x19\x45\x05\xf8\ -\x77\xa8\x39\xbe\x1d\x1a\xb6\x87\x55\x99\xcf\xc0\x5d\x46\x62\x14\ -\xe4\x6c\xcd\x86\xdb\xc9\x0b\x03\xe9\x15\xcb\x43\xcc\xf6\x73\xe8\ -\x0f\xac\xe4\xc8\xf2\x67\x8c\xac\xd5\x2a\x65\x3b\xce\x25\xc4\x9b\ -\x9a\xb1\xc7\x02\x58\x9e\xbb\xb4\x03\x20\xfc\x0d\x19\x0b\x03\xfd\ -\x85\x04\x30\x63\x80\xb9\x45\x10\xad\x3d\x0e\x7d\x66\x27\x25\x68\ -\xc8\x08\x55\x21\xc7\xdf\xc7\xac\xa6\x78\x94\x4b\x64\x4e\x00\x27\ -\xe5\x61\x04\xe9\x38\x49\x9e\x3b\x54\x12\xa4\x85\x7c\x43\x6f\x91\ -\x31\x07\x59\xf0\x74\x20\x33\x35\x38\x41\xc3\x72\x83\xc3\xe9\xf3\ -\x31\xbb\x82\x84\xbc\x05\x16\x56\xa0\x05\xe8\x35\xb2\x35\xab\x7d\ -\x9d\xbc\x4c\xd0\xb1\x7d\xdf\x52\x8d\x07\xe3\xf3\x28\x3e\x63\xfa\ -\xae\x63\xba\xee\xa3\x21\x50\x20\x57\xa4\xa4\x85\xed\x6a\x16\x4a\ -\x20\x8e\x54\x47\xb3\x1a\x50\xae\xbd\x4f\xa1\x08\x9c\x2f\x07\x44\ -\x80\xa7\x9e\xd0\x9d\x9a\xf5\x45\x5c\xc1\xb4\xb5\xa0\xb5\xb9\x33\ -\x98\xd3\x2c\x70\x05\xd3\xd0\xba\xa1\x64\x20\xd3\x5b\x80\x87\xa0\ -\x5c\x02\xb9\x08\x35\x4f\x0c\x9c\x85\x88\x73\xe4\x6b\x4e\x33\x63\ -\x21\x01\x0d\x34\xb7\x95\x81\xf9\x13\x44\x1d\xc3\xf6\xbf\x22\xa2\ -\x70\xf4\x8d\x56\xa1\xfd\x35\xd2\xd1\xcc\x35\xf8\x44\x8f\x40\xb5\ -\x3f\x3b\xff\x49\x39\x46\xe3\xb2\xe2\x35\x9c\x9a\x40\x85\x8f\xa9\ -\xda\x54\xa4\x33\x77\xd0\x44\x10\xae\x65\xf5\xb2\x3e\x7d\x72\x89\ -\xa3\x3f\x89\x1b\x13\x87\xfa\xf0\x3b\xe6\x89\x42\x61\x99\xc2\xf1\ -\x6e\x85\x22\x7c\xf6\x50\x78\x8f\xe5\x15\xcf\xfe\x66\xb5\xad\x9b\ -\x31\x78\x78\xf6\x79\xa2\x18\xf0\xd4\x7c\x23\x06\x0f\x2f\xda\x9f\ -\x62\x89\x59\x0c\x4b\x4c\xbb\xbd\x80\x7c\x80\x43\x5c\x4a\x36\x7c\ -\xb5\x5c\x79\xbf\x52\x70\xaa\xd6\x77\x03\x88\x19\x88\xab\xf9\x26\ -\x40\xcc\x67\x0d\xc8\xa8\xec\xb1\xe4\x47\x48\xf3\x3a\x79\xb9\x06\ -\xc1\xd7\x4c\x14\x5f\xd6\x27\x44\x91\x76\x63\x90\x38\xdf\x0d\x20\ -\xd2\xd8\xdb\x00\xf9\x1f\x95\xc5\x4c\x17\x6e\xdc\x73\xe3\x70\xb8\ -\x6e\xea\x3c\xbc\x1f\xd7\xf5\xef\x2e\xe0\xf3\x5a\x54\xad\x6f\xd7\ -\x98\x33\x47\xb0\x35\xfd\x38\xc3\xec\xb1\xec\xfa\x71\xa2\xce\xeb\ -\x9d\x4b\xf4\xe3\xa6\x1c\x5e\xec\x8b\x0a\x79\xd8\x97\x1b\x45\x31\ -\x6f\xc0\x39\x70\xd2\xb6\x13\x5a\xf6\x67\x7a\xe2\x1c\x94\x8e\xe6\ -\x9a\x9e\xef\x86\xdf\xa2\xa9\x24\x3f\xd9\x06\xf7\xdc\x5b\x74\xa5\ -\x73\x12\x3c\xfc\x12\xbb\xb5\xaf\x34\x06\x6a\x1e\x37\xf1\xe1\xe8\ -\x84\xdf\x00\xb8\xfe\xeb\xc1\xf4\x78\x07\xd3\xd0\xc2\xf9\x0e\xa6\ -\x6d\x38\xee\xe3\xc2\xb6\xd4\x77\xeb\xbb\x25\xff\xd1\x61\x7d\xf7\ -\x1f\x25\xc2\x15\x46\ -\x00\x00\x12\xc2\ -\x00\ -\x00\xe7\x3e\x78\x9c\xd5\x5d\x5b\x73\xdb\xba\x11\x7e\xcf\xaf\x60\ -\x95\x97\x64\x6a\x52\xc4\x8d\x20\x5c\x3b\x9d\x69\xcf\x9c\xb6\x33\ -\x27\x2f\xbd\x9c\xce\x9c\x37\x5a\xa2\x6d\xcd\x91\x25\x8f\x24\xc7\ -\x76\x7e\x7d\x01\x12\x04\x01\x12\x50\xe4\x98\x48\xbd\xf6\x64\x62\ -\x2e\xb0\xb8\x7c\x58\x2c\x76\x17\x00\x79\xf1\xe7\xa7\xbb\x75\xf2\ -\xa5\xde\xed\x57\xdb\xcd\xe5\x0c\x65\xf9\x2c\xa9\x37\x8b\xed\x72\ -\xb5\xb9\xb9\x9c\xfd\xe7\xdf\x3f\xa7\xe5\x2c\xd9\x1f\xaa\xcd\xb2\ -\x5a\x6f\x37\xf5\xe5\x6c\xb3\x9d\xfd\xf9\xd3\xbb\x8b\x3f\xa4\x69\ -\xf2\xd7\x5d\x5d\x1d\xea\x65\xf2\xb8\x3a\xdc\x26\xff\xd8\xfc\xbe\ -\x5f\x54\xf7\x75\xf2\xe1\xf6\x70\xb8\x3f\x9f\xcf\x1f\x1f\x1f\xb3\ -\x95\x26\x66\xdb\xdd\xcd\xfc\x63\x92\xa6\x9f\xde\xbd\xbb\xd8\x7f\ -\xb9\x79\x97\x24\x89\xac\x77\xb3\x3f\x5f\x2e\x2e\x67\x9a\xe1\xfe\ -\x61\xb7\x6e\x32\x2e\x17\xf3\x7a\x5d\xdf\xd5\x9b\xc3\x7e\x8e\x32\ -\x34\x9f\xf5\xd9\x17\x7d\xf6\x85\xaa\x7d\xf5\xa5\x5e\x6c\xef\xee\ -\xb6\x9b\x7d\xc3\xb9\xd9\xbf\xb7\x32\xef\x96\xd7\x26\xb7\x6a\xcd\ -\x23\x69\x32\x21\x21\xc4\x3c\xc7\x73\x8c\x53\x99\x23\xdd\x3f\x6f\ -\x0e\xd5\x53\xea\xb2\xca\x36\xfa\x58\x71\x9e\xe7\x73\x99\xd6\xe7\ -\x3c\x2d\xd7\xf9\x5e\x02\x7a\x2f\xff\x99\xec\x1d\x21\xdb\x6f\x1f\ -\x76\x8b\xfa\x5a\xf2\xd5\xd9\xa6\x3e\xcc\x7f\xfa\xf7\x4f\x26\x31\ -\xcd\xb3\xe5\x61\x69\x15\xd3\xe1\xe9\xd4\xea\x80\xbc\xa9\xee\xea\ -\xfd\x7d\xb5\xa8\xf7\xf3\x8e\xde\xf0\x3f\xae\x96\x87\xdb\xcb\x19\ -\xa1\x19\x22\xf2\x87\x35\xc4\xdb\x7a\x75\x73\x7b\x18\x52\x57\xcb\ -\xcb\x99\x6c\x3d\x16\x65\xfb\x6c\x09\x07\x6a\x33\xe8\x82\xcf\x4d\ -\x4a\x9e\x09\x9c\xa1\x64\x87\x18\xe1\x6d\x9e\xae\x0b\xe7\xcb\xed\ -\x42\xb5\x49\x16\x59\xdf\xad\xaa\x87\xc3\xf6\x4e\x8e\xda\x62\xb1\ -\xae\xf6\xfb\xd5\xf5\x6a\x21\x1f\xb6\x9b\xfb\xf5\xc3\xcd\x6a\x93\ -\x75\x90\x99\xf2\xeb\xa7\xfb\xed\xee\x90\x3e\x2d\xef\x25\x70\x8c\ -\xe6\xde\xd4\x67\x93\xfa\x49\x26\x5f\x2c\xeb\xeb\xbd\xca\xd6\xf6\ -\x43\x3d\xc9\x8e\xf0\x26\x4d\xa6\x5e\xaf\xd6\x87\x7a\xd7\xa6\x5b\ -\x45\x2d\xb6\xeb\x75\xbd\x90\x48\x54\xeb\xc7\xea\x79\x3f\xeb\x32\ -\xec\x0f\xcf\x6b\xd9\x74\x99\xbc\xdd\xa5\xab\x8d\x64\xbd\xdf\xae\ -\x9b\x26\xa7\x6d\x49\x72\x64\xff\xf9\xb7\xbf\x98\xfc\xaa\xca\x36\ -\xa1\x60\x25\x32\xe4\xa7\xcb\x99\x1c\xca\x9c\x14\x86\xa2\x87\x43\ -\x4e\x37\x8e\x0d\xf1\x79\x94\xad\x1b\xa0\x36\xdf\x27\x4d\xbe\xb8\ -\xae\xff\x56\x3d\x48\xfc\xaa\xcd\x5f\xd6\x0f\xa6\x37\x27\xf4\x47\ -\xf5\x68\xf9\x53\xfd\x65\xd5\xf4\x41\x8d\x1b\x62\xa2\xf9\xb1\xb2\ -\x34\x9d\x70\x6a\x90\x9d\x21\xb3\x64\xae\x31\x9c\xb7\x3d\xfc\xe1\ -\x88\x16\xf9\x08\x51\x2c\x05\x2e\xcf\x29\xf6\xe0\x4a\x49\x6e\x33\ -\x68\x6c\x71\x21\x10\x66\x05\xf2\x21\xcc\x48\x89\x19\x8a\x82\x32\ -\x2e\x79\x5e\x70\x42\x8f\xa3\x5c\xe4\x7e\x94\x2f\xe6\x4a\x8c\x9b\ -\xbf\xcc\xb4\x52\x73\x6a\xf9\x65\x55\x3f\xf6\xb2\x7e\x55\xed\x6b\ -\x5d\xc1\x7d\x75\x53\x37\x10\x5f\xce\xde\x5f\x37\x3f\x3a\xe1\x6a\ -\xbb\x5b\xd6\xbb\x2e\xa9\x68\x7e\x9c\xa4\xad\xd4\x1d\xab\xc3\x73\ -\xbb\x12\xbc\x73\xfb\xab\x4a\x35\xe9\xb9\x3f\x7d\x7f\x5b\x2d\xb7\ -\x8f\x97\x33\x3c\x4c\xfc\xba\xdd\xde\x5d\xce\x78\x26\x50\x99\x53\ -\xc4\x87\xc9\x0b\x39\xa2\x65\x56\x10\x21\x0a\x24\x46\x89\xb2\x3e\ -\x8c\xb2\x12\x97\x0c\x15\xa3\xc4\x87\xdd\x4e\x2e\x15\xe9\xba\x7a\ -\xae\x65\xa7\x9a\xff\xba\xf1\xdd\xdf\x6e\x1f\x6f\x76\x0a\x9c\xc3\ -\xee\xa1\x1e\x72\xaa\x94\xf4\xea\x6a\xfb\xe4\x4f\x96\x9a\xeb\x41\ -\x2d\x42\xe9\xc3\x66\x75\x90\x8a\xfe\xfe\xc9\x2e\xf5\x61\xb5\xac\ -\x25\xf1\xba\x5a\xef\x47\x9c\xfb\x4d\x75\x9f\xde\xac\xb7\x57\xd5\ -\xda\x5f\xf4\xe3\x6a\x23\x51\x4a\x3b\x69\x25\xc5\xa8\x57\x3a\x47\ -\x27\x9e\x3c\x2f\x03\x39\x64\xe3\x47\x03\xa1\x93\x9e\xc3\x49\x77\ -\xd5\xd3\xea\x6e\xf5\xb5\x96\xc8\xa0\x11\x2c\xaa\x6b\x36\x2e\x5a\ -\x22\x1d\xdc\x3a\x41\x3e\x3c\xab\xd5\xe8\xe9\x59\xd1\x9c\x49\xab\ -\x08\x58\x08\x6e\x88\xdb\xdd\x4a\x2a\x79\xab\xb9\x1d\xe9\xd9\x26\ -\xa9\xb5\x4b\x9a\x1e\x4f\x8d\x00\x36\xe2\xc9\x87\x69\xcf\x76\x5a\ -\x3b\x5f\x2e\xe6\xe3\x89\xd1\xd0\xef\xea\x43\xb5\xac\x0e\x55\x3f\ -\x4b\x3a\x8a\x6c\x5b\xde\xf5\x4c\x9a\x01\xe7\xff\xfc\xe9\x67\x33\ -\xf3\x17\x8b\xf3\xff\x6e\x77\xbf\xf7\x93\x55\x65\xa8\xae\xb6\x0f\ -\x72\x24\x8c\x7e\x50\x6b\xcd\xe2\x5c\x2e\xdc\x72\x41\xfb\xb4\xba\ -\x93\xb2\xaf\xd6\xfc\x3f\xca\x85\x5a\xce\x57\x93\xe0\x64\x56\x60\ -\xf5\x85\xb6\xc5\xee\xea\xd6\x02\xf0\x9a\x41\xcb\xc5\xdd\x4a\x31\ -\xcd\xff\x75\x58\xad\xd7\xff\x50\x95\x18\x0d\x61\x0a\x5d\x1d\xd6\ -\x75\x4f\xbc\x98\xeb\xd6\x77\x7a\xc4\xea\xdc\xc5\xbc\xeb\x7d\xf3\ -\x74\xd3\xa3\xe2\xcc\x1a\x33\xd0\xeb\xea\xaa\x96\x12\xfc\x8b\x4a\ -\x4c\xc6\x72\xb2\xdb\x3e\xdc\xdf\x6d\x97\xb5\x66\xef\xd0\xbc\xaf\ -\x0e\xb7\x9e\xf5\x60\xb3\x91\xba\x52\x2a\x7d\x39\x5f\xbf\x54\x87\ -\x87\x5d\x6d\x0f\xbb\x1a\x98\x84\xe0\x2c\x57\x3f\xf8\x4c\x5a\x1a\ -\x54\x4e\xf6\x92\x24\xb7\x89\x1e\x6b\x9e\x7c\x49\x34\x99\x63\x49\ -\x4e\x0d\xfd\x6b\x72\x97\xa4\x44\x9a\x20\xca\x84\x21\xc5\x59\x9e\ -\xfc\x3d\xc1\xda\xa0\x41\xc9\xaf\xf2\x6f\xc5\x83\x18\x93\x74\xcd\ -\x54\xd2\xe4\x37\xc9\x95\x9f\x9c\xf7\x73\x42\xb2\x12\x15\x14\x73\ -\x5e\xa7\xc5\x99\xce\x46\x59\xcf\x2e\x1b\xf5\x6b\x42\x33\x45\xc5\ -\x42\x92\xed\xfc\xba\xb2\xa2\x4e\x79\x80\xa1\x18\x73\x7c\xee\x1b\ -\x70\xd6\x21\x43\x2d\xf6\x52\xb2\x13\xd2\x20\x52\x8c\x5a\xcb\x33\ -\x54\x88\xb2\x40\xb2\xc6\x33\x2c\x32\x55\x47\x59\xf6\xcc\x14\x49\ -\x34\xbb\xbe\x4a\xb2\x95\xbd\x69\x2b\xce\xe4\x43\x8e\x89\xea\x6b\ -\xaa\xf3\x61\xab\x6e\x85\x54\x5b\x6a\xdb\x55\xc6\xcb\x3c\x17\xa8\ -\xef\x6a\xc7\x54\xd8\x4c\xa6\x4a\x7a\x9c\x89\x78\x99\xd8\xf7\xd4\ -\xe4\x61\xfa\x2c\x99\x50\xd9\x26\x73\x29\x48\x9a\x89\x50\x97\x2b\ -\xd7\xa3\x8e\x72\x84\x38\x56\x40\xa0\xa2\x1d\x04\xab\x79\x05\x1b\ -\x76\xca\x64\x6f\xd8\x45\xc6\xa4\x61\x4a\x0b\xa6\xc6\x01\x91\x76\ -\x1c\x84\x35\x0e\xd4\xe5\xb7\xf3\x8f\xa5\x0e\xa1\xac\x11\x7f\xea\ -\x08\xd1\xa0\x01\x03\x19\xa2\x19\x16\x04\x17\x54\xa8\x02\x84\x91\ -\x96\x8e\x7d\x00\x95\x9d\x5b\xb3\xe7\x8c\x96\xb4\x68\x24\xa1\xc8\ -\x9a\x6a\x88\x2d\x09\x4c\x8a\x82\xd0\xd3\x92\x37\x25\xf4\x0c\xba\ -\x07\x3d\xfa\x67\xd6\xfc\xb0\x44\xa9\x2b\xd7\x3b\x58\x9d\xe8\x9b\ -\x49\x57\xd8\x83\x66\xf5\x9e\x2a\xa5\x60\xe8\x8d\x52\xe8\xea\x90\ -\xd3\xfc\x85\x2c\xe4\xe5\x2c\xf4\x4c\xaa\xa4\xa6\xd9\x86\x91\x9a\ -\x19\x4e\x2c\x36\x1a\xae\xe9\x14\x06\xf6\x52\x86\x41\x5f\x7c\x0c\ -\x47\x3b\xff\x6d\x06\xfa\xd2\x26\x05\x19\xa4\x1e\x93\xba\xa7\x99\ -\xda\xdf\x0d\x90\x1a\x09\xd6\xaa\x5a\x94\x67\xad\x9d\x30\x50\xb5\ -\x65\xc6\xda\xc5\xc2\xad\x89\x37\xeb\x41\x97\x48\x06\x4c\x45\x46\ -\x5a\x5f\xc9\x65\xc2\x0d\x53\x91\xd1\x46\x4c\xd1\x80\x49\xce\x28\ -\xdd\x82\x61\x9f\x4c\xda\x68\x21\x30\xcd\x69\x26\x80\x54\xb4\xa5\ -\xca\x26\xd4\x04\xa0\x94\x17\xd8\x91\x31\xd2\xaf\x5a\x45\x79\xfa\ -\x90\x7e\x9b\x45\xa2\x28\xb2\xa2\x59\x86\x15\x98\xce\x10\x74\x2a\ -\x83\x9f\x2e\xd6\xdf\x66\x19\x09\xf6\x0b\x6b\x21\x01\x96\xd3\x90\ -\x38\xc2\x32\x92\xd6\x6f\x37\xec\x08\xcb\x29\x22\xee\xe4\x36\x32\ -\xac\xa4\xc1\x48\xee\x19\xcf\x94\x30\x20\x81\xc7\xa2\xde\xb1\xe3\ -\xa0\xa8\xe3\xd2\x16\x75\x4a\x06\x4c\x9d\x34\xbb\xcd\xa4\x68\x24\ -\xea\x36\xd3\xa9\xa2\x6e\xf3\xb8\xa2\xde\xeb\x7a\x3d\xc7\x11\x02\ -\xa4\xeb\x7b\x46\x76\xea\xb4\x38\x85\x85\xbd\x9c\x25\xd8\x23\xf6\ -\x72\x10\xc2\x2c\xf4\xe5\x0d\x1b\x4d\x0b\xbd\xf4\x37\x86\xf4\xb7\ -\xa6\xc5\x49\x3d\x97\x23\x43\xc7\x13\xa2\xab\x26\xac\xfa\xb1\xa3\ -\xfa\x4b\x97\xa7\x93\x78\xea\x5b\x2e\xec\xe9\x60\xf1\x04\x66\x03\ -\xb6\xa7\x43\x21\x5c\x9e\x2e\x13\x4b\x7e\x1b\x06\xcc\xae\xa5\xff\ -\x77\xfe\x1e\x33\xbe\xcc\xc5\x9f\xd4\x43\xaa\x23\x31\xe7\xe8\x4f\ -\xfb\xc3\x6e\xfb\x7b\x7d\xbe\xd9\x6e\x6a\xfd\x77\x1b\x59\x38\x97\ -\xd3\x09\x95\x94\x4a\x1d\xd1\xd1\xa5\x3b\x59\xef\xd6\xd2\xf5\x3f\ -\x9c\xd3\x8e\xb6\xac\xf6\xb7\xd5\x6e\x57\x3d\x3b\x25\x98\xe2\x1d\ -\xaf\x7e\x27\x7d\xb8\xb2\x2c\x53\xc1\x53\x94\xd2\x94\xc9\x7f\x42\ -\xed\x10\x74\x51\xab\x1b\x27\x04\x20\x58\x4e\x0c\xfb\x61\x57\x6d\ -\xf6\xca\x2b\x96\xae\x5e\x75\xd8\xad\x9e\x3e\x48\x75\x22\x7f\x55\ -\x6c\xb3\x31\x4b\xcf\x48\x56\x30\xc4\xa5\xfd\xd7\xb8\x1d\x34\x13\ -\x82\x94\xa8\x94\xa6\x6c\xf9\xd1\x0f\x07\x5b\xa8\xdf\x21\x1c\x6d\ -\xe0\xec\x5c\xba\xd1\x1f\xde\xf7\xa1\xc3\x8f\x7d\x60\xcf\x76\x50\ -\x4f\x2a\x31\x08\x30\x55\xd1\xda\xb2\x24\x25\x99\x02\xe0\xc6\x0d\ -\x56\x5a\xb0\x95\x09\x8a\x91\x48\x7e\x51\x8f\x8d\x81\x2d\x71\x41\ -\xed\x63\xe3\x07\x70\x2e\x45\xbf\x7d\x6c\xfc\x0a\x39\xce\xfa\xb1\ -\xd0\xff\x37\x3e\x0e\x62\xea\xb1\xb1\x21\x38\x92\x2e\xa0\x43\xe5\ -\x19\x27\x98\xe2\x41\x5e\x96\x31\x21\x8a\x5c\x04\xa8\x38\x97\xba\ -\x19\x4b\xf9\x75\xa9\xb8\x6d\x32\x76\xa9\x4c\xb7\x5c\x51\x49\x46\ -\xe5\x74\x10\xdc\xa5\xa2\x4c\x0a\xbc\x90\x6e\xab\x4d\x45\xb2\xc7\ -\x42\xa8\xfe\x07\xa8\xbc\x47\xc0\xa2\x8a\x1e\x88\x9e\x4a\x54\x93\ -\x10\x57\xee\x31\xcd\x0b\xfd\x48\x55\xb4\x80\x09\xaa\x1f\x65\xe3\ -\xf3\x5c\xe1\xdb\x3e\x36\x9a\x23\x47\x3a\x73\xa3\x14\x70\x4e\x74\ -\x6a\x33\xdf\x89\xe8\x8a\x52\x53\x99\x33\xc3\xab\xa6\x30\x2e\x11\ -\x66\xa3\x47\xda\x83\x69\xf1\x58\x54\xab\x60\x8b\x6a\xd5\x6e\x51\ -\xad\x26\xda\xd4\xbe\x1f\x36\xb5\xef\xac\x4d\xed\x11\xb1\xa9\x3d\ -\x6c\x16\xb5\x1f\xa4\x00\x15\xbb\x23\x69\x8d\x83\x45\xb5\xc6\xcc\ -\x92\x05\x9b\xda\xcb\x8d\x4d\x35\x52\x1a\xa0\xda\xd2\xd4\x53\x6d\ -\x79\xec\xa9\xb6\xec\x9a\x39\x61\x53\x89\x9b\xa9\xd9\x19\x53\x03\ -\x18\xa0\xda\x53\xc4\xa2\x0e\x1e\xed\x09\xda\x53\xed\x59\x6c\xa8\ -\xce\x54\x37\xd4\x81\x3e\xe8\x1f\xbf\x26\x96\xf6\x08\x69\xd8\x2e\ -\x34\x46\xd0\x59\xea\xe8\x58\x2a\x85\x28\x2f\x05\x27\x8e\x8a\x75\ -\x35\x7d\x91\x96\x4c\xea\x78\x91\x32\x6b\x6f\xe2\xc6\xaf\xee\x89\ -\xb5\xe1\xe2\xa8\xd5\xba\xba\xca\x69\x35\x50\xab\x27\xac\x0c\x48\ -\x29\x57\x44\xe4\x5f\x4c\x2e\x63\x65\x29\x97\xf6\x52\x99\x5e\xbc\ -\x28\x30\xa1\xcc\xd2\xe9\xaa\xb9\x7d\x07\x9e\x2f\x67\xdd\xb2\x5c\ -\x58\xfd\x7a\xba\x9c\x75\x4b\xac\xbd\xe1\xd5\x05\xd9\x8d\x0d\x61\ -\xa5\xe9\x10\xbd\x2f\xc9\x5d\x0f\x67\x81\x15\xc5\xdb\xf5\xf0\x8a\ -\x42\x32\xd1\x5a\x13\xaf\x59\x50\xac\x68\xf0\xa9\xb8\x18\x8b\x64\ -\x5a\x5c\x8a\x14\x3a\x30\xc6\xbc\x9b\x16\x18\x94\x16\xc0\x81\x31\ -\xb6\xf2\xd4\x12\x93\xa7\x9c\x00\xc3\x06\xb9\xd0\x18\xd7\x63\x62\ -\x68\xe0\x09\xcd\x10\x18\xb9\x2a\x4f\x2d\x2e\x2c\x65\xc0\x41\xa1\ -\xed\xfa\x4c\xa7\xd6\x30\x02\xbc\xb8\x70\xbd\xa9\x35\xbd\x8a\xa1\ -\x29\x74\x1d\x23\x32\x1c\x61\x5d\x92\x96\x1e\x6c\x5c\x5a\x87\x63\ -\xf2\xd9\x24\x65\x46\xa4\x14\x38\x34\x8d\xd7\x35\xb9\x8d\x87\xe4\ -\x6f\x09\x1c\x19\x96\x15\xcd\xc9\x83\x08\xb6\x4c\x8a\x80\x61\x83\ -\x07\xd8\x28\xef\x99\x74\x87\x43\xa7\xc3\x06\x49\x68\x30\x70\x68\ -\xba\xad\xb9\xe9\x6d\x1a\x04\x47\x0f\xfb\x1c\x81\xde\xd3\xa6\x13\ -\xcf\x29\x91\x03\xc7\xa5\xdb\x0a\x9b\x7c\x81\x02\xa3\x83\x03\xc0\ -\x74\xaa\x79\x62\x45\x03\x68\x71\x0a\x00\xd3\xed\xd2\x4e\xed\x4e\ -\xca\xd5\x09\x8c\xeb\xe4\xc3\xc0\xf2\xb4\xa7\xf6\x10\x50\x0a\x4d\ -\xcd\x8c\x90\x69\xf6\x02\x26\xf7\x0f\xd4\xda\x04\x6d\x65\x1a\x41\ -\xa3\x1d\xee\xc9\x15\x8d\x74\xb8\xc1\x78\x95\x21\x6c\xb4\xcb\x3d\ -\xb9\x49\xa3\x5c\x6e\x68\x8a\x78\x04\x4e\x2c\x9f\x1b\xba\x1a\x8e\ -\xe9\x74\x83\x89\x61\x85\xb0\x89\xe7\x75\x83\xf1\x2c\x43\xd0\x44\ -\x75\xbb\xa1\x4d\x2a\x36\x44\x27\xa2\xe3\x0d\x6d\x09\x1f\x61\x13\ -\xd3\xf3\x06\xb3\x4c\xf9\xf6\x99\xac\x3d\xee\x89\xfd\x05\xe8\xb0\ -\x44\xdb\xe2\x06\xa3\x86\x03\xc0\xf8\x36\x78\x27\x59\xa1\xc0\xf8\ -\x50\x01\x60\x22\x6e\x71\x83\xf1\x13\x7c\x1e\x76\xd4\x2d\xee\x1c\ -\xcc\x2e\x4b\x08\x9a\x28\x9b\xdc\xe0\x51\x89\xb7\xcb\x0d\x1e\x9a\ -\x98\xdb\xdc\xe0\xc1\x89\xe5\x73\x83\x39\x98\x16\x00\x26\xaa\xcf\ -\x0d\x7d\x79\x8a\xe9\x74\x83\x17\x9c\x98\x5e\x37\x18\xa7\xbb\x03\ -\x47\x0c\xc0\x89\xe9\x74\x83\x09\x65\x85\xc0\x69\xbd\x6e\x1e\x61\ -\x4f\x01\xc1\x39\x0b\xe0\xdb\x59\xe9\xbd\xee\x7c\xe2\x55\x1c\x8e\ -\xb6\xf1\xc3\xa2\xbd\xee\xe9\x77\xbb\xe1\x68\x1a\x3f\x30\xfa\x3a\ -\x79\x39\xb1\x1a\x46\xe0\x25\x46\x7b\xdd\x79\x8c\x2d\x28\x38\xa1\ -\x1a\x3f\x36\x9d\x62\x9e\x7a\x3a\x41\x0a\x7a\x06\x90\xc1\x19\x57\ -\xf3\x69\xf2\x43\x12\x2c\x65\x60\xa2\xe5\x21\x6c\xb4\xef\x3d\xf9\ -\x1d\x16\x48\x5e\x54\x00\x1a\xed\x7b\x4f\xef\x45\xa9\xeb\xd1\xd0\ -\xc1\x69\x6e\x83\x4e\x3e\xa7\x04\xa0\xe8\x67\xc0\xd6\xd3\xbe\x77\ -\x04\xd7\x1b\xba\x1e\xee\x3c\xef\xc9\x0f\xd7\xc8\x25\x0a\xbc\xd8\ -\x48\xcf\x3b\x86\xd3\x8d\xc0\x09\x0d\x19\x00\xa3\xbd\xee\xa9\x43\ -\x12\xad\xd7\x0d\x27\x04\x1a\x40\x47\x6f\x76\x47\x30\x6d\x10\x20\ -\x55\xec\xd9\x40\xb0\x36\xbb\xa7\xc5\xa6\x84\x13\xaa\xf1\xc3\xa2\ -\xdd\x6e\x36\xbd\x13\x05\x67\x36\xf9\x91\x89\x76\xa1\xbb\x84\xa3\ -\x85\xfd\xc8\x44\xdc\xee\x86\x0e\x4d\xbc\xed\x6e\x38\xbe\x65\x00\ -\x99\x28\xbb\xdd\x70\xdc\xca\x00\x2a\xf1\x8e\x98\x73\xe8\x4b\x53\ -\xdc\xed\x6e\xe8\xf6\x4c\xb4\xfd\x6e\x38\x87\xb1\x02\x86\x9e\xf6\ -\xb9\xa7\xdf\xb6\x84\x14\x8f\x08\x60\xa3\x9d\xee\x89\x97\x27\x04\ -\xea\x0c\x5f\x00\x9a\x98\xbb\xdd\xd0\x17\xef\xce\xef\x9e\x7e\x3b\ -\x81\xa7\x18\x4e\xf4\x33\x00\x4e\xcc\x33\xe6\x70\xbc\x28\xcf\x6a\ -\x6d\xdc\x6e\x2c\x26\x06\x07\x8e\xcc\xf8\x61\xd1\x6e\xf7\xd4\x3b\ -\x2d\x05\x20\x4d\xe3\x07\x26\xda\x6e\x37\xf4\x89\x14\x71\xb7\x1b\ -\x8e\xa3\xe0\x87\x26\xde\x66\xb7\x80\x73\xd8\x28\x00\x4d\xbc\xdd\ -\x6e\xf0\xd0\xc4\xdb\xec\xa6\x70\xc2\x12\x01\x6c\x62\xee\x76\x83\ -\x07\x27\xd6\x6e\x37\x83\xbe\x46\xc5\xdc\xee\x86\x73\x22\x2b\x80\ -\x4d\xbc\xfd\x6e\x38\x9a\xd8\x13\xb3\x7a\xf2\xf7\x71\x02\x68\xe0\ -\x44\x24\xfc\xb0\x74\xf7\x50\x27\x57\xc2\xd0\xe5\xa5\xfb\xc0\xd2\ -\xe4\xf7\x50\x11\x74\x91\xd1\x4e\x02\x8e\x10\x32\x67\x70\x14\xb0\ -\x1f\x9b\x78\x5b\x73\xe0\x91\x89\xb2\x35\x07\x7d\x2e\x75\xfe\xc1\ -\xc4\xd6\x0c\x4a\x21\x9d\xdd\x0b\x40\x13\x73\x67\x8e\x81\x17\x1c\ -\xed\x1f\x4c\xfd\xe9\x08\x40\x71\x9a\x80\x9d\x17\xf3\x95\xcb\xe0\ -\xc1\x89\x77\x13\x15\xce\x0e\x8b\x4f\x42\xe2\x39\x08\x82\xc3\x89\ -\x0a\x07\x90\x89\xe6\x23\x70\x38\xeb\x77\x00\x9a\x68\x5e\x42\x01\ -\x47\x11\x07\xa0\x89\xe8\x26\x70\x02\xc7\xbd\x0c\xa0\x13\xf1\xab\ -\x2c\x70\xb6\xe7\x42\xd8\xc4\xf9\x30\x0b\x7c\x5c\xe2\x39\x0b\x05\ -\x78\x4d\x1c\xf7\xf3\x2c\x70\xbc\xa9\x10\x3c\xb1\xfc\x05\x01\x27\ -\x32\x11\x32\xfc\x62\x7a\x0c\x70\x4e\xf3\x85\xd0\x89\xf8\x9d\x16\ -\x40\xa2\xe3\x39\xd3\x18\xd1\x67\xc8\x01\xa9\x63\x3f\x32\xd1\x7c\ -\x86\x12\xd0\x8c\xf2\x43\x13\xed\x0d\x97\x25\x20\x0b\xc7\x0f\x4d\ -\xc4\x4b\x3f\x0c\xbc\xb2\x89\xf8\x96\x4b\xf0\x82\x13\xc7\x65\x00\ -\x14\x0d\x0d\xe1\x12\xf3\xeb\x12\xf0\xa5\x26\xea\xf7\x25\x00\x2d\ -\x54\xee\xab\x00\xe2\x19\x36\x80\xce\x4b\x8c\x31\x89\x66\xd2\x00\ -\xba\xd7\x32\x46\x25\x5a\x04\x34\x07\x14\x37\x1f\xa1\x12\x31\xf8\ -\x49\x00\x2d\x4a\x23\x5c\x62\xbe\xa9\x1b\x50\x4c\x78\x8c\x4b\x9c\ -\xd7\x74\x83\x16\x95\x78\xd1\x4e\x40\xc7\x83\x3d\xb8\x44\xbd\xb1\ -\x0c\xe7\xd2\x93\xef\xba\xa0\xf5\xe6\xd3\x89\xd7\x23\x40\xd7\x2b\ -\x03\xc0\x74\xb7\xc1\x26\x7f\xe9\x53\x09\x69\x67\xc5\x8f\x8d\x36\ -\x62\xf8\xe4\x57\x96\x39\x20\x0d\xec\x87\x46\x5b\x32\x11\x94\x0d\ -\x24\xb3\xd7\x8f\x4d\x67\xcd\x4c\x8d\x8e\x0a\xe5\xc1\x31\x66\x02\ -\xd8\xe8\x4b\x61\x93\xab\x1b\xf5\x0a\x54\x40\xeb\x77\x00\x1d\x6d\ -\xdc\x4c\x6f\xdb\xc0\xd7\x38\x71\xdf\x82\xfa\x36\xc3\xc0\x17\xf3\ -\x1b\xfd\xc7\xcd\x3b\xab\xed\x37\x2c\x17\x6c\x16\x46\x90\x65\x1c\ -\x51\x5c\x0e\xaf\x01\x91\x63\x6f\x6d\xa1\x82\xb0\xdc\x71\xc0\x4e\ -\x3f\xc9\x16\x9c\x76\x14\x13\x8c\x8a\x93\xb1\x93\xb6\x08\x2a\x48\ -\xc9\x31\x8f\x25\x5b\x01\x64\x58\xbb\xc7\x19\x88\x87\x7e\x37\x34\ -\xc5\xb1\x69\x07\x05\x1b\xd1\xbe\x9b\x24\xf7\xcf\xbb\x57\x60\xd3\ -\x1c\xd8\x0a\x9a\x88\x50\xe0\x41\xe8\xd8\xeb\x49\xbe\x1f\x1e\x74\ -\xec\xf0\x0d\x18\x70\x8a\xac\x91\x1d\xff\x1b\x15\xbe\x1b\x9c\xf6\ -\x68\x52\xf0\xec\x0d\x18\x74\xca\xb6\x9f\x93\x6b\x9d\xf6\x6c\x12\ -\x78\xad\x8c\x71\xbb\x25\x3e\xb1\xf4\xe8\x13\x38\xe0\x27\x17\xa6\ -\xad\x0f\xe6\xf7\x4e\x5f\x31\xb9\xd0\xb1\x4d\xaa\xb7\x8a\x8e\xf3\ -\xba\x0c\x85\x4e\x39\x7e\x4f\xf1\x34\x7a\x99\xa7\x18\x3e\x3c\x24\ -\x6f\x3d\x0d\xbf\x1f\xf6\x8a\xb9\xc5\x8e\x7f\x72\xe1\xcd\xe1\x53\ -\x4a\xa3\x98\x73\x41\x87\xf8\xc4\xb1\x95\xf3\x14\xc3\x31\x08\x43\ -\xd0\xe4\xc7\xbe\x92\xf9\x3a\x6c\x00\x09\x0e\x22\x19\x12\xb4\xcc\ -\xf9\x0f\x11\x1c\x7e\xec\x56\xcc\xdb\xc3\x86\x65\x45\x59\x12\x44\ -\x7f\xd8\xa4\x02\x64\x0d\xe2\x3c\x2b\x38\x23\xce\xcd\xb8\xb8\x82\ -\x03\x47\xe5\x60\x39\xa9\x94\xe4\xfc\x18\x6c\x1a\xc1\x09\x46\x54\ -\xdf\x1e\x38\xd2\x5f\x60\xac\xa4\x3f\x2c\xac\x13\x3e\x6a\xf1\xe6\ -\xb0\x91\x8b\x52\xa1\xfa\x4a\x7e\x9c\xe0\x70\x38\xb1\x8b\x00\x3a\ -\x3a\xec\x45\x27\x0f\xed\x48\x95\x03\xc8\x44\x0e\xa0\x23\x32\xd6\ -\x1c\x61\x8a\x14\xf8\x02\x14\xfa\x0a\x00\x14\x35\xf4\x05\x48\x2f\ -\x87\xe0\x99\xd8\xb7\xd2\x51\x2f\x40\x96\x4e\x08\x98\xc8\x71\x2f\ -\x40\xaa\x27\xb0\xa4\xc7\x43\xa8\x89\x7c\x01\xf4\x24\x86\x9f\x9b\ -\x2a\xc7\x1f\x2f\x9b\x30\xba\x13\xde\x0d\x7c\x7b\x00\x69\x37\x74\ -\x68\x14\x6a\x27\xdd\x7f\x1c\xec\xf5\xf1\x9d\xf0\x81\xb0\xb7\x87\ -\x90\x5f\x84\x22\x45\xc0\xb4\x6d\x08\xc8\x74\x0e\xf8\xa3\x5d\x78\ -\x39\x52\x00\x35\x3d\xf2\x59\xa1\xb7\x07\x91\x76\x4b\x87\x5a\x28\ -\xd6\x06\x85\x99\x64\x80\xac\xa0\x10\x46\x5a\x8c\xa2\x2d\x65\xc7\ -\x0e\xa7\xbe\x39\x90\x42\xcb\x59\xd1\x9e\x18\x8b\xa7\xad\xe5\x94\ -\x3b\xf2\x09\x99\x37\x87\x53\x48\x98\xf2\xf6\xb4\x6a\x64\x9c\xde\ -\x66\x10\x3a\x7c\x18\x08\xf7\x0d\x3e\xec\xaa\xcd\xfe\x7a\xbb\xbb\ -\xbb\x9c\x35\x7f\xae\xab\x43\xfd\x21\x45\x59\x81\x05\x11\xac\x4e\ -\xf9\x59\x2e\x75\x16\xe2\x24\x17\xe5\x47\xc3\xa5\x3b\xd9\x1f\x29\ -\xba\xaf\x0e\xb7\x01\x0c\xd8\x55\xbd\xbc\xbe\xfe\xc1\x18\xf4\x6d\ -\x91\x3d\xfe\x9c\xa8\x01\xc5\x25\xc2\x2c\xa1\x99\xe0\xb8\x60\x05\ -\x4e\x7e\xb1\xa8\x5c\xdd\xeb\xe3\xa2\x10\x0e\x55\x64\xa2\xc8\x05\ -\xe1\x4c\x52\xd5\xb1\x67\xce\x78\x89\x02\x54\xbb\x84\xe6\x66\x36\ -\x11\x79\x11\xa0\xda\x6d\xe8\x4b\xf0\xb7\xac\xa7\x7e\x4d\x3e\x27\ -\xcd\x29\x5a\x9c\x13\x37\x77\x4f\xb5\xeb\x6b\x4f\x95\xe6\xc8\x6d\ -\x45\xfb\x39\xd6\x61\x8b\x7b\xaa\x5d\x6e\x5f\x82\xbf\x36\xb7\x6d\ -\xed\x59\x44\x26\xa8\x5b\x86\xa1\x3a\xf5\x35\x67\xf3\xe8\x00\xa1\ -\xf6\xe5\x22\x18\x89\x00\xd5\x29\xd7\x94\xe0\xaf\xcd\x6d\x5b\xfb\ -\x52\x0a\x51\xba\x6d\xeb\xa9\xce\xf8\x93\xf6\x81\xbb\x54\xa6\xa2\ -\x3b\x72\xe0\x03\x54\xa7\x5c\x53\x82\xbf\xb6\x41\xdb\xd4\xf1\x45\ -\x4c\x31\x76\x73\x1b\xaa\x53\x9f\xfa\x7c\x0f\x47\x65\x19\xa0\xda\ -\xb2\x49\xf0\xf0\xd1\xe6\x21\x83\xea\x4c\x11\xfe\x46\x0c\x9a\x6c\ -\xc4\x53\x0a\x0e\x65\x44\xfd\x65\x0b\xad\x1a\x06\x2a\xf3\x17\x2e\ -\x55\xd6\x4f\x91\x1a\x32\x5b\xec\x03\x54\xab\x04\x8b\xea\xaf\xcd\ -\x50\x9b\xb6\x99\x9e\x38\xb9\x7b\xaa\xdd\x36\xd3\x3f\x87\x6a\x06\ -\x35\x40\xb5\x5a\x6c\x95\x60\x53\xfb\xda\x2c\x2a\xc1\xa3\x47\xab\ -\x7c\xf5\xe8\x6f\xb0\xdb\xbd\xbe\xdb\xa2\x93\x75\x1b\x0c\x65\x62\ -\x62\xce\xc9\x80\x2a\x2b\xc2\xa8\x1c\xe8\xac\x00\xd5\x2a\xc1\x82\ -\xde\x5b\x5b\x4f\x6d\xda\x66\xe4\xde\xc9\x6d\xa8\x4e\xdb\xcc\x6c\ -\xb0\xa9\xfd\x5c\x0f\x50\xad\x16\x5b\x25\xd8\xd4\xbe\x36\x9b\x6a\ -\x06\x2f\x40\xb5\x5b\xd6\x0f\xb4\xb7\x17\x83\x3e\xf7\x18\xcb\xb1\ -\x55\x43\xeb\xea\x6f\x39\x8e\x22\x2f\xa5\xba\x74\xa8\x44\x39\x02\ -\x98\x50\x17\x63\x9b\xda\xaf\x16\x7e\xaa\x5d\xae\x35\x76\x7e\xaa\ -\xbf\x65\x86\xda\x68\x6f\xa3\x4f\xed\xdc\x16\xd5\x2a\xb9\xd7\xb2\ -\x7e\xaa\xdd\xe2\xbe\x04\x87\x6a\x46\xd4\x4f\x75\xca\xed\xa9\xfe\ -\x96\x39\xfd\xe8\x57\x27\xbb\x8c\x9e\xea\xd4\x67\xd6\x37\x87\x6a\ -\xd6\x42\x3f\xd5\x69\x9b\x29\xc1\x5f\x5b\x4f\xfd\x9a\x58\x36\x89\ -\xd7\xe8\xb2\x6d\xae\xd4\x67\x74\x7d\xc3\x06\x4d\xe9\x37\x2d\x3f\ -\x94\xa3\x12\x5b\x6e\xb4\xb7\x1d\x84\xb6\xd6\x2f\x3d\x4b\x8d\xbf\ -\x3a\xb2\xfc\x8e\x99\xb7\xf2\x51\x1a\x6c\xe7\x0f\xbb\xf5\x87\xf7\ -\xed\xdf\x05\x2b\xd1\xc7\x23\xe7\xcf\x69\x3e\x3e\x99\x26\xad\xf7\ -\xa6\x7e\xaf\xe5\xfe\x9a\x3b\x31\x02\x1f\x7b\xd9\xd8\x0b\x2d\xf6\ -\xe8\x97\x1b\x48\xd1\x78\x30\x3e\x64\xc2\x91\x84\xd7\x5d\x19\x9a\ -\xee\x24\x68\x7c\x74\xca\x31\x0c\xf1\x04\xe7\xd8\x7b\x27\xde\x1a\ -\x32\xc1\x29\x75\x34\x72\xf0\x8a\x2b\x43\x74\xc2\x73\x23\xff\x3f\ -\x74\x8e\x06\x9f\x5e\x75\x67\xa8\x38\xf6\xb9\x62\x30\xf8\x1c\x8d\ -\xa7\xbc\xea\x36\x1e\x3e\xf6\x76\x4c\x28\xf8\x1c\xdf\x87\x7b\xdd\ -\xcb\x06\x54\x14\x7c\xaa\xc0\x65\x7c\x80\xf0\x58\xcd\x44\x53\xcc\ -\xea\x77\xaa\x50\x65\x7c\x64\xe8\xf8\x9c\x79\x34\x64\x8a\xc6\x30\ -\x9c\x6a\xdf\xe4\x87\x5c\x55\xa4\xea\xae\xaf\x81\xef\x26\xd0\xf2\ -\x6b\xa2\x7e\x87\x2d\xff\x96\x89\xdd\x22\x86\x05\x3b\xeb\xde\xe4\ -\x85\x86\xe6\xb5\xb4\x91\xa5\xb3\x6d\x1a\x30\x0a\x6d\x9e\xd4\x8e\ -\xb8\x08\xda\x8d\x69\xa2\x9b\xbd\x17\xd2\x7b\x29\xb6\x6f\xd2\x7b\ -\x66\x0e\xd5\x78\x50\xb6\xc7\x62\x53\x7b\x6f\x33\x40\x35\x9e\x99\ -\x53\x82\x45\xb5\x6a\xf3\x52\x7b\x1f\xde\xa1\x1a\x5f\xdb\xf1\xbb\ -\xfc\x54\xbb\x04\x43\x75\x6a\x33\xbd\x77\xa8\xa6\x47\x01\xaa\xd5\ -\x63\xab\x04\x9b\xda\xd7\xe6\xa7\xda\xa8\xf7\x54\xff\x08\x19\xaa\ -\xe3\x27\x86\xc2\xf3\xbd\x1c\xa7\x5e\x41\xf6\xeb\x01\x5b\x2d\x99\ -\xc9\xd7\xfe\xd1\xfc\x77\x31\xdf\x7f\x91\xff\xfd\x0f\xc9\x3d\x8a\ -\x57\ -\x00\x00\x12\x2a\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x34\x20\x28\x35\x64\x61\ -\x36\x38\x39\x63\x33\x31\x33\x2c\x20\x32\x30\x31\x39\x2d\x30\x31\ -\x2d\x31\x34\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\ -\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\ -\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x64\ -\x6f\x5f\x73\x61\x76\x65\x5f\x72\x6f\x69\x2e\x73\x76\x67\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ -\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ -\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ -\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ -\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ -\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ -\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x36\x2e\x33\x38\x30\x33\ -\x31\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x79\x3d\x22\x31\x36\x2e\x31\x30\x34\x39\x38\x39\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ -\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ -\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ -\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\ -\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x37\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ -\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ -\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ -\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ -\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ -\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ -\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ -\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ -\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ -\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ -\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ -\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x32\ -\x34\x37\x35\x31\x33\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ -\x65\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x33\x32\x35\x36\x36\x65\ -\x2d\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\ -\x35\x2e\x32\x31\x30\x36\x34\x36\x38\x65\x2d\x31\x35\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\ -\x34\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x33\x2e\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\ -\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\ -\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ -\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\ -\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\ -\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ -\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\ -\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\ -\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\ -\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\ -\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\ -\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\ -\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\ -\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ -\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\ -\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\ -\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\ -\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\ -\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\ -\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\ -\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\ -\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ -\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ -\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\ -\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\ -\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\ -\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x2e\x35\x35\x32\x32\x36\x39\ -\x35\x2c\x31\x31\x2e\x36\x39\x35\x31\x30\x38\x20\x43\x20\x36\x2e\ -\x39\x35\x35\x30\x32\x35\x35\x2c\x33\x2e\x33\x31\x30\x30\x37\x35\ -\x38\x20\x31\x33\x2e\x35\x39\x30\x30\x36\x35\x2c\x34\x2e\x35\x32\ -\x38\x36\x37\x30\x31\x20\x32\x32\x2e\x32\x39\x32\x35\x35\x36\x2c\ -\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x4c\x20\x32\x34\x2e\x32\ -\x39\x33\x32\x31\x33\x2c\x31\x2e\x39\x34\x31\x30\x36\x32\x34\x20\ -\x33\x30\x2e\x37\x34\x39\x37\x31\x36\x2c\x31\x35\x2e\x39\x30\x32\ -\x37\x20\x32\x39\x2e\x33\x32\x39\x36\x30\x37\x2c\x31\x36\x2e\x34\ -\x39\x37\x36\x33\x35\x20\x31\x36\x2e\x30\x33\x31\x37\x37\x31\x2c\ -\x31\x37\x2e\x30\x36\x38\x36\x35\x31\x20\x31\x39\x2e\x33\x34\x33\ -\x36\x35\x34\x2c\x31\x31\x2e\x35\x31\x34\x35\x34\x38\x20\x43\x20\ -\x31\x33\x2e\x35\x33\x39\x36\x35\x35\x2c\x31\x30\x2e\x32\x32\x38\ -\x34\x34\x33\x20\x37\x2e\x37\x33\x33\x37\x30\x36\x35\x2c\x38\x2e\ -\x39\x32\x32\x37\x33\x39\x32\x20\x34\x2e\x39\x35\x39\x33\x39\x30\ -\x35\x2c\x31\x34\x2e\x32\x30\x36\x34\x31\x34\x20\x63\x20\x2d\x32\ -\x2e\x35\x32\x34\x36\x31\x33\x2c\x32\x2e\x32\x38\x32\x34\x32\x38\ -\x20\x2d\x33\x2e\x39\x39\x32\x33\x38\x34\x30\x33\x2c\x31\x2e\x37\ -\x33\x34\x33\x39\x32\x20\x2d\x32\x2e\x34\x30\x37\x31\x32\x36\x2c\ -\x2d\x32\x2e\x35\x31\x31\x33\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\ -\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ -\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\ -\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ -\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\ -\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\ -\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\ -\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\ -\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\ -\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\ -\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\ -\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\ -\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\ -\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\ -\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\ -\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\ -\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\ -\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\ -\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\ -\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\ -\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\ -\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\ -\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\ -\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\ -\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\ -\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\ -\x34\x31\x33\x33\x33\x33\x34\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\ -\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\ -\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\ -\x2e\x38\x36\x37\x31\x38\x37\x35\x2c\x39\x2e\x33\x38\x30\x39\x31\ -\x34\x31\x20\x43\x20\x37\x2e\x32\x36\x39\x39\x34\x31\x35\x2c\x30\ -\x2e\x39\x39\x35\x38\x38\x31\x30\x37\x20\x31\x33\x2e\x39\x30\x34\ -\x39\x38\x32\x2c\x32\x2e\x32\x31\x34\x34\x37\x35\x36\x20\x32\x32\ -\x2e\x36\x30\x37\x34\x37\x34\x2c\x35\x2e\x31\x35\x32\x34\x37\x32\ -\x32\x20\x4c\x20\x32\x34\x2e\x36\x30\x38\x31\x33\x2c\x2d\x30\x2e\ -\x33\x37\x33\x31\x33\x32\x36\x39\x20\x33\x31\x2e\x30\x36\x34\x36\ -\x33\x33\x2c\x31\x33\x2e\x35\x38\x38\x35\x30\x35\x20\x32\x39\x2e\ -\x36\x34\x34\x35\x32\x32\x2c\x31\x34\x2e\x31\x38\x33\x34\x34\x32\ -\x20\x31\x36\x2e\x33\x34\x36\x36\x38\x39\x2c\x31\x34\x2e\x37\x35\ -\x34\x34\x35\x38\x20\x31\x39\x2e\x36\x35\x38\x35\x37\x31\x2c\x39\ -\x2e\x32\x30\x30\x33\x35\x34\x31\x20\x43\x20\x31\x33\x2e\x38\x35\ -\x34\x35\x37\x32\x2c\x37\x2e\x39\x31\x34\x32\x34\x39\x36\x20\x38\ -\x2e\x30\x34\x38\x36\x32\x34\x35\x2c\x36\x2e\x36\x30\x38\x35\x34\ -\x34\x35\x20\x35\x2e\x32\x37\x34\x33\x30\x38\x35\x2c\x31\x31\x2e\ -\x38\x39\x32\x32\x31\x38\x20\x32\x2e\x37\x34\x39\x36\x39\x36\x35\ -\x2c\x31\x34\x2e\x31\x37\x34\x36\x34\x36\x20\x31\x2e\x32\x38\x31\ -\x39\x32\x35\x35\x2c\x31\x33\x2e\x36\x32\x36\x36\x31\x20\x32\x2e\ -\x38\x36\x37\x31\x38\x31\x35\x2c\x39\x2e\x33\x38\x30\x39\x31\x38\ -\x34\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ -\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\ -\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\ -\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x38\x30\x30\ -\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ -\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ -\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ -\x2e\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ -\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\ -\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x34\x2e\ -\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x31\x38\x2e\x31\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x79\x3d\x22\x31\x39\x2e\x32\x30\x30\x30\x30\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\ -\x34\x34\x34\x34\x34\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ -\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x09\x99\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x70\x65\x6e\x5f\ -\x64\x69\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ -\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ -\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ -\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ -\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ -\x22\x2d\x36\x38\x2e\x36\x31\x31\x38\x34\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x2d\ -\x32\x2e\x36\x31\x31\x30\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ -\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ -\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ -\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ -\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ -\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ -\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ -\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x38\x30\x38\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x31\x2e\x31\x39\x32\x35\x36\x39\x36\x31\x70\ -\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ -\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\ -\x33\x33\x33\x33\x33\x20\x48\x20\x32\x36\x2e\x36\x36\x36\x36\x36\ -\x37\x20\x56\x20\x32\x38\x2e\x38\x20\x48\x20\x30\x20\x5a\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ -\x30\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ -\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\ -\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x30\x2e\x38\x37\x30\x39\x32\x39\x37\x32\x70\x78\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ -\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ -\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x64\x3d\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\ -\x33\x20\x31\x36\x2c\x39\x2e\x32\x34\x34\x34\x34\x34\x35\x20\x56\ -\x20\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x4c\x20\x30\x2c\x32\ -\x37\x2e\x30\x32\x32\x32\x32\x32\x20\x76\x20\x2d\x32\x34\x2e\x38\ -\x38\x38\x38\x38\x38\x37\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ -\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ -\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x12\xe9\ -\x00\ -\x01\xe7\x43\x78\x9c\xed\x5d\x4b\x73\xdb\xc8\x11\xbe\xfb\x57\x30\ -\xf4\x25\xa9\x18\x43\xcc\xe0\x4d\x4b\xde\x43\xb6\xb6\xb2\x55\xc9\ -\x25\xd9\x24\x55\xb9\x6c\x51\x24\x28\x31\x26\x09\x15\x08\x5a\xd2\ -\xfe\xfa\xcc\xe0\x49\x42\xad\xb5\xb8\x0d\x34\xac\x45\xd3\xbb\x65\ -\x13\x00\x5f\xf3\xa1\x9f\x5f\x4f\xf7\xd5\x77\x8f\xbb\xed\xe4\x4b\ -\x9c\x1e\x36\xc9\xfe\x7a\x2a\x85\x3d\x9d\xc4\xfb\x65\xb2\xda\xec\ -\x6f\xaf\xa7\xff\xfa\xe9\x07\x2b\x9c\x4e\x0e\xd9\x62\xbf\x5a\x6c\ -\x93\x7d\x7c\x3d\xdd\x27\xd3\xef\x3e\xbd\xbb\xfa\x83\x65\x4d\xfe\ -\x92\xc6\x8b\x2c\x5e\x4d\x1e\x36\xd9\xdd\xe4\xc7\xfd\xe7\xc3\x72\ -\x71\x1f\x4f\xfe\x78\x97\x65\xf7\xf3\xd9\xec\xe1\xe1\x41\x6c\xca\ -\x83\x22\x49\x6f\x67\x7f\x9a\x58\xd6\xa7\x77\xef\xae\x0e\x5f\x6e\ -\xdf\x4d\x26\x13\xfd\xb9\xfb\xc3\x7c\xb5\xbc\x9e\x96\x2f\xb8\x3f\ -\xa6\xdb\xfc\xc2\xd5\x72\x16\x6f\xe3\x5d\xbc\xcf\x0e\x33\x29\xe4\ -\x6c\xda\x5c\xbe\x6c\x2e\x5f\x9a\x4f\xdf\x7c\x89\x97\xc9\x6e\x97\ -\xec\x0f\xf9\x2b\xf7\x87\xf7\x27\x17\xa7\xab\x75\x7d\xb5\xf9\x36\ -\x0f\x4e\x7e\x91\x8c\xa2\x68\x66\xab\x99\x52\x96\xbe\xc2\x3a\x3c\ -\xed\xb3\xc5\xa3\x75\xfe\x52\xfd\x1d\xa1\x97\x2a\xdb\xb6\x67\xfa\ -\x5c\x73\xe5\xeb\xae\x9a\x1f\xf4\x82\xde\xeb\xff\xeb\xcb\xab\x03\ -\xe2\x90\x1c\xd3\x65\xbc\xd6\xaf\x8b\xc5\x3e\xce\x66\xdf\xff\xf4\ -\x7d\x7d\xd2\xb2\xc5\x2a\x5b\x9d\xbc\x4d\xb5\x9e\x67\x9f\x7a\xb6\ -\xc8\xfb\xc5\x2e\x3e\xdc\x2f\x96\xf1\x61\x56\x1d\xcf\x5f\xff\xb0\ -\x59\x65\x77\xd7\x53\xc7\x15\xd2\xd1\x0f\x2f\x3f\x78\x17\x6f\x6e\ -\xef\xb2\xf6\xd1\xcd\xea\x7a\xaa\xbf\xbd\xe7\x28\x3b\x7f\x7e\x72\ -\x73\xc8\xe2\x82\xf2\x8d\xe7\xf5\x19\x5b\x44\x4a\xc8\x49\x2a\x3d\ -\x27\x28\xae\xa9\x7e\xc2\x7c\x95\x2c\xcd\x77\xd2\x6f\x19\xef\x36\ -\x8b\x63\x96\xec\x34\x6a\xcb\xe5\x76\x71\x38\x6c\xd6\x9b\xa5\x7e\ -\x92\xec\xef\xb7\xc7\xdb\xcd\xfe\x67\xfd\xa6\x59\x16\xa7\x3f\xa7\ -\x8b\x83\xf9\x6b\xb3\x5b\xe8\x35\xa9\xd6\xb1\xfe\xd0\xf8\xf1\x3e\ -\x49\x33\xeb\x71\x75\xaf\x57\xd3\x0f\x84\x07\x9e\x7e\x6a\x4e\x7f\ -\xd2\xe7\xaf\x56\xf1\xfa\x60\xae\x2b\x7e\x9e\x79\xa6\x7f\x9f\x9a\ -\x4e\x66\xf9\xd9\xfa\xdb\x9a\xaf\xba\xfa\xb2\x89\x1f\x9a\x6b\x6f\ -\x16\x87\x62\x09\x27\x93\x7b\xfd\x85\x96\xc9\x36\x49\xaf\xa7\xef\ -\xd7\xf9\xa3\x3c\x71\x93\xa4\xab\x38\xad\x4e\xf9\xf9\xe3\xec\x54\ -\xa2\x21\xd9\x64\x4f\x85\x80\x95\xef\x5d\x7d\x63\xf3\xae\xf5\x79\ -\x1b\x3e\x7f\xb8\x5b\xac\x92\x87\xeb\xa9\x6a\x9f\xfc\x25\x49\x76\ -\xd7\xd3\x40\x44\x32\xb4\x5d\x19\xb4\x4f\x2f\x1f\xaf\xa7\x96\xaf\ -\x84\xf2\xdd\x28\x72\x9f\x9d\x35\x5f\x28\x12\xa1\xe3\xf9\x25\x6c\ -\xa7\x27\x8f\x69\xaa\x45\xd0\xda\x2e\x9e\x62\xfd\xab\xf2\xbf\x9c\ -\xf2\xa2\xc3\x5d\xf2\x70\x9b\x9a\xd5\xc9\xd2\x63\xdc\x7e\xa5\x39\ -\x63\xdd\xdc\x24\x8f\xf0\x69\x7d\x47\x1c\x8d\x70\x5b\xc7\xfd\x26\ -\xd3\x02\x74\xff\x78\xfa\xae\xc7\xcd\x2a\x3e\xbc\xf0\xbe\xe6\xdc\ -\xaf\xbc\xf1\xc3\x66\xaf\x17\xc9\x2a\x6f\x75\xe9\xd4\x18\xb4\xaf\ -\xa8\xee\xfb\xc0\x0e\x5f\xb8\x42\x7f\xc2\x33\x1c\xca\x53\x4f\x2f\ -\x9f\xda\x2d\x1e\x37\xbb\xcd\x2f\xb1\x5e\x17\x99\xdf\x76\xfa\xd6\ -\x3a\x5b\x95\xe2\x65\x93\x49\xf6\x64\x64\xf8\xf1\xc9\x1c\x9b\x56\ -\x07\xcd\x72\x9a\x03\x9e\xe3\xfa\xf5\xc1\x24\xdd\x68\xd1\x38\xf9\ -\x3a\xd5\xa1\xa7\xd3\x43\x46\xe2\xb5\xc2\x7e\xcc\xef\xaf\xfc\xee\ -\x0b\xda\xe7\x9e\x4e\xcf\x95\xb7\xfd\xec\xf9\x7d\x9f\x1f\xdf\xc5\ -\xd9\x62\xb5\xc8\x16\x8d\x10\x54\x47\xb4\xd0\x78\xd5\x2f\xd3\xca\ -\x73\xfe\x8f\xef\x7f\xf8\x54\x7e\xd0\xd5\x72\x39\xff\x4f\x92\x7e\ -\xae\x3e\x77\x32\x31\x17\x2c\x6e\x92\xa3\x5e\xe9\xe9\xa7\xfa\xf0\ -\xd5\x6a\x39\xd7\xea\x4e\xab\x81\x4f\xb9\x84\x1b\x4d\xf9\x67\xad\ -\xde\xae\x66\xcd\x89\xb3\x8b\xcd\x62\x35\x6f\x5a\xbc\x6d\x1a\x17\ -\x7a\x13\x34\x1e\xab\xe5\x6e\x63\x5e\x34\xfb\x67\xb6\xd9\x6e\x7f\ -\x34\x1f\x52\xfe\xe2\x93\x37\xdd\x64\xdb\xb8\x39\x78\x35\x2b\xbf\ -\x7d\xf9\xdb\x66\x27\x3f\xee\x6a\x56\xfd\xfa\xfc\xd9\x6d\xb3\x2a\ -\xb9\x4c\x3c\x13\x9c\xed\xe2\x26\xde\x5e\x4f\xff\x66\x4e\x4e\x9e\ -\x9d\xbd\x4d\x93\xe3\xfd\x2e\x59\xc5\xe5\xcb\x2b\x2c\x6e\xbf\x76\ -\x5d\xeb\x63\x9d\x97\x3e\x56\x9b\xc4\xed\x36\xa9\x41\x8a\x97\x59\ -\x7d\x27\x64\x4f\x5b\xfd\x76\xb9\x9a\x9a\xbf\xb7\xf3\xc7\xc7\xd5\ -\xe6\x70\xaf\xdf\x50\x9b\x96\xed\x66\x1f\x7f\x4c\xb4\x4e\x5f\x6f\ -\x93\x87\xf9\x97\xcd\x61\x73\xb3\x8d\x3f\xe6\x7f\x6f\xb6\x7a\x41\ -\xeb\x43\x6b\xbd\xaa\xf3\xf7\x37\x8e\xf9\x93\x3f\xb1\x4a\xf5\x35\ -\x97\xc5\xd3\xf4\xb8\x8d\xe7\xfb\x64\xff\x8b\x56\x7c\x1f\x0f\x59\ -\x9a\x7c\x8e\xe7\xef\xa5\xb7\x5e\xeb\xcf\x2b\x9e\x16\x42\x3a\xd7\ -\x8a\xc9\xcd\xbf\x86\xac\x8e\x9b\x2f\xa1\x7f\xce\xfc\xe6\x98\x65\ -\xa7\xc7\xfe\x97\x6c\xf6\x73\x0d\x6b\x9c\x56\x47\xf3\x27\x5b\x2d\ -\x6f\xd9\xdc\xad\x8e\xad\x16\x5a\x51\xa6\xa9\xfe\x39\xfa\xd3\xe3\ -\xd3\xa3\xc9\x7a\x7d\x88\x33\xfd\x81\xa1\xa3\x42\x5b\x7a\x61\x75\ -\xb2\xf9\xea\xbb\x45\xfa\x39\x4e\x8b\x57\xc6\xfb\x85\xfe\xa5\xd6\ -\xcd\x62\xf9\xd9\x00\xb1\x5f\xcd\x17\x4b\xad\xb5\x8e\x5b\xed\xf0\ -\x9c\x09\xac\x59\x5f\xc7\xb6\x1b\x71\x2b\xb5\x8f\xeb\x8a\x20\x32\ -\x8f\xfa\x44\x6d\x6c\x03\x61\x6c\xad\xa3\xea\x33\xb9\x8e\x16\xe5\ -\x42\xd4\x47\xb5\xc0\x5a\xaa\xb0\xcb\x8e\x5b\x1f\x4d\xf5\xe1\x48\ -\x68\x2b\x6b\x2b\xdb\xa9\xef\xea\xab\xfb\x45\x76\xd7\x82\xb9\x42\ -\x69\xbd\x0e\xed\x1a\x84\x12\xf4\x33\x10\xb4\x59\x77\x02\xfd\xf0\ -\xa3\xfb\xc7\xcb\x61\xa8\xd7\xaf\xfe\x8a\x7a\x55\xfe\x3e\x91\x52\ -\xe4\x6f\x1a\x7e\xb0\x27\x95\x7b\xe1\x7c\xa8\x8f\x4e\x94\x12\x81\ -\x67\x1e\x1f\xea\xb3\x13\xfb\x43\x7d\x74\xf2\xdf\xb3\x55\x36\x3f\ -\x4f\x45\x51\xb3\xca\x8d\x95\x4a\xf6\xfa\x9b\x66\x49\x6a\x69\x7b\ -\xf5\x65\x91\x1d\xd3\xd8\x28\xc6\xaf\x2e\xcc\xc9\xfd\x01\xaf\x4a\ -\xbd\xf4\x6e\x9f\xb7\xe6\x4b\xab\x57\x69\xea\x0f\x56\xfd\xcf\xc9\ -\xbf\x27\x8e\x53\x3c\x09\xa0\xc5\xf1\x5f\xbd\x38\xf5\x7a\xd4\xda\ -\x5f\xab\x19\xa3\x30\xb5\xdd\x5d\x2e\xdf\xfa\xda\x39\x9e\x50\x1f\ -\xea\x95\x9a\xfc\x75\xf2\xdc\x24\x9e\xac\x5a\xf8\xed\xac\x9a\x14\ -\x1a\x44\x5b\x79\x61\x67\x62\xb8\x9b\x54\x48\x38\x1f\x54\x20\x82\ -\x42\xcc\x96\xf5\x51\x57\x0b\xe7\x0b\xff\x7e\xb6\x56\x5a\x6e\x95\ -\x65\xd3\x0a\xa0\x0c\x3c\x57\x7a\x5e\x87\xeb\xa1\xd5\xec\x89\xc2\ -\x59\x6a\x95\x63\xb9\xda\x39\x36\x8f\x97\xfe\xfd\x7c\x25\x42\xf7\ -\xcd\xaf\x83\x56\xc4\xc5\xdd\xd0\xc9\x6a\x58\xaf\x97\xa2\x6f\x74\ -\x3d\xb4\xe1\xe9\xe6\xc6\xb0\xa2\x37\xbf\x14\x41\xa7\xb7\xc6\x9b\ -\x17\x95\xda\x94\x74\xb3\x1e\xce\x5b\x5f\x0f\x19\x74\xba\x1e\xaf\ -\x77\x5b\xbe\xee\xec\x9a\x8c\x8c\xfd\x35\x67\xb7\x57\x23\xab\xd5\ -\x08\xca\xbe\x5a\xea\xf7\xb4\x1c\xf5\xad\x82\x5b\x13\x49\x28\x32\ -\x3d\x2f\x88\xec\xc2\x09\x23\xd5\x21\xfd\x2e\x88\x8f\x95\x17\xf7\ -\x77\xb3\x14\x4d\xa0\x87\x5a\x90\xdf\xe0\x7f\xf4\x97\x23\x32\xfa\ -\x47\xbf\xfe\xd5\x39\x22\x68\xd5\xed\xcb\xd7\xfa\x37\xa5\x86\xec\ -\x67\x48\x21\x32\x42\xa1\xdd\x28\xf2\x2a\x1f\x2d\x9a\x43\x55\x2e\ -\xc8\x16\x91\x74\x55\xe8\x05\x67\xc9\x20\xe9\x08\xf7\xdc\x62\x9a\ -\xe4\x6d\xa9\x3a\x3c\xc6\xad\x5f\xdc\x4e\x54\xca\xe5\xc8\x79\x22\ -\x3c\x4f\x35\x30\x72\x84\xc8\x45\x08\xe4\x5c\xe1\x3f\x47\xce\x13\ -\x4e\x64\xbb\x81\xcf\xc8\xf5\x2d\x73\x27\x29\x84\xcb\xb1\x2b\xdd\ -\xcc\x90\xb1\x1b\x02\x3b\x8c\xa5\x83\xa4\x2e\x12\x39\x6e\x8e\x62\ -\xe4\x7a\x97\x3a\xbf\x63\xa9\x63\xec\xc8\x6c\xdd\x49\x14\xd8\x91\ -\x9f\xe2\x08\xcf\x97\x91\xcd\x7e\x0a\x81\xb5\x43\xf9\x2a\x61\x3b\ -\xa3\xc6\xe8\x51\xda\xbb\xae\x05\x2f\x14\x76\xa0\xa1\x93\x11\x43\ -\xd7\xbb\xe0\x75\x2d\x76\x8c\x1d\x9d\xc1\x43\x38\x9a\xca\x16\x3e\ -\xa7\x54\x86\x35\x78\xb2\x6b\x8b\xc7\xf0\x11\xc1\x87\x89\x12\xc0\ -\x5c\x26\xfb\x2a\x64\x82\x87\x70\x56\x60\xa5\xc9\xd8\x91\x19\x3c\ -\x8c\xc6\x8c\x0a\xb9\xe3\xcc\xca\x60\x06\x0f\xa1\x35\x95\x04\xc2\ -\x04\x52\xf4\xcc\xab\xc3\xb1\xa2\x17\x01\x4a\xb3\x5d\x43\x5a\x01\ -\xf8\xfc\x4c\x81\x5f\xc1\xd3\x9e\x69\x4e\xbb\x4a\x76\x32\x7e\xbd\ -\x5b\x3d\x34\x82\x0e\xa0\x3f\x19\x41\x3a\xdb\x07\x68\xcf\xcb\x00\ -\x54\xe2\x5c\xfa\x5c\x11\xe5\x32\xc9\xd8\x11\xd8\x3e\x0f\x8b\x9e\ -\x2b\xbc\x02\x2d\x86\x70\x88\x14\x27\x14\x36\xa0\xc4\x2f\x2c\xf1\ -\x0c\x19\xbb\xfe\x49\x3d\x28\x70\xc0\x8b\x1f\x43\x48\xc8\xed\xe1\ -\x35\x28\xe8\xc0\x28\xc1\xe8\x91\x24\x3b\x21\xa2\xe1\x32\xfc\x3c\ -\xe1\x33\x74\xe4\xd4\x1e\x1e\x37\x48\xee\x9a\xdd\xbd\x8c\x60\xef\ -\x0c\x1f\x3e\x74\x68\x89\x1e\xa3\x47\xc8\xf1\xe1\xd1\x2b\xf7\xaf\ -\x71\xee\x65\x40\xaa\x0f\xef\x81\xb6\xcd\x1f\x03\x48\x45\xf6\xe1\ -\x63\x3f\x30\xfb\xc9\xfe\x0b\x49\xe2\xd3\x7a\xd6\x8a\xa4\x13\xfd\ -\xc9\xe8\x91\x10\x7e\x78\xf7\xd3\x07\x38\x5b\x8e\xdc\x49\x79\x3f\ -\x7c\xec\x1e\xb6\x9b\x07\x31\x88\x84\x20\x62\xed\x5f\xe3\xab\x9c\ -\x6a\xd0\x48\x28\x0e\x22\x88\x8c\x20\xb0\x85\xef\x32\x04\x8d\xb9\ -\x63\xf0\x06\xb1\x81\x58\xff\xa5\x2a\x0b\x3c\xf3\x5f\x9a\xac\x0c\ -\x03\x48\x60\x01\xb1\x06\x50\x3a\x40\xfd\x0b\x63\x48\x47\xff\x01\ -\xa5\xd6\x78\x21\x6c\x76\x8c\x31\x80\xfd\x73\x80\x68\x3d\x0a\xc9\ -\x20\x43\x48\xc9\x01\x62\x53\xa1\x6d\x37\xa6\x49\xcc\x30\x7a\x14\ -\x1c\xa0\x8d\xc5\xaf\x2e\x78\x61\x10\x87\x61\x03\xd1\x08\xb6\x03\ -\x09\x2e\x61\x22\x24\x02\x7b\x91\x3f\x86\x90\x92\x0d\x44\x7b\x31\ -\x60\x6f\x10\x0e\xe7\x69\xd9\x40\x74\x38\x01\x0a\x22\xa3\x48\x47\ -\x09\xa2\x55\x29\x94\x13\x65\x57\x86\x92\x18\x44\x27\x65\x20\x55\ -\xca\x10\x92\xb2\x83\x68\x0c\xcf\x8b\x2a\x38\x9a\x27\xe5\x05\xd1\ -\x4a\x34\x2c\xfb\x7f\x32\x88\x03\x6d\x4a\x42\xd7\x35\xc1\x10\x92\ -\x34\xa9\x1b\x35\x76\xf9\xa6\x24\xb4\x1f\xaa\x6c\xa8\x0f\x05\xa3\ -\x47\x91\x0c\xf5\xd0\xb5\x31\x4d\xc0\x70\x8a\x5e\x9d\xe6\x66\x10\ -\x49\xf6\x45\xe0\x85\x10\x2c\x2f\x64\x18\xe9\x82\x41\xbc\x24\x82\ -\x59\x19\x86\x90\xb2\x4c\x14\x5f\x28\x0a\xee\x30\x63\x10\x09\xbd\ -\x51\x74\xa5\x1a\x6f\x31\x1b\xc8\x11\x45\x07\xf2\x60\x1c\xc1\x00\ -\xd2\xb9\x31\xfd\x78\xa3\xbc\xcd\x85\xd0\x8d\xc1\xe6\x63\xc0\x3a\ -\x6d\xaf\xf0\x4e\x69\xda\x12\x8e\x1a\xc2\xd2\x8d\x41\x57\xdb\x7f\ -\x03\xcd\x9a\xcc\xa8\xae\x91\xa2\x18\x39\xd0\xec\x07\xd7\x33\x7f\ -\x3c\x00\x41\xc7\x76\x02\xfd\x5f\x2b\x2d\x13\x99\xcb\xcf\xbd\x19\ -\x4f\x04\xbe\x8a\x7c\x22\x66\x62\xc4\x08\x9a\x76\x5b\x50\xad\xda\ -\x65\x18\xea\xc0\xc1\x5c\xcf\x18\x0e\x16\x4d\x00\xbb\x26\x2e\x83\ -\xb0\xd5\xf3\xc7\x88\xa5\x99\xf6\x4d\xd2\x1b\x7b\xd4\xe8\x15\x41\ -\x05\xe0\x91\x5e\x86\x9f\x76\x5d\xec\xc8\x8e\x14\x83\x38\x50\xd3\ -\x2d\x88\xa3\x47\x89\xa0\x74\x84\xf4\xf4\x83\xdd\x98\xfe\x45\xd0\ -\xb7\xc0\xb6\x07\x78\x11\x64\x10\x89\x79\x26\x20\xad\xd6\x81\x2f\ -\x13\x0a\x73\xa1\xcf\x8a\x94\x2a\x43\x83\x16\x46\x5f\x7b\x9f\x8e\ -\xef\x84\x0c\xe3\x50\xcd\xb8\xa0\x0c\x77\x07\xa2\x68\x0b\xcf\x0d\ -\xa5\x4b\x94\x2c\x1d\x31\x86\x79\x3b\x2e\x7c\x7c\x0f\x0a\x22\x83\ -\x48\xdc\xd2\xa9\x27\x85\xca\x31\x3e\x61\xca\x1b\x1d\x60\x80\xa9\ -\x36\xb6\x89\x94\xbb\x9a\xd0\x46\x51\x2a\xa1\x64\xa8\xff\x9c\x81\ -\x18\x09\x3f\x70\xed\x80\x68\xbc\xc4\x88\x41\xcc\xeb\x48\x21\xf2\ -\xe9\x32\x10\x7d\xe1\x69\x0c\x39\x59\x33\x24\x8d\x0f\x15\xd1\x5c\ -\x86\x62\x24\x5c\x1d\xef\x4b\x46\x71\xc0\x78\x1f\xaf\x50\x43\xa1\ -\xcd\x9f\xe3\xb3\x55\x1c\x34\xe0\x07\x9b\xc7\x76\xe0\xde\xb0\x65\ -\xa4\xac\x2d\x45\x87\x19\x3a\xa2\x90\x2a\x50\x81\x64\x69\x1c\xb0\ -\x2c\x03\x4f\x47\x81\xa9\x1b\x96\x45\xca\xfa\x52\x34\x88\xd2\xd1\ -\x78\x69\x61\x1c\x72\xdf\xe1\x88\x41\xac\xaa\x4d\x7b\x89\x36\x18\ -\x46\x5a\x3f\x55\xa1\x2b\x34\x60\xcb\xe8\xea\x37\x89\x94\x4f\xd4\ -\x47\x61\xc4\x30\xd6\xa5\xc3\xe8\x8c\x38\x1c\x70\x30\x90\xc4\x95\ -\xa7\xf8\x92\xa9\x6f\xa0\x72\x71\xc4\x15\xc4\xa6\xf6\x14\x3d\x6f\ -\x84\x07\xfe\x0c\x5e\x7c\x8a\xde\x52\xca\x13\x7f\x06\x82\x2f\x2f\ -\x7a\x03\xac\x21\x7e\x5c\xa1\x5b\x6e\xd5\x27\x0a\xf8\x47\x8c\x61\ -\x51\xfa\x86\xde\x86\x01\x4d\xae\x60\x10\x69\x43\x0c\xb4\x24\xb6\ -\x14\x29\x0f\xad\xa0\x8e\x2d\xd0\x08\x42\xe3\x7f\x18\x46\xd2\xa2\ -\xb7\xae\x87\xa7\xa9\x72\xaf\x30\x07\x14\xfd\x4b\xa1\x49\x9b\xf6\ -\x32\xc2\x90\x41\xa4\x33\x85\x9d\x4c\xc1\x8b\x80\xfe\xf9\x1c\x58\ -\x90\x17\x2d\xa2\x37\x79\x43\xc2\xc8\x38\x52\x52\xc2\xbd\x74\xaa\ -\x61\x9f\x86\x36\x5b\x8a\x36\x8a\x90\x3e\x65\x10\xe9\x8c\xa2\xec\ -\x60\x38\x17\xd8\x31\x83\x83\x7c\x4a\xa3\xe8\x77\xd0\x07\xd3\xb1\ -\x8b\x7e\xec\x8a\x61\x1c\x96\x47\xc4\x0e\x3a\x04\x7b\x9f\xb0\x73\ -\x43\xda\x84\x08\x6d\x19\x41\x69\x6c\xae\x64\x10\x89\xc8\x60\x74\ -\x06\x9c\x99\xc4\x81\xc9\x60\x34\x82\xad\xc4\x1b\xb7\x73\x23\xa5\ -\x81\xd1\xc3\xd3\xa1\x50\x9f\x31\x24\xe5\x82\xd1\x18\x42\x34\x22\ -\x87\x89\xb4\x5c\x30\x1a\x44\x28\x4c\x64\x10\x69\xb9\x60\x74\x6c\ -\x01\x6a\x53\x6e\x51\x4b\x17\x1f\xa2\xdd\x19\x28\xe5\xc6\x08\x52\ -\x98\xc2\x9c\x06\xee\x45\x02\x39\xa0\x20\x6e\x7e\xd2\x4b\xe2\x9b\ -\x51\xa4\x65\x83\xd1\x39\x9a\xf3\xe4\x0c\xc7\x14\xd4\x34\x30\xba\ -\x2e\x0a\xb4\x85\x8c\x23\x61\xa6\xb4\xeb\x2a\x6f\xf6\x64\xc8\xb2\ -\xa3\xd8\x22\x8c\x96\xfa\x64\xe0\x28\xec\x9e\x21\x7c\x7b\xe1\x26\ -\x38\x92\x27\x27\x7c\xd1\x38\x3a\xe5\x51\xc6\x71\x58\xc6\xb7\x97\ -\xed\x6a\xec\xc7\xd0\x32\xbe\xd8\x02\x6f\x50\x1a\x79\xf0\x0c\x39\ -\xe3\x8b\xce\x73\x33\x5f\x38\x94\x77\x83\x67\x0b\x23\xe1\xe7\x2b\ -\x72\x9e\xdf\xae\xa7\x7a\x11\x20\xb8\x5e\xe7\xaf\x1f\x27\x82\x39\ -\xe3\x8b\x1e\xa3\x27\x21\x8e\x82\x12\xc3\x51\x4b\xa1\x61\x7c\xd1\ -\x33\x2c\x6b\x9d\x79\x0a\x21\x6d\x6b\x9a\x11\x43\x58\x10\xbe\xd8\ -\xec\x5a\x1e\xd1\x33\x7e\xc3\xed\xfb\x45\x4b\x21\xa4\x48\x9b\xea\ -\x52\x46\x91\x26\x3e\xc4\xe6\xd9\x9a\xf1\xcd\x0c\xe3\x50\xb4\x2f\ -\x96\xf5\x85\x7d\x1a\xb7\xc8\xc3\x39\x8c\x21\x09\xeb\x8b\x76\x4c\ -\x21\x41\x64\x10\x69\x49\x5f\x2c\xe1\x24\xdb\xad\x4b\x39\xac\x20\ -\x1e\x58\x82\xd6\xa5\xa0\x18\x32\x90\x84\xd9\x52\x6c\x68\x01\xa6\ -\x69\xd8\xa5\xa1\xcd\x95\x76\xab\x49\x19\x3d\x5a\x12\x18\x4b\x57\ -\x34\x7e\x0b\x87\xf8\x03\x92\xc0\xd8\x84\x77\x83\x18\xc3\x38\x28\ -\x07\x8c\x05\xb2\xe1\xed\x4f\x95\xaa\x5d\xee\xdf\x66\x20\x49\x38\ -\xe0\x7e\xa4\xb1\xf6\x57\x19\x44\x22\x0e\x18\xdb\x12\xe3\x5b\xc8\ -\x9c\x8e\xb8\x95\xb7\x69\x01\x8d\x1e\x1b\x34\x7c\x3b\x76\xa6\x82\ -\x3b\x18\x33\x0b\x36\x63\xe7\xa6\xfa\x84\x03\x67\x5c\x28\x52\x44\ -\x0f\xd4\xe3\xa1\x41\x94\x3e\xaa\x07\x7b\xa8\x97\x89\xa2\x12\xed\ -\x92\x0c\x46\x90\x6e\x13\x3e\x7e\x5c\x10\x24\x85\x52\x84\x9e\x0c\ -\x3d\x22\xf6\x62\xc4\x18\x16\x35\x19\xe0\x36\x7c\x9c\x14\x32\x82\ -\xa4\x55\x19\x11\xb8\xe7\xa9\x03\x9f\x86\x07\x77\x11\xe7\x6c\x3a\ -\x90\x45\x70\x1a\x22\x03\x49\x59\x99\xe1\xf4\x33\x5f\x36\x12\xca\ -\xd5\x0f\x8f\x51\xec\x5f\x1c\xf3\x1d\xf9\x78\x18\x21\x61\x64\x18\ -\xe9\xf9\x7d\xf4\xac\x60\x58\xad\x72\xcc\x4f\x98\x0a\xc7\x4f\xd1\ -\x83\xd3\x6f\x94\xb6\x71\xd4\xe9\xb7\x28\x0f\x37\x6c\x28\x13\xde\ -\xc1\xac\x60\x8e\xfc\x49\x73\x37\xca\x0a\xf0\xd3\x49\xa1\x61\xc1\ -\x8c\x23\x6d\xec\xd8\xc5\xf0\x6e\x70\x5c\x30\xc7\x1c\xc4\xc1\xa3\ -\x82\xeb\x89\x3b\x30\x91\xa1\x30\x17\x52\x75\x6c\x1f\x31\x94\xc6\ -\xcf\x31\x59\x00\x34\xd1\xa8\x84\x92\x5a\xb5\xb2\x44\x0e\x49\xfa\ -\x1b\x99\xec\x25\x2f\xc7\xf2\x48\xeb\xeb\x78\xda\x6b\x45\x3b\x3b\ -\xa0\xd7\x4a\x3b\xc2\x7b\xc4\x48\x16\xde\x4e\x2e\x9a\xbd\xe8\x56\ -\x47\x48\x4f\x3f\x88\x0a\xaa\x46\x0c\x64\x53\xde\x18\xf6\xe4\xb8\ -\x32\x94\xd4\xb5\x71\x2e\x9e\x48\xe6\xca\xaa\x41\x91\x04\x94\xaa\ -\x7a\x86\x9c\xf6\x65\xa4\xab\x42\x2f\x50\x67\xd0\xb9\x50\x63\x06\ -\x25\x7c\x37\xf0\x25\x89\x8b\x33\x6e\xe8\xac\x10\x48\xc8\xbd\x1a\ -\x3c\xb0\xba\x98\xc1\x23\xab\xc2\x01\x22\xc5\x57\x63\xe7\xc1\xad\ -\x6a\x43\x19\xd9\x24\xcd\xc1\x46\x0d\x9d\x29\xbe\x01\xfc\x97\x57\ -\x83\x17\x56\xdb\x30\x18\xbc\x61\xf6\x7d\x03\x01\xe1\x6b\xc1\x53\ -\x12\x1e\x98\xc0\x5a\x93\x92\x17\xc6\x98\xbd\x08\xea\x8e\xc9\x00\ -\x12\x6e\x37\x45\x18\x3e\x65\x03\xb3\x9f\x58\x77\x92\x6e\x33\x05\ -\xb8\xfc\x57\xc3\xe7\x40\x3e\x27\xc3\x47\xe4\x72\x62\xd4\x26\x18\ -\xea\x05\x22\x0a\xed\xc8\x65\xb5\x49\x20\x79\x98\x70\xe1\x85\x6d\ -\xdd\x0c\x1e\x91\xcd\x0b\x30\x92\x07\xc5\x7a\xda\x0d\xf5\x1d\x83\ -\x1e\x83\x47\x60\xf3\x00\x2a\x10\x15\xec\x31\x7a\x74\x59\x16\x44\ -\xac\x07\x67\x59\x7c\x21\x3d\x45\x33\x10\x61\xd4\xd0\xb9\x38\x57\ -\x13\xce\xb2\x30\x78\x74\x9c\xad\x8f\xc9\x91\x81\x1e\x4b\x24\xb4\ -\xd2\xf4\x14\x93\x42\x24\x69\x96\xee\xb3\x2c\x8c\x1f\xdd\x5e\x26\ -\x8c\xcf\x02\x0a\x9f\x2b\x1c\xad\x39\x19\xbb\xfe\x65\x0f\xdc\x5c\ -\x8f\x93\x3c\x06\x8f\x8e\x5d\x00\x36\x2c\xe1\xd8\x05\x0e\xd4\x69\ -\xd9\x05\x4c\xa6\x05\x94\x3e\x06\x90\xac\x08\xbb\xf3\x14\x27\xfb\ -\x2c\x84\x25\x65\x9d\x13\xb3\x8c\x1e\x21\xaf\x87\x70\x39\x61\x5e\ -\x8f\xa3\x75\x4a\x5e\xcf\x46\x54\x02\xc2\xc4\x1e\xe3\x47\x55\xc3\ -\x89\xb2\x7b\x60\x9a\x33\x14\xa1\x56\x9c\x0e\xfb\x2c\x04\xc2\x17\ -\x40\x9b\xff\x70\x89\x4e\x86\x8f\xae\x8e\x13\x15\xae\xff\x5a\xc7\ -\x6d\xe6\x87\x28\x48\x06\x70\xe2\x32\x36\xe0\x63\xfc\xe8\xaa\x39\ -\x31\xc6\x0f\x76\x5c\x58\x7b\x12\xd7\x73\x76\x1f\x3b\x30\x84\x94\ -\x15\x9d\xd0\xd6\x4c\x6c\xd2\x93\x55\x28\x65\x51\x27\x4a\x89\xba\ -\x90\x0b\x4a\x89\xa0\x79\xf5\x88\x07\x15\x14\xfb\x6a\x01\x37\x06\ -\x37\xa2\x97\x87\x11\x92\x76\x2d\xf4\xd0\xb3\x5d\x5b\x00\x36\x53\ -\x60\x18\xc0\xfe\xfd\x50\xb0\x5c\xa9\x83\x29\x5a\x06\x54\xc6\x8f\ -\xa8\xdf\x24\x7a\x4a\x76\x5b\x87\x32\x7a\x34\xd4\x11\xd8\xd3\xae\ -\x03\xe9\x63\x1b\x48\x3b\x88\x10\x2d\x80\xe0\x3c\x57\xbb\xa2\x76\ -\x19\x45\x9a\x49\x84\x68\x57\xa6\xbd\xc3\x8f\xf1\x23\x9c\x5c\xd7\ -\xed\x30\xd7\xa0\x48\x91\x52\xa1\x37\xea\xb6\x3c\xe5\x58\x10\x74\ -\xa3\x5e\x25\x3c\x3b\xb2\xa3\x33\x21\xf4\x84\x0a\xc3\x90\x5b\xd7\ -\xd1\x44\x83\x21\xba\xf3\xb9\x36\x85\x91\xef\xf8\x8e\xd7\x72\x48\ -\xfd\x50\xba\x21\x51\x97\xde\x11\xab\xd2\x7c\x66\x9d\xc2\x4f\x01\ -\xe5\xa0\x7e\x50\x6d\xea\xe1\x87\x63\x43\x2e\xa9\x2f\xdc\x7c\xad\ -\x88\x26\x10\x8c\x18\xc6\xa2\x7f\x24\xb8\x8b\x13\x17\xda\xb3\x53\ -\x4a\x9c\xe0\x0e\xf1\x61\x05\x18\xe3\x33\x90\x94\x33\x96\xc0\x49\ -\x59\x17\xa1\xd8\x0c\x32\x3f\x41\xd1\x2b\xe6\x29\x3b\x24\x7d\x44\ -\x46\x8d\x62\xe1\x9f\xfa\x78\x61\x8c\x84\x2a\x4c\x20\xc3\x38\x18\ -\x67\x01\x16\xdd\xe3\xc7\xd4\xb3\x97\x4a\x4e\x5d\xd8\x78\x47\x15\ -\xb2\x8e\x8c\x24\x2d\x8d\xe1\xe3\x1d\x55\xb0\xa6\x94\x9d\x1c\x52\ -\x22\x23\xc0\x53\x89\x67\xee\x0d\xc7\x8b\xd4\x14\x86\xc2\x3b\x38\ -\xa1\x90\xcf\xf4\x29\x03\x49\xcb\x65\x80\xe5\xf9\x97\x85\x1b\xad\ -\x21\xd9\x8e\xe0\xe4\x69\xef\x4a\x34\x9f\xf9\xc1\xc5\x18\x6f\x0f\ -\xb9\x3c\xed\xdd\x41\x31\x22\xd7\x42\x0d\x95\xa4\x31\xf9\xd2\x08\ -\x1f\x16\x72\x21\xc6\xf0\xe4\x45\x07\x72\xc8\x85\x18\x03\xb2\x16\ -\x6e\x3f\x31\x3d\x57\xb5\x51\x53\x17\x1e\x5e\x10\x5f\xe8\xca\xc5\ -\x40\x12\x52\x17\xe0\x0c\x3a\xce\xb1\xbd\x1d\x18\xcb\xda\x1a\xbf\ -\x1f\x71\x24\xc5\x71\xd4\xbb\xd6\x0a\xf2\xc2\xc7\x7b\xa9\x10\x07\ -\xc5\x61\x06\x25\x6f\x01\xee\xdf\xee\xc0\x34\x32\x88\x34\x29\x36\ -\xd5\x7d\x9e\x86\xd2\xab\x19\xb5\x1a\x2d\x28\x27\x1b\x6f\x0d\x41\ -\x35\xca\xce\x29\x29\xe5\xd4\x41\x45\x06\x44\x58\x70\xcc\x4f\xce\ -\x3c\x81\x7d\x2c\xf1\x25\x52\x8c\x24\x2d\xf5\x24\xd1\xee\x29\x08\ -\x23\xf1\x7e\x9a\x11\xc3\x58\x8f\xb9\x8e\x98\x8b\x7a\x8b\xf8\x39\ -\xe8\xf4\x69\x13\xd1\x9f\x60\xa7\x9c\xaa\xe9\x17\x03\xd8\xbb\x00\ -\x82\x13\xe6\x2f\x13\x3d\x1b\x68\xec\xcc\x18\xd2\x39\xa7\xf8\x5a\ -\xa8\x48\xf8\xf9\x92\x9c\xd5\x61\xa8\x40\x04\x46\x36\xb9\xc3\x10\ -\x89\x63\xea\x41\x5d\x4a\x2f\x13\x44\x59\x01\xc6\x28\x0e\x35\x94\ -\x09\x9f\x31\x05\xb5\xa9\x27\x7c\xc6\x8f\x84\x4b\xb4\xf1\x6d\x86\ -\x5a\xae\x28\x83\x47\x44\x58\x80\x6d\x2e\xf1\xec\x21\xbb\x32\xc4\ -\x9c\x85\xea\xbc\xd5\x1e\x43\x48\x98\x99\xb1\xd1\x36\x10\x8e\x0a\ -\x59\x8d\xd2\x64\x64\x3a\xe8\x2e\x04\xaa\x51\x32\xfc\x46\xdc\xdb\ -\x24\xca\x7b\xcd\x02\xea\xf3\xa2\xce\x26\x60\x5a\x54\xe3\xa7\x5c\ -\xfd\x60\x10\x29\xcc\xa0\x07\xd7\x96\x5e\x06\xa3\x23\x64\xe0\x05\ -\x5e\x5b\x8d\x32\x8c\x64\xb5\x50\xb6\x89\x09\x91\x30\xea\x88\xd0\ -\x0e\xdd\xd0\x6d\xe7\xd7\x22\xd7\x0e\x68\x1a\xb0\x8f\x1a\xc6\x28\ -\xaf\xf4\x06\x39\xfc\xcb\x60\x74\x85\xab\x51\x0c\xdb\x46\x91\xa5\ -\x91\x50\xa9\x9a\x20\x11\xdd\xbc\x2d\x10\x8e\xd6\xaa\x01\x5b\xc7\ -\x01\xd3\x34\x65\x77\x05\x2c\x94\xa1\x08\xa5\x92\x4a\xb1\x6a\x1d\ -\x90\xff\xb5\xc0\xdd\x50\x97\xb9\x3a\x52\x04\xca\x20\x39\x20\x90\ -\x23\x0e\x1b\x23\x07\x9e\xaa\x7d\x51\xd4\xd8\xd4\x5d\x70\xe6\x66\ -\xa8\x8d\xa5\xf8\x6e\x7c\x30\x8a\x4c\x42\xd1\x76\xe3\x73\xd0\x39\ -\x1c\x98\x12\xe6\x1c\x1c\x9d\x83\xd3\x41\xd9\x30\x48\x08\x33\x86\ -\x34\x74\x94\xaf\xff\xef\xa5\xb7\x29\xdb\x44\xf2\x4d\x34\x5d\xec\ -\x4c\x04\x85\x91\xa1\x24\x2c\x19\x06\x7b\x7e\x77\xe0\xdd\xb0\x46\ -\xa5\x8a\x15\x15\xbe\x3a\x03\xd4\xa8\x8c\x20\x59\xb4\xef\x99\x26\ -\x7c\x6f\xdb\x39\x1d\x71\xca\xa6\x20\x18\x15\x54\xab\xd8\x41\x12\ -\x95\x33\x6f\xc4\x14\x63\x07\x24\x23\xc8\x15\x33\x90\xc4\xec\x54\ -\x00\x05\xfc\x97\x49\xa4\x14\x9e\x13\x39\x11\xe7\xc2\x07\xe6\xa7\ -\xc0\x0d\xfb\x1d\x50\x8d\x94\x50\x8e\x7a\xd7\x77\x64\x05\xa8\x89\ -\xeb\xda\x45\x05\xd3\x36\x91\xed\x06\x24\x1e\xce\xa8\xd1\x33\x82\ -\xa8\x30\x03\xd7\xa5\x0f\xec\xf2\x66\xf8\x28\x77\x61\x44\x98\x71\ -\xeb\x70\xf5\xa2\x2b\xec\xc0\x97\x34\xe3\xd9\x46\x0d\x60\x91\xfe\ -\x06\x63\xc4\x57\x23\x18\x14\x53\x2e\x5c\x46\x70\x98\x54\x1b\xe8\ -\x8d\xbe\x1a\x3d\x55\x94\x7f\x33\x7a\x83\xa5\x69\x42\x28\xbe\x7f\ -\x35\x7e\x11\xe4\xbe\xb4\xf0\xbb\x9a\xdd\x7e\x7a\x77\x35\x3b\x7c\ -\xd1\x7f\xfd\x1f\xc3\xde\xb3\xe7\ -\x00\x00\x08\xd9\ -\x00\ -\x00\x28\xf8\x78\x9c\xe5\x5a\xd9\x6e\xdb\x48\x16\x7d\xf7\x57\xd4\ -\x28\x2f\x33\x18\xb1\x54\xfb\xa2\xc8\xee\x87\x34\x1a\x68\xa0\xe7\ -\x65\xba\x07\xf3\x18\xd0\x24\x6d\x73\x42\x91\x02\x49\x79\xc9\xd7\ -\xf7\x29\x6e\x92\x6c\x39\xf0\xc4\x71\x3a\x89\x69\x18\x22\xef\x52\ -\x75\xeb\xd4\xb9\xf7\x16\x65\xaf\x7e\xba\x5d\x17\xe4\x3a\xab\x9b\ -\xbc\x2a\x4f\x67\x9c\xb2\x19\xc9\xca\xa4\x4a\xf3\xf2\xf2\x74\xf6\ -\x9f\x3f\x7e\x89\xdc\x8c\x34\x6d\x5c\xa6\x71\x51\x95\xd9\xe9\xac\ -\xac\x66\x3f\x9d\x9d\xac\xfe\x16\x45\xe4\x5d\x9d\xc5\x6d\x96\x92\ -\x9b\xbc\xbd\x22\xbf\x96\x1f\x9a\x24\xde\x64\xe4\xef\x57\x6d\xbb\ -\x59\x2e\x16\x37\x37\x37\x34\x1f\x84\xb4\xaa\x2f\x17\xff\x20\x51\ -\x74\x76\x72\xb2\x6a\xae\x2f\x4f\x08\x21\x98\xb7\x6c\x96\x69\x72\ -\x3a\x1b\x1c\x36\xdb\xba\xe8\x0c\xd3\x64\x91\x15\xd9\x3a\x2b\xdb\ -\x66\xc1\x29\x5f\xcc\x76\xe6\xc9\xce\x3c\x09\xb3\xe7\xd7\x59\x52\ -\xad\xd7\x55\xd9\x74\x9e\x65\xf3\x66\xcf\xb8\x4e\x2f\x26\xeb\x10\ -\xcd\x8d\xec\x8c\xb8\xf7\x7e\xc1\xc4\x42\x88\x08\x16\x51\x73\x57\ -\xb6\xf1\x6d\x74\xe8\x8a\x18\x8f\xb9\x0a\xc6\xd8\x02\xba\x9d\xe5\ -\xd3\xac\x96\x0d\x00\xdd\xe0\x77\x32\x1f\x05\xb4\xa9\xb6\x75\x92\ -\x5d\xc0\x2f\xa3\x65\xd6\x2e\x7e\xfe\xe3\xe7\x49\x19\x31\x9a\xb6\ -\xe9\xde\x30\x23\x9e\x07\xb3\x1e\x80\x5c\xc6\xeb\xac\xd9\xc4\x49\ -\xd6\x2c\x46\x79\xe7\x7f\x93\xa7\xed\xd5\xe9\x4c\x2a\xca\x25\x2e\ -\xdd\x09\xaf\xb2\xfc\xf2\xaa\xbd\x2f\xcd\xd3\xd3\x19\xa2\x17\xde\ -\xf5\xcf\x7b\xe4\xe0\xbd\xc1\x30\xf0\x72\xd2\x30\xea\x05\xe5\xa4\ -\xe6\x5a\xda\xde\x66\x5c\xc2\x32\xad\x92\x10\x13\x86\xcc\xd6\x79\ -\xbc\x6d\xab\x35\x76\x2d\x49\x8a\xb8\x69\xf2\x8b\x3c\xc1\x43\x55\ -\x6e\x8a\xed\x65\x5e\xbe\xff\xed\xdd\xef\xef\xdb\xab\x3a\x6b\xae\ -\xaa\x22\x7d\xdf\x56\x55\x41\x47\x14\xa7\x29\xb3\xdb\x4d\x55\xb7\ -\xd1\x6d\xba\x01\x96\xc6\x1e\x55\xde\x8d\xca\x33\x68\x57\x69\x76\ -\xd1\x04\xab\x7e\x61\xe1\x09\x2b\xb3\x33\xb2\xe8\xb4\x53\x9c\x21\ -\xc8\xf4\x3a\xcf\x6e\x76\xb6\xe7\x71\xd3\x83\x47\xc8\x26\xbe\x04\ -\xd1\x8a\xaa\x3e\x9d\xbd\xb9\xe8\xae\x41\x71\x5e\xd5\x69\x56\x8f\ -\x2a\xd3\x5d\x07\xaa\x0a\x9b\x91\xb7\x77\x7d\x6a\x0d\x63\x8f\xf1\ -\x86\x51\x27\x3d\x3b\xae\x6f\xae\xe2\xb4\xba\x39\x9d\x89\xfb\xca\ -\x8f\x55\xb5\x3e\x9d\x69\xaa\xbd\xf3\x8c\xdf\xd7\x26\xb7\xa7\xb3\ -\x48\x7b\xea\xbc\x12\xd6\x3e\xd0\x62\x3e\xa1\xa9\xf2\x4e\xf0\x87\ -\xca\x6d\x5d\x23\xf7\xa2\x22\xbe\xcb\xb0\xa8\xee\x63\x1c\x1f\x5b\ -\x73\x73\x59\x07\x70\xda\x7a\x9b\xdd\xf7\x0c\x9a\xe8\xfc\xbc\xba\ -\x3d\xae\x06\x15\xb6\x21\xab\xa3\x6d\x99\xb7\xc8\x9c\xcd\xed\xfe\ -\xa8\xdb\x3c\xcd\x9a\xe3\x8e\x4d\x19\x6f\xa2\xcb\xa2\x3a\x8f\x8b\ -\xe3\x06\x37\x79\x09\x90\xa2\x81\xe4\x5c\x4e\x7b\x70\xdf\x62\x64\ -\xbc\x65\xee\x11\x0b\xc4\xfe\x60\x1f\x06\xd5\xdd\xe3\xaa\x75\x7c\ -\x9b\xaf\xf3\x8f\x19\x80\x79\xb0\x15\xdd\xca\xf6\x61\x39\xeb\x0c\ -\x56\x07\xb0\xf5\x3e\x84\xb4\x77\x21\xbb\x6f\xef\x82\x6c\x36\x0a\ -\x03\xde\x41\x20\xbc\xb7\x93\xb0\xaa\x73\x24\xcd\x5e\xb8\xa3\xe8\ -\x6e\x5f\x14\x6a\x01\x4a\xf9\x6d\xc7\xbf\x8e\x9d\xf6\xbe\xee\x6e\ -\x5f\x37\xa4\xc5\xe2\x61\x5e\x74\xf2\x75\xd6\xc6\x69\xdc\xc6\xbb\ -\x24\x19\x25\x88\x8d\x8d\x2b\x43\x59\x5d\xfe\xfb\xe7\x5f\xce\x86\ -\x89\x56\x49\xb2\xfc\x6f\x55\x7f\x18\xe7\x25\x24\x18\xc4\xe7\xd5\ -\x16\x3b\x31\x3b\x9b\xc4\xab\x34\x59\xa2\x10\xa2\x40\x9c\xe5\x6b\ -\x50\x3f\xd4\xd0\x7f\xa2\xf0\xad\x16\x3b\xc5\x81\x71\x00\x6b\x37\ -\x68\x3f\x2c\xca\x47\x57\x51\x8f\xb6\x95\x34\x59\xe7\xc1\x69\xf1\ -\x7b\x9b\x17\xc5\xaf\x61\x92\x61\xc5\x7b\x83\xe6\x6d\x91\xed\x84\ -\xab\xc5\x10\xfd\xb0\xb6\xc5\xde\xe2\x56\x8b\x71\xf5\xdd\xd3\xe5\ -\x0e\x95\x83\xa4\x99\x36\xba\x88\xcf\x33\x30\xf8\xb7\xa0\x24\x0f\ -\x79\x52\x57\xdb\xcd\xba\x4a\xb3\xc1\x7d\x42\x33\x4b\xda\x69\xcb\ -\xda\xbb\x02\xfa\xae\xde\x2c\xdf\xb0\xee\x7a\x9b\xe6\xcd\x06\x1e\ -\xe8\x0e\x45\x5e\x66\x6f\x2b\x94\xe5\x8b\xa2\xba\x59\x5e\xe7\x4d\ -\x7e\x5e\x64\x6f\xbb\xcf\xbc\xc0\xca\x27\xd1\x05\x96\xbf\x1c\x2a\ -\x59\xf7\x10\x0d\x75\x68\xc9\xfb\xc7\x7a\x5b\x64\xcb\xb2\x2a\x3f\ -\xa2\x82\xbd\x6d\xda\xba\xfa\x90\x2d\xdf\xa4\xe7\x81\x24\xc3\x63\ -\x9f\x6d\xcb\x89\x3a\x62\x94\x87\x20\xb0\xa0\xe5\xf9\xb6\x6d\xf7\ -\x65\xff\xab\xf2\x72\x09\xfc\xb3\x7a\x94\x76\x0f\x05\x12\xa7\x5d\ -\xaa\x51\x96\xc6\xa8\x78\x75\x8d\xe5\x60\xf6\x6c\x5f\x5a\x5d\x5c\ -\x34\x59\xbb\x64\xa3\x6c\x17\xf1\x3a\xae\x3f\x64\x75\xef\x90\x95\ -\x31\x16\x18\x9d\xc7\xc9\x87\x00\x68\x99\x2e\xe3\x04\x65\x67\x5b\ -\xe0\xa8\x72\x90\x50\x01\x56\xe9\xb8\x9e\x84\x63\x8b\xb4\x34\xf4\ -\x42\x29\x26\xc5\xd4\x26\x1f\x68\x0e\xb2\x0f\x79\x14\x49\xba\x53\ -\xd6\x10\x48\x2a\xd1\x13\x8d\x77\x13\xcd\x56\x9b\xb8\xbd\xba\xb7\ -\x9d\xfd\x6e\x88\xf8\xe2\x42\xc4\xf7\x77\x63\xc4\x3e\xec\x34\x4f\ -\x0e\xb1\x67\x2f\x09\xf9\x14\xc2\xb4\x20\x80\xf6\x2f\xa2\x38\x35\ -\xca\x70\x35\xe7\x8a\x7a\xaf\x99\xd3\xe4\x1d\x01\x32\xca\x72\xe6\ -\xed\x5c\x30\x2a\x85\x36\xda\x11\x61\xa9\x55\xde\x58\x37\xe7\x96\ -\x32\xaf\x5d\x90\xf1\x1e\x41\xd9\x79\x77\x77\x04\x5a\x6f\x24\x2a\ -\xdb\x9c\x4b\x6a\xbd\xb5\x1a\x32\x43\xa5\x71\x5a\xdb\xb9\xa3\xd6\ -\x72\xc5\x0c\x64\x82\x3a\x21\xb9\x13\x90\x69\x26\xb4\xe2\xc4\x51\ -\xe9\x98\x93\x5e\x43\xc4\x0d\x66\x95\x8e\x28\xea\xd0\xf3\xd0\x11\ -\xc3\xb4\x5c\x39\xe6\x1d\xe9\x38\x6a\xd1\x27\xc3\xb4\xce\x30\xce\ -\x38\x89\x04\x3a\xa7\x12\xcc\xc3\x50\x50\x63\x9c\xb3\x96\x44\x9c\ -\x7a\xf8\x08\x26\xe7\x3a\xf8\x08\x2d\x14\xbc\x39\x97\x4c\x33\x2c\ -\x0e\x32\xc6\x9d\xd2\x04\x6d\x57\x38\xe3\xb5\x9e\x63\x1c\x29\xd0\ -\x70\x60\x27\x31\x0c\x33\x4e\xcd\x71\x1c\xf2\x4e\x39\xab\x2c\xe1\ -\x1e\x0b\xf0\x1a\x21\xe2\x80\x24\xac\x91\x5a\x10\x29\xa9\x36\x58\ -\x15\x9f\x2b\x8a\x4f\xcf\x6c\x27\x52\xce\x58\x33\x8f\x02\xbe\x12\ -\x9b\xad\x89\x74\x54\x75\x50\xc3\xb5\x43\xda\x93\x84\x48\x0a\x11\ -\x7e\x20\xb4\x5c\x38\xe1\x1c\x82\xf1\x9c\x3b\xa9\xe7\x1e\xe8\x5a\ -\x84\xc0\x61\x25\xc2\xb2\xac\x0f\x17\x27\x1f\x0f\x98\x1f\x18\x28\ -\x61\x1f\xed\xb8\xbb\x6b\xfe\x55\x09\x2a\xb5\x55\x1d\xe1\x18\x70\ -\x1d\xb7\xdb\x3a\x3b\x68\x27\x53\x5b\x40\x9d\x0a\x95\x14\x1d\x3b\ -\x0e\x57\xd3\xc4\x4f\xa1\x78\x12\x33\x91\x3c\x4e\x71\x25\xbf\x09\ -\x8a\x33\xaa\x7b\x96\x7a\x6a\x02\xbb\xc1\x46\xed\x84\xef\x49\xcb\ -\xb4\x95\x44\x18\x6a\xc0\x50\x0b\xf2\x70\x6a\x19\xb3\x41\xc6\xa8\ -\x10\x4c\x0b\x0b\x37\x30\x51\x28\xab\x03\x91\x9d\xe6\xdc\x83\xa0\ -\x8a\x09\x90\x10\x34\xd1\x54\x80\xd9\x7a\x8e\xda\x00\x3e\x08\xce\ -\x49\x18\x83\x33\xd9\xc9\x38\xb3\x4a\x23\x55\x2c\x15\xc6\x31\x29\ -\xba\x8d\xb6\x4c\x23\x1d\xb0\xab\xd6\x82\xa9\xd2\x77\xb3\x6a\xc9\ -\xb8\x24\x78\x47\x60\xca\x84\x08\x30\xad\x32\x9a\x21\x11\x08\xea\ -\x90\x65\x96\x71\xed\xe6\x18\xc7\x4a\xeb\xb9\x0b\x42\x06\x06\x0a\ -\x04\x1d\x85\x2c\x75\x0e\xbf\x9a\x08\x90\x0c\x19\x61\x6c\x16\xa9\ -\x39\x6c\xa4\x44\xf6\x80\x92\x8a\x2a\xf8\x23\x67\x22\x24\x32\x07\ -\x99\xbd\x08\x39\xa8\x95\x45\xa6\xcc\x23\x45\xa5\x37\xda\x5b\x64\ -\x97\xa3\xa1\xfe\x3b\x17\xbc\x05\x96\xa8\x99\x24\x12\xc3\x6a\x85\ -\x57\x8a\x30\x97\x45\xde\x5a\xa7\x4d\x27\x05\x94\x36\x8c\xc9\x42\ -\xee\x06\xaa\xda\xb1\x26\x04\xf7\x63\x0c\x37\x7e\xa4\xb8\x99\x28\ -\xee\x46\x8a\xbb\x47\xc8\xfd\xf5\xa9\xed\x7c\xcc\x3e\x55\xbd\x19\ -\xfb\xab\xa9\xbd\x26\xa1\xd2\xe1\xd2\x66\x8e\x5d\xe3\x7d\x01\x4e\ -\x20\x15\xd8\x6a\xcb\x7c\xa8\x66\xd8\x52\x8e\x9a\x69\xc2\x8d\xee\ -\xb6\x1a\x75\x4d\x70\x83\x32\xc2\x59\xef\x6e\x55\xbf\x57\x9a\x1a\ -\x6f\x98\xf2\x28\x78\x46\x63\xab\x38\xf1\xe0\x36\x0b\xc5\x17\x37\ -\x1e\xd9\x0c\xba\x0f\x85\x5e\x85\xb2\xdd\xdd\x84\x8c\x92\xc1\x0e\ -\x8e\xa2\xab\x51\x42\x81\x30\x8a\xe2\x43\x86\xc6\x82\xf2\xe9\xc0\ -\x7d\x13\x0a\xa0\x1f\xda\x45\xd8\x68\x05\x16\x30\x8d\x3a\x39\xe7\ -\xe1\xdd\x45\x6b\x98\x40\x86\xd0\x15\x22\x12\xa8\xb4\x20\xae\xf4\ -\xc8\xdf\xb9\xd4\x1d\x95\xc0\x52\xe1\xa5\x33\x02\x95\x16\xac\x0c\ -\xeb\x8a\x10\x90\x46\x7a\xa2\x9c\xa3\xfa\x1a\xcf\x3c\x72\xa8\xa7\ -\x30\x16\x36\x67\x68\x0c\x88\x49\x63\x78\x21\x00\x87\xa6\xc8\x12\ -\xe9\x3a\xa3\x2e\x23\xac\x92\xc1\x13\xdc\x86\xd1\x9e\xa7\x0a\xae\ -\x32\xe0\x60\x25\x1a\x51\x00\xc8\x23\x7d\x91\x34\x21\xa7\x7c\x07\ -\x2f\xa4\x21\x83\xd0\xbc\x90\xf4\x0c\x0f\xb6\x3f\x3c\xd9\xe3\x1c\ -\x96\x91\xfb\xda\x2c\x66\x88\xc7\x7d\x92\xc5\x38\x2f\xfe\xe5\x2c\ -\x9e\xce\x9c\x73\xa1\x86\x52\xbd\x63\x31\xe7\x47\x58\x2c\x8f\xb0\ -\xd8\xc8\xe7\xb2\x18\xad\xba\x67\xb1\x47\x83\xee\x59\x2c\x42\xf7\ -\xee\x58\x8c\xb2\x36\xb0\x78\x2a\x70\x38\x0c\x08\xa2\x50\x39\x7b\ -\x16\xe3\x34\xe4\x06\x16\xa3\xfd\xf7\x2c\x46\xaf\xe1\x3d\x8b\x43\ -\xf7\x9f\x87\xd3\xd6\x73\x79\x0c\x8b\x89\xc7\x6e\x8f\xc6\xfc\x08\ -\x8d\x81\xc9\x3e\x8d\x8f\xb0\x98\xeb\xff\x93\xc4\x5f\x9b\xc2\x3c\ -\x11\x4a\x88\x1d\x67\xd3\xf0\x73\xc8\x59\x89\x33\x22\x9a\x31\x3a\ -\xe9\xf3\xc8\x1b\x76\x1d\x97\xe3\x9f\x75\xcc\xd8\x63\x31\xda\x62\ -\xe0\x13\x3a\x5a\x77\xfb\xe0\xe6\x21\xb0\xd6\x8a\x88\x45\xe2\xc9\ -\xe0\xfe\x30\xb8\xed\x67\xff\x8e\x7a\x21\xfb\xf9\x90\x65\xec\xb1\ -\xfb\xc7\x50\xe4\xaf\x1c\x45\x9c\x25\x77\x35\xf4\xb3\x51\x7c\x7a\ -\xa2\xff\x30\x28\xee\xe7\xb0\x99\x52\xd8\x0c\x89\xbb\xf7\xf9\x18\ -\x66\xea\xf5\x61\x76\xc0\xbc\xf1\xee\x79\xcc\xf3\x2f\x88\xe2\x91\ -\x73\xfb\xb7\x81\xa2\x1e\x0e\x15\x72\x3e\xfe\xf5\x26\xe4\x2f\x0b\ -\x2f\x66\xa2\x03\xf5\xb1\xfb\x23\x4d\x5a\x3d\xfd\x8b\x80\x1f\x08\ -\xc1\xf0\x4e\xf1\x45\xc0\x8b\xcc\x6b\x84\x4f\xb8\x2f\x05\xdf\x4b\ -\x9e\x62\xbe\x5d\xf8\xa6\xaf\x42\xbf\x08\x86\xf6\x75\x77\x92\xf0\ -\x65\xf3\xf3\xcf\x30\xaf\x91\x87\xd1\xbd\xd7\x90\x1d\x7e\x6a\x0f\ -\xb3\x7b\xf7\x8f\xbe\x8f\xbc\xe8\x29\xf0\x7b\xc0\xf0\xd8\x2b\xc9\ -\x67\x00\xc9\x5f\xe7\xa1\x26\xfa\xf4\x5b\xc9\x67\x00\x29\x5f\xf4\ -\xed\xee\x7b\x00\x12\xaf\x1f\x5d\x98\xfc\x79\x40\xaa\x17\x7d\x59\ -\xf9\x1e\x80\x1c\xef\xdc\xf3\x80\xf4\xaf\x9e\x91\xc7\x9a\xf5\xe7\ -\xd4\xc8\xa7\xff\x8d\x67\xfc\xaf\x96\xcb\xb3\x93\x55\xf8\xaf\x92\ -\xb3\x93\x3f\x01\x78\x38\x9b\x3d\ -\x00\x00\x06\xa9\ -\x00\ -\x00\x52\x92\x78\x9c\xe5\x9c\x5b\x8f\xa3\x36\x14\xc7\xdf\xe7\x53\ -\x50\xe6\xa5\x55\x65\x30\x97\x84\xcb\x26\xd9\x87\xae\x56\x5a\xa9\ -\x4f\xed\x56\x7d\xac\x1c\xec\x64\xd0\x02\x8e\x80\x4c\x92\xfd\xf4\ -\xb5\x09\x90\x00\xde\xaa\x92\x1d\xc9\x0a\x48\xa3\x15\xe7\x1c\x1b\ -\xf3\xc3\x97\x3f\x07\x6f\x56\x1f\xcf\x79\x66\xbc\x93\xb2\x4a\x69\ -\xb1\x36\x1d\x0b\x9a\x06\x29\x12\x8a\xd3\x62\xbf\x36\xff\xfa\xfa\ -\x19\x84\xa6\x51\xd5\xa8\xc0\x28\xa3\x05\x59\x9b\x05\x35\x3f\x6e\ -\x5e\x56\x3f\x01\x60\xfc\x56\x12\x54\x13\x6c\x9c\xd2\xfa\xcd\xf8\ -\x52\x7c\xab\x12\x74\x20\xc6\xcf\x6f\x75\x7d\x88\x6d\xfb\x74\x3a\ -\x59\x69\x6b\xb4\x68\xb9\xb7\x7f\x31\x00\xd8\xbc\xbc\xac\xaa\xf7\ -\xfd\x8b\x61\x18\xec\xba\x45\x15\xe3\x64\x6d\xb6\x05\x0e\xc7\x32\ -\x6b\x02\x71\x62\x93\x8c\xe4\xa4\xa8\x2b\xdb\xb1\x1c\xdb\xbc\x85\ -\x27\xb7\xf0\x84\x5f\x3d\x7d\x27\x09\xcd\x73\x5a\x54\x4d\xc9\xa2\ -\x7a\xbd\x0b\x2e\xf1\xae\x8f\xe6\xad\x39\x79\x4d\x90\x13\x45\x91\ -\x0d\x5d\xdb\x75\x01\x8b\x00\xd5\xa5\xa8\xd1\x19\x0c\x8b\xb2\x36\ -\x8a\x8a\xba\x10\x42\x9b\xf9\x6e\x91\xff\x2f\x2a\xae\x18\xd0\x03\ -\xfb\xeb\xc3\x3b\x83\x55\xd1\x63\x99\x90\x1d\x2b\x47\xac\x82\xd4\ -\xf6\xa7\xaf\x9f\x7a\x27\x80\x16\xae\xf1\x5d\x35\x1d\xcf\xc1\x55\ -\x07\x90\x0b\x94\x93\xea\x80\x12\x52\xd9\x9d\xbd\x29\x7f\x4a\x71\ -\xfd\xb6\x36\x3d\xdf\x72\x3c\x76\x2c\x1a\xe3\x1b\x49\xf7\x6f\xf5\ -\xd8\x9a\xe2\xb5\xc9\x5a\xef\x46\xe1\xf5\xfc\xae\x73\x38\xd7\x80\ -\xb6\xe2\xb8\xf7\x40\x2b\x72\x2d\xc7\x28\x9d\x85\x17\x5c\x63\xba\ -\x5b\x88\x31\x4d\x78\x9b\x58\x95\x24\x4f\xd1\xb1\xa6\x39\x7b\x6a\ -\x49\x92\xa1\xaa\x4a\x77\x69\xc2\x4e\x68\x71\xc8\x8e\xfb\xb4\xf8\ -\x67\x68\xb4\x3a\x82\xfd\xe5\xc8\xf9\x40\xcb\x1a\x9c\xf1\x81\x71\ -\x5c\x06\x42\xe7\xa5\x73\x6e\x98\x77\x85\xc9\xae\xe2\x51\xd7\x9b\ -\xe2\x67\xec\xae\x02\xd3\xb0\x1b\x6f\xdf\x46\xde\x40\xfc\x9e\x92\ -\xd3\x2d\x76\x8b\xaa\x2b\x38\xc3\x38\xa0\x3d\xeb\x64\x19\x2d\xd7\ -\xe6\xeb\xae\x39\x5a\xc7\x96\x96\x98\x94\x9d\x6b\xd9\x1c\x03\x17\ -\x65\x0f\x22\xad\x2f\xd7\x61\xd5\xd6\xdd\xb5\x97\xd7\xda\xfb\xa1\ -\xd8\x5f\xbd\x21\x4c\x4f\x6b\xd3\x1d\x3b\xbf\x53\x9a\xaf\xcd\xc0\ -\x8a\x9c\x10\xfa\x4e\x30\x76\x27\xe7\xb5\x09\x3c\xcf\x72\x3d\x18\ -\x2c\xbc\x89\x97\x37\xc8\xb7\xbc\x20\xf4\xdc\x49\xcd\xc9\xb1\x2c\ -\xd9\xc0\x03\x19\xba\x10\x76\x57\xcd\x3f\x4e\x1b\x54\xbd\xd1\xd3\ -\xbe\xe4\x74\xea\xf2\x48\xc6\x25\xb9\x07\x6c\xb7\xf4\x2c\x76\xb3\ -\x7e\x70\xe4\x43\x1a\x1c\x8b\xb4\x66\xc3\xe6\x70\xbe\xaf\xf5\x98\ -\x62\x52\x89\x0b\x56\x05\x3a\x80\x7d\x46\xb7\x28\x13\x07\x9c\xd2\ -\x82\x51\x02\x6d\x0f\x77\xbc\xfe\x21\x8c\x23\xba\xee\x1e\xc0\xf0\ -\x07\x11\xac\xed\x93\x07\xd1\xba\x2e\x3f\x76\xe5\xe8\x9c\xe6\xe9\ -\x77\xc2\xc0\x38\x4d\xbf\x63\x7d\x6b\x80\xe5\x5a\xcc\x30\xea\x0b\ -\x1f\xba\xe7\x0b\xb7\x99\x9d\x91\xf3\xe4\x06\x37\x8a\x82\xde\x48\ -\xcb\x94\x8d\x88\xbb\xe6\x74\xa6\xcb\xbd\x89\x0f\x74\x36\x4f\x9f\ -\x9b\x0e\xd6\x74\xbf\x60\xec\xbb\xdc\xfb\xda\x7e\x6f\x4f\x3b\x7e\ -\x63\xcf\x49\x8d\x30\xaa\xd1\x6d\x14\x74\x16\xd6\x36\xd8\xdd\x19\ -\x9b\x33\xe3\x3f\x3e\x7d\xde\xb4\x17\x5a\x25\x49\xfc\x37\x2d\xbf\ -\x75\xd7\x35\x0c\x1e\x80\xb6\xf4\xc8\x48\x9b\x9b\xde\xbc\xc2\x49\ -\xcc\x66\x39\x36\xfa\x37\x69\xce\xfa\x36\x9f\x20\x7f\x65\xb3\xda\ -\xca\xbe\x39\x06\xc1\x1c\xd6\xad\xd2\x6b\xb5\x25\xb9\x4e\x97\xc2\ -\x35\x03\x27\x79\xca\x0b\xd9\x7f\xd6\x69\x96\x7d\xe1\x17\x69\xef\ -\xf8\xae\xd2\xb4\xce\xc8\xcd\xb8\xb2\xdb\xd6\xb7\xf7\x66\xdf\xdd\ -\xdc\xca\xee\xee\xbe\x39\xdb\xdf\xa8\x0c\x06\x45\xff\xa0\x33\xb4\ -\x25\xac\x87\xfe\xce\x9d\xc6\xc4\xbb\x2f\xe9\xf1\x90\x53\x4c\xda\ -\xe2\x3d\x4d\x92\xd4\xfd\x23\xab\x2f\x19\xf3\xef\x58\xeb\xe3\x57\ -\x08\x93\x64\xb7\xfb\xc0\x4f\x40\x3b\x4f\xc4\xce\xf5\xb4\x3c\x66\ -\x6c\xbe\x7b\x27\x05\xc5\xf8\x43\x55\x97\xf4\x1b\x89\xdb\x99\xa9\ -\x3d\xbd\x0e\x86\x18\x76\xa7\x0c\x0c\x29\x33\xd6\x49\xeb\xd8\xef\ -\x6c\x18\xb1\xe9\xa5\x2c\xd1\x25\x2e\xd8\xc2\xde\x59\xfb\x4b\x0d\ -\xfa\x27\x6f\xe5\x22\xf4\xa2\xde\xd8\x0e\x36\xdf\x72\x9b\xae\x75\ -\x73\x74\x63\x6c\xea\x19\x74\xe6\x8b\x28\xa2\x1c\x84\x94\x4d\xd7\ -\xf5\x5d\x7e\x78\xfd\x83\xfc\x2f\x60\x08\x61\x5f\x33\x60\xc0\x91\ -\x44\x36\x35\x3e\x04\xdd\x72\x19\x42\xed\xd0\x81\x50\x12\x5e\x68\ -\x2d\xb8\xac\xf1\xc2\xc7\xc2\xf3\xfd\xc5\x42\x3f\x78\x50\x12\x9e\ -\xe3\x5a\x0f\xe5\xb6\xdb\xb9\xc8\x45\xda\x71\xf3\x64\xb1\x05\xd7\ -\xe5\x76\x8e\xec\x40\x20\x09\xcf\x75\xac\x66\xc0\xfa\x73\x84\x17\ -\x82\x85\x2c\xbe\x85\xb5\x9c\x23\x39\x08\x64\x47\xad\x1b\x59\xe1\ -\x50\x3f\xcf\x47\xa1\x00\x5f\x12\x9e\x50\xa3\x40\x65\xd0\x34\xd5\ -\x26\xd2\xd2\x4e\xa8\x4e\xd4\x61\xd3\x54\x95\x48\xaf\x11\x63\x5d\ -\xa2\x8a\xd8\x6e\x17\x45\x1a\x12\xf3\xc0\x52\x16\x98\x48\x91\x3c\ -\x39\x35\x10\x00\x57\x12\x9b\x50\x8b\x3c\x3b\x36\xa6\x41\x80\xec\ -\x5b\xfe\x58\x85\xa8\x9b\xd2\x34\xcc\x88\x48\xbf\xa3\x0e\x72\x22\ -\x83\xb9\xed\x39\xc5\x46\x28\x0b\x4c\xa8\x36\x94\x82\xd3\x55\x70\ -\xc8\x0e\x4c\xa1\xe0\x50\x4a\x4e\x57\xcd\x21\xbd\x84\x8e\x34\x87\ -\x42\x68\x21\xe4\x87\x76\xd0\x3c\xe9\xf5\x53\x28\x3b\x9e\x1f\x1c\ -\x53\x1e\xd2\x2f\xa3\x22\xe5\x31\x03\x72\x5c\x7c\xc8\xae\x0e\x63\ -\xf1\x31\x03\x6c\x10\x78\xf2\x89\x37\x51\xfe\x43\xe9\xd2\xa0\xa3\ -\x76\x83\xd2\xa9\x8f\x81\x7a\x9b\xae\xaf\xcf\x29\xe1\x7c\xe9\xb5\ -\x41\xa8\xe1\xd4\xe3\xd3\x55\xc8\x39\xd2\x99\x5e\xa1\x94\x53\x0f\ -\x50\x57\x3d\x17\x48\x6b\xe1\xb1\xa2\x53\xcd\x0e\xfb\x5a\x2e\x16\ -\x1e\x58\x3e\x46\xd8\xcd\x84\x1f\xcf\x2b\x3d\xe6\x2b\xd7\x5c\x00\ -\x36\x19\x26\xe9\x8f\xd3\x63\x99\x37\x17\x7a\x5c\xeb\xb9\xd2\x5f\ -\x1e\x84\x6a\x4f\x35\x42\xbe\xf8\xea\x87\x10\xca\xbe\x9c\x0d\x14\ -\xdf\x74\x24\x3f\x23\x33\x47\x3a\x7f\x22\xd4\x7b\x73\x81\x17\x4a\ -\x2f\x18\x42\xb5\x37\x17\x7c\x50\x3a\x27\x30\xd6\x7a\xaa\xc9\x41\ -\xc8\x1e\x8d\x7e\xe4\xd8\x4a\x21\xfd\xad\x55\x24\xf5\xd4\xe3\xf3\ -\x7d\xa4\xe1\xae\x92\x40\x7e\x3f\x8e\x48\xe8\xa9\xc6\xe7\xa2\x60\ -\xa7\x5f\x6a\xe5\x2a\xf4\xa4\x33\xa1\x23\x99\xa7\x9a\x5d\x18\x20\ -\x84\x89\x7e\xec\x9a\x94\xde\x43\xf6\x34\xa9\x26\xc8\x33\x04\xfa\ -\xad\x1a\xf2\xbb\x4c\x86\x9f\x65\x27\xd3\xe0\x33\x42\xe3\x89\xbd\ -\x87\x08\xbd\xb9\xe0\x6b\x12\x7b\x0f\xc9\xec\xcd\x85\x20\xcf\xec\ -\xc9\xa6\xe4\x27\xdf\x6a\x15\xb3\xd3\x56\xed\x2d\xa5\xf5\x8a\xf8\ -\x93\xad\x72\x7e\xba\xca\x3d\x57\x7a\xfa\x13\x7f\xb9\x55\x0c\x50\ -\x67\xc1\x17\x29\x97\x7c\xaa\xe9\xe9\x2c\xf9\x5c\xf9\xbc\xa8\xf0\ -\x3b\xae\x62\x84\xdb\x04\x7b\x0b\x1d\x3b\xa0\xfc\x9e\x6c\x71\xa2\ -\x6a\x02\xf5\x49\xf9\xb1\xe1\xfb\x98\x54\xd5\x4c\x00\x42\xb6\x06\ -\xab\xde\x6a\xa6\x9a\x9d\xb6\xf2\xc5\x7d\x8c\x7c\x51\xcf\x4f\x57\ -\xf9\xe2\x49\x4b\x67\x71\xbe\x4a\x31\x40\x9d\xe5\x8b\xfa\xff\x82\ -\xa7\x9a\x5e\x18\x22\xa4\xdf\x9b\x1b\x04\xbe\xf4\xd2\x3b\xfc\xb0\ -\x76\x8f\xf1\x19\x89\x35\xbb\xa8\xa4\x57\x5b\xb1\x5c\x79\x7e\x76\ -\x4d\xa6\x45\x5a\x2c\x8b\xb5\xca\xf3\xd3\x6b\xf6\x4f\x49\xbf\xa8\ -\x4d\x84\x8a\x3a\x70\xda\x6a\x94\xa5\x82\x57\x34\xb1\x4a\x51\x09\ -\x4f\x57\x81\xc2\xe6\xbb\xc7\xec\x9d\x52\x48\x4f\x67\x75\xc2\xd7\ -\x59\xd5\x1b\xa7\x54\x4e\x77\x5a\x67\x56\x9c\xc7\xec\x9a\x52\xc7\ -\xef\xee\x9e\xf8\x20\x6e\xf6\x9f\x0d\xd8\xb8\x96\x13\x2c\xa0\xe3\ -\x86\x9e\x4a\x48\x6e\x14\x4d\xf6\xd2\x7a\xee\x84\xc8\x9d\x49\xf8\ -\x73\x63\x17\x91\x91\xf3\x58\xb0\xf1\x0a\xbd\xfb\xdf\x50\x60\xa1\ -\x9e\x15\x42\x3f\x0c\xc2\x45\xff\x93\x64\xfb\xcd\xcb\x8a\xff\x24\ -\xd8\xe6\xe5\x5f\xd1\x32\xdf\x60\ -\x00\x00\x08\x5d\ -\x00\ -\x00\x5c\xbe\x78\x9c\xe5\x5c\x59\x8f\xe3\xb8\x11\x7e\xef\x5f\xa1\ -\x68\x10\xec\x0e\xd2\xba\xa8\x5b\x6d\x7b\x81\x64\xb0\xc0\x22\x9b\ -\x97\xec\x06\x79\x5c\xb0\x25\xda\x2d\x8c\x0e\x83\xa2\xdb\xf6\xfc\ -\xfa\x14\x75\xdb\x6d\x6a\x73\x34\xa7\xd3\x1c\x0f\x66\x7a\x54\x55\ -\xbc\xbe\x2a\x92\x9f\x4b\x6c\xae\x7e\x38\x95\x85\xf6\x4c\x68\x93\ -\xd7\xd5\x5a\x77\x4c\x5b\xd7\x48\x95\xd6\x59\x5e\xed\xd6\xfa\x3f\ -\x7e\xfd\xd1\x88\x74\xad\x61\xb8\xca\x70\x51\x57\x64\xad\x57\xb5\ -\xfe\xc3\xe6\x6e\xf5\x07\xc3\xd0\xfe\x42\x09\x66\x24\xd3\x8e\x39\ -\x7b\xd2\x7e\xaa\x3e\x37\x29\xde\x13\xed\xfb\x27\xc6\xf6\x89\x65\ -\x1d\x8f\x47\x33\xef\x85\x66\x4d\x77\xd6\x47\xcd\x30\x36\x77\x77\ -\xab\xe6\x79\x77\xa7\x69\x1a\xb4\x5b\x35\x49\x96\xae\xf5\xbe\xc0\ -\xfe\x40\x8b\xd6\x30\x4b\x2d\x52\x90\x92\x54\xac\xb1\x1c\xd3\xb1\ -\xf4\xc9\x3c\x9d\xcc\x53\xde\x7a\xfe\x4c\xd2\xba\x2c\xeb\xaa\x69\ -\x4b\x56\xcd\x87\x99\x31\xcd\xb6\xa3\x35\xef\xcd\xd1\x6d\x8d\x9c\ -\x38\x8e\x2d\x1b\x59\x08\x19\x60\x61\x34\xe7\x8a\xe1\x93\x71\x59\ -\x14\xfa\x78\xab\x28\xb2\x6d\xdb\x02\xdd\x64\xf9\xef\x59\x25\x0d\ -\x00\xba\x87\xbf\xa3\xf9\x20\x30\x9b\xfa\x40\x53\xb2\x85\x72\xc4\ -\xac\x08\xb3\x3e\xfd\xfa\x69\x54\x1a\xb6\x99\xb1\x6c\x56\xcd\x80\ -\xe7\x45\xab\x17\x20\x57\xb8\x24\xcd\x1e\xa7\xa4\xb1\x06\x79\x5b\ -\xfe\x98\x67\xec\x69\xad\xbb\x9e\xe9\xb8\xf0\xf1\x5b\xe1\x13\xc9\ -\x77\x4f\xec\x5a\x9a\x67\x6b\x1d\x7a\x8f\xe2\xa8\x7b\x9e\x05\x87\ -\xd3\x19\xf4\x15\x27\xa3\xc6\x36\x63\x64\x3a\x1a\x75\x7c\x37\xec\ -\x6c\x86\x21\x24\x59\x9d\xf2\x3e\x41\x95\xa4\xcc\xf1\x81\xd5\x25\ -\x78\x2d\x4d\x0b\xdc\x34\xf9\x36\x4f\xe1\xa1\xae\xf6\xc5\x61\x97\ -\x57\xbf\x7d\x2e\x8b\xdf\x70\x96\x99\x03\x74\x63\x3b\xe4\xb4\xaf\ -\x29\x33\x4e\xd9\x1e\x00\x0c\xc2\x9b\xca\xf3\xa0\xdc\x80\x76\x95\ -\x91\x6d\xc3\xad\xba\xd1\xf0\x27\x18\x4e\xa8\x6b\x56\xab\x1d\x3b\ -\xc7\x7b\x96\x3d\xe7\xe4\x38\xd9\x3e\xe2\xa6\x43\x4c\xd3\xf6\x78\ -\x07\xd1\x55\xd4\x74\xad\x7f\xd8\xb6\x9f\x5e\xf1\x58\xd3\x8c\xd0\ -\x41\x15\xb4\x9f\x0b\x55\x0d\x1e\xc8\xd9\xb9\x9b\x4f\x7d\xdd\x43\ -\x7f\x79\xad\xa3\xde\xbe\xad\x6f\x9e\x70\x56\x1f\xd7\x3a\xba\x56\ -\x7e\xa9\xeb\x12\xfc\x65\xc6\x7e\x6c\x23\x3b\xbe\x56\xa7\xa7\xb5\ -\x6e\x38\x1e\xb4\xea\xc2\xbf\x2f\xb4\xd0\xa0\x17\x9a\x76\x80\xe2\ -\xde\xd5\x73\xe5\x81\x52\x98\x71\x46\x81\xcf\x04\x46\xd5\xfe\x18\ -\x6a\x68\x9e\xea\xe3\x8e\x72\x74\x18\x3d\x90\xeb\x92\x5c\x63\x3c\ -\x3e\xd6\xa7\xdb\x6a\x08\x80\x03\x9f\xcb\xc6\xa1\xca\x19\xcc\x97\ -\xfd\x69\x5e\xeb\x21\xcf\x08\x08\xb7\xb8\x68\x5e\x94\x3c\xe6\x15\ -\xa0\x60\xf4\xa1\xeb\xb8\x23\xc8\xd7\x16\x43\x1c\x87\x76\x24\xb0\ -\x80\xbe\xbd\x00\xba\x57\x9d\xc5\xaa\x12\x9f\xf2\x32\xff\x42\x60\ -\xe0\x4e\x1b\x57\x10\x3b\x17\xc3\xee\x8a\x69\x1a\x3b\xf3\x39\x79\ -\x3a\x73\x99\x3e\x08\x39\x5e\x5c\xe0\x86\x81\x3f\x0a\x6b\x9a\x43\ -\xa8\xcf\xba\x33\x88\xce\x73\x11\x9f\xc1\xb0\x00\x9f\xda\x00\x6a\ -\xc3\x2b\xbc\xd6\x9d\xe7\xba\x3e\xae\xad\x97\x81\xdd\xca\x4b\xc2\ -\x70\x86\x19\x9e\xa2\x7c\x90\xa0\x38\xb6\x87\x91\xc1\x62\x98\xfc\ -\xfd\xd3\x8f\x9b\xbe\xa1\x55\x9a\x26\xff\xac\xe9\xe7\xa1\x5d\x4d\ -\xe3\x06\xf8\xb1\x3e\x00\xd2\xfa\x66\x14\xaf\xb2\x34\x81\xe5\x0b\ -\xa6\xf5\x26\x2f\x21\x76\xf9\xca\xf7\x27\x58\xae\x56\xd6\xa4\xb8\ -\x30\xe6\x60\x4d\x95\x76\xd5\x52\xd2\xad\x83\x37\x37\x83\x2c\x2d\ -\x73\x5e\xc8\xfa\x85\xe5\x45\xf1\x13\x6f\xa4\x1f\xf1\xac\xd2\x9c\ -\x15\x64\x12\xae\xac\xbe\xf7\xfd\xd8\xac\xd9\xe0\x56\xd6\x30\xfa\ -\xf6\x69\x37\xa1\x72\x11\xf4\xa3\xa3\x0b\xfc\x48\x8a\xb5\xfe\x33\ -\x57\x6a\x2f\xb4\x3b\x5a\x1f\xf6\x65\x9d\x91\xbe\xf8\x80\xe6\xee\ -\x22\x0c\xbc\xd0\x46\xa3\x07\x19\xc5\x55\xc3\x91\x01\x3f\x60\x46\ -\xf3\xd3\xf7\x8e\x09\x7b\x46\x18\x7a\xd1\xbd\x6d\xa2\xc8\x0b\x42\ -\xe4\x85\xf7\xb0\xfa\xfb\x0e\x8a\x1d\x58\xb8\x40\x0c\x7e\xf6\x5c\ -\xcf\x8f\xef\x23\x64\xda\x20\x0c\xd1\xbd\x8b\x4c\xb0\x0b\x1d\xff\ -\xe3\xe8\x8e\x15\x25\x29\x9b\x79\xac\x8d\x12\x0f\xf1\x8f\xab\xcf\ -\xe4\x17\x01\xa8\x69\x67\xbe\x6c\xb4\x6d\x04\x41\x3c\x93\xf3\xe5\ -\x24\xb4\x4d\x0f\x36\xb4\x59\xff\xa7\x8d\xc3\x33\xd1\x8b\x32\xfd\ -\x74\xbd\xa5\xe2\x50\xf0\x0e\xfa\x91\x3b\x17\x37\xec\x5c\x00\x7c\ -\x5b\x70\x6e\xf2\xc1\xb6\xd3\x74\xbb\x7d\xe0\x0f\x46\xbf\x4c\x26\ -\x4e\xf7\x48\x0f\x05\x2c\xf7\xcf\xa4\xaa\xb3\xec\xa1\x61\xb4\xfe\ -\x4c\x92\x7e\x61\xee\x1f\xbb\xb5\x22\xb1\x87\x47\x88\x1b\x42\x0b\ -\x98\xc3\x2c\xf1\x06\x59\x86\x61\x75\xa5\x14\x9f\x93\x0a\x08\xcd\ -\x20\x1d\x9b\x9a\x45\x96\x04\x30\x83\xa0\xdb\x69\xe3\xd7\x05\xd3\ -\x70\xc4\x70\x62\x9c\x79\xca\xc2\xe9\x98\xd1\xb5\xfc\x55\xe0\x34\ -\x22\x31\xa0\x41\x10\xd9\xaa\x02\xea\x87\x66\x20\x61\xb2\x03\xa0\ -\xb6\x18\x50\xcf\xf3\x7d\x65\x01\x75\x4d\x3e\xdf\xdd\x57\x07\xd4\ -\x15\xe1\xb9\xdd\x22\x8c\xb0\xaa\x78\x7a\x71\x4f\x7a\x5e\x3d\x40\ -\xc3\x6f\x14\x50\xcf\x8c\xf8\x8c\x77\x5f\x7f\x09\x35\xfc\x6f\x14\ -\x52\x20\x6e\xed\xa4\x7f\xfd\x45\xd4\x50\x7d\xda\x7b\x66\x3c\x65\ -\x22\x26\x48\xa5\xf1\x26\xc3\x53\x9c\x39\x89\x00\x95\xc7\x9c\x96\ -\xc8\xa8\x12\xdc\x49\x00\xa9\x44\xee\x24\xde\x9c\x14\x61\x4f\x22\ -\x48\xa5\xb1\x27\x23\x10\x2f\xa4\x71\xac\x2e\xa2\x12\xf9\x93\x81\ -\xbe\x51\x48\x65\x32\x28\x43\x98\x28\x51\x03\x54\xd4\xed\xeb\x1e\ -\xba\x02\x55\x52\xd6\x69\xe9\x7b\xbd\x0a\x79\x27\x11\x9c\xf2\xf8\ -\x53\xb4\x80\xa8\x0a\x04\x4a\x88\xa8\x44\x02\xb5\x90\x1c\x55\x81\ -\x40\x89\x20\x95\x49\xa0\x84\xdb\xbd\x1a\x04\x4a\x08\xa9\x3c\x02\ -\x25\xdc\xed\xdb\xcd\x50\xd9\x20\x95\x49\xa0\x84\x5f\xee\x15\x87\ -\x54\x2a\x81\x12\xee\x4f\x8a\x83\x2a\x33\x09\x25\xfe\x3e\xaa\x06\ -\xa8\x41\x47\x3e\xed\xe0\x0a\x54\x59\xac\xd4\x5e\x4a\x43\xa9\xc0\ -\x4b\x45\x80\x4a\xcc\xeb\x89\x37\x28\x35\x88\xa9\x10\x52\x99\x99\ -\x3d\x71\x4a\x5f\x0d\x6a\x2a\x02\x55\x6a\x6e\x6f\x89\xef\xab\x40\ -\x4e\x85\xa0\x4a\xcc\xee\x89\x67\x7f\xe6\xa9\xbc\x43\x49\xcd\xef\ -\x89\xb7\x7d\xc5\x41\x95\x9b\xe1\x13\x9f\x8d\x50\x1c\x56\xa9\x14\ -\x15\x89\xdf\x43\x29\x01\xeb\x57\xe7\xa8\xc2\x6f\xa7\x7c\xe3\x57\ -\x16\x4e\x79\x0c\x55\x98\x92\x52\x1b\x4f\x89\xf4\x54\xb8\x3d\x29\ -\x8d\xa8\x4c\x6e\x2a\x4c\x9e\xa8\x8d\xa8\xc4\xac\xe9\xc2\x9b\x7c\ -\xd7\x7d\xf7\x5f\xa0\xde\x82\x96\x2e\x7c\x25\xf5\x3c\xfc\xde\x8f\ -\x44\xbd\x0d\x27\x15\xee\xf5\x08\x87\xdb\x77\x9f\x8e\x7a\x1b\x42\ -\x1a\x8a\xd3\xfb\x21\xc6\x19\x79\xe7\xa0\x7e\xed\x37\xf9\x0b\x87\ -\xa2\x78\xd2\xe4\xdd\x6f\x4e\x5f\xff\x55\xbe\x27\xa6\xa4\x6a\x23\ -\x2a\x37\x63\x2a\xdc\x9f\x94\x06\x55\x6e\xc6\x54\xf8\xba\x44\x6d\ -\x4c\x65\x26\x4c\x17\x68\x94\x02\xc4\xf4\x2d\x5e\xe7\xa3\xe5\x53\ -\x27\xef\x9e\x9a\xbe\xcd\xfb\xfc\x58\x71\x72\xfa\x36\x2f\xf4\x91\ -\x38\x09\xad\x04\x3b\x1d\x0e\xef\xba\x57\xa8\xca\x3c\x18\x29\x4e\ -\x40\x3f\xa6\x99\xeb\xbf\xf7\x40\x15\x42\x2a\xf3\x64\xa4\x98\xf4\ -\x2b\x8d\xa9\xd4\xa3\x91\xe2\x6d\x4a\x6d\x4c\x25\x66\xf9\x14\x67\ -\x53\x22\x48\xa5\x1e\x8e\x5c\x3a\x23\xa5\x00\x9b\x12\x62\x2a\xf7\ -\x74\xa4\x38\x52\x95\x60\x53\xc3\xef\xe8\x86\x57\xa8\x4a\x3c\xc9\ -\x27\xde\xf6\xa3\x08\xe3\x77\xff\xe5\x54\x84\xa8\xd4\xa3\x7c\x0b\ -\x07\x4e\x95\xc6\x54\x6e\x66\x6a\x81\xf3\xab\x8c\xaa\xe4\xc3\x7c\ -\x0b\xc7\xf8\x95\x46\x55\xea\x69\xbe\xa5\xfb\x63\x54\x20\x54\x02\ -\x50\x25\x1f\xe7\x5b\xfe\xbd\xf2\xf7\x4f\xa9\x44\xa8\xca\x3e\xcf\ -\x27\x8e\x56\xa5\x49\x95\xf4\x03\x7d\x0b\xd4\xea\xff\x25\x49\xb5\ -\xb2\x76\xc3\x7d\x8a\x33\x78\x6f\x5c\xf9\x77\x6f\xf3\x1b\xfe\x60\ -\x23\x8a\x62\xe4\xc1\x93\x19\xc6\xb1\x8b\xe2\x98\x2b\xec\x8f\xe3\ -\x38\xb9\x5b\x62\x33\x02\x55\xe0\x4f\x78\x73\xa7\x04\x66\xe0\x04\ -\x91\x1b\x4d\x04\xbe\xff\x2d\xf5\x20\x8c\xe2\x60\x5a\x86\xdb\x5b\ -\x24\x23\x2f\x70\x62\x7b\x32\x1d\xdc\x12\xf8\xa6\x1b\x45\x8e\x3d\ -\x55\xdd\x3b\xc5\xf7\x4d\x1f\xaa\xf7\xa6\x95\x67\x70\x89\x1b\x86\ -\x93\x1b\x2e\x9c\x40\x02\xfe\xe7\xd2\x09\x30\x44\xc7\xb3\x63\x37\ -\x0e\xfe\x43\x6f\xf8\x40\xd0\x5d\x3b\xb4\x3d\xff\x7f\x71\xcb\xd8\ -\xf9\xa5\xbb\x64\x6f\x19\x8c\xf7\xc9\x8e\x8e\x65\xe4\x34\xfa\xf3\ -\x54\x16\x49\x7b\xcd\xee\x5a\xdf\x53\xd2\x10\xfa\x4c\x5e\x40\x52\ -\x57\xcc\x68\xff\x0f\x5d\xa3\x25\x2e\x1e\x5a\xc9\xb1\x05\x3e\x79\ -\xac\x8b\xac\x13\x34\xf9\x17\x92\x38\xa8\x5b\x91\x6c\x27\xde\x9f\ -\x1e\x8a\xbc\x22\xfd\xa5\xa6\x89\xfd\xc7\xce\x6c\x8b\xcb\xbc\x38\ -\x27\x0d\xc4\x91\x01\xed\xe5\xdb\x07\x63\xe8\xb2\xd1\xd5\xb3\x27\ -\xe9\x78\xa3\x6e\xf2\xdd\x2f\x60\xa8\xfd\x19\x5a\xf9\xee\xa1\x20\ -\x0c\x80\x33\xfa\x8b\x43\x13\x1b\x5a\x38\xd6\x34\xbb\x10\x0c\xab\ -\xfe\xad\x83\xb1\x4b\x5e\x1a\xef\x20\x45\x62\xec\xbb\x6b\x4c\x63\ -\x3f\xf0\x23\x6f\x1e\xab\x08\x99\x21\xf2\x90\xeb\x5d\x84\x18\x87\ -\xd9\x0d\x63\x5f\xdf\xac\x18\xf4\xb0\x9a\x4d\xf8\xe1\x76\x53\x5a\ -\x73\x80\x39\x4a\x57\x2b\x46\x5b\x00\x0a\x5f\x2d\x4c\x2f\x5b\x17\ -\xb4\xff\x7b\xce\x7b\xc6\x34\xc7\x15\xfb\x1d\x87\x32\x4a\x58\xfa\ -\x74\x61\xd4\x39\xb9\x67\x48\xae\x8d\xae\x9c\xec\x98\xc8\xff\xef\ -\xdc\x3c\x19\xde\xf7\xde\x9e\x77\xd4\x28\xf2\x1d\x66\x07\x88\xd0\ -\x5b\xc3\x30\xa0\xd6\xdb\x8a\xea\x50\x42\x95\xe9\x85\x6e\x4b\xda\ -\x9a\xa0\x31\xc6\x20\x6a\xc6\x82\xdc\x5f\x06\x86\x86\xaa\xa4\x61\ -\x98\xb2\x87\x23\xcd\xb9\x81\xc1\x2f\x45\x4d\x0a\x6a\xb0\xc7\xde\ -\xa6\x4a\x9f\x6a\xda\x1b\xf5\x31\x35\x9f\xb4\xd7\x01\xa5\x6f\xfe\ -\xfa\xb7\x9f\x57\x56\xeb\xd3\x0d\xfc\x84\x3a\xba\xeb\x5b\x61\x81\ -\x5d\xf1\x5b\x66\x37\x77\xff\x02\x1c\x7f\x12\x5b\ -\x00\x00\x07\x4c\ -\x00\ -\x00\x1f\xb7\x78\x9c\xdd\x59\x5b\x6f\xeb\xb8\x11\x7e\xcf\xaf\x60\ -\x9d\x97\x5d\xd4\xa4\x2e\xd4\x85\x52\x9c\xec\x43\x0f\x16\x3d\xc0\ -\x29\x0a\xec\x6e\x51\x60\x5f\x16\xb4\x44\xdb\x6c\x64\xc9\xa0\xe8\ -\xdb\xfe\xfa\x0e\x25\x51\x17\xdb\x49\x4f\x80\x14\x38\x27\x04\x02\ -\x8b\x33\x43\x72\xf8\xcd\x37\x43\x12\x59\xfc\x74\xda\x16\xe8\x20\ -\x54\x2d\xab\xf2\x71\xe6\x11\x77\x86\x44\x99\x55\xb9\x2c\xd7\x8f\ -\xb3\x7f\xfd\xf6\x33\x66\x33\x54\x6b\x5e\xe6\xbc\xa8\x4a\xf1\x38\ -\x2b\xab\xd9\x4f\x4f\x77\x8b\xbf\x60\x8c\xfe\xa6\x04\xd7\x22\x47\ -\x47\xa9\x37\xe8\x73\xf9\x5c\x67\x7c\x27\xd0\x0f\x1b\xad\x77\xa9\ -\xe3\x1c\x8f\x47\x22\x3b\x21\xa9\xd4\xda\xf9\x11\x61\xfc\x74\x77\ -\xb7\xa8\x0f\xeb\x3b\x84\x10\xac\x5b\xd6\x69\x9e\x3d\xce\xba\x01\ -\xbb\xbd\x2a\x1a\xc3\x3c\x73\x44\x21\xb6\xa2\xd4\xb5\xe3\x11\xcf\ -\x99\x0d\xe6\xd9\x60\x9e\x99\xd5\xe5\x41\x64\xd5\x76\x5b\x95\x75\ -\x33\xb2\xac\xef\x47\xc6\x2a\x5f\xf5\xd6\xc6\x9b\x23\x6d\x8c\xbc\ -\x24\x49\x1c\xd7\x77\x7c\x1f\x83\x05\xae\xcf\xa5\xe6\x27\x3c\x1d\ -\x0a\x3e\xde\x1a\xea\xbb\xae\xeb\x80\x6e\xb0\xfc\x3a\xab\xb4\x06\ -\x40\x77\xf0\xd7\x9b\x5b\x01\xa9\xab\xbd\xca\xc4\x0a\xc6\x09\x52\ -\x0a\xed\x7c\xfa\xed\x53\xaf\xc4\x2e\xc9\x75\x3e\x9a\xc6\xe2\x39\ -\x59\x75\x02\x72\xc9\xb7\xa2\xde\xf1\x4c\xd4\x8e\x95\x37\xe3\x8f\ -\x32\xd7\x9b\xc7\x19\x0d\x88\x47\xa1\x85\x8d\x70\x23\xe4\x7a\xa3\ -\x2f\xa5\x32\x7f\x9c\x81\xf7\x7e\xc2\xda\xfe\x88\x1c\x5e\x6b\xd0\ -\x4d\x9c\xf6\x1a\x97\x24\x3e\xf1\x90\xf2\x42\x1a\xb7\x36\x76\x0b\ -\x69\x5e\x65\xc6\x27\x98\x52\x6c\x25\xdf\xeb\x6a\x0b\x51\xcb\xb2\ -\x82\xd7\xb5\x5c\xc9\x0c\x3a\x55\xb9\x2b\xf6\x6b\x59\xfe\xb1\xe5\ -\xe5\x9e\x17\x7f\xfc\xf2\xcf\xcf\xc4\xa2\xd7\x2f\x25\x4e\xbb\x4a\ -\x69\x7c\xca\x77\x80\x61\x14\xdf\x54\x9e\xad\xf2\x09\xb4\x8b\x5c\ -\xac\x6a\x63\xd5\x6e\xc8\xf4\x60\x47\xf1\x0c\x39\x8d\xb6\xf7\xcf\ -\x38\x97\x1f\xa4\x38\x0e\xb6\x4b\x5e\xb7\xa0\x21\xb4\xe3\x6b\x20\ -\x58\x51\xa9\xc7\xd9\xfd\xaa\x69\x9d\x62\x59\xa9\x5c\x28\xab\x8a\ -\x9a\x36\x51\x55\x10\x04\xa9\xcf\x6d\x4a\x75\x73\x5b\x7f\xcd\xac\ -\xbd\xde\xbd\xad\xaf\x37\x3c\xaf\x8e\x8f\x33\xff\x52\xf9\x67\x55\ -\x6d\x61\x56\x08\x46\x12\x33\xf7\x4a\x9d\x9d\x1e\x67\x38\x20\x49\ -\x12\x53\xca\xa2\x2b\xad\x71\x28\x82\x68\x47\x7e\xe4\x5d\x29\xf7\ -\x4a\x41\xd2\xe1\x82\x9f\x05\xec\xaa\xf9\xb1\x46\xf5\xa6\x3a\xae\ -\x95\x41\x47\xab\xbd\xb8\x1c\x69\x34\x78\xb9\xac\x4e\xb7\xd5\xc0\ -\x81\xbd\x49\x67\xbc\x2f\xa5\x86\x94\xd9\x9d\xc6\xb3\xee\x65\x2e\ -\xea\xdb\x03\xeb\x92\xef\xf0\xba\xa8\x96\xbc\xb8\x6d\x70\x94\x25\ -\xa0\x84\x3b\x76\xc3\xb6\xae\x76\xdc\x59\x58\xaa\xc7\x2e\x7b\xc1\ -\x02\x7c\xbf\x0a\x44\xa7\x3a\xbf\xac\xda\xf2\x93\xdc\xca\x3f\x05\ -\x00\xe3\x35\xbc\x03\x6e\x4d\x60\x69\x87\x21\xa4\xcf\x26\x6d\x4f\ -\x67\x23\x9b\x59\xa1\xc1\xd3\x08\x7c\x08\x57\x2f\xac\x94\x84\x6c\ -\x18\xb9\x63\x45\xe7\xb1\xc8\x24\x39\xd4\xe8\x53\x43\xb0\x86\x7e\ -\xf1\xa5\xee\x3c\xd6\x75\xbc\x77\xae\x89\xdf\xc8\xb7\x42\xf3\x9c\ -\x6b\x3e\x64\x81\x95\x80\x6f\xae\xdd\x19\xd4\xcb\xf4\x97\x4f\x3f\ -\x3f\x75\x0b\x2d\xb2\x2c\xfd\x77\xa5\x9e\xed\xba\x08\x19\x03\xbe\ -\xac\xf6\x80\xf4\xec\xa9\x17\x2f\xf2\x2c\x85\x0a\x07\x99\xff\x24\ -\xb7\xc0\x6d\x53\x1c\xff\x0a\x15\x6d\xe1\x0c\x8a\x89\xb1\x01\x6b\ -\x98\xb4\x9d\x56\x89\xb6\x54\xde\x3c\x2f\xf2\x6c\x2b\xcd\x20\xe7\ -\x57\x2d\x8b\xe2\xb3\x59\xa4\xdb\xf1\x68\x52\xa9\x0b\x31\x08\x17\ -\x4e\xe7\x7d\xb7\x37\x67\xb4\xb9\x85\x63\x77\xdf\xf4\xd6\x03\x2a\ -\x93\xa4\xe8\x03\x5d\xf0\xa5\x00\x86\x7e\x31\x4a\x74\xa5\x5d\xab\ -\x6a\xbf\xdb\x56\xb9\xe8\x86\xf7\x68\x8a\x4c\xf7\x21\xd3\xe7\x02\ -\xf4\x2b\xf0\x3e\xbd\x17\x09\x5f\x7a\xd1\x83\xe9\xe0\xae\x4e\xa4\ -\x5e\xdb\x55\xfb\x02\xea\xdd\x41\x94\x55\x9e\x3f\xd4\x5a\x55\xcf\ -\x22\xbd\xf7\x58\x1e\xad\x56\x5d\xb7\x4d\x86\xd4\xb5\x5d\x00\x46\ -\xa8\x02\x48\xaa\xd3\xc0\xca\x72\x0e\xe5\x45\x29\x7e\x4e\x4b\x38\ -\xd4\xad\xb4\x5f\x6a\xc2\x4f\xe3\x25\x70\x20\xc1\x0c\xd3\x5e\x61\ -\x13\x2e\x20\x11\x8b\x59\x14\xf6\x0a\x9b\x67\x8c\xb0\x30\x71\x43\ -\x16\xf4\x1a\x60\xaa\x1f\x11\xe6\x07\x34\x1e\xe6\x69\xea\x5f\x4c\ -\x59\x12\x85\xf1\x30\x89\x32\xb6\x24\x08\xa2\xc8\x8b\x07\x67\x54\ -\xcb\xe7\x90\xd2\x88\x26\xbd\x54\x2b\x5e\xd6\x86\x43\xc0\x58\xae\ -\x95\x3c\xfd\x00\x13\x86\x2c\x49\x58\xe4\xcf\x5d\x12\x85\x9e\x9b\ -\xf8\x3e\x9d\xc3\x59\x1a\xc7\x31\x75\xa9\xe7\x19\xb1\x9f\x78\x7e\ -\xe4\xb3\xb9\x3b\x77\x7f\xec\x99\xf2\xfd\x45\x24\xbe\x0e\x89\x47\ -\x42\x3f\x09\x99\x77\x15\x12\x2f\x24\xae\x17\xc5\x21\x1d\x87\x04\ -\x84\x01\x83\x36\x8e\x08\x66\x84\x26\xd4\xf5\xc2\x64\x12\x11\x0f\ -\x0e\x79\x37\xf4\x59\x72\x11\x91\x98\x85\x20\x65\xaf\x46\x24\xf1\ -\x03\x2f\x8c\x92\x18\xa0\xa7\xcc\x77\x3d\xf0\xb0\x89\x88\x89\x8d\ -\xc7\x20\x0c\xf0\x19\xc0\x85\x83\x06\xdf\x7d\x44\x30\xbb\x0c\x89\ -\x1f\x03\xc5\xa1\x05\x57\x21\x09\x88\xdf\x94\xe7\x64\x1c\x92\x6b\ -\x21\xc0\xec\x33\x12\x27\xa6\x4d\x42\x02\xe9\xe7\x41\xea\x50\x7f\ -\x12\x12\x97\x84\x6e\x4c\x21\x75\x92\xef\x19\xc7\xff\x07\x8a\xd7\ -\x47\xe5\xc7\x46\xf1\x0a\x43\x8f\xd0\xdb\x18\x8e\x36\x7f\xf3\x4a\ -\xf1\x22\x78\x94\x84\x21\x0d\xe3\x24\x9a\x80\x47\x09\x73\x03\x38\ -\x19\xc2\x01\xbb\x1d\xd7\x9b\x0b\xec\x9a\xeb\x73\x7a\xef\x36\xed\ -\x61\x55\xc1\x0d\xb1\xd1\xc0\x1e\xe1\x4e\x50\xb4\x92\x03\x57\x92\ -\x97\x7a\x22\x3b\x36\x5e\x4f\x44\x80\x88\xd0\xd9\x66\x2a\x83\x8b\ -\x59\x0a\xb7\x1c\xb9\xdf\x3e\x14\xb2\x14\xdd\x2d\x70\x62\xb3\xe2\ -\x5b\x59\x9c\xd3\x5f\xa1\x66\x3d\x60\x7b\x64\xe3\x76\xf8\x4e\x64\ -\xfd\x1b\xa5\xb5\xd0\xe2\xa4\xc1\x2a\x87\xcb\x2c\xc4\xab\xe9\xf1\ -\x42\xae\xcb\x14\x9e\xc8\x4a\xb7\x82\x1c\x5e\x0c\xaa\x1d\xd3\xc4\ -\xea\x42\x88\x8d\x27\xad\xa6\x10\x1a\x22\x8d\xbb\xeb\x9a\x75\xeb\ -\x08\xef\x87\x4b\x59\x33\x47\x5f\x58\xdb\xd1\x47\x25\x35\x98\x60\ -\x73\xb3\x48\x0b\x85\xf5\xf2\x21\x97\x26\xf6\x66\xe5\x42\xab\x07\ -\xf3\x8e\x69\xb6\x5d\x6f\xe4\x4a\xa7\xb6\xdb\xb9\x5d\x66\x1b\x00\ -\xbf\xf5\x3b\x97\xf5\x0e\xae\x26\xf0\xbe\x6c\x0c\x2a\x78\xd8\xad\ -\x8a\xea\x98\x1e\x64\x2d\x97\x85\x78\x68\x7e\x65\x61\xa8\x66\x45\ -\x2d\xef\x3b\x1e\x7f\x2d\xef\xc7\xdc\x6d\x49\x0f\xcf\xc6\x38\x84\ -\xf3\x80\xd1\x87\x2d\x57\xcf\x42\xb5\x36\xa2\xe4\xb0\x08\x5e\xf2\ -\xec\xd9\xdc\x9e\xca\x3c\xe5\x19\xbc\x21\xf6\x05\xd7\xa2\x27\x9a\ -\xb9\xa4\x22\x38\x45\x5c\xda\xb6\xf9\xe8\x1b\x1d\x10\xbc\x90\x5a\ -\x66\x51\x44\x7d\x62\x3f\x41\x8a\x36\xaf\xe8\x0e\x08\x9b\x9f\x2f\ -\xc8\x3e\x8a\xe9\x9c\xc2\xf9\xd5\x4e\xea\x53\x12\x34\x29\x30\xf7\ -\x12\xe2\x1b\xdb\x88\x04\xa8\x40\x1e\xdc\x28\x9a\x36\xc7\x09\x89\ -\x50\xe7\xc6\x1c\xfb\xdd\x14\xb4\x9b\xd6\x2e\xb4\x69\x17\xf9\x3b\ -\xea\x73\x0a\xfd\x8e\xfe\x81\xc0\xbc\xed\xcd\xfb\x2f\xb0\xa1\x70\ -\xf0\xb6\xdf\x5f\x90\x4d\x60\x3a\x87\x73\x3e\xb6\x53\x33\x12\x36\ -\x59\xdd\x79\xd2\x7c\x37\x06\x30\x7a\x98\xe9\xf7\x9b\x45\x62\x10\ -\xf6\xcf\xc0\xaa\x2c\x41\x59\x29\x0c\x0f\xc2\x03\xd7\x7b\x25\x26\ -\x0f\x8f\xfe\x01\x01\xbc\x33\x77\x6e\x78\xbb\x65\x2f\xb4\x57\xb3\ -\xbf\x65\x10\x03\x40\x98\x7b\xc9\x20\x5b\x27\x57\x6d\x69\x98\x50\ -\xc6\x23\x2c\x88\x43\xdf\x65\x74\x77\xb2\x1a\x43\x5b\x70\x3e\x5d\ -\xee\xb5\x1e\xcb\xfe\x53\xc9\x32\x6d\xea\xe9\xcb\x25\xb3\xa1\x91\ -\xef\xb6\xe7\x05\x44\x96\x75\x41\x43\x19\x82\xe8\xce\x4d\x84\x2f\ -\x7e\x27\x40\x9a\x9d\xd1\xc4\x0d\xbe\x1a\xc8\xff\x8d\x89\xeb\x46\ -\xd4\xbb\xca\xaa\xd7\x30\xb1\x44\x0b\x82\xf7\xc4\x24\x22\xd1\x35\ -\x26\xd8\x82\x71\xf5\x71\x0b\x96\xe8\x1d\x61\xf9\xe6\xa8\x12\xb7\ -\xd5\x00\x72\xab\xa7\x4a\x97\xe0\xaf\xf4\x6e\x92\x07\xfb\x1f\x99\ -\x3e\x63\x9c\xf0\x14\x9a\x57\xbb\x37\x09\x85\xbd\x0f\x48\xa9\x84\ -\xb0\x16\x2a\x3c\x9c\x08\x6f\x2b\x3f\xd8\x7f\x57\x60\xbe\x11\x0e\ -\xd1\xc8\xe6\xda\x04\x98\x37\xd6\x20\xec\x7d\x44\xd2\x0c\xb7\x8b\ -\xf1\x45\xe3\xcd\xac\x89\x3f\x1e\x6b\xec\xdb\x2f\x9e\x02\xf3\x76\ -\xd6\x7c\xfd\xed\xe8\xfb\x61\x4d\x9f\x47\xf3\xbe\xea\xbc\x9d\x34\ -\xef\x09\xcc\x37\x42\x9a\x90\xd8\x67\xc4\x18\x97\xb7\x73\xe6\x3d\ -\x2f\x82\xdf\x08\x67\x86\xe3\xc9\x67\x84\xbd\x9d\x2d\x1f\xf0\x72\ -\x33\x1c\x4c\x1d\x24\x6f\x27\xca\x5b\xaf\xc6\x0b\x67\xfd\x74\xb7\ -\x30\xff\x3b\x79\xba\xfb\x2f\x49\x7d\x2d\x30\ -\x00\x00\x04\xe3\ -\x00\ -\x00\x1a\x61\x78\x9c\xed\x58\x59\x6f\xe3\x36\x10\x7e\xf7\xaf\x50\ -\x95\x97\x16\x0d\x75\x5a\xd6\x11\xd9\xfb\xd0\x60\x81\x05\xfa\xd4\ -\x6e\xd1\x67\x5a\xa2\x65\x36\x12\x29\x50\x54\x6c\xef\xaf\xdf\xa1\ -\x6e\x1f\x59\x64\x93\x06\x5d\xd4\x51\x10\x38\x9c\x6f\x86\x9c\xf9\ -\xe6\x10\x9d\xf8\xc3\xbe\xc8\xb5\x47\x22\x2a\xca\xd9\x52\xb7\x0d\ -\x4b\xd7\x08\x4b\x78\x4a\x59\xb6\xd4\xff\xfa\xfc\x11\x05\xba\x56\ -\x49\xcc\x52\x9c\x73\x46\x96\x3a\xe3\xfa\x87\xd5\x2c\xfe\x09\x21\ -\xed\x37\x41\xb0\x24\xa9\xb6\xa3\x72\xab\x7d\x62\x0f\x55\x82\x4b\ -\xa2\xfd\xbc\x95\xb2\x8c\x4c\x73\xb7\xdb\x19\xb4\x13\x1a\x5c\x64\ -\xe6\x2f\x1a\x42\xab\xd9\x2c\xae\x1e\xb3\x99\xa6\x69\x70\x2e\xab\ -\xa2\x34\x59\xea\x9d\x41\x59\x8b\xbc\x51\x4c\x13\x93\xe4\xa4\x20\ -\x4c\x56\xa6\x6d\xd8\xa6\x3e\xaa\x27\xa3\x7a\xa2\x4e\xa7\x8f\x24\ -\xe1\x45\xc1\x59\xd5\x58\xb2\xea\x66\xa2\x2c\xd2\xcd\xa0\xad\xbc\ -\xd9\xb9\x8d\x92\x1d\x86\xa1\x69\x39\xa6\xe3\x20\xd0\x40\xd5\x81\ -\x49\xbc\x47\xc7\xa6\xe0\xe3\x25\x53\xc7\xb2\x2c\x13\xb0\x51\xf3\ -\x79\x5a\x51\x05\x84\x96\xf0\x3b\xa8\xf7\x02\xa3\xe2\xb5\x48\xc8\ -\x06\xec\x88\xc1\x88\x34\xef\x3f\xdf\x0f\x20\xb2\x8c\x54\xa6\x93\ -\x6d\x7a\x3e\x8f\x4e\x3d\x22\x99\xe1\x82\x54\x25\x4e\x48\x65\xf6\ -\xf2\xc6\x7e\x47\x53\xb9\x5d\xea\xee\xdc\xb0\x5d\x78\xbc\x46\xb8\ -\x25\x34\xdb\xca\x53\x29\x4d\x97\x3a\x78\xef\x84\x41\xbb\x9e\x14\ -\x87\xdd\x2a\x74\x1b\x47\x03\x62\x19\xa1\x63\xd8\x9a\xb0\x3d\xd7\ -\x6f\x75\xfa\x10\xa2\x94\x27\xca\xa7\xa5\x9e\xd5\x34\x25\x46\x4f\ -\xcb\xb0\x07\xd9\x97\x5c\x48\xb4\x4f\x4b\x20\x67\xe1\x5f\x04\x0f\ -\x3d\xb8\x02\x34\x4e\xc9\xa6\x52\x5a\xad\xa7\x6a\x05\xae\xfa\xba\ -\x66\x36\xe8\x70\xb0\x3a\x35\x7d\xa4\x64\x37\xea\xae\x71\xd5\xb2\ -\xa1\x69\x25\xce\xa0\x72\x72\x2e\x96\xfa\xcd\xa6\x79\x3a\x60\xcd\ -\x45\x4a\x44\x0f\x2d\x9a\xe7\x08\xe2\xc0\x2e\x95\x87\xb6\x57\xba\ -\xbd\x7b\x7f\xd5\xae\x03\x6e\x5d\xc6\xab\x2d\x4e\xf9\x6e\xa9\x3b\ -\xa7\xe0\x17\xce\x8b\xa5\xee\x19\x5e\x18\x84\x96\x7d\x8a\x26\xfb\ -\xa5\x8e\x7c\xcf\x00\x77\x02\xcb\x3b\x43\xe1\x3c\xe4\x18\x0b\xdb\ -\xb6\x5c\xcf\x3f\x43\x6b\x21\xa0\x9b\x50\x8e\x0f\x04\xa2\x6a\x3e\ -\xfa\x03\xaa\x2d\xdf\x65\x42\xb1\x23\x45\x4d\x4e\x2d\x15\x82\xd6\ -\x6b\xbe\xbf\x0c\x43\x72\x6b\xd5\xa7\xa8\x66\x54\x42\x2f\x94\xfb\ -\xe9\xae\x2a\xe1\xd5\x65\xc3\x1d\x65\x40\x02\xea\xaa\xd2\x76\x07\ -\x8e\x4f\x35\xfa\x12\xf5\xad\xe0\x09\x0d\x70\xed\x8c\xe7\x0e\x3a\ -\x3c\x0d\x15\x78\x4f\x0b\xfa\x85\x40\xdc\x67\x54\x57\x0c\x97\x28\ -\xcb\xf9\x1a\xe7\x9d\xf7\xab\x46\x23\x3e\xa2\xa5\x35\xd2\x34\x79\ -\x50\xfd\xb8\x3f\x28\x99\xde\x0b\x15\x9f\x4a\xe0\xfa\x0b\x6f\x10\ -\x72\x41\x33\xca\x26\xfe\xf6\xa2\xc3\x54\xa4\xba\x17\x86\xef\xbe\ -\x29\xb0\xa6\xfc\xfc\x53\xec\x30\xc5\xba\xba\x37\xcf\x0b\xbf\x91\ -\x17\x44\xe2\x14\x4b\x3c\x76\x41\x2f\x71\xc2\xd0\xea\x23\x83\x41\ -\x18\xfd\x71\xff\x71\xd5\x1d\x14\x27\x49\xf4\x37\x17\x0f\xfd\xb9\ -\x9a\xa6\x14\xf0\x9a\xd7\x90\x0a\x7d\x35\x88\xe3\x34\x89\x60\x74\ -\x15\x58\xae\x68\x01\xb5\xad\xa6\xde\xaf\x30\xaa\x62\x73\x04\x8e\ -\x94\x15\x59\xe3\xa6\xed\xb6\x82\xb4\x33\xf0\xe2\x8b\x20\x4d\x0a\ -\xaa\x8c\xcc\x3f\x25\xcd\xf3\x4f\xea\x90\x2e\xe2\xc9\xa6\x54\xe6\ -\x64\x14\xc6\x66\xe7\x7d\x17\x9b\x39\x09\x2e\x36\xfb\xe8\x9b\x55\ -\x36\xb2\x72\xd4\x14\x43\xa2\x73\xbc\x26\x50\x04\xbf\x2b\x50\x3b\ -\x43\x33\xc1\xeb\xb2\xe0\x29\xe9\xcc\x07\x36\x49\x22\x87\x94\xc9\ -\x43\x0e\x78\x33\x50\xa2\x1b\xab\x79\xee\x52\x5a\x95\x60\x01\xf3\ -\x3c\xa7\x8c\xdc\x71\x18\xa4\x9b\x9c\xef\xa2\x47\x5a\xd1\x75\x4e\ -\xee\x9a\x4f\x9a\x43\xe4\x83\x68\x03\xe1\x37\xf6\x1b\xc7\x69\x16\ -\xa8\x1b\x34\x91\xdd\x2e\x45\x9d\x93\x88\x71\xf6\x05\x46\xd4\x5d\ -\x25\x05\x7f\x20\x83\x7e\xbb\x6c\xdb\x2d\xb2\xfa\xa5\x3a\x1b\xe2\ -\x88\xd6\xb5\x94\x53\xd9\x3f\x9c\xb2\x08\x68\x27\xa2\x97\x36\x8b\ -\x1c\x1a\x46\x46\xf3\x5e\x96\x62\x98\x64\x42\x40\x14\x70\x28\x99\ -\x4a\xf9\x66\x53\x11\x19\x39\x46\xe0\x3a\x81\x65\x7b\x41\x0f\x8e\ -\x1e\x17\x58\x3c\x10\xd1\x5a\x12\x86\x21\x40\xb4\xc6\xc9\x83\x22\ -\x94\xa5\x11\x4e\x60\xac\xd4\x39\x5c\x2e\x8e\x1a\x4a\xd1\xea\x42\ -\x44\x28\x18\xc4\xfd\x6b\xcd\x19\x24\xfd\xc0\x98\x8f\x4a\xaa\x95\ -\x16\xc3\xea\xa8\xd9\x84\xc2\xe6\x86\x1b\xb8\x73\x77\x6c\x33\x01\ -\x3a\xbe\x61\x2f\x82\xc0\xb5\xc2\xa1\xdc\xde\xd3\xfa\xc6\x69\xb5\ -\xd1\xe2\xbb\x13\x8b\x7e\xf0\xcc\x92\x40\xfd\x3c\x3f\xb3\x8b\xd0\ -\xc6\x36\xfe\x9f\x65\xf6\xfb\xdb\xd5\x6f\x5f\x6f\xc1\x34\xb7\x4e\ -\x7b\x49\x75\xe7\xef\x39\xfe\x01\x73\x8c\xec\x17\xf4\xee\xdc\x08\ -\x9b\x94\xfe\x8b\x69\x2e\xb1\xdc\x9e\xa4\xf9\x5b\x33\xf6\x5b\x13\ -\xd5\x35\xdc\xf6\x92\x65\xbf\x65\x72\x06\x5f\x86\xc8\xd4\x1d\x4d\ -\xeb\x5b\xc0\xbf\xf5\x8d\x79\x7b\xd5\xd3\x12\xcd\xba\x75\x7d\xc3\ -\x6d\x9f\xa7\x17\x47\x09\x52\x84\xb8\x96\x33\x36\xe1\xf8\xb5\x80\ -\x33\x08\x47\x72\x81\xe0\x0b\xc2\x23\x96\xb5\x20\x6a\x82\xbe\x05\ -\x95\xb6\x31\x6f\x33\x3d\xff\x0f\xa8\x74\x1c\x63\x7e\x6b\x43\xe5\ -\x03\x81\xb6\x65\xb4\x64\xde\x5a\x4f\xfd\x7d\xce\x9e\x1f\x5e\x3d\ -\x7b\x41\xd7\x95\xaf\xa0\x10\x79\x57\x4e\xa2\xe3\xb6\x9d\xec\xbf\ -\x86\xc4\xc5\xb5\x93\x18\xbc\xaa\x8f\x91\x87\xdc\xeb\x65\x70\xf8\ -\xaf\xc1\xe9\x38\x5c\xb8\x13\xee\xce\x16\x97\x99\xf4\xdf\x79\xf4\ -\x2f\x0e\xc6\x97\x90\xe9\xa1\x2b\x7e\xc5\x8c\x74\x5e\x1a\x91\x2f\ -\xa1\x73\x71\xcd\x2f\x9b\x09\x9d\xc1\xab\xbb\x1c\xe6\xe5\xe4\x6a\ -\xff\x3c\x2e\x63\x33\x5b\xcd\x62\xf5\xcf\xc0\xd5\xec\x2b\xe2\xa2\ -\xf8\x66\ -\x00\x00\x0b\x5c\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x61\x64\x64\x2e\x73\ -\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\ -\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ -\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\ -\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\ -\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\ -\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ -\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ -\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ -\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\ -\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x35\x38\ -\x2e\x36\x33\x38\x31\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x35\x2e\x35\x33\ -\x38\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ -\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ -\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\ -\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\ -\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ -\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\ -\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ -\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ -\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ -\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\ -\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\ -\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\ -\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\ -\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\ -\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ -\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\ -\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\ -\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ -\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\ -\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\ -\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\ -\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\ -\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x64\x35\x66\x66\ -\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ -\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ -\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x34\x35\x34\x35\ -\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ -\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\x33\x38\x32\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x38\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x30\x30\x30\x38\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x35\x2e\x31\x39\x31\x32\x39\x38\x39\x36\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ -\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ -\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ -\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\ -\x20\x35\x2e\x38\x36\x36\x36\x36\x36\x37\x2c\x31\x36\x2e\x38\x36\ -\x31\x32\x31\x31\x20\x48\x20\x32\x38\x2e\x32\x36\x36\x36\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ -\x68\x33\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ -\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ -\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x38\ -\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ -\x30\x38\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x35\x2e\x34\x39\x33\x32\x35\x38\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ -\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x36\x2e\ -\x39\x33\x31\x39\x35\x33\x2c\x35\x2e\x38\x36\x36\x36\x36\x36\x37\ -\x20\x56\x20\x32\x38\x2e\x32\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x34\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ -\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\ -\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x06\xfb\ -\x00\ -\x00\x17\xd8\x78\x9c\xed\x58\x5b\x8f\xe3\xb6\x15\x7e\x9f\x5f\xa1\ -\x6a\x51\x24\x8b\xae\x28\x5e\x74\xa1\xe4\x4b\x80\x66\xb1\x40\x80\ -\xf4\xa5\x49\xd0\xc7\x40\x96\x68\x0f\x3b\xb2\x68\x50\xf4\xd8\xde\ -\x5f\x9f\x43\xdd\x2c\xc9\xf6\x76\xda\x4d\x51\x14\xad\x3c\x03\x5b\ -\xe7\x1c\x92\xe7\xf2\x7d\x87\x94\x96\xdf\x9d\xf7\xa5\xf3\x2a\x74\ -\x2d\x55\xb5\x72\x09\xc2\xae\x23\xaa\x5c\x15\xb2\xda\xad\xdc\x5f\ -\x7e\xfe\xe4\x71\xd7\xa9\x4d\x56\x15\x59\xa9\x2a\xb1\x72\x2b\xe5\ -\x7e\xb7\x7e\x5a\xfe\xc1\xf3\x9c\xef\xb5\xc8\x8c\x28\x9c\x93\x34\ -\xcf\xce\x0f\xd5\x4b\x9d\x67\x07\xe1\x7c\xfb\x6c\xcc\x21\xf5\xfd\ -\xd3\xe9\x84\x64\x27\x44\x4a\xef\xfc\xf7\x8e\xe7\xad\x9f\x9e\x96\ -\xf5\xeb\xee\xc9\x71\x1c\x58\xb7\xaa\xd3\x22\x5f\xb9\xdd\x80\xc3\ -\x51\x97\x8d\x61\x91\xfb\xa2\x14\x7b\x51\x99\xda\x27\x88\xf8\xee\ -\xd5\x3c\xbf\x9a\xe7\x76\x75\xf9\x2a\x72\xb5\xdf\xab\xaa\x6e\x46\ -\x56\xf5\xbb\x91\xb1\x2e\xb6\x83\xb5\xf5\xe6\xc4\x1a\x23\x92\x24\ -\x89\x8f\xa9\x4f\xa9\x07\x16\x5e\x7d\xa9\x4c\x76\xf6\xa6\x43\xc1\ -\xc7\x7b\x43\x29\xc6\xd8\x07\xdd\xd5\xf2\x6d\x56\x69\x0d\x09\x3d\ -\xc0\xff\x60\xde\x0b\x50\xad\x8e\x3a\x17\x5b\x18\x27\x50\x25\x8c\ -\xff\xf1\xe7\x8f\x83\xd2\xc3\xa8\x30\xc5\x68\x9a\x3e\x9f\x93\x55\ -\x27\x49\xae\xb2\xbd\xa8\x0f\x59\x2e\x6a\xbf\x97\x37\xe3\x4f\xb2\ -\x30\xcf\x2b\x97\x05\x88\x30\xb8\xc2\x46\xf8\x2c\xe4\xee\xd9\xcc\ -\xa5\xb2\x58\xb9\xe0\x3d\x4d\x78\x7b\x3f\x02\x07\x69\x0d\xba\x89\ -\xd3\x41\x83\x51\x42\x11\x71\x34\x09\x59\xdc\xda\xf4\x21\xa4\x85\ -\xca\xad\x4f\x30\xa5\xd8\xcb\xec\x68\xd4\x1e\xaa\x96\xe7\x65\x56\ -\xd7\x72\x2b\x73\xb8\x51\xd5\xa1\x3c\xee\x64\xf5\xeb\xa9\x71\xe7\ -\x57\xa3\x54\x89\xfa\xf4\x0d\x6b\x89\xf3\x41\x69\xe3\x9d\x8b\x03\ -\x24\x31\x8a\xef\x2a\x2f\xbd\x72\x0d\xda\x65\x21\xb6\xb5\xb5\x6a\ -\x23\xb2\x77\x10\x52\xec\x3a\x7e\xa3\x1d\x1c\xb4\xde\x15\xaf\x52\ -\x9c\xae\xb6\x9b\xac\x6e\xb3\xe6\x38\x87\x6c\x07\x08\x2b\x95\x5e\ -\xb9\xef\xb6\xcd\xd5\x29\x36\x4a\x17\x42\xf7\xaa\xa8\xb9\x26\x2a\ -\x05\x55\x90\xe6\xd2\x72\xaa\x9b\xbb\xf7\xd7\xce\x3a\xe8\xf1\x7d\ -\x7d\xfd\x9c\x15\xea\xb4\x72\xe9\x5c\xf9\x59\xa9\xfd\xca\x8d\x51\ -\x42\x38\x0e\x48\x3c\x57\xe7\xe7\x95\xeb\x31\x8c\x58\x42\x93\xe8\ -\x56\x0b\x0b\x86\x28\x20\x41\xcc\xd8\xcd\xcc\xf9\x51\x6b\x60\x9d\ -\x57\x66\x17\x01\x51\x35\x5f\xa4\x33\xaa\x9f\xd5\x69\xa7\x6d\x76\ -\x8c\x3e\x8a\xf9\x48\xab\xf1\x36\x1b\x75\xbe\xaf\x06\x10\x1c\x2d\ -\x9f\xbd\x63\x25\x0d\x70\xe6\x70\x1e\xcf\x7a\x94\x85\xa8\xef\x0f\ -\xac\xab\xec\xe0\xed\x4a\xb5\xc9\xca\xfb\x06\x27\x59\x41\x96\xbc\ -\x0e\xde\x84\x0d\x45\x98\x5b\xf4\x58\x8f\x31\x7f\x60\x01\xbe\xdf\ -\x14\xa2\x53\x5d\x1e\xab\xf6\xd9\x59\xee\xe5\x67\x01\x89\x21\x37\ -\x59\xb1\x91\x8d\xd3\xb2\x6e\x0c\x96\x93\xb4\xb5\x63\x1c\xc7\x5c\ -\x2c\xaf\xcf\x17\x2b\x73\x7b\xa1\xcd\xb7\x15\xd0\x24\x89\x07\xa1\ -\xd2\x12\xe8\x32\x72\xb7\x17\x5d\xc6\x22\xdb\x05\xa0\x89\x9f\x1b\ -\x00\x36\xf0\x8c\xe7\xba\xcb\x58\xd7\xf1\xc2\xbf\x25\x46\x23\xdf\ -\x0b\x93\x15\x99\xc9\xae\x2c\xe9\x25\xe0\x1b\xee\x23\x83\x86\x9a\ -\xfe\xf5\xe3\xa7\x75\xb7\xd0\x32\xcf\xd3\xbf\x29\xfd\xd2\xaf\xeb\ -\x38\xd6\x20\xdb\xa8\x23\x54\xc2\x5d\x0f\xe2\x65\x91\xa7\xd0\x02\ -\xa1\x35\xac\xe5\x1e\xb0\x6f\xbb\xe7\x9f\xa0\xe5\x2d\xfd\xab\x62\ -\x62\x6c\x93\x75\x9d\xb4\x9d\x56\x8b\xb6\x97\xde\xdd\x50\x8a\x7c\ -\x2f\xed\x20\xff\x27\x23\xcb\xf2\x07\xbb\x48\x17\xf1\x68\x52\x69\ -\x4a\x71\x15\x2e\xfd\xce\xfb\x2e\x36\x7f\x14\xdc\xd2\xef\xa3\x6f\ -\xee\x76\xd7\xac\x4c\x48\x33\x14\xba\xcc\x36\x02\x10\xfc\xa3\x55\ -\x3a\xb7\x38\xd1\xea\x78\xd8\xab\x42\x74\xc3\x87\x6c\x8a\xdc\x0c\ -\x25\x33\x97\x12\xf4\x4d\xc3\x49\xdf\xe1\xe6\x5a\x14\xb2\x3e\xc0\ -\x08\xd8\x17\x4a\x59\x89\x85\x82\x86\xbc\x2d\xd5\x29\x7d\x95\xb5\ -\xdc\x94\x62\xd1\x7c\xcb\x12\x22\x1f\x44\x5d\xdb\x49\xa1\x65\xf3\ -\xa4\xb9\x16\x5b\xc8\x08\x4c\x59\xd8\x4f\x73\xe3\xf5\x46\xa4\xbd\ -\xd5\xc7\x52\xa4\x95\xaa\x3e\x43\x57\x5b\xd4\x46\xab\x17\x91\x76\ -\xdd\xb0\xbb\x6d\x09\x98\x52\x84\x39\xb3\xfb\x2b\xef\xe5\xd6\x2f\ -\x88\x31\xdd\x1c\x8d\x19\xcb\xfe\xae\x64\x95\x42\x49\x84\xee\xa5\ -\xcd\x4d\x09\x5c\x32\x69\xd0\xcb\x8a\x0c\xba\xa0\xd6\x10\x21\xac\ -\x2e\xc6\x52\xb5\xdd\xd6\xc2\xc0\x82\x9c\x51\x8e\x49\x38\x2c\x78\ -\x75\x7d\x9f\xe9\x17\xa1\xdb\x91\xa2\xca\x20\x78\x6f\x93\xe5\x2f\ -\x36\xd9\x55\x91\x66\x39\xb4\xa4\x63\x09\x07\x98\x09\xd9\x6c\xca\ -\x19\x26\xc4\x0b\xbd\x60\x50\x74\xdd\x25\xe0\x83\xa4\xef\x26\x04\ -\xa3\x19\xb5\x80\x6f\x11\x0a\x9a\xf2\x90\x41\x68\x89\x96\x20\x3a\ -\x15\xea\xb3\x6d\xc5\x21\x86\x2e\xce\x47\x52\xb0\x65\x28\x61\x24\ -\xc6\x71\x32\x40\xf4\xff\x50\xf8\x4f\x42\xe1\x5f\x05\x02\x6d\x8f\ -\x55\x2c\xf8\xdf\x06\x42\x4c\x22\x12\x61\xf6\xdf\x8e\x83\xb7\xa0\ -\x80\x77\x15\x1f\xa3\xc0\x0b\x51\x23\x63\xe1\x18\x06\x94\xa0\x19\ -\x36\x1e\xc3\x20\x42\x11\x67\x09\x86\x03\xdb\x00\x83\xdd\xe0\xe1\ -\x17\xb7\x98\xf1\x9e\xe4\x5d\xb1\x69\x74\x56\xd5\x76\x5f\x85\x5d\ -\x3c\x33\x5a\x9e\xbf\xc5\x28\x4c\x48\xc0\xe3\x30\xfc\x80\xed\x07\ -\x85\x51\xc4\x39\x21\xc1\x87\x18\xc5\x09\xc7\x2c\x09\x3f\x00\x9c\ -\xa3\x98\xc7\x31\x79\x3f\x6c\xdd\x13\x38\x7e\xe1\x40\xfe\xd8\xe4\ -\x7c\x6b\x72\xeb\x1d\x01\x97\xe0\x61\x88\x07\x0c\x1c\x08\xb8\x75\ -\x8f\x45\xf0\x23\x4e\xac\xaf\xef\x47\x63\x6d\xba\x00\x71\x38\x0c\ -\xe3\x51\x12\xdb\xe4\x52\x14\x06\x38\xe2\xf1\x58\x0e\xe6\x01\x9c\ -\x87\x43\x88\x34\x19\x89\x6d\x29\x28\xa2\x84\x72\x4a\x47\xe2\xa1\ -\xce\x31\xe2\xdc\x6a\x47\xba\x0e\x15\xb6\xae\x24\x4a\xa6\x31\x77\ -\x28\x82\x93\x12\x1b\x89\x3b\xfa\x76\x54\x03\x97\x8b\xe0\x31\xd5\ -\xc4\xab\xa8\x54\x51\x0c\x54\xeb\xd8\x3e\xa3\x1a\xe1\x0c\x62\xc7\ -\xc9\x3f\xcf\xa0\x61\xcd\xd1\xb1\x68\x56\xdd\x99\xbf\x59\x06\xeb\ -\x7f\xa5\xbf\x38\xa0\x38\x48\x48\xfc\x35\xfe\xde\xe6\x99\xc5\x93\ -\xf4\x7f\xa1\x32\x43\x41\x13\x44\x08\x65\x01\x99\x62\x80\x85\xd0\ -\x11\x31\x0f\xa2\x29\x62\xa8\xe5\x44\x12\x47\xfc\x0d\x00\x6b\x01\ -\xc9\x21\x46\x82\xf9\x5b\x40\x1e\xf3\x84\xc5\x34\x61\x00\xf2\x88\ -\xb0\x04\xfe\x78\x0b\xf2\x87\x75\x79\x3c\x15\x8b\x28\xf4\x93\xc4\ -\x4e\x05\x29\xc1\x3c\xe2\xf7\xf8\xc2\x10\xc1\x98\x85\xa3\xfe\xf4\ -\x45\xbe\x10\x0a\x8e\x01\x5c\xe3\x69\xae\x28\x43\x8c\xe2\x88\x26\ -\x77\xd2\x4b\x31\x82\x2a\x33\xf6\xc6\xaa\x8c\xea\x98\x3c\xe2\xcb\ -\x76\xdb\xe0\xe9\xab\xf0\x47\x50\x12\x04\x50\xc8\xf8\xdf\xc3\x97\ -\xdf\xa7\x1b\x4e\xa2\xce\x9b\xeb\xab\xa3\xc6\x71\x44\x83\x24\xfa\ -\xbd\x59\x37\x41\xca\x1b\x58\x07\x3a\x4a\xa1\xc6\x74\x8a\x24\xc2\ -\x10\x9f\x9e\xa5\x1a\xdc\x79\x01\xb4\x0b\x4c\x18\x0f\x84\x47\xde\ -\x82\xd5\x16\xdb\x94\x90\x38\x9a\x30\xf8\x31\x5f\x08\x8e\x09\x09\ -\x29\xf0\x25\xc6\x2c\xe0\x2c\x9c\x51\x6f\xe9\xef\xba\x1f\x46\x9c\ -\x87\x4a\xc3\x83\x6a\xda\xbc\x73\x5b\xb9\x07\x78\x08\x15\xfa\xf5\ -\x7a\x80\xe8\xab\xa7\x2a\xe3\x35\xbf\x21\x9d\xf0\x38\x5b\x2e\x1a\ -\x49\xfb\xc6\x6b\x22\xaa\xe5\x67\x91\x02\xc5\x78\xfb\x08\x91\x1c\ -\xce\x0b\x7b\x38\xea\xde\x5f\xa4\xf8\x8f\xad\xd9\x36\xdb\xcb\xf2\ -\x92\xd6\x10\x89\x07\x2b\xca\xed\xa2\x14\x06\xaa\xe8\x75\x8f\xf6\ -\x29\x86\x81\x27\xa5\x8b\x89\xa0\x6f\xdd\x96\x3c\x73\x10\x75\x90\ -\x19\x57\xbb\xc7\x4b\xf7\x8a\xe0\x5a\x26\x48\x38\x87\x2d\xd8\x5e\ -\xd7\x9e\x66\xb3\x7d\x35\x69\xde\x14\x41\x92\x18\xf4\x77\x77\xbd\ -\x34\xe0\x46\x35\x02\x75\xff\x92\x41\x2b\x9b\x1e\x1b\xe1\x0c\x51\ -\xcd\x00\x86\xc3\x59\x47\xbe\x5d\x76\xbe\xf0\x3f\xca\xf9\x6b\xa6\ -\x65\x56\x99\x7b\x75\xd8\xa8\xb2\xe8\xaa\x60\xb4\x30\xf9\xf3\x9d\ -\xca\xc0\xd1\x83\x52\x0e\x27\x91\x78\x56\x19\xc0\x72\x38\xa9\xcd\ -\x27\x2d\xc4\x5f\x54\xa5\x16\x5e\xcf\x72\xaf\x9d\xe7\x20\xf2\xe1\ -\xd5\x67\xfa\x4d\x6f\xe6\xfc\x19\x56\xff\x66\x5a\xa2\x47\x75\x58\ -\xc3\xef\xa5\xdf\xa4\x68\x0d\xdf\x90\xe6\xf6\xa5\x04\xa0\x73\x69\ -\xdf\x9d\xac\x9f\x7e\x03\x05\x60\xed\xea\ -\x00\x00\x09\x49\ -\x00\ -\x00\x1f\x4f\x78\x9c\xed\x59\x5b\x6f\xdb\xc8\x15\x7e\xf7\xaf\x98\ -\x2a\x2f\x09\x4a\x52\x73\xbf\xc8\x97\x45\x91\x60\x17\x0b\x6c\x5e\ -\xda\x6d\xfb\xb8\xa0\x48\xda\x66\x4d\x91\x02\x49\x59\x56\x7e\x7d\ -\xbf\xa1\xc4\x8b\x6c\xd9\x49\xba\xce\xa6\x40\x2b\x21\xb0\x38\xe7\ -\xcc\xf0\x5c\xbe\x73\x9b\x5c\xfc\xf0\xb0\x2a\xc8\x7d\x56\x37\x79\ -\x55\x5e\xce\x58\x44\x67\x24\x2b\x93\x2a\xcd\xcb\x9b\xcb\xd9\xdf\ -\x7f\xfd\x31\xb4\x33\xd2\xb4\x71\x99\xc6\x45\x55\x66\x97\xb3\xb2\ -\x9a\xfd\x70\x75\x76\xf1\xa7\x30\x24\xef\xeb\x2c\x6e\xb3\x94\x6c\ -\xf3\xf6\x96\xfc\x5c\xde\x35\x49\xbc\xce\xc8\xdb\xdb\xb6\x5d\x2f\ -\xe6\xf3\xed\x76\x1b\xe5\x87\xc5\xa8\xaa\x6f\xe6\xef\x48\x18\x5e\ -\x9d\x9d\x5d\x34\xf7\x37\x67\x84\x10\xbc\xb7\x6c\x16\x55\xb3\xbc\ -\x9c\x4d\x76\x54\xeb\xac\x6c\xb6\x71\x9b\xdc\x2e\xab\xea\xae\xdb\ -\xb7\xa9\xf3\x39\xa7\xd4\xcd\xc1\x3b\x1b\x77\xa6\xc9\xb0\x71\xbd\ -\xa9\x8b\x8e\x35\x4d\xe6\x59\x91\xad\xb2\xb2\x6d\xe6\x2c\x62\xf3\ -\x09\x7b\x32\xb2\x27\x5e\xee\xfc\x3e\x4b\xaa\xd5\xaa\x2a\x9b\x6e\ -\x67\xd9\xbc\x99\x30\xd7\xe9\xf5\x91\x54\x5b\xd1\x31\x31\xe7\xdc\ -\x9c\xf2\x39\xe7\x21\x38\xc2\x66\x57\xb6\xf1\x43\x78\xbc\x15\xda\ -\x9d\xda\x0a\x05\xe8\x1c\xb4\x91\xf3\xcb\xb8\x16\x0d\x5c\xb1\xc6\ -\xbf\x81\xbd\x5f\x88\x9a\x6a\x53\x27\xd9\x35\xf6\x65\x51\x99\xb5\ -\xf3\x0f\xbf\x7e\x18\x88\x21\x8d\xd2\x36\x9d\x1c\xd3\x7b\xe2\xe8\ -\xad\x47\xee\x29\xe3\x55\xd6\xac\xe3\x24\x6b\xe6\xfd\x7a\xb7\x7f\ -\x9b\xa7\xed\xed\xe5\x4c\xc8\x88\x09\x7c\x54\xb7\x78\x9b\xe5\x37\ -\xb7\xed\xe3\xd5\x3c\xbd\x9c\x41\x7a\xee\x9c\xe9\x9e\x27\xb0\x62\ -\x7b\x86\xc3\xc1\x8b\x81\x42\x23\xc7\x23\x46\x6a\xa6\x84\xd9\xf3\ -\xf4\x2a\x2c\xd2\x2a\xf1\x32\xe1\xc8\x6c\x95\xc7\x9b\xb6\x5a\xc1\ -\x6b\x49\x52\xc4\x4d\x93\x5f\xe7\x09\x1e\xaa\x72\x5d\x6c\x6e\xf2\ -\xf2\xb7\x26\x6b\x5b\x00\xb6\xf9\xad\xad\xaa\x22\xea\x0d\x38\xbc\ -\x2d\x7b\x58\x57\x75\x1b\x3e\xa4\x6b\x98\x51\x9b\x93\xc4\x5d\x4f\ -\xbc\x02\xf5\x62\x10\xc2\x4b\x90\xde\xe7\xd9\xd6\xef\xd9\x6b\xb8\ -\x8c\x9b\xbd\x65\x08\x59\xc7\x37\x40\x51\x51\xd5\x97\xb3\x37\xd7\ -\xdd\xe7\x40\x58\x56\x75\x9a\xd5\x3d\x49\x77\x9f\x23\x52\x05\x4b\ -\xe7\xed\x6e\x1f\x71\x87\xb3\x7b\x89\xfc\xa9\x03\x9d\x9e\xa6\x37\ -\xb7\x71\x5a\x6d\x2f\x67\xfc\x31\xf1\x53\x55\xad\x2e\x67\x26\x72\ -\xcc\x52\xc9\xec\x63\x72\xf2\x70\x39\x0b\x99\x8c\x28\xb7\xe2\x04\ -\xd5\x0b\x24\x22\x29\x94\x79\x4a\xdb\xd4\x35\x02\x2b\x2c\xe2\x5d\ -\x06\xa5\xba\x3f\xec\xc0\xd4\xdc\x56\xdb\x9b\xda\x1b\xa7\xad\x37\ -\xd9\xe3\x9d\x9e\x12\x2e\x97\xd5\xc3\x69\x32\xfc\xbc\xf1\x21\x1b\ -\x6e\xca\xbc\x45\x58\xac\x1f\xa6\xa7\x6e\xf2\x34\x6b\x4e\x6f\x6c\ -\xca\x78\x1d\xde\x14\xd5\x32\x2e\x4e\x33\x6c\xf3\x12\x46\x0a\x0f\ -\x08\x66\x62\xf0\xc1\x63\x8e\x1e\xce\x86\x3e\x51\xfb\xc0\x01\xd9\ -\x9f\xf8\xe1\x40\xda\x3d\x4f\x5a\xc5\x0f\xf9\x2a\xff\x94\xc1\x30\ -\xac\x03\x16\xa0\x75\x64\x96\xfd\xb6\x3d\xae\xfc\xb3\xa0\x54\xcd\ -\xfa\xc5\x76\xe7\xe3\xf5\x61\xe7\x09\xc3\x62\x55\xe7\x40\xfc\x44\ -\x9c\x7e\x69\x37\x5d\xf2\x81\x8c\x80\x78\xe8\xf0\xd5\xa1\xcf\x3c\ -\xa6\xed\xa6\x34\x32\xef\x60\x3f\x7f\x8a\xfb\x6e\x3d\xcd\xae\x9b\ -\x31\x00\xfc\x13\x62\xdc\xf5\x1a\x15\x79\x99\xc5\xf5\x4f\x75\x9c\ -\xe6\x70\xe3\x54\xa5\x63\x8a\xb2\x9c\x8d\x42\x37\x4b\x00\x39\x2f\ -\x61\xf5\xa6\x2a\xa0\xe0\xd5\x81\x72\xd1\xb4\xd5\xba\xe7\x82\xb4\ -\xed\xae\xf0\x39\x00\x8b\x61\x17\x4f\x8b\x37\xd7\x1a\x69\x92\x9e\ -\x77\x4b\x87\x38\x59\xd0\xc8\x58\xcb\x85\x12\xec\x7c\x36\x6e\xae\ -\xae\xaf\x91\x1a\xa6\x86\x39\x24\x29\x6c\x85\x34\xe2\xa0\xb7\xd7\ -\xfc\x58\xd4\xaf\xd6\x8c\xa9\x57\xd1\xec\x7a\x69\x96\xe6\x58\xb3\ -\xaf\x50\x88\x99\x17\x15\xba\x98\x7b\xcf\x75\xbf\x56\x59\x1b\xa7\ -\x71\x1b\x8f\x4e\xed\x57\x80\x40\xde\x3b\x16\x45\x6e\xf1\xd7\x0f\ -\x3f\x0e\xf2\x27\xc9\xe2\x9f\x55\x7d\x37\xbe\xda\x33\xc4\xcb\x6a\ -\x03\x89\x06\x2d\x3d\x5c\x92\x05\xca\x12\xd2\xf5\x55\xbe\x42\xae\ -\xf2\x15\xed\xcf\x28\x43\x78\xff\x40\x38\x62\xf6\x40\x1f\x0f\xdd\ -\x1f\x5b\x67\xfb\xfa\x76\xb2\xc8\xa7\xc9\x2a\xf7\x9b\xe6\x7f\x6b\ -\xf3\xa2\xf8\xd9\xbf\x64\xd0\x7c\x38\x34\x6f\x8b\x6c\x5c\xbc\x98\ -\x1f\xa4\xef\xed\x33\x51\xee\x62\xde\x6b\xdf\x3d\xdd\x3c\xc9\x5f\ -\xd5\x66\xbd\xaa\xd2\xec\x90\xf5\x1e\x07\x7b\x11\x2f\x33\x64\xa0\ -\x5f\x3c\x8d\xf4\x08\xef\x40\xb2\xcf\x91\x87\x37\xae\xe3\xf6\x76\ -\x88\xc1\xbd\xef\xaf\x21\xfd\xe2\x8d\xb4\xc2\x08\xef\xf5\xba\xba\ -\xcb\x16\x6f\xb8\xf4\xdf\xc3\xe3\x3e\x79\x2d\x64\x24\xad\x07\x3d\ -\xe5\xfd\xba\x77\x2f\xde\xbe\x58\x6e\xda\x76\xba\xf6\xaf\x2a\x2f\ -\x17\xb0\x4e\x56\xf7\xab\xdd\x43\x81\x3c\xd4\x2e\x86\x53\xd3\x18\ -\x05\xa4\xae\xe3\xdd\xa2\x44\x57\xd7\xaf\x0e\x90\x1b\xd0\xe5\x81\ -\x41\x50\x2e\x1c\x75\xd4\xba\x80\xd9\x48\x52\x67\x9c\x24\x4c\x07\ -\x21\x53\x91\xdb\x7f\x66\xd3\xd0\xf0\x7a\x0a\x6a\x47\x88\x8e\x25\ -\xa4\x2a\x21\x74\x5b\xd5\x21\x8a\xc9\x7d\xdc\x6e\xea\xcc\x43\x79\ -\xc0\xec\xb3\x16\x82\xe2\xd7\x9c\x9f\xfb\x87\x49\x5c\x74\x8f\xf5\ -\xa6\x40\x0d\xbf\xcf\xca\x2a\x4d\x5f\x34\x21\x0a\xa9\x51\x5c\x4a\ -\xae\x5f\x32\xcc\x49\x13\x7c\x24\x50\x55\xa2\x7e\xf0\x80\xab\x48\ -\x73\x41\x9d\x25\x3a\x62\x4a\x5a\x4b\x55\x20\x44\xe4\x10\x7c\x82\ -\x91\xf7\x44\x45\x42\x1a\x29\x8d\x08\xd0\x1a\x69\xab\x90\xcf\x09\ -\x0a\x2a\xe3\xdc\x1a\x16\x08\x16\x29\x2d\x94\x96\x84\x47\xda\x29\ -\xca\x1c\x76\x23\x75\x69\xae\x95\x26\x05\x09\x59\x84\x74\xcc\xb5\ -\x80\x71\x23\xab\xa9\x32\x38\x92\x46\x82\x31\x89\x7a\xae\x02\x6e\ -\x23\x46\x19\x33\x06\x8b\x54\x70\x6a\xa5\x36\x01\x87\x24\x4c\xe1\ -\x05\x58\xb4\xc2\x29\xa6\xe1\x29\xc8\x29\xac\x15\x8a\xfc\x42\x18\ -\x78\x9d\xe5\x4a\x07\xcc\x44\x54\x09\xc1\x0c\x49\x08\xf3\x2d\x80\ -\x51\x2c\x08\x7d\x0b\xa6\x19\xd3\x90\xc9\x2a\x34\x0d\xce\xbf\x9c\ -\x52\xc3\x0c\x87\xe8\xd6\x08\xcb\xb8\xe7\x62\x86\x69\x45\x68\x40\ -\xb1\xd7\x09\xed\xa8\xf6\xab\x14\x7b\x3c\x1f\x75\x52\x39\x17\x08\ -\xbc\x56\x81\x81\x29\xa3\x9d\xc4\xa3\x44\x4d\xe5\x92\x80\xd3\x70\ -\x7f\x64\x20\x23\xc8\xea\x20\xad\x57\x56\x09\x2a\x4d\x00\x59\x61\ -\x13\xd8\xef\xd3\x11\x90\x6a\x60\x05\x6e\x54\x5f\x0c\xa4\x01\x3b\ -\x43\x15\x43\xd0\xfa\x3c\x81\x06\xa2\xe9\x3e\xc9\xa7\x66\x84\x5b\ -\x56\x14\xf9\xba\xc9\x4e\x22\xee\x80\xa0\x2f\x46\xdc\xbe\xfb\x7b\ -\x8c\x38\xed\x1c\xe2\x56\xab\xd7\x08\xc5\x21\xb4\x1c\x17\xa1\x18\ -\x9b\x84\x3a\x2e\x1b\x9f\x54\x11\xa9\x71\x5b\xe7\x0f\x6f\xbd\x53\ -\xd0\x4d\x1b\xc7\x4c\xe7\x5c\x67\x95\xe2\x00\x8f\xff\x6d\xa4\x95\ -\x07\xc7\x71\x20\x46\x6b\x26\x02\x78\xf4\xdd\x70\x5c\xd7\x1f\x02\ -\x66\x96\x31\xc4\xf9\xb8\xbc\xf3\xcb\x70\xa6\x96\x46\x8d\xad\x44\ -\x0d\x6e\x09\xc7\x5a\xe5\x98\x1c\x57\x77\x7e\x15\xf8\xb4\x4e\xb2\ -\xcf\x47\xf7\x44\xed\x2e\xd2\xf7\xb5\xfd\xc8\x8e\xdc\x18\x2a\x80\ -\xc3\x3f\x3c\xf9\x7d\xf4\xd1\x03\x28\x73\x89\xe8\xd1\x91\xb5\x0c\ -\xdd\x12\xe0\x8d\x18\x52\x14\x61\x8a\x30\xe3\x4c\x1b\xfa\xd4\x4d\ -\xca\x3a\x1d\x4e\x1d\xf5\x7b\xb2\xe0\xa1\x3d\x38\x18\x27\xcd\x9b\ -\x35\x4a\x0b\x66\x3a\xaf\xf3\x79\x85\x61\xea\xba\xa8\xb6\x8b\xfb\ -\xbc\xc9\x97\x45\x76\xde\xfd\xcd\x0b\xaf\x4c\xbf\xf4\xd4\xd0\xcb\ -\xcc\x7f\x8f\x0d\x8d\xb0\x47\xfa\x60\x86\xba\x6f\x69\x68\xbf\xba\ -\xef\x63\x16\xf4\x89\xf1\xcf\x57\x71\x7d\x97\xd5\xfb\x0d\x59\x19\ -\x43\xf8\x70\x19\x27\x77\xbe\x06\x97\xe9\x22\x4e\x30\x2b\x6c\x8a\ -\xb8\xcd\x1e\x95\x28\xa4\x65\x04\x9b\x41\xe2\xe3\x91\x07\xa3\x45\ -\x7e\xd1\x11\x62\x00\x79\x45\x23\xc1\x18\x9f\x02\x9f\x73\x12\x7b\ -\xc5\x52\x85\x54\x6a\x95\x7e\x9c\x38\x7a\xab\x27\xc6\x7f\xbf\x87\ -\xd5\x9f\x83\xb7\x88\x18\x47\x7d\x11\xbe\xb6\x2b\x86\x74\x2c\x51\ -\xd9\x50\x23\xa4\x76\x2c\xe0\x72\x9f\x26\xd4\xb3\x96\x0b\xdd\xeb\ -\xd9\xee\xb3\x89\x00\x96\xb2\xdc\x0f\x2c\xf2\x3b\x58\x0a\x75\xfa\ -\xd0\x05\x01\x6b\x5d\x13\xc4\x08\x47\x6a\xf2\x85\x82\xfb\xe4\xc0\ -\x91\x1c\xf5\xb3\x89\xe0\x15\xed\xf4\x4c\x3b\x34\xb1\x9c\xa7\xfe\ -\xb7\xf4\x8f\x1f\x09\x1a\x14\xc3\x95\x13\xc2\xe3\x09\x89\x13\xbf\ -\x89\x43\x6d\x94\x52\x19\x19\x38\x9f\xdd\xdd\x74\x80\x9a\x36\x91\ -\xa1\xf9\x5f\xc1\x17\x43\xfb\x85\x66\x4b\x70\x58\x84\x6a\xa9\x34\ -\x73\xc4\xc7\x9f\x44\x0a\xeb\x3a\x6f\xe7\xf4\x70\x3d\xf1\x14\x5e\ -\xa1\xfe\x46\x86\x3a\xd5\xd9\x30\x8c\x01\x9d\xa1\xfe\xf8\x94\xb5\ -\x02\x74\x10\x7c\x14\xcd\x0d\x72\x97\x12\x0a\xad\x31\x61\xa8\xc8\ -\x0a\x0d\xa4\x86\xed\x9c\x60\x8a\xbd\x60\x27\x17\xf2\xdf\x69\xa9\ -\xbe\xbb\xdc\xdf\xcf\xc4\x75\x32\xfb\x26\xe5\xfa\xb3\x53\x0f\x6c\ -\xf5\x29\xab\xab\x71\xea\x41\xeb\x6d\xf5\xb1\xa7\xe8\xb7\x74\xd0\ -\x2b\x57\xf2\xb1\xc3\x9d\x4c\x94\x83\xb5\xbb\xce\xd4\x37\xa6\xdc\ -\x99\xc9\x3d\xd2\x48\x47\xd7\x69\x23\x63\x8c\x16\x93\x30\x19\xc8\ -\xbe\x55\xc5\x9c\x21\xc6\xdb\xea\x63\xf2\xee\x14\xb9\x0b\xcc\xd0\ -\x0f\x31\x4e\x0b\xab\x83\xe1\x7c\xf2\x17\x32\x70\x07\xc3\x2f\x42\ -\xf1\x65\x04\x52\x1a\xe0\x52\x70\x19\x60\x74\x66\x8c\x0a\xa7\x5f\ -\x62\xf7\x4c\x52\xa2\xc1\xc5\xf9\xc8\x92\x1c\xc3\xd5\x4b\xec\x48\ -\x0f\x52\xa3\xea\x58\x3f\x5d\x49\x87\x81\x9c\x63\x74\x44\x25\x12\ -\x42\x2a\xde\x4d\x53\xdc\x72\xb4\xa5\x93\x71\x6a\xd0\xb3\x69\xe3\ -\xba\x3d\x39\x2b\x65\x65\xea\xdb\x76\xad\x31\x77\xf2\x31\x99\x4c\ -\xe6\x8b\xba\x6a\xe1\xae\xb7\xa1\xc3\x54\x88\xb4\x44\xc5\xbb\xff\ -\x07\xc8\x77\x0b\x90\xf0\x99\x10\xe1\xfe\x52\xc6\x50\x2a\x4f\x47\ -\x48\x37\xdb\x19\x0c\x77\x27\x22\xe8\x3f\x0d\x91\x15\x11\xc8\xbf\ -\x02\x00\xc6\xc0\x39\x9c\x4f\xe2\x97\x40\x8c\xb9\x49\x29\x80\xb7\ -\xa3\xa0\x73\x52\x2f\x33\x4b\xf4\x5d\x94\x05\xf8\xc5\x8c\x61\x94\ -\xbf\xc0\xad\xd0\x4e\x1b\x34\x68\x9e\x59\x5a\x61\xad\x1a\xa3\x43\ -\xf4\xc1\xc1\xbf\x51\x6c\x38\x8a\xf3\xfd\x6d\xca\x73\xa1\xf1\xa5\ -\x6d\xdc\xd8\x91\xec\x6f\xe8\xf9\xb1\xc1\x15\x8f\x44\xb7\x1e\x84\ -\xe8\x0c\xba\xff\x82\x13\x24\xf1\xb7\x2c\x4e\x51\x63\x31\xd4\xfb\ -\xeb\x15\x13\x60\x78\x55\x52\x2b\xb9\x7f\x62\xde\x0a\x9e\xf3\x9e\ -\x28\x1a\xd9\xee\x00\xec\xa2\x60\xd3\xc6\x6a\xe3\x60\x27\x23\x1d\ -\x67\x13\xd6\xa3\x7d\xb7\x44\xa0\x5d\xeb\x24\xf2\xfb\xc6\x97\x79\ -\xae\x70\x78\x59\xf7\x34\x6c\xfa\x87\x87\x87\x23\xef\x89\x85\x43\ -\xfc\xf5\x21\xf3\xf7\x58\x92\x2a\x67\x89\xa5\x01\x67\x11\xd3\x0e\ -\x53\x93\x7f\xf0\x4d\x90\xff\x8b\x7e\x15\x78\xb2\x68\x81\xc6\x4d\ -\x21\x68\xd8\x64\xac\x21\xc8\x40\x7b\xa7\x07\x18\xf2\xbc\x3a\x21\ -\xc6\xf4\x4e\x24\x2f\xc5\x41\x97\x70\x50\x66\x94\x25\x3c\x16\xed\ -\xe9\x7d\x93\x30\xee\x6b\xdb\x83\x8b\xf9\xcd\xd5\xd9\x85\xbf\xe4\ -\xbe\x3a\xfb\x37\x6c\xd0\x04\x1c\ -\x00\x00\x16\x64\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x73\ -\x65\x74\x5f\x63\x75\x6d\x75\x6c\x61\x74\x69\x76\x65\x5f\x73\x74\ -\x72\x65\x74\x63\x68\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ -\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ -\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ -\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ -\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ -\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ -\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ -\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ -\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x31\x2e\x31\x32\x37\ -\x38\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x79\x3d\x22\x31\x37\x2e\x39\x39\x37\x31\x35\x36\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ -\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ -\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ -\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ -\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\ -\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\ -\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ -\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ -\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ -\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ -\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ -\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ -\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ -\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ -\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ -\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ -\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ -\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ -\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ -\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ -\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ -\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ -\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ -\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x66\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ -\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\ -\x38\x33\x37\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ -\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\x2e\x34\x35\ -\x31\x31\x34\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\ -\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\ -\x30\x2e\x38\x34\x33\x36\x37\x38\x34\x38\x2c\x30\x2e\x35\x33\x36\ -\x38\x34\x38\x37\x39\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ -\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x38\x39\x33\x37\ -\x32\x39\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\x39\x38\x2c\x30\ -\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x37\x2e\x37\x39\ -\x39\x37\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x33\x35\x2e\x39\x38\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\ -\x33\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ -\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x69\x6c\x6c\x3a\x23\x38\x66\x66\x66\x38\x66\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\ -\x30\x34\x39\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x66\x66\x61\x33\x61\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\ -\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ -\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\ -\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ -\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ -\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ -\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\ -\x31\x33\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x32\x33\x2e\x33\x32\x30\x36\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x79\x3d\x22\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ -\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ -\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\ -\x35\x30\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\ -\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\ -\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\ -\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\x30\ -\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x32\x31\x31\x37\x36\x34\ -\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ -\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x2d\x34\x2e\x30\x34\x30\x31\x33\x38\x34\x65\x2d\x31\ -\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x33\x2e\ -\x38\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\x36\x39\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x30\x37\x36\x32\x34\ -\x39\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\ -\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\ -\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\ -\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\ -\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ -\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\ -\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\ -\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\ -\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\ -\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\ -\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\ -\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\ -\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\ -\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\ -\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\ -\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\ -\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\ -\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\ -\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\ -\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\ -\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ -\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ -\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ -\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\ -\x36\x32\x37\x65\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ -\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x70\x78\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\ -\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\ -\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\ -\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x6d\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x20\x63\x20\x2d\x34\x2e\x30\x37\x34\x32\x30\x34\x2c\x30\x2e\x30\ -\x30\x31\x34\x20\x2d\x38\x2e\x33\x37\x31\x35\x35\x35\x35\x2c\x33\ -\x2e\x39\x39\x32\x38\x32\x33\x36\x20\x2d\x39\x2e\x36\x2c\x36\x2e\ -\x34\x20\x43\x20\x35\x2e\x31\x37\x31\x35\x35\x35\x35\x2c\x39\x2e\ -\x38\x37\x33\x38\x34\x33\x20\x33\x2e\x30\x38\x34\x32\x38\x33\x2c\ -\x31\x38\x2e\x39\x31\x31\x35\x36\x34\x20\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x2c\x32\x35\x2e\x36\x20\x30\x2e\x30\x35\x37\x38\x35\ -\x38\x36\x37\x2c\x32\x38\x2e\x39\x34\x34\x32\x31\x38\x20\x2d\x31\ -\x2e\x38\x30\x38\x38\x30\x38\x2c\x33\x30\x2e\x32\x37\x37\x35\x35\ -\x31\x20\x2d\x32\x2e\x33\x35\x36\x36\x30\x36\x2c\x33\x30\x2e\x37\ -\x37\x34\x38\x33\x20\x2d\x32\x2e\x39\x30\x34\x34\x30\x34\x31\x2c\ -\x33\x31\x2e\x32\x37\x32\x31\x30\x39\x20\x2d\x33\x2e\x32\x2c\x33\ -\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x32\x2c\x33\x30\ -\x2e\x39\x33\x33\x33\x33\x33\x20\x63\x20\x30\x2e\x37\x30\x36\x38\ -\x37\x35\x37\x2c\x30\x2e\x31\x35\x38\x36\x32\x39\x20\x30\x2e\x34\ -\x34\x30\x34\x38\x31\x33\x2c\x31\x2e\x30\x31\x35\x33\x37\x32\x20\ -\x30\x2e\x31\x33\x30\x35\x36\x35\x31\x2c\x31\x2e\x38\x30\x34\x30\ -\x38\x37\x20\x2d\x30\x2e\x33\x30\x39\x39\x31\x36\x32\x2c\x30\x2e\ -\x37\x38\x38\x37\x31\x33\x20\x2d\x30\x2e\x36\x36\x33\x33\x35\x34\ -\x31\x2c\x31\x2e\x35\x30\x39\x33\x39\x39\x20\x2d\x30\x2e\x31\x33\ -\x30\x35\x36\x35\x31\x2c\x31\x2e\x33\x39\x35\x39\x31\x33\x20\x30\ -\x2c\x30\x20\x30\x2e\x32\x36\x30\x34\x35\x35\x36\x2c\x31\x2e\x35\ -\x33\x32\x30\x34\x31\x20\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x2c\ -\x30\x20\x31\x2e\x38\x37\x32\x38\x37\x37\x37\x36\x2c\x2d\x31\x2e\ -\x35\x33\x32\x30\x34\x20\x35\x2e\x33\x35\x38\x31\x37\x37\x36\x2c\ -\x2d\x33\x2e\x39\x39\x34\x38\x32\x37\x20\x36\x2e\x34\x2c\x2d\x38\ -\x2e\x35\x33\x33\x33\x33\x33\x20\x43\x20\x37\x2e\x34\x31\x36\x39\ -\x37\x38\x31\x2c\x31\x36\x2e\x35\x32\x32\x39\x38\x38\x20\x39\x2e\ -\x35\x37\x36\x37\x38\x34\x2c\x35\x2e\x32\x38\x32\x39\x30\x35\x31\ -\x20\x31\x36\x2e\x31\x37\x35\x35\x34\x39\x2c\x35\x2e\x33\x32\x34\ -\x32\x38\x35\x20\x32\x32\x2e\x34\x2c\x36\x2e\x34\x20\x32\x31\x2e\ -\x33\x33\x33\x33\x33\x33\x2c\x39\x2e\x36\x20\x32\x36\x2e\x36\x36\ -\x36\x36\x36\x37\x2c\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\x63\ -\x20\x32\x2e\x34\x31\x37\x33\x38\x34\x2c\x36\x2e\x32\x38\x35\x32\ -\x20\x36\x2e\x34\x2c\x39\x2e\x36\x20\x31\x30\x2e\x36\x36\x36\x36\ -\x36\x36\x2c\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x20\x36\x2e\x34\ -\x2c\x31\x2e\x30\x36\x36\x36\x36\x37\x20\x35\x2e\x33\x33\x33\x33\ -\x33\x34\x2c\x30\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\x30\x20\ -\x43\x20\x34\x34\x2e\x38\x2c\x33\x32\x20\x34\x33\x2e\x37\x33\x33\ -\x33\x33\x33\x2c\x33\x35\x2e\x32\x20\x34\x32\x2e\x36\x36\x36\x36\ -\x36\x37\x2c\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x34\x31\x2e\ -\x39\x32\x34\x35\x30\x33\x2c\x33\x31\x2e\x31\x38\x30\x37\x32\x31\ -\x20\x33\x35\x2e\x30\x35\x38\x33\x34\x37\x2c\x33\x32\x2e\x33\x32\ -\x36\x32\x35\x32\x20\x33\x32\x2c\x32\x35\x2e\x36\x20\x32\x38\x2e\ -\x39\x34\x31\x36\x35\x33\x2c\x31\x38\x2e\x38\x37\x33\x37\x34\x38\ -\x20\x32\x37\x2e\x34\x38\x30\x35\x39\x35\x2c\x31\x31\x2e\x33\x30\ -\x39\x36\x35\x33\x20\x32\x35\x2e\x36\x2c\x37\x2e\x34\x36\x36\x36\ -\x36\x36\x37\x20\x32\x33\x2e\x37\x31\x39\x34\x30\x35\x2c\x33\x2e\ -\x36\x32\x33\x36\x38\x20\x32\x31\x2e\x37\x35\x39\x31\x38\x37\x2c\ -\x31\x2e\x31\x31\x34\x34\x33\x35\x35\x20\x31\x36\x2c\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ -\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ -\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ -\x3d\x22\x63\x7a\x73\x73\x63\x73\x63\x73\x73\x63\x73\x63\x63\x63\ -\x73\x7a\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\ -\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\ -\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\ -\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\ -\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\x30\x30\ -\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\ -\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\ -\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\ -\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\ -\x42\x6f\x6c\x64\x27\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ -\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\ -\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x38\x39\ -\x38\x39\x38\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x36\x36\x36\ -\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\ -\x74\x33\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\ -\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x34\x2e\x32\x36\x36\x36\x36\x36\x39\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x79\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\ -\x73\x69\x7a\x65\x3a\x32\x35\x2e\x36\x30\x30\x30\x30\x30\x33\x38\ -\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\ -\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ -\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x32\x22\x3e\x25\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\ -\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0a\ -\x00\x00\x07\x98\ -\x00\ -\x00\x2c\xab\x78\x9c\xed\x5a\x5b\x6f\xdb\xd8\x11\x7e\xf7\xaf\x50\ -\xe5\x97\x04\x0d\xc9\x73\xbf\x28\x92\x17\x48\x83\x5d\x2c\xd0\xa7\ -\xed\x16\x7d\x0c\x68\xf2\x48\x66\x43\xf1\x08\x24\x65\x49\xfb\xeb\ -\x3b\x87\x14\xaf\xa2\x36\x29\x52\xc0\xae\x12\x39\x86\xc3\x99\x39\ -\x97\xf9\x66\xce\x37\xc3\x63\x2f\x7f\x3a\x6e\xd3\xd9\xb3\xc9\x8b\ -\xc4\x66\xab\x39\xf6\xd1\x7c\x66\xb2\xc8\xc6\x49\xb6\x59\xcd\xff\ -\xf9\xfb\xcf\x9e\x9a\xcf\x8a\x32\xcc\xe2\x30\xb5\x99\x59\xcd\x33\ -\x3b\xff\xe9\xe1\x6e\xf9\x17\xcf\x9b\xfd\x2d\x37\x61\x69\xe2\xd9\ -\x21\x29\x9f\x66\xbf\x66\x9f\x8b\x28\xdc\x99\xd9\x9b\xa7\xb2\xdc\ -\x2d\x82\xe0\x70\x38\xf8\xc9\x59\xe8\xdb\x7c\x13\xbc\x9d\x79\xde\ -\xc3\xdd\xdd\xb2\x78\xde\xdc\xcd\x66\x33\x58\x37\x2b\x16\x71\xb4\ -\x9a\x9f\x07\xec\xf6\x79\x5a\x19\xc6\x51\x60\x52\xb3\x35\x59\x59\ -\x04\xd8\xc7\xc1\xbc\x33\x8f\x3a\xf3\xc8\xad\x9e\x3c\x9b\xc8\x6e\ -\xb7\x36\x2b\xaa\x91\x59\x71\xdf\x33\xce\xe3\x75\x6b\xed\x76\x73\ -\xa0\x95\x11\xd6\x5a\x07\x88\x04\x84\x78\x60\xe1\x15\xa7\xac\x0c\ -\x8f\xde\x70\x28\xec\x71\x6a\x28\x41\x08\x05\xa0\xeb\x2c\xbf\xce\ -\x6a\x51\x00\xa0\x3b\xf8\x6e\xcd\x1b\x81\x5f\xd8\x7d\x1e\x99\x35\ -\x8c\x33\x7e\x66\xca\xe0\xe3\xef\x1f\x5b\xa5\x87\xfc\xb8\x8c\x7b\ -\xd3\x34\x78\x0e\x56\x1d\x80\x9c\x85\x5b\x53\xec\xc2\xc8\x14\x41\ -\x23\xaf\xc6\x1f\x92\xb8\x7c\x5a\xcd\x29\xf3\x31\x85\x0f\xaf\x84\ -\x4f\x26\xd9\x3c\x95\x63\x69\x12\xaf\xe6\xb0\x7b\xa2\x55\xfd\xdc\ -\x4b\x0e\x5c\x1b\x9c\x27\x5e\xb4\x1a\xe4\x6b\xe2\xe3\x59\x8e\x39\ -\x95\xb5\x4d\xe3\xc2\x22\xb6\x91\xdb\x13\x4c\x69\xb6\x49\xb8\x2f\ -\xed\x16\xa2\x16\x45\x69\x58\x14\xc9\x3a\x89\xe0\xc1\x66\xbb\x74\ -\xbf\x49\xb2\x4f\x51\x6a\xf7\xf1\xa7\x6d\x58\x7c\x86\xe4\xfb\x54\ -\x5a\x9b\xfa\x0d\x8a\xed\x92\xe6\xb8\xb3\x79\xe9\x1d\xe3\x1d\x60\ -\x29\xe4\xa4\xf2\xd4\x57\x3e\x27\xe6\xf0\xc1\x1e\x61\x8f\x33\x34\ -\xa3\x04\xfe\xcd\x1f\x40\xbe\x8c\xcd\xba\x70\xfa\xda\x5f\xf7\x04\ -\x0e\xcb\x4a\x07\xda\x75\x92\x96\x26\xaf\xf5\xbd\x05\x22\x9b\xa6\ -\x26\x02\xc4\xc2\xf4\x10\x9e\x8a\x79\x63\x50\x94\xa7\x14\x5c\x04\ -\xb5\xcd\xbd\x24\x83\xa1\x3b\x9b\x56\xae\x79\xf5\x4c\x90\x01\xbf\ -\xfd\xf2\xa1\xb5\x77\x4b\xd6\x0a\x8c\x34\x6b\xc5\xb0\x4b\x08\x39\ -\x26\x9a\x71\x85\x48\x2b\x3e\xc7\x0e\xfb\x84\x2b\x8d\x45\x2b\x3f\ -\x55\xe6\x84\x4a\x46\x99\xa4\xad\xb8\x89\x2a\xf6\x99\x64\x4a\x68\ -\x7e\x76\xca\xb9\x65\x7e\x09\xf7\x00\x7c\x98\x7d\x48\xf7\xad\x7b\ -\x5f\xe1\xa0\x73\x31\xfe\x68\x9e\x93\xca\x29\x17\x70\x8a\x05\xc6\ -\x42\xa8\x9e\x49\xe5\xd5\x60\x05\xf0\x4e\xcc\x67\xc1\x19\xd4\xa0\ -\x76\xf9\x05\x20\x56\x63\x88\xa9\x66\x58\xf0\x09\x84\xa5\x52\x94\ -\x8e\x11\xd6\x48\x0a\xca\xc5\x04\xc2\x5c\x61\x4e\x20\xe5\x5f\x0e\ -\x61\x8c\xd0\xcb\x23\x8c\x7b\xd9\x7a\x46\x98\x29\xce\xd5\x99\x0c\ -\x86\x10\x6b\x89\xb1\x64\x63\x8c\x41\xa4\xdc\x01\x9c\xc8\x62\xca\ -\xb4\xd4\xf2\x45\x31\x66\xaf\x01\x63\x31\xc2\x98\x50\x42\x05\x65\ -\x13\x18\x33\xc1\x24\xe9\x79\x55\x63\x4c\x99\xa0\x84\xf7\x42\xd5\ -\x61\x2c\x34\x11\x2f\xc9\x13\x18\xa9\x57\x80\x30\x46\x37\x4c\xc5\ -\x18\x93\xd7\x00\xf1\x45\xb5\xbb\x21\x2a\xc6\xaf\xa0\xd8\x61\x7c\ -\x51\xec\x6e\x8a\x8a\xc9\x6b\x28\x77\x64\x5c\xee\x6e\x89\x8a\xc9\ -\x6b\x28\x76\x64\x5c\xec\xce\x54\x3c\x95\xc5\xff\x7f\x54\x4c\x5e\ -\x43\xb5\xa3\x17\xd5\xee\x86\xa8\x98\xbe\x86\x62\x47\x2f\x8a\xdd\ -\x4d\x51\x31\x7d\x0d\xe5\x8e\x8e\xcb\xdd\x2d\x51\x31\x9b\x2e\x76\ -\xcb\xc0\xdd\x57\x54\xff\x6b\xef\x59\xdc\x25\x4b\xec\x2e\x3b\xee\ -\xda\xd9\x1e\xc3\xc2\x9c\x17\xd8\x85\x1b\x53\xc1\xbb\x9a\xdf\xaf\ -\xab\xcf\x59\xf1\x68\xf3\xd8\xe4\x8d\x4a\x54\x9f\x81\xca\xee\xc2\ -\x28\x29\x4f\xf5\xd5\xe0\xdd\xd0\x5f\x37\x6b\xab\x47\xd3\xfa\xe2\ -\x29\x8c\xed\x61\x35\x27\x63\xe5\x1f\xd6\x6e\x57\x73\xea\x6b\xae\ -\x11\x41\x7a\xac\x8e\x5c\x34\x31\xc3\xbe\xe2\x8a\xb3\x0b\x2d\x2c\ -\xa8\x7d\x02\xac\xc4\x15\xbd\x50\xee\xf3\xdc\x64\xa5\x97\x86\x27\ -\x03\x5e\x55\x3f\x9a\x74\x28\x9e\xec\x61\x93\x3b\x74\xca\x7c\x6f\ -\xc6\x23\x9d\xc6\x7b\x7c\x74\xd7\x45\x53\xea\xd8\x46\x7b\x77\x2d\ -\xe9\xed\xb3\xa4\x2c\x56\xf3\xdd\xb1\x3f\xeb\x3e\x89\x4d\x31\x3d\ -\xb0\xc8\xc2\x9d\xb7\x49\xed\x63\x98\x4e\x1b\x1c\x92\x0c\x50\xf2\ -\x9a\x54\xa5\x6d\x10\xc6\x16\x4d\x72\x4a\xa4\xae\x58\xb8\xab\xae\ -\x2b\xaa\xd3\x75\xd5\x36\x3c\x26\xdb\xe4\x0f\x03\xc0\xe0\x0b\x54\ -\x9c\x67\x7d\x58\xce\x19\x39\x80\xad\x49\xe4\xf2\xe4\xae\x27\x8f\ -\x27\x27\x1b\x1c\x58\x27\x20\x5a\x77\x5c\x66\xf3\x64\x93\x64\xbd\ -\xed\x36\xa2\x53\x5f\xe4\x2e\x33\x93\x6c\x73\xec\xf6\xd5\xca\x5c\ -\x52\x9e\xcf\xc7\x32\xb8\x3c\x08\x95\x7c\x6b\xca\x30\x0e\xcb\xb0\ -\x3b\x15\x8d\x04\xf6\x82\x1a\x4f\xf2\x78\xbd\xf8\xed\xe3\xcf\xed\ -\x49\x8f\xa2\xc5\xbf\x6c\xfe\xb9\x3b\x9c\xce\x20\x7c\xb4\x7b\x40\ -\xbe\xe5\x03\x77\x89\x18\x2d\xd6\x36\xdf\x86\xe5\x43\xb2\x85\x5c\ -\x77\x97\xbe\x7f\x3d\x6e\x53\x38\x9f\xad\x62\x60\xec\xc0\xe9\x26\ -\xad\xa7\xcd\x4d\x7d\x05\x3c\x79\x0f\x1e\x47\xdb\xc4\x0d\x0a\xfe\ -\x51\x26\x69\xfa\xab\x5b\xa4\x65\x84\x76\xd2\xa4\x4c\x4d\x27\x5c\ -\x06\xe7\xdd\x37\xbc\xd1\x73\x6e\x19\x34\xde\x57\x4f\x9b\x0e\x95\ -\xc1\x21\x69\x03\x9b\x86\x8f\x06\x32\xf6\xef\x4e\x39\xbb\xcc\x8b\ -\xdc\xee\x77\x5b\x1b\x9b\xf3\xf0\x16\x4d\xe0\xc0\x11\xb5\x03\x77\ -\xa5\x8b\x7b\x84\x38\x8f\xd9\x7b\xf7\xe0\x9d\x79\x63\x81\xeb\xc7\ -\x7c\x9f\x9a\x85\x79\x36\x99\x8d\xe3\xf7\x45\x99\xdb\xcf\xc6\xd9\ -\xbb\xcf\xf9\xb1\x3e\x1c\x0b\xec\x63\x2d\xa4\x26\x84\x35\x72\x40\ -\xc8\xe4\x29\x64\x6f\xb9\x68\x65\x71\x08\xbc\x93\xe7\xe1\x69\x91\ -\xd9\xcc\x34\xd2\x76\xcd\x41\x62\xba\xed\x42\x32\x74\xfd\x4d\x73\ -\x0a\xa5\x0f\x0c\xdc\x27\xe9\xb6\x32\x30\x9f\x30\xcd\x45\x37\x0f\ -\xa4\x27\xa7\x3e\x34\x3d\xbc\xd7\x3f\x41\x7e\x32\xe1\x73\x44\x69\ -\xaf\x82\xe7\xc7\xaa\x14\x21\xa5\x04\xea\x66\xce\x4f\x75\x67\x0a\ -\x45\x5d\x75\xd2\x32\x0f\xb3\xc2\xe5\x11\x64\x6d\x58\xe6\xc9\xf1\ -\x0d\x7e\x87\xde\x41\xcd\x52\x1c\x21\x2a\x24\x7d\x87\x60\x4d\x21\ -\x09\x65\x04\x14\xe8\x6d\xe7\xd7\x9f\xdd\x97\x4f\x19\xb4\x77\xe6\ -\x6d\xbd\xe9\x47\xf1\xea\x46\xa0\x03\xc1\xee\x1b\x36\x22\x10\xb4\ -\xdc\x40\xe4\xc3\x8d\xd4\x8e\x71\x21\x61\x93\xfa\x0b\x20\x80\x29\ -\x21\xbe\x46\x40\x7f\xb4\x8f\x2c\x25\xd0\xe3\x33\xa6\x26\x4a\x34\ -\x87\x6c\x60\x54\xaa\x2f\xc7\xae\x89\x34\x95\x3d\x14\x46\xd9\x19\ -\x86\x90\x6d\xdf\x9a\x9d\x58\x2a\x0e\x30\x7c\x4b\x76\x4e\xc6\x60\ -\xb0\xd7\xf5\xba\x5a\xfb\x1b\xf7\x8a\xa0\x7f\x57\x4c\x93\xff\xe5\ -\x49\x02\x7c\xf5\x7f\x71\x92\x04\x84\x16\x4a\xf8\xe0\x24\x41\x54\ -\x89\x26\x8c\x0d\x4e\x12\xf6\x25\x95\x84\xf5\x42\xfd\x67\x27\x49\ -\x48\xc6\xc9\x97\xcf\x11\x58\xc1\x9b\x26\x93\x2e\x7d\x05\x74\x7b\ -\xf4\x7c\x8c\xda\x00\x98\x34\x4d\x76\x85\x19\xc5\x60\x88\xf8\xe2\ -\xde\x08\xf7\xd5\x82\x5d\x37\x58\x43\xb0\x11\x74\x9f\x4a\x32\xad\ -\x55\x23\x4f\x93\xcc\xc0\x09\x5c\x00\x89\x66\x71\x5f\xf8\x6f\x9b\ -\x64\x8b\x2a\x14\x13\x71\x21\x3e\xff\xca\xc8\xbc\xaf\xfb\xc5\x05\ -\x54\x93\x37\xf7\x5d\xb7\xfc\x76\x10\xb1\x5d\x58\x3e\x29\xd5\x01\ -\xed\xba\x2e\x0c\xa0\x62\xe8\xb9\xba\x98\xb8\x6e\x8b\x40\xbb\x85\ -\x14\x62\x64\x84\xbf\x6b\x9e\x89\x1e\xc1\x8f\x34\xa7\x04\x5e\xb1\ -\x6f\x17\x47\x36\x89\xa3\x47\x87\x48\x42\x22\x0b\x2d\x19\x1d\x22\ -\x29\x7d\x4d\x31\x51\x6c\x80\x24\x6c\x88\x53\xe7\xdb\x08\x4a\xc9\ -\x18\x96\xf0\xf2\x7d\xbb\x50\xa2\x69\x28\xc5\x10\x4a\x09\x2f\xc3\ -\x54\x69\x31\x4e\x4a\x0c\x9d\x70\x0f\xe0\x1a\x4a\x09\x04\x8c\xc9\ -\x08\x49\x8a\xe0\x4d\x8f\xdd\x2e\x90\x44\x4c\x03\x29\x07\x40\x12\ -\x68\x19\xb0\x80\xf6\x65\x9c\x93\x88\x72\x4d\xc5\x08\x48\x4d\x11\ -\xc1\x42\x8c\x90\xe4\x5a\x0a\x81\xc8\x0d\x43\x49\xa6\xa1\xbc\x20\ -\x4a\x2d\x15\xe2\x6c\x00\x25\xd6\x3e\x92\x8a\xaa\x71\xa1\xfa\x3e\ -\x89\x12\x4f\x17\x1c\x8f\x5e\x52\xa5\x82\xa2\xcf\xf9\x10\x4b\xe9\ -\x2b\x84\xc5\xf8\x78\x7f\xa7\x4c\x89\xaf\x14\x1d\x31\xce\x4b\xe9\ -\x4b\x78\x93\x40\xfa\x22\x2f\x19\xc4\x43\xff\xe0\x4a\xf7\x9b\xde\ -\x2b\x5c\x39\x2a\x3b\x04\x8e\xa8\xe4\x52\x90\x21\x94\x02\xde\x52\ -\x04\x51\x64\x92\x2d\xe9\xf7\xc6\x96\xe8\x4a\xe1\x21\xc3\xac\x24\ -\x3e\x72\x77\xb3\x6a\x00\xa5\xf0\xa9\xc0\x1c\xe1\xf1\x0b\xf2\xf7\ -\xc9\x96\xe8\x4a\xdd\xa1\x9e\xbe\x60\x4b\xa0\xbb\x61\xe1\xe1\x3e\ -\x74\x42\xd0\x6c\xf2\x1f\x6c\x59\xff\xd1\xd7\x35\xb6\xc4\x63\xb6\ -\x54\xf0\xba\xa3\xc9\x38\x2f\x09\x83\xe3\x2c\x7f\xb0\xa5\xfb\x13\ -\xc5\x6b\x6c\x49\xc6\x6c\x89\x01\x1f\x36\x2c\xe2\xcc\x87\xa2\x43\ -\x35\x1f\x17\x9e\xaf\x61\xcb\x65\xb0\x79\xb8\x5b\xba\x7b\xd5\x87\ -\xbb\xff\x00\x92\xa3\x93\xf5\ -\x00\x00\x07\x3d\ -\x00\ -\x00\x54\xb5\x78\x9c\xe5\x9c\x4b\xaf\xa3\x36\x14\xc7\xf7\xf7\x53\ -\x50\x66\xd3\xaa\x63\x30\xaf\xf0\x98\x24\xb3\xe8\xa8\x52\xa5\xae\ -\xda\xa9\xba\xac\x1c\x70\x12\x3a\x04\x23\x20\x37\x49\x3f\x7d\x6d\ -\x5e\x81\xe0\x3b\xed\xc8\x8e\x64\x25\x91\x46\x23\x7c\x8e\xc1\xfc\ -\xf0\xb1\xff\x1c\xfb\xb2\xfc\x78\x3e\x64\xda\x2b\x2e\xab\x94\xe4\ -\x2b\xdd\x32\xa0\xae\xe1\x3c\x26\x49\x9a\xef\x56\xfa\x1f\x9f\x7f\ -\x06\x81\xae\x55\x35\xca\x13\x94\x91\x1c\xaf\xf4\x9c\xe8\x1f\xd7\ -\x2f\xcb\xef\x00\xd0\x7e\x2a\x31\xaa\x71\xa2\x9d\xd2\x7a\xaf\xfd\ -\x92\x7f\xa9\x62\x54\x60\xed\xfb\x7d\x5d\x17\x91\x69\x9e\x4e\x27\ -\x23\xed\x0a\x0d\x52\xee\xcc\x1f\x34\x00\xd6\x2f\x2f\xcb\xea\x75\ -\xf7\xa2\x69\x1a\xbd\x6e\x5e\x45\x49\xbc\xd2\xbb\x0a\xc5\xb1\xcc\ -\x1a\xc7\x24\x36\x71\x86\x0f\x38\xaf\x2b\xd3\x32\x2c\x53\xbf\xba\ -\xc7\x57\xf7\x98\x5d\x3d\x7d\xc5\x31\x39\x1c\x48\x5e\x35\x35\xf3\ -\xea\xdd\xc8\xb9\x4c\xb6\x83\x37\x6b\xcd\xc9\x69\x9c\xac\x30\x0c\ -\x4d\x68\x9b\xb6\x0d\xa8\x07\xa8\x2e\x79\x8d\xce\x60\x5a\x95\xb6\ -\x91\x57\xd5\x86\x10\x9a\xd4\x76\xf5\xfc\x7f\x5e\x51\x45\x81\x16\ -\xf4\xdf\xe0\xde\x17\x18\x15\x39\x96\x31\xde\xd2\x7a\xd8\xc8\x71\ -\x6d\x7e\xfa\xfc\x69\x30\x02\x68\x24\x75\x32\x3a\x4d\xcf\x73\x72\ -\xd5\x09\xe4\x1c\x1d\x70\x55\xa0\x18\x57\x66\x5f\xde\xd4\x3f\xa5\ -\x49\xbd\x5f\xe9\x8e\x6b\x58\x0e\xfd\x79\x4d\xe1\x1e\xa7\xbb\x7d\ -\x7d\x5b\x9a\x26\x2b\x9d\xb6\xde\x0e\x83\xf6\x78\xd4\x39\xac\xd6\ -\xa1\x3b\x71\x34\x58\xa0\x11\xda\x86\xa5\x95\x96\xe7\xf8\xad\x4f\ -\x7f\x0b\x51\x42\x62\xd6\x26\x7a\x4a\x7c\x48\xd1\xb1\x26\x07\xfa\ -\xd4\xe2\x38\x43\x55\x95\x6e\xd3\x98\x1e\x90\xbc\xc8\x8e\xbb\x34\ -\xff\xab\x28\xf1\x6b\x8a\x4f\x46\x8f\x6e\xb8\x0e\x3e\x17\xa4\xac\ -\xc1\x39\x29\x28\xc0\x85\xcf\x35\x5e\x7a\xe3\x9a\x5a\x97\x09\xde\ -\x56\xcc\xab\xbd\x1b\x76\x44\x6f\xc7\xd7\x35\xb3\xb1\x0e\x8d\x63\ -\x2d\x4b\xd8\x35\xaf\xbe\x1b\x54\xb5\xc4\x34\xad\x40\x3b\xda\xbb\ -\x32\x52\xae\xf4\x77\xdb\xe6\xd7\x19\x36\xa4\x4c\x70\xd9\x9b\x16\ -\xcd\x6f\x62\x22\xf4\x09\xa4\xf5\xa5\x8d\xa7\xee\xdc\x7d\x7b\xd9\ -\x59\x07\x3b\xe4\xdb\xab\x3d\x4a\xc8\x69\xa5\xdb\xb7\xc6\x7f\x08\ -\x39\xac\x74\xdf\x08\xad\x00\xba\x96\x7f\x6b\x8e\xcf\x2b\x1d\x38\ -\x8e\x61\x3b\xd0\xf7\x9c\x99\x95\x35\xc8\x35\x1c\x3f\x70\xec\xd9\ -\x99\xe3\x63\x59\xd2\x88\x03\x19\xba\x60\x7a\x57\xcd\x7f\x56\xe7\ -\x54\xed\xc9\x69\x57\x32\x3a\x75\x79\xc4\xb7\x35\x99\x05\x6c\x36\ -\xe4\xcc\x37\xd3\x0e\x70\x64\xb1\x0c\x8e\x79\x5a\xd3\x78\x29\xce\ -\xe3\xb3\x1e\xd3\x04\x57\xfc\x8a\x55\x8e\x0a\xb0\xcb\xc8\x06\x65\ -\x7c\x87\x53\x9a\x53\x4a\xa0\xeb\xda\x96\x33\x3c\x84\x5b\x8f\xbe\ -\x9f\xfb\x30\x78\xc3\x83\xb6\x7d\xf6\x20\x3a\xd3\xe5\x6d\xd3\x01\ -\x9d\xd3\x43\xfa\x0f\xa6\x60\xac\xa6\xdf\xd1\xbe\x35\xc1\xd2\x56\ -\xd3\xb4\xfa\xc2\x62\xf6\x7c\x61\x65\x7a\x5f\xc8\x78\xb2\x02\x3b\ -\x0c\xfd\xa1\x90\x94\x29\x0d\x85\x51\x73\xfa\xa2\xcb\xb8\x88\x45\ -\x38\x1d\xa0\xcf\x4d\x07\x6b\xba\x9f\x7f\x6b\xbb\x8c\x6d\x5d\xbf\ -\x37\xe7\x1d\xbf\x29\x3f\xe0\x1a\x25\xa8\x46\xd7\x28\xe8\x4b\x68\ -\xdb\x60\x7f\x67\x74\xb0\x8c\x7e\xfb\xf4\xf3\xba\xbb\xd0\x32\x8e\ -\xa3\x3f\x49\xf9\xa5\xbf\xae\xa6\x31\x07\xb4\x21\x47\x4a\x5a\x5f\ -\x0f\xc5\xcb\x24\x8e\xe8\xf0\x46\xc3\x7e\x9d\x1e\x68\xdf\x66\x23\ -\xe3\x8f\x74\x38\x5b\x9a\x57\xc3\xc4\x99\xc1\xba\x9e\xb4\x3d\x6d\ -\x89\xdb\x71\x92\x3b\x59\x24\xf1\x21\x65\x95\xcc\xdf\xeb\x34\xcb\ -\x7e\x61\x17\xe9\xee\x78\x74\xd2\xb4\xce\xf0\xb5\x70\x69\x76\xad\ -\xef\xee\xcd\x1c\xdd\xdc\xd2\xec\xef\xbe\x39\xda\x5d\xa9\x4c\x82\ -\x62\x78\xd0\x19\xda\x60\xda\x43\x7f\x65\x46\x6d\x66\xdd\x95\xe4\ -\x58\x1c\x48\x82\xbb\xea\x03\x4d\x1c\xd7\xc3\x23\xab\x2f\x19\xb5\ -\x6f\x69\xeb\xa3\x77\x10\xc6\xf1\x76\xfb\x81\x1d\x80\x6e\x9c\x88\ -\xac\xf6\xb0\x3c\x66\x74\xbc\x7b\xc5\x39\x49\x92\x0f\x55\x5d\x92\ -\x2f\x38\xea\x46\xa6\xee\xb0\x0d\x86\x08\xf6\x87\x14\x0c\x2e\x33\ -\xda\x49\xeb\xc8\xed\xcb\x12\x44\x87\x97\xb2\x44\x97\x28\xa7\x33\ -\x7a\x5f\x3a\x5c\x6a\xd2\x3f\x59\x2b\xbd\xc0\x09\x87\xc2\x2e\xd8\ -\x5c\xc3\x6e\xba\xd6\xd5\xd0\xc7\xd8\xdc\x32\xe9\xcc\x17\x9e\x47\ -\x39\x71\x29\x9b\xae\xeb\xda\xec\xe7\x0c\x0f\xf2\x6b\xc0\x10\x4a\ -\x5c\xc5\x80\x01\x4b\x10\xd9\xbc\xf0\x2e\xe8\x16\x8b\x00\x2a\x87\ -\x0e\x04\x82\xf0\x02\xc3\x63\x7a\xc6\x09\xee\x0b\xcf\x75\x3d\x4f\ -\x3d\x78\x50\x10\x9e\x65\x1b\x77\xe5\xb6\xdd\xda\xc8\x46\xca\x71\ -\x73\x44\xb1\xf9\xed\x74\xfb\x8c\xec\x80\x2f\x08\xcf\xb6\x8c\x26\ -\x60\xdd\x67\x84\x17\x00\x4f\x14\x9f\x67\x2c\x9e\x91\x1c\x04\xa2\ -\x51\x6b\x87\x46\x30\xd5\xcf\xcf\xa3\x50\x80\x2b\x08\x8f\xab\x51\ -\xa0\x34\x68\x8a\x6a\x13\x61\x69\xc7\x55\x27\xf2\xb0\x29\xaa\x4a\ -\x84\xe7\x88\x5b\x5d\x22\x8b\xd8\x76\x1b\x86\x0a\x12\x73\xc0\x42\ -\x14\x18\x4f\x91\x3c\x38\x35\xe0\x03\x5b\x10\x1b\x57\x8b\x3c\x3a\ -\x36\xaa\x41\x80\xe8\x5b\xfe\xad\x0a\x91\x37\xa4\x29\x98\x11\x11\ -\x7e\x47\x9d\xe4\x44\x26\x63\xdb\x63\x8a\x8d\x40\x14\x18\x57\x6d\ -\x48\x05\xa7\xaa\xe0\x10\x0d\x4c\xae\xe0\x90\x4a\x4e\x55\xcd\x21\ -\x3c\x85\xde\x68\x0e\x89\xd0\x02\xc8\x7e\xca\x41\x73\x84\xe7\x4f\ -\xae\xec\x78\x7c\x70\x54\x79\x08\xbf\x8c\xf2\x94\xc7\x13\x90\x63\ -\xe2\x43\x74\x76\xb8\x15\x1f\x4f\x80\x0d\x02\x47\x3c\xf1\xc6\xcb\ -\x7f\x48\x9d\x1a\x54\xd4\x6e\x50\x38\xf5\x31\x51\x6f\xf3\xf9\xf5\ -\x31\x25\x9c\x2b\x3c\x37\x70\x35\x9c\x7c\x7c\xaa\x0a\x39\x4b\x38\ -\xd3\xcb\x95\x72\xf2\x01\xaa\xaa\xe7\x7c\x61\x2d\x7c\xab\xe8\x64\ -\xb3\x4b\x5c\x25\x27\x0b\x07\x2c\xee\x23\xec\x9e\x84\x1f\xcb\x2b\ -\xdd\x67\x95\xeb\x59\x00\x36\x19\x26\xe1\xc5\xe9\x5b\x99\xf7\x2c\ -\xf4\x98\xd6\xb3\x85\x57\x1e\xb8\x6a\x4f\x36\x42\x36\xf9\xaa\x87\ -\x10\x8a\xbe\x9c\x4d\x14\xdf\x3c\x92\x1f\x91\x99\x25\x9c\x3f\xe1\ -\xea\xbd\x67\x81\x17\x08\x4f\x18\x5c\xb5\xf7\x2c\xf8\xa0\x70\x4e\ -\xe0\x56\xeb\xc9\x26\x07\x21\x7d\x34\xea\x91\xa3\x33\x85\xf0\x5a\ -\x2b\x4f\xea\xc9\xc7\xe7\xba\x48\xc1\x5d\x25\xbe\xf8\x7e\x1c\x9e\ -\xd0\x93\x8d\xcf\x46\xfe\x56\xbd\xd4\x4a\x2b\xf4\x84\x33\xa1\x37\ -\x32\x4f\x36\xbb\xc0\x47\x28\xc1\xea\xb1\x6b\x52\x7a\x77\xd9\xd3\ -\x24\x9b\x20\xcb\x10\xa8\x37\x6b\x88\xef\x32\x99\x2e\xcb\xce\x86\ -\xc1\x47\x84\xc6\x12\x7b\x77\x11\x7a\xcf\x82\xaf\x49\xec\xdd\x25\ -\xb3\xf7\x2c\x04\x59\x66\x4f\x34\x25\x3f\x5b\xab\x95\xcc\x4e\x59\ -\xb5\xb7\x10\xd6\x2b\xfc\x25\x5b\xe9\xfc\x54\x95\x7b\xb6\xf0\xf0\ -\xc7\x5f\xb9\x95\x0c\x50\x65\xc1\x17\x4a\x97\x7c\xb2\xe9\xa9\x2c\ -\xf9\x6c\xf1\xbc\x28\x77\x1d\x57\x32\xc2\x4d\x9c\x38\x9e\x8a\x1d\ -\x50\x7c\x4f\x36\x3f\x51\x35\x83\xfa\xa0\xfc\x68\xf8\xde\x27\x55\ -\xf5\x24\x00\x21\x9d\x83\x65\x6f\x35\x93\xcd\x4e\x59\xf9\x62\xdf\ -\x47\xbe\xc8\xe7\xa7\xaa\x7c\x71\x84\xa5\x33\x3f\x5f\x25\x19\xa0\ -\xca\xf2\x45\xfe\x9f\xe0\xc9\xa6\x17\x04\x08\xa9\xf7\xe6\x06\x81\ -\x2b\x3c\xf5\x4e\x17\xd6\xc6\x18\x1f\x91\x58\xb3\x8b\x4a\x78\xb6\ -\xe5\xcb\x95\xc7\x67\xd7\x64\x5a\x84\xc5\x32\x5f\xab\x3c\x3e\xbd\ -\x66\xff\x94\xf0\x8b\xda\x4c\xa8\xc8\x03\xa7\xac\x46\x59\x48\x78\ -\x45\xe3\xab\x14\x99\xf0\x54\x15\x28\x74\xbc\xbb\xcf\xde\x29\x89\ -\xf4\x54\x56\x27\x6c\x9e\x95\xbd\x71\x4a\xe6\x70\xa7\x74\x66\xc5\ -\xba\xcf\xae\xa9\x6f\xe7\x57\xa0\x7a\xcf\xe5\xd7\x7d\x5d\xe1\x6b\ -\x78\x1c\xc3\x76\x21\xf4\x16\xd0\x2d\xce\xbd\x25\x4b\x73\x1c\xa3\ -\x22\xda\x1c\xeb\x7a\x5c\xf6\x37\x49\xf3\xa8\xc1\xf8\x36\x29\xf6\ -\x89\x2f\xad\x1f\x90\xfc\xf7\x81\x11\x86\xbe\x6f\xc1\x50\x8b\x35\ -\xf8\xde\x0a\x0d\xbb\xf9\x93\x07\xeb\xed\x83\x09\x73\x76\x67\x8e\ -\xbf\x08\x47\xef\xc0\xd7\xef\xca\x91\x9c\x36\xb3\x26\x25\x88\x8f\ -\xe5\x2b\xaa\x8f\x25\x66\xac\xfe\x9b\x4a\xb7\x54\xf1\x75\x2a\x5e\ -\x10\xc2\xd0\xb3\x6c\x89\x54\x7c\xc3\x5d\xb4\x54\xac\xa0\xfd\x2c\ -\xa2\x43\xa9\x0c\x77\xee\xbc\x87\x6f\x1f\xcc\xa9\x04\xae\xff\xed\ -\x4c\xde\x8a\xb4\x51\xef\x67\xc3\x7d\xb3\x53\x71\x02\xc4\x36\x2c\ -\xdf\x83\x96\x1d\x38\x32\xc3\xc9\x0e\xc3\xd9\xae\x6b\xc7\x9e\xc5\ -\xce\xa8\x88\xfb\x61\xba\x0b\xaf\x90\x45\x8e\x47\x47\x76\xe8\x8c\ -\xbf\xb6\x41\x5d\x1d\x23\x80\x6e\xe0\x07\xde\xf0\xf1\xba\xdd\xfa\ -\x65\xc9\x3e\x1e\xb7\x7e\xf9\x17\x80\x2a\x7a\x3f\ -\x00\x00\x13\x72\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x72\x64\x65\x72\ -\x5f\x62\x79\x5f\x6e\x61\x6d\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\ -\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ -\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\ -\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ -\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\ -\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ -\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ -\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\ -\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x39\x2e\x34\x30\x30\x32\x35\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x63\x79\x3d\x22\x31\x38\x2e\x39\x32\x37\x30\x34\x32\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\ -\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ -\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\ -\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ -\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\ -\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\ -\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ -\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\ -\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ -\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ -\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ -\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\ -\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ -\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ -\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ -\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ -\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ -\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ -\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ -\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ -\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ -\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ -\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ -\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ -\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x69\x6c\x6c\x3a\x23\x64\x35\x66\x66\x64\x35\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ -\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\ -\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ -\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ -\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ -\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ -\x36\x2e\x30\x39\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ -\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\ -\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ -\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ -\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\ -\x3a\x31\x32\x2e\x38\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\ -\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\ -\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\ -\x65\x72\x69\x66\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\ -\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\ -\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\ -\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\ -\x30\x36\x36\x36\x36\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x78\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x31\x32\x2e\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x74\x65\x78\x74\x32\x39\x39\x35\x22\x3e\x3c\x74\ -\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x74\x73\x70\x61\x6e\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x78\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x32\x2e\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\ -\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x38\x2e\x35\x35\x30\x30\x39\ -\x38\x34\x32\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\ -\x74\x3a\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\ -\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x32\x22\x3e\x61\x3c\x2f\x74\x73\x70\x61\x6e\x3e\ -\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\ -\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\ -\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\ -\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\ -\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\ -\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\ -\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ -\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x6c\ -\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\ -\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\ -\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\ -\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ -\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x38\x2e\ -\x35\x33\x33\x33\x33\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x32\x38\x2e\x37\x39\x39\x39\x39\x39\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x32\x39\x39\ -\x39\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\ -\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x30\x30\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x38\x2e\x35\x33\ -\x33\x33\x33\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x32\x38\x2e\x37\x39\x39\x39\x39\x39\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\ -\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x38\x2e\x35\x35\x30\x30\x39\ -\x38\x34\x32\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\ -\x74\x3a\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\ -\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ -\x36\x36\x36\x37\x32\x22\x3e\x62\x3c\x2f\x74\x73\x70\x61\x6e\x3e\ -\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\ -\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ -\x22\x38\x2e\x35\x33\x33\x33\x33\x33\x38\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x35\x31\x2e\x39\x38\x37\x36\x32\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x74\x73\x70\x61\x6e\x33\x30\x30\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\ -\x73\x69\x7a\x65\x3a\x31\x38\x2e\x35\x35\x30\x30\x39\x38\x34\x32\ -\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\ -\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ -\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ -\x37\x32\x22\x3e\xc2\xa0\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\ -\x74\x65\x78\x74\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\ -\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\ -\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ -\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ -\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\x30\x30\ -\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\ -\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\ -\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x6c\x65\x74\ -\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\ -\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\ -\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\x69\ -\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\ -\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x31\x2e\x33\ -\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ -\x22\x32\x38\x2e\x37\x39\x39\x39\x39\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\x30\x30\x35\x22\ -\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\ -\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\ -\x3d\x22\x32\x31\x2e\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x38\x2e\x37\x39\x39\x39\ -\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x74\x73\x70\x61\x6e\x33\x30\x30\x39\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\ -\x2d\x73\x69\x7a\x65\x3a\x31\x38\x2e\x35\x35\x30\x30\x39\x38\x34\ -\x32\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\ -\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ -\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x32\x22\x3e\x63\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\ -\x74\x65\x78\x74\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\ -\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\ -\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\ -\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\ -\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\ -\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\ -\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\ -\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\ -\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\ -\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\ -\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\ -\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\ -\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\ -\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\ -\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\ -\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\ -\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\ -\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\ -\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\ -\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\ -\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\ -\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\ -\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\ -\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\ -\x61\x63\x61\x37\x39\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\ -\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ -\x3a\x33\x2e\x36\x32\x36\x36\x36\x36\x37\x38\x3b\x6d\x61\x72\x6b\ -\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\ -\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\ -\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ -\x4d\x20\x37\x2e\x32\x38\x34\x38\x33\x37\x31\x2c\x2d\x31\x32\x2e\ -\x34\x31\x35\x34\x38\x34\x20\x35\x2e\x33\x31\x38\x32\x30\x35\x37\ -\x2c\x2d\x31\x30\x2e\x37\x37\x34\x32\x31\x35\x20\x33\x2e\x33\x35\ -\x31\x35\x37\x35\x33\x2c\x2d\x39\x2e\x31\x33\x32\x39\x34\x37\x34\ -\x20\x32\x30\x2e\x38\x30\x30\x35\x35\x33\x2c\x31\x32\x2e\x32\x32\ -\x33\x39\x31\x36\x20\x31\x36\x2e\x30\x30\x31\x31\x30\x34\x2c\x31\ -\x34\x2e\x38\x34\x37\x38\x33\x33\x20\x32\x37\x2e\x37\x33\x30\x30\ -\x33\x35\x2c\x31\x37\x2e\x34\x39\x32\x38\x37\x36\x20\x33\x30\x2e\ -\x35\x36\x38\x33\x33\x33\x2c\x35\x2e\x34\x35\x33\x36\x33\x37\x33\ -\x20\x32\x35\x2e\x36\x2c\x39\x2e\x36\x20\x5a\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x31\x33\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ -\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x0a\ -\x00\x00\x0a\x55\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\ -\x6f\x61\x64\x5f\x6c\x6f\x67\x69\x6e\x2e\x73\x76\x67\x22\x0a\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ -\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ -\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\ -\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x39\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\ -\x38\x34\x2e\x32\x36\x31\x35\x31\x33\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x2d\x35\x2e\ -\x30\x33\x36\x33\x36\x34\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ -\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\ -\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\ -\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\ -\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ -\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ -\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ -\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ -\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\ -\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ -\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ -\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ -\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ -\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ -\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ -\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ -\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ -\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ -\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ -\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ -\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ -\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ -\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ -\x3a\x23\x33\x33\x33\x33\x33\x33\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x31\x2e\x31\x32\x33\x33\x32\x35\x31\x31\x70\ -\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ -\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x2d\x30\x2e\x35\x34\x39\ -\x36\x33\x37\x33\x35\x2c\x33\x37\x2e\x37\x38\x33\x32\x37\x20\x63\ -\x20\x30\x2c\x30\x20\x38\x2e\x34\x39\x33\x38\x31\x39\x33\x35\x2c\ -\x2d\x32\x33\x2e\x34\x34\x37\x35\x37\x20\x31\x36\x2e\x31\x30\x35\ -\x31\x36\x30\x33\x35\x2c\x2d\x32\x33\x2e\x33\x33\x36\x34\x38\x32\ -\x20\x37\x2e\x35\x30\x31\x38\x37\x38\x2c\x30\x2e\x31\x30\x39\x34\ -\x38\x38\x20\x31\x35\x2e\x37\x31\x35\x39\x31\x39\x2c\x32\x33\x2e\ -\x34\x36\x31\x39\x31\x33\x20\x31\x35\x2e\x37\x31\x35\x39\x31\x39\ -\x2c\x32\x33\x2e\x34\x36\x31\x39\x31\x33\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x38\x38\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\ -\x73\x3d\x22\x63\x61\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ -\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x33\x33\x33\ -\x33\x33\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ -\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ -\x2e\x32\x35\x32\x38\x36\x32\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6c\x69\x6e\x65\x63\x61\x70\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x72\x6f\ -\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ -\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ -\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x38\ -\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x31\ -\x35\x2e\x34\x35\x38\x36\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x63\x79\x3d\x22\x37\x2e\x32\x31\x35\x36\x35\x30\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x32\x38\x32\ -\x38\x31\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ -\x22\x35\x2e\x36\x39\x30\x38\x31\x37\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\ -\x74\x61\x74\x65\x28\x2d\x30\x2e\x33\x38\x39\x31\x37\x31\x35\x33\ -\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0a\ -\x00\x00\x15\xfd\ -\x00\ -\x02\x17\xe5\x78\x9c\xed\x5d\xdb\x8e\xe3\x48\x72\x7d\x9f\xaf\x90\ -\x35\x30\xb0\x03\x37\x53\x79\xbf\xa8\xab\x7b\x1f\x76\xb1\xf0\x02\ -\xf6\x8b\xbd\xb6\x1f\x17\x2c\x89\x55\x2d\xb7\x24\x96\x29\xd5\x6d\ -\xbe\xc6\xdf\xe2\x2f\x73\x26\xa9\x2b\x45\x35\x66\x46\x8c\x8a\x1a\ -\x75\x68\xd0\x53\x12\x93\x94\xc8\x38\x19\xf7\xc8\xc8\x9b\x3f\xbe\ -\x2c\xe6\x83\xa7\xa2\x5a\xcd\xca\xe5\xa7\xa1\x60\x7c\x38\x28\x96\ -\x93\x72\x3a\x5b\xde\x7f\x1a\xfe\xc7\xdf\xfe\x92\xf9\xe1\x60\xb5\ -\xce\x97\xd3\x7c\x5e\x2e\x8b\x4f\xc3\x65\x39\xfc\xe3\xe7\x1f\x6e\ -\xfe\x21\xcb\x06\x7f\xaa\x8a\x7c\x5d\x4c\x07\xcf\xb3\xf5\x97\xc1\ -\x5f\x97\x5f\x57\x93\xfc\xa1\x18\xfc\xe1\xcb\x7a\xfd\x30\x1e\x8d\ -\x9e\x9f\x9f\xd9\x6c\x73\x90\x95\xd5\xfd\xe8\xa7\x41\x96\x7d\xfe\ -\xe1\x87\x9b\xd5\xd3\xfd\x0f\x83\xc1\x20\xfe\xee\x72\x35\x9e\x4e\ -\x3e\x0d\x37\x17\x3c\x3c\x56\xf3\xfa\xc4\xe9\x64\x54\xcc\x8b\x45\ -\xb1\x5c\xaf\x46\x82\x89\xd1\x70\x7f\xfa\x64\x7f\xfa\x24\xfd\xfa\ -\xec\xa9\x98\x94\x8b\x45\xb9\x5c\xd5\x57\x2e\x57\x3f\x1e\x9c\x5c\ -\x4d\xef\x76\x67\xa7\xbb\x79\x56\xf5\x49\x22\x84\x30\xe2\x72\x24\ -\x65\x16\xcf\xc8\x56\xaf\xcb\x75\xfe\x92\x1d\x5f\x1a\xef\xb1\xeb\ -\x52\xc9\x39\x1f\xc5\xb1\xfd\x99\xbf\xec\xac\xf1\x2a\x12\xf4\x21\ -\xfe\xdb\x9d\xbe\x3d\xc0\x56\xe5\x63\x35\x29\xee\xe2\x75\x05\x5b\ -\x16\xeb\xd1\x9f\xff\xf6\xe7\xdd\x60\xc6\xd9\x74\x3d\x3d\xf8\x9a\ -\x2d\x3d\x8f\x7e\xf5\x88\xc8\xcb\x7c\x51\xac\x1e\xf2\x49\xb1\x1a\ -\x6d\x8f\xd7\xd7\x3f\xcf\xa6\xeb\x2f\x9f\x86\x4a\x33\xa1\xe2\xcb\ -\xd4\x07\xbf\x14\xb3\xfb\x2f\xeb\xf6\xd1\xd9\xf4\xd3\x30\xde\xbd\ -\x0c\xbe\xf9\x7c\x30\x39\x44\x73\xc2\xe6\x8b\xc7\xbb\x11\xce\x82\ -\x64\x62\x50\x09\xa3\x5c\x73\xce\xf6\x11\xc6\xd3\x72\x92\xee\x29\ -\x7e\x65\xb1\x98\xe5\x8f\xeb\x72\x11\x51\x9b\x4c\xe6\xf9\x6a\x35\ -\xbb\x9b\x4d\xe2\x87\x72\xf9\x30\x7f\xbc\x9f\x2d\xff\xfe\x75\x51\ -\xe4\xcb\xd5\xdf\xd7\x65\x39\x67\x5b\xf2\xed\x7e\xab\x78\x79\x28\ -\xab\x75\xf6\x32\x7d\x88\x44\xb4\xae\x73\xf0\x75\x3b\xf8\x39\x8e\ -\xde\x4c\x8b\xbb\x55\x3a\xab\x79\xa2\xf4\x29\x3e\x92\x1b\x0e\x46\ -\xf5\xe8\xee\x06\xd3\xdd\x4d\x9f\x66\xc5\xf3\xfe\xdc\xdb\x7c\xd5\ -\x50\x6d\x30\x78\xc8\xef\xe3\x0c\x9b\x97\xd5\xa7\xe1\x8f\x77\xf5\ -\x6b\x33\x70\x5b\x56\xd3\xa2\xda\x0e\xd9\xfa\x75\x34\x54\x46\x14\ -\x66\xeb\xd7\x86\xa7\x36\xdf\xbd\xbd\xdf\xf4\xad\xbb\x71\xde\x3d\ -\xbe\xfa\x92\x4f\xcb\xe7\x4f\x43\xd9\x1e\xfc\xb9\x2c\x17\x35\xc9\ -\x7d\x70\xc6\xc8\x93\xf1\xc9\xcb\xa7\x61\xa6\x79\x60\x3a\x08\x63\ -\x4e\x46\xd3\x1d\x99\x08\xb8\xf4\xa7\x57\x3e\x56\x55\xe4\xba\x6c\ -\x9e\xbf\x16\xf1\xa9\xea\x3f\x62\x73\xd2\xea\x4b\xf9\x7c\x5f\x25\ -\xea\xac\xab\xc7\xa2\x7d\x65\x1a\xc9\x6e\x6f\xcb\x97\xee\xe1\x38\ -\x09\x1e\x13\x3f\x67\x8f\xcb\xd9\x3a\xf2\xcc\xc3\xcb\xe1\xb7\x3e\ -\xce\xa6\xc5\xaa\xfb\xc2\xe7\xd9\x32\x12\x21\xdb\xcc\x5e\xa1\x76\ -\x34\x6e\x9f\xb1\x9d\xca\x8e\xfb\x33\x67\xc4\x5b\x3b\xa1\xf3\x66\ -\xe8\xf5\xfc\xd0\x22\x7f\x99\x2d\x66\x3f\x17\xf1\xb9\x45\xfb\x94\ -\xd5\x32\x7f\xc8\xee\xe7\xe5\x6d\x3e\xdf\xdc\xfd\xe7\xfa\x8c\x9b\ -\x23\xb2\x34\x17\x0d\x06\xeb\xd7\xc4\xb7\x2f\xaf\xe9\xd8\x70\x7b\ -\x30\xd1\x33\x1d\x50\xce\x9a\xdd\xc1\xb2\x9a\x45\x76\x38\xb8\xdf\ -\xed\xa1\xd7\xc3\x43\x89\xcb\xa3\x90\x7e\xa9\x27\x58\x3d\xfd\x5c\ -\x7b\xec\xf5\x70\x6c\x33\xef\x47\xa7\x13\xbf\x3e\xbe\x28\xd6\xf9\ -\x34\x5f\xe7\x7b\x2e\xd8\x1e\x91\x21\xf0\xed\x93\x45\x81\x39\xfe\ -\xb7\x3f\xff\xe5\xf3\xe6\x87\x6e\x26\x93\xf1\x7f\x95\xd5\xd7\xed\ -\xef\x0e\x06\xe9\x84\xfc\xb6\x7c\x8c\x50\x0c\x3f\xef\x0e\xdf\x4c\ -\x27\xe3\x28\xe2\x22\xeb\x7f\x9e\x2d\xe2\xdc\x4e\xd2\xf1\x9f\xa2\ -\x48\xbb\x19\xed\x07\x8e\x4e\x4e\xc4\xda\x7f\x69\xf3\xb5\x55\xd1\ -\xc8\xca\x4e\x85\x31\x9d\x2c\x66\xe9\xa2\xd1\xbf\xaf\x67\xf3\xf9\ -\x5f\xd3\x8f\x6c\x9e\xf8\xe0\x4b\x67\xeb\x79\xb1\x3f\x78\x33\xda\ -\xdc\xfd\xe6\xd9\x46\x07\x0f\x77\x33\xda\x3e\x7d\xfd\xe9\x7e\x4f\ -\x95\x23\xa6\xd8\x01\x3d\xcf\x6f\x8b\x38\x09\xfe\x25\x0d\x0e\x4e\ -\x46\xef\xab\xf2\xf1\x61\x51\x4e\x8b\xcd\xe5\x3b\x6a\x16\x93\xf5\ -\x0e\xb2\xf5\xeb\x3c\x8e\xdf\xc5\xbb\x1f\x6f\x24\xcd\xc7\xf4\x21\ -\xdb\xc8\x89\xb1\x68\x3e\x56\x8f\xf3\x28\xef\x9e\x8a\x65\x39\x9d\ -\x7e\x5c\xad\xab\xf2\x6b\x31\xfe\x91\x73\xed\x39\xdf\x7c\x6c\xb8\ -\x65\xbc\xfb\x38\x9f\x2d\x8b\x78\x1b\xe3\xd5\xff\x3c\xe6\x55\x71\ -\x78\xf4\xbf\xcb\xd9\x72\x1c\xe9\x56\x54\xdb\xa3\xf5\x87\x79\x9c\ -\xf1\xeb\xb1\xde\x1e\x9b\xe6\x51\x14\x55\x55\xfe\x3a\x5e\x46\x0b\ -\xe0\xf0\x68\x79\x77\xb7\x2a\xd6\xfb\x5f\xda\xde\x2a\x67\x6a\xf3\ -\x3a\x9a\xe8\xe9\x71\x55\x08\x62\x77\xb0\x53\x29\xa5\x57\xb7\x62\ -\x4a\xaf\x23\xae\x88\xf3\x3b\x4a\x39\xa7\x02\x57\xb6\xc8\x84\xdd\ -\x0d\x54\x47\xa7\x55\xf1\x3c\xc5\x54\x54\x4e\x36\xf8\xdd\xac\xd8\ -\x82\xba\x61\x42\x65\xc5\xfe\x8a\x75\x15\x15\x51\x9a\x97\x91\x0b\ -\xf2\x75\x35\x7b\xf9\x03\x67\xd6\x3b\xf3\x81\xa7\xff\xa2\xe4\x35\ -\x4a\x39\xa9\x3e\x48\xa6\x1b\xee\x8a\x07\x95\xd6\xdc\x5b\xa5\x7f\ -\x1a\xb6\x20\xdd\x83\x94\x5e\x6d\x5a\x89\x1d\x9b\xdc\x3c\xe4\xeb\ -\x2f\xfb\x49\xbf\xe7\xd3\x38\x71\xd2\xd4\x8e\x22\x72\x32\x19\xee\ -\x4f\xd8\x8b\xed\x72\x19\x11\x5e\x97\x55\x16\x05\xf8\x53\xbe\x7e\ -\xac\x8a\xc3\xc7\x6f\x1e\x30\x7d\x79\xe4\x64\x7b\x70\x38\x1e\xfd\ -\xd7\x41\x7c\x9e\xc1\x7f\x0e\xb6\x84\x56\x07\xc3\x87\x33\xf2\x00\ -\xf9\xf6\x83\x34\xb3\x4d\x6e\xae\xd7\xba\x3d\xed\x6e\x1f\xd7\xeb\ -\xbe\x26\xdd\x9e\x68\x07\x6c\xfc\x16\x64\xf3\x6d\xb2\xed\x08\xf6\ -\x61\xf7\x6e\xf0\xcf\x03\xfe\xbb\x27\xdf\xaf\xa7\x8e\x72\x4e\x66\ -\xbc\x4d\x9f\x9d\xde\xf9\x20\x3d\xf3\x83\x3f\x0d\x14\x93\xcd\xdb\ -\x93\x37\xbf\x95\x66\x82\xc5\xe9\xcc\xa5\xf1\x0f\x2f\xbf\x9e\x68\ -\x30\xa4\xf0\xba\x45\x88\xc5\xc0\x6c\x65\xe1\x07\x65\x98\x1c\x4c\ -\x22\xc3\x65\x9a\xc9\x9a\x36\xe7\xde\x5f\x30\x8b\x84\x33\x3a\x5a\ -\x7d\xef\x8a\x24\x99\x6f\x13\x45\x44\x71\xda\xcc\x8e\xef\x97\x28\ -\xa1\x4d\x14\x29\xd8\x77\x3f\x53\x4e\xd8\x47\x5a\x9a\x29\xaa\x4d\ -\x14\x25\xbf\x63\x6a\xd8\x13\x61\x62\xbf\x53\x6a\xd4\x8a\x37\x93\ -\x27\xf4\xd8\xab\x5e\xd5\xd8\xa7\x2e\xd2\x66\x6b\x61\xa8\x68\xef\ -\x9d\x79\x7f\x86\x36\xb5\x37\xb2\xa3\xc7\xef\x46\x17\x37\xd4\x11\ -\xe7\xa9\x23\xfc\xd6\x70\xfb\x6e\xa9\xa3\xce\x9b\x6d\x42\xee\xcc\ -\xb6\xfa\xed\xc9\x9b\x2b\x32\xdb\x1a\x62\xe8\xf3\x53\xc5\x6d\xfd\ -\xbc\x8b\xa6\xca\xef\x97\x34\x27\xb6\xca\x81\x8c\xd9\x3e\xf6\xef\ -\x8a\x34\x37\xa3\xfb\xee\x28\x80\xb4\x7b\xfd\x72\xc4\xe6\xf6\x2e\ -\x08\x9f\x7f\x33\x42\x60\x82\x55\x81\x07\x5d\x47\x09\x04\x13\x5a\ -\x2b\xe3\xcc\x87\x4c\x09\xe6\xb9\xf1\xc1\x7c\xb0\x8c\xbb\x60\xac\ -\x54\x3f\xed\xbd\xfe\xc3\x20\x50\x1d\xd2\xd0\xcc\x4a\xc9\xa5\x3e\ -\x14\x5d\x2f\x9f\x86\xd6\x30\x27\x8d\xd5\x87\x2a\x6c\x1b\x27\xe1\ -\x71\x48\x79\xc9\x85\x39\x18\xdc\x06\x4d\x99\x8e\xaa\x2b\x58\xd3\ -\x82\xb7\x8e\xc6\x78\x2e\x4f\x11\xa9\x83\xda\x3b\x18\xa6\xb3\xd5\ -\xc3\x3c\x3a\x92\xb3\x65\x22\xee\xc7\xf2\xa9\xa8\xee\xe6\xe5\xf3\ -\xf8\x69\xb6\x9a\xdd\xce\x8b\x8f\xf5\xdf\xd9\x3c\xd1\x77\x7b\xe8\ -\x90\x62\xe7\x83\x58\x11\xf3\x9f\x8b\xaa\xfc\x26\xec\x27\x41\xac\ -\x3e\xdd\xe1\x6f\x85\xb0\xc4\xc7\x45\x5e\x7d\x2d\xaa\xe6\x82\x62\ -\x99\xc7\xe7\xca\x6e\xf3\xc9\xd7\x14\xcb\x5b\x4e\xc7\xf9\x64\xf2\ -\xb8\x78\x9c\xe7\xeb\xc3\x30\xe3\x2f\xc7\xd2\x33\xa3\x83\xd4\x3d\ -\x43\x79\x24\xc2\x08\xcc\xbe\xc1\x74\xcc\x08\xa7\xb8\x0a\x2d\x30\ -\x5d\x14\x6f\x4e\xeb\xde\xd1\x0c\x84\x26\x02\x9a\x81\x05\x2b\x78\ -\xff\x68\xea\xac\xc3\x64\x22\x3c\x7b\xc3\x53\x31\xe1\xb4\xf2\x6f\ -\xc6\x9d\xa4\x38\x31\xd0\x84\xe3\x4e\x4b\x78\x02\xe2\x19\x2d\x5f\ -\x1b\xec\x11\xfd\x01\xed\xa0\x90\x75\x24\xb2\x08\x4d\x60\x34\x9d\ -\x60\xca\x49\x2f\x2d\x80\xea\x24\x63\x08\x14\x50\x11\xe1\xb1\x51\ -\xe0\xbe\x11\x7f\x4a\x62\x4f\x04\x34\x01\xf9\x93\xb8\x13\x21\x8a\ -\xe0\x34\x13\xc1\xea\xfe\xf1\x0c\x64\xdc\xa2\xe0\x09\xaa\x3f\x05\ -\x41\xfa\xf6\xf6\x2d\x50\xcc\x96\x9c\x15\x0c\xf3\x16\x4a\xdc\x6a\ -\xf2\x56\x30\x62\x09\x4e\x32\xe7\xb5\x55\xfd\x6b\x4f\x12\xb5\x18\ -\x70\x1a\x66\xb9\x97\x4a\x40\x68\x4f\x92\xb7\xb0\x88\x3a\xe7\xcc\ -\x71\x75\x4e\x23\x70\x83\xe7\xce\x74\x23\xea\xb5\xd6\xc6\xba\xd0\ -\x85\xa8\x8c\x5e\xab\xe2\xe2\x2c\x87\x92\xbc\xc5\x80\xd3\x31\x1d\ -\xb8\x95\xdd\x02\xf7\x02\x38\xa3\xfe\x24\x40\x61\x53\x65\xc2\x18\ -\x15\x4e\xfc\x15\xcb\xa4\x32\xd6\x77\x5b\xb7\x97\xf0\x27\xc9\x5b\ -\x14\x3c\x3d\x73\xda\x18\x23\xfb\x67\x50\x9f\x19\x42\x14\x10\x51\ -\xc9\xb8\xf7\xd6\x48\xff\x46\x1c\x2a\xc9\x65\x41\xc1\x13\x8e\x43\ -\x2d\x79\x2d\xa0\x88\x9a\x54\x42\xaa\x5d\x68\x23\x0a\x65\x14\x85\ -\x4c\x91\xcc\xc5\x40\xd4\x73\xc6\xd3\x7a\xdc\xde\xbd\x96\x3a\x8a\ -\x4b\x99\x16\x50\x4c\x39\x53\x21\x38\x75\x9c\xf2\x84\x64\x53\xa9\ -\x08\x51\x14\x44\x01\xd9\x94\xdc\x17\x94\xf8\x82\x97\xcc\x08\xae\ -\x94\xef\x5f\x95\x52\xc2\x05\x07\x51\x50\x55\x2a\xc8\xe2\x45\xb1\ -\x78\xa1\xa2\xba\x96\x7c\x52\x14\x7b\x17\x4a\xec\xea\xe8\xc1\x74\ -\xac\xd7\x25\x44\xa1\xa3\x0c\x3e\x41\x63\x34\x0f\xfd\x2b\x52\x41\ -\xd6\x2e\x0a\xa2\x51\xc1\xc6\xa3\xb6\xbb\x74\xe1\x42\x45\x6a\x29\ -\xce\x00\x5b\xcd\xc9\x99\x51\x4a\xca\xf6\x1a\x42\xc9\xb4\x12\xda\ -\xf4\x2e\x77\x49\x8b\x62\xa0\x19\xad\x22\x2d\xd4\x51\x81\x42\x5f\ -\x5a\x94\x56\x85\x82\x02\xaa\x58\x10\x82\xb7\x2b\xff\x14\xb3\xde\ -\x2a\xdf\xbb\xc4\x0d\x64\x13\x61\xc0\x69\x53\xed\x9f\xec\xdf\x69\ -\xa9\x15\x28\xe9\x4f\x48\x44\x7d\xc2\x47\x71\xd7\x5e\x4a\x08\xc5\ -\xa1\xb4\x34\x14\x07\x4f\x38\x16\xb5\x24\x73\x61\x65\xae\x64\x32\ -\x5a\x44\x27\xab\xcf\xa0\x6c\xa2\x94\x1b\xa5\x80\x2e\x06\xa2\x8e\ -\x69\x23\x04\x40\xa8\x28\xa5\x46\x3b\x9a\x0b\x11\xa4\xd0\x45\x63\ -\x60\x4c\x2a\x15\x01\x8a\x02\x28\x18\x8f\x12\x87\xe2\x84\x16\xbe\ -\xd9\x33\xe3\xc2\xbc\x28\x19\x46\x18\x88\x42\xaa\x51\x41\xee\x0b\ -\x8a\x69\x04\x15\xce\xb5\x99\x22\xb1\x8b\x01\x28\x94\xd8\xd5\x54\ -\xd9\x89\x14\x61\xf0\xcc\x71\xdb\xff\x6a\xb4\x94\x15\x25\x40\x11\ -\x00\x75\x11\x1b\x61\x8e\x97\x7e\xf6\x98\x16\x25\xb1\x0b\xeb\xbe\ -\x84\x10\xbc\xe1\xea\x8d\x30\x0d\xb4\x44\x02\x09\x51\x95\x9a\x68\ -\x78\x80\x65\xa3\x3e\x33\x64\xec\x02\x77\xd2\x50\x82\x07\x65\x4f\ -\x5b\x2f\x68\xc7\x03\x07\xd0\xa5\xd1\x36\xa2\x1a\x23\x14\x4c\xa1\ -\xea\x3a\x37\xeb\x5e\x88\x53\x31\x50\x05\xf3\x62\xa2\x5b\x4a\x7c\ -\x8a\xc2\xa7\x80\x6d\x18\x32\x47\x01\x41\x8c\x1a\x6c\x30\xcf\x94\ -\x6a\xea\x71\xd6\x48\x40\x3a\xa6\xd1\xe6\xa5\x68\x03\x46\xff\x1b\ -\x28\xa3\x77\x6b\x20\x91\x3a\x85\x44\x35\xe3\x2c\x42\xe4\x44\x44\ -\xf6\x18\x57\xb0\xe2\xfa\x64\x22\x51\x0c\xe9\x9a\x1a\x8f\x6d\x4c\ -\x24\x12\xbf\xb0\x61\x24\x2f\xa4\x08\xaa\xbd\x84\x5f\x33\x23\xb5\ -\x16\x5d\x9e\x8c\x60\x5c\x49\x21\x54\x27\xa6\x4e\x08\x69\x8f\xc2\ -\x4f\xad\x66\x72\xb4\xb1\x0b\x0a\x9e\x8e\x05\x6d\x83\xee\xb2\x91\ -\x2e\xc1\x33\x75\x93\xa3\xea\x40\xd8\x8c\xa9\x88\xd0\x71\xab\xdb\ -\x9e\xe9\x37\xba\x55\x5d\xc4\xa1\x51\x93\xd2\x1a\x18\x0c\x40\x03\ -\xb3\xc6\xcb\xce\x42\x95\xcb\x58\xd4\x53\x94\x17\xdc\x33\x75\xd1\ -\x2f\xb5\xb6\x9d\x8c\x01\xe2\x51\x49\x45\x0d\x48\x80\x82\xf1\xa8\ -\xcd\xa8\xc3\x06\x2c\xa4\x81\x79\x67\x75\xbb\x3a\x10\xca\x30\xda\ -\xe4\xd6\x28\x20\xf8\xf6\x90\x7a\xc1\x54\x44\x34\x74\xf5\x7d\xbc\ -\x54\x91\x06\x6a\x58\x0f\x1e\x65\x88\x10\x38\xe5\x4e\x5b\x3f\x82\ -\xf0\x69\x6a\x29\x47\x61\x7b\x0c\x44\xe1\xd8\x34\xb9\x30\x14\x65\ -\x40\x88\x32\x80\x4a\x5e\x41\x16\x12\x8e\x85\x04\x14\x0a\xb4\xe4\ -\xc4\xc0\x2f\x88\x09\xdc\x1b\xd5\x4a\xc1\x58\xcd\x64\x74\x4a\x79\ -\xff\xb1\xc0\x90\x71\xd2\xa5\x18\xb1\x23\x1b\x98\x0a\xdc\x0a\x88\ -\x60\xa0\xa0\xb4\x1a\x4a\x38\x50\x46\x1d\xab\x84\xe9\x4a\x94\x5e\ -\x1e\x0e\xa4\xb5\x88\x28\xaa\x54\x30\xc1\x85\x0f\x5d\xa9\xd2\x1e\ -\x82\x0d\x24\x7b\x31\xd4\x29\x94\x7d\xb4\xab\xe4\xa5\xfc\x1a\x02\ -\xab\x5a\xc7\xac\x0b\xaa\x73\xf3\x90\x4b\xad\x5e\x0a\x21\xe1\x30\ -\x2a\x5c\x0e\x3c\xd5\xa9\x50\x8a\x0d\x65\x99\xa9\x61\x21\xfa\x32\ -\xae\x7f\x95\x4a\x35\xf7\x58\x90\x02\x39\x33\xdb\x72\x5e\xf2\x67\ -\x80\x57\x52\x38\xcf\xb9\x6f\x2f\x4c\x84\x52\xa8\x8d\xed\x2b\xa9\ -\x66\x05\x03\x54\x28\x87\x66\x57\xa4\x4d\x71\xfc\x6b\xaa\xfe\xdc\ -\x56\xf4\x12\xb3\x5e\xd7\xbe\x5c\xa9\xaa\x97\x9c\xd4\x2b\xdb\x98\ -\x4b\x29\x5a\x44\x0c\xbb\x46\x26\x82\x10\x55\xa7\xd3\x6d\x36\x85\ -\xda\xb7\xb4\x2e\x1b\x24\x85\x8a\x81\x29\xd8\x2e\x31\x4d\xe5\x20\ -\xe5\x51\x31\xf6\x89\x81\x92\xbd\x8d\x4b\x43\x8c\x8a\x81\x29\xdc\ -\xfe\x5c\x9e\xfc\x19\x78\xf1\x2b\x59\x88\x8e\xaa\xf7\xed\x92\x50\ -\x28\x56\x95\x14\xcd\x47\xc3\x14\x8e\x55\x53\xf0\x97\xfc\x19\x14\ -\x7f\xc6\x30\x2e\xb9\x08\x00\x0d\xe9\x68\xcf\x4b\x34\x50\x41\x95\ -\xaa\xa0\x0a\x25\x1c\x5b\x09\x2c\x9c\x64\x69\x2f\x53\x24\xeb\x17\ -\x4a\xfa\x36\x81\x5f\x52\xa9\x28\xa1\x07\xa8\x8e\x2b\x75\x2b\x66\ -\x62\x54\x1c\x50\x2d\x93\xce\x08\x05\xb3\xc5\x1e\x75\x7a\xc5\xca\ -\xd0\x40\xb7\x05\x0d\x94\x7a\x83\xe5\x57\xcd\xa2\xa4\x8d\xaf\x56\ -\x4d\x8b\xd7\xcc\x05\xef\x3a\x3b\x83\x26\x16\xf7\xc6\x79\xd3\x85\ -\xab\xf0\xce\x4b\x11\xbe\x65\x2a\x71\x52\xac\xd7\x95\x4e\xdd\xa5\ -\xc9\x29\xac\x8f\xd0\xcf\x0c\x2e\xac\x4f\xeb\xdd\x70\x00\x85\x0b\ -\x3f\x28\x2a\x11\xc5\x71\x54\xa1\xd2\xa9\x75\x8a\x9c\x20\xc5\x80\ -\x14\xca\x4d\x6d\x32\xe4\x84\x29\x42\x67\x66\x30\xc9\xdb\x64\xc8\ -\xc9\x95\xc1\xc0\x14\x2e\x46\xd8\xb8\xa8\x64\x23\x5d\x55\x8e\xa6\ -\xc9\x90\x13\xab\x5e\x55\x36\x75\xd3\x63\x87\xe2\x0e\x18\xee\x8c\ -\x63\x46\x71\x0e\x10\xce\x97\x54\xf6\x80\x04\x29\xa8\x4e\x4d\x09\ -\x72\x2a\x3b\xc3\x30\x95\xa0\x22\x49\x29\xea\x4b\x09\x1a\x0c\x44\ -\x81\x64\x6f\x13\xf1\xa5\x2a\x16\x8c\xb8\x03\x54\x26\xb5\x49\x8f\ -\x93\x3e\xc5\xc0\xd4\x33\xe7\x75\xf0\x20\x05\x67\x75\x76\x9c\x60\ -\xc5\xd8\x69\x06\x2e\xe1\xb6\xcd\x8e\x13\xae\x38\xbb\x42\x41\x31\ -\x6c\x93\x1f\xa7\x02\xfd\x6b\xca\xa3\xee\xd2\xe3\x14\xd3\x07\xee\ -\xa2\x64\x94\x92\x27\x8d\xb1\x04\x13\x29\x51\xd3\x7b\xea\x2d\x50\ -\x2e\x15\x07\xd0\xd4\x9f\xdb\x2a\x0f\xe1\xd4\x50\xc5\x03\x4e\x07\ -\x25\xc9\xb4\x12\xda\xf4\x1f\xcc\x8f\xa2\x97\xd6\xd0\x60\x20\xaa\ -\x59\xd0\xa9\x1d\x2c\x4c\x76\x9c\xc2\x83\xa0\x82\x57\x32\x19\xc5\ -\xae\x32\x6f\x24\x78\x37\xeb\xc7\x89\x51\x31\x40\xb5\x4c\x04\x2b\ -\xe1\x2a\xb8\x29\x48\x08\xdb\x10\x4b\x18\xa3\xa2\xa8\x7d\x23\x56\ -\xad\xb3\xe3\x94\x1c\xc7\x80\x14\x8e\x51\x53\x6e\x9c\xec\x5e\x0c\ -\x57\xc6\x33\xc7\x2d\x40\x24\x3f\x05\x92\x28\xe1\x86\x81\x28\xa8\ -\x3a\xad\xb7\x14\x22\xe9\x8b\x61\x26\x41\x45\x91\x52\xc0\x97\xbc\ -\x19\x0c\x44\x61\x64\x6f\x13\xec\x25\xd9\x8b\x11\x73\x70\x4c\x1b\ -\xd1\xb9\xd7\x6d\x0f\x89\x71\xca\xc9\xe0\xb4\x56\x0f\x56\xf0\xce\ -\x65\xa8\xbd\x24\xc6\x29\x82\x0f\xbc\x55\x94\x72\xce\xb6\x51\x35\ -\x11\x55\x29\x4c\x00\xcc\x8b\x13\xae\xb0\xdd\xd5\x95\xe0\x41\xb5\ -\x17\x8d\x83\x71\x6b\x93\x15\x27\x4c\xaf\x29\xe8\xbb\xcb\x8a\x53\ -\x43\x96\x2b\xda\x08\x21\x75\x56\xa7\xa2\x24\x14\x44\xe1\xf6\x40\ -\x50\xb4\x3f\x35\xd2\x0e\x60\x40\x7b\x6a\xa6\x80\xaf\x26\x27\x15\ -\x05\x52\xcb\xa4\x32\xd6\xc3\x6c\x16\x45\x86\x2f\x2c\xa8\x3a\xc2\ -\x60\xbc\x91\x6d\xd9\x0b\xc4\xa7\x75\x77\x07\xca\xa0\xa2\x40\x0a\ -\xc6\xa7\xa9\x7e\x85\xfa\x3b\xa0\x84\x93\xa0\x6c\xa4\xcd\x7e\xc6\ -\xb4\xc8\x0d\x07\x55\xb0\x7d\x52\x9b\x68\x12\x31\x2b\xf4\xa2\x28\ -\x6b\x84\x95\x5a\xbe\x0d\xb3\xd6\x25\x2c\x8a\x9c\x54\x14\x4c\xc1\ -\x58\xb5\xee\xef\x40\xa0\xa2\x44\x1e\x20\xe5\x6f\x5d\xf2\x40\xc9\ -\x37\x14\xbd\x0a\x14\x23\xb4\xd4\x0c\x0b\x2b\xfa\x00\xb9\xfb\xb8\ -\xc8\x38\xc5\xf2\x51\x40\x85\xdd\x7f\x3c\x73\x14\xfc\x45\x2a\x67\ -\x01\xdc\x80\x3c\xfd\x9f\xdc\x1a\x48\x58\x03\xf3\xce\xea\x76\x81\ -\x28\xf4\x0e\xe4\x92\x6a\xb9\xd1\x56\xbc\x49\x13\x75\x6b\xdf\x56\ -\x70\xb2\x96\x52\x0c\x82\x5c\x1b\x04\x66\x85\xdd\x57\x3e\xb1\x2b\ -\xa1\x0a\xba\x94\xc6\x0b\x29\x82\xd2\x6f\x63\x05\x6f\x0c\x26\x13\ -\x0d\x61\xb2\x98\x60\xbb\x9d\x39\xed\x82\xb5\xea\x6d\x44\x70\x63\ -\x31\xd5\x6c\x4b\xb0\x22\xc0\x0a\x64\x08\xef\xab\x45\x3d\x99\xc2\ -\xd7\x54\x84\xb6\x2b\x2d\xd4\x94\x3b\x07\x66\x58\xa5\x8d\xd7\xca\ -\x9f\x30\xac\x50\x4e\x9f\xa9\x03\x76\x52\x79\xc9\x45\xe7\xee\x51\ -\x5a\x88\x28\x00\xcc\x59\x60\x49\xfe\x62\xc0\xf9\xcd\xb2\xee\x4b\ -\xe0\xcc\x3c\x05\x0c\x61\x3b\x9d\xf9\x10\xc1\x39\x09\x18\x7a\x66\ -\xf4\x71\xf3\xf5\x5e\xf0\x94\xe4\xa4\x62\xc0\xe9\xd2\x2a\x1b\xe9\ -\x65\x77\x89\xfe\x45\xfc\x69\xc9\x30\xc2\x90\xb8\xce\x30\xcb\xbd\ -\x3c\xd3\xe3\xf7\x02\x44\x53\x7c\x90\x5c\x53\x0c\x44\x65\x6a\x18\ -\x7a\xe4\xd9\xf4\xa5\x42\x53\x8e\x9c\xd4\x28\x86\xdc\xd5\xa9\xd7\ -\x83\xee\x5f\xee\x52\xb8\x17\x0b\x51\x97\xf6\xb5\xe0\x5d\x81\x86\ -\x8b\xb9\xd4\x52\xc5\x03\x70\x04\xdf\x58\x2f\xa4\x69\x75\xf5\x05\ -\xf3\x45\x25\xc9\x5c\x0c\x38\x01\x7d\x51\x12\xb9\xc0\xeb\x8b\xa3\ -\xfd\xa3\x79\x3b\xb8\x00\xe4\x8b\x86\xcc\x11\x83\x22\xe0\x09\xe8\ -\x8c\x7a\xca\x96\x02\x17\x36\x08\xc9\xb5\x77\xf2\x6d\x38\x94\x3c\ -\x51\x14\x38\x41\xa3\x45\x64\xe2\x02\xb7\xd3\x89\xd0\xb8\xf6\xc6\ -\x15\x60\x36\x51\xbd\x4c\x86\x02\x80\x08\x90\x82\x86\x8b\x28\x5a\ -\x04\x9c\xec\xb6\x51\xbe\xea\x93\x2a\x06\x28\x2e\x95\xb4\xec\x14\ -\x05\x50\x38\x1e\xa5\x2e\x0e\x28\xb1\x05\xd0\xac\x0b\xad\x60\xc3\ -\x40\x14\x36\xeb\x42\x01\x23\x0c\x6b\x17\x2a\xa0\x6b\xc9\x2e\x42\ -\x31\x75\xa1\xa4\xae\xa6\xce\xda\x48\x11\x06\xc8\xbc\x28\x99\xba\ -\x18\x88\x82\xe6\x45\x39\x55\x75\x02\xaf\x1a\x96\x41\x04\xdd\xd6\ -\xa3\x40\x61\x5d\xad\x48\x8f\x62\xe0\x09\x99\x78\x71\xb4\xa4\xf4\ -\x2d\x96\x94\x9e\xae\xeb\x07\x8a\x18\x51\x5d\x27\x0a\xa0\x70\xee\ -\xa8\xa5\xad\xe0\x91\xa4\x2e\x90\x65\x54\x17\xea\x92\x22\x45\x81\ -\x14\xca\x7d\xd9\xd6\xea\x92\x0f\x83\x21\x7b\xe1\x82\xbb\x22\xf5\ -\x68\x20\x48\xdf\x1e\x52\x9f\x76\x0d\xf7\xbc\x7b\xc3\xa7\xcb\xcb\ -\x75\x49\xfc\xa2\xec\x73\x0a\xb7\x73\x78\xb3\xdc\x9b\xec\x24\xd8\ -\xc6\x9f\xdc\x7b\x6b\x64\xbb\xcc\x13\x0e\xd5\x7a\xf7\x5a\x5a\xe7\ -\x0d\xbb\xa8\x49\x5b\xab\x5d\x38\x5d\xe7\x0d\xb4\xe1\x9e\xa4\x5a\ -\x32\x24\x48\x41\xa5\x6f\x6a\xe5\x4a\x96\x12\x86\x52\x05\xe2\xd4\ -\xa6\xd3\x06\x65\xd9\x60\xd7\xaa\x39\xe7\x8c\x3d\xc9\x83\x43\xed\ -\x34\xbd\xd9\xee\x94\xf8\x14\x03\x54\xa8\x4d\x89\x9b\xdd\x4e\xc9\ -\x4a\x02\x8d\x27\xb1\xd4\x2b\x30\xd8\xb6\xec\x85\xc1\xb4\xd9\x13\ -\x93\x42\x49\xb0\xda\x54\x2b\xeb\xfd\x49\x62\x46\x33\x13\x02\xb7\ -\x5d\xea\xb4\x97\xbd\x81\x28\xf0\x00\xdc\xa2\xc1\x49\x1b\xcd\xa1\ -\x13\x85\xaa\x04\x57\xaa\x2b\x3d\xd3\xc7\xde\x14\x54\x01\x7a\x5d\ -\x71\x07\xa5\xa2\x9b\x4a\x69\x54\x48\x50\x39\x53\x21\x38\x75\x5c\ -\xa5\x02\x69\xfb\x36\x12\xd8\x10\xaf\xa2\x18\xbf\x50\xbc\xda\xf4\ -\x6f\xa5\xe5\xc3\x38\xa8\x82\x85\x1e\xfc\xa6\x77\x2b\x79\x35\x90\ -\xb0\x66\x9c\x45\x90\x9c\x70\xa6\x9d\x7e\x8b\x80\x4b\xe3\xbb\xab\ -\x59\x2e\x00\x56\x2a\xda\x73\x0f\x11\x55\xc9\xb4\xe3\x81\x03\xa8\ -\xd6\x64\x06\x5b\xe2\x56\x14\x33\xf8\x9b\xa5\x84\x17\xa7\x6a\x68\ -\xa1\x05\x0e\xaa\x90\xaa\x55\xd4\x1b\x7a\x91\x21\x8c\x61\x32\x41\ -\x71\x6b\x93\xae\xb1\x64\x08\xe3\x78\xad\x30\x81\xe0\x26\x5f\xe3\ -\x28\xb1\x8a\x02\xaa\x8b\xf8\x08\x73\x5c\x4c\xd6\x6b\xce\x46\x92\ -\xc5\x04\x6b\x09\x4b\x26\x94\xb2\xc7\x61\x87\x04\xac\x65\x52\x19\ -\xeb\xbb\x76\x55\xec\x21\x71\x43\x2b\x30\xae\xab\xbe\x25\xd4\x5b\ -\x04\x11\xa4\xd7\x53\x85\x56\x47\xf8\xa9\x5c\xf4\xba\x8a\x5b\x64\ -\x0a\x05\x07\x72\x57\xaf\xaa\xb8\xc5\xd6\x16\x30\x31\xea\x15\x15\ -\x16\x36\x29\x1b\x4d\xf1\x07\x14\x50\xe1\xe2\x0f\x4d\xce\xc6\x10\ -\xb3\x5e\x53\xbc\xb0\xc9\xd8\xd0\xee\x98\xd7\x15\xda\xdf\xd4\x2d\ -\x59\xe2\x55\x0c\xaf\x06\x2c\x0f\xd7\x64\x6c\x2c\x99\xc0\x28\xbe\ -\x2a\xa8\x66\x4d\x29\x1b\x6a\x1a\x70\x5d\xab\x56\x53\xb4\x50\x52\ -\x60\x09\x03\x53\xc0\x52\x88\x94\x86\xe3\xa4\x58\x31\xa2\x10\x60\ -\x09\x9b\x26\x0f\x47\x05\x2e\x38\xa8\x02\x15\xa3\xed\xb2\x70\xd4\ -\x1d\x16\x65\xf1\x14\x14\xae\x4d\x12\x4e\x90\x15\x7c\x55\x49\xb8\ -\x46\xb1\x3a\x93\x9c\x1c\x02\x16\x92\x5b\x15\x0b\x42\xf0\x56\xca\ -\xdc\x44\xef\x26\xe9\xd6\xde\xb9\x55\x51\x1c\x18\x01\x4e\x2b\x53\ -\x7f\x25\x6d\x20\x32\xab\x9a\xcc\x24\x58\x44\x1d\x93\xde\x7b\xd7\ -\x5e\xb9\x2a\x98\x70\xd6\xc8\xd0\xbf\xf1\x4b\x05\x68\x38\x88\x2a\ -\x66\xbd\x55\xbe\xbb\x5b\xe1\xa5\x96\xaf\xa1\xc6\xbf\xb0\xa0\x9a\ -\xb4\x92\x3c\xd8\xf6\x96\x8b\x50\x92\xb7\xde\xd1\x8d\x8c\x5e\x14\ -\x4c\x61\xfb\xda\x71\xea\x97\x85\x61\x22\x01\x76\x40\xa3\x3e\xb1\ -\x28\x88\x02\x37\x40\x93\x14\xf5\xc5\x90\xbe\x60\xae\xa9\xcd\x14\ -\x27\x85\x8a\xa2\x50\x01\x7b\xda\x51\xab\x2c\x70\x48\x95\xf0\xda\ -\xb5\x8b\x1e\xce\x47\x7b\x2f\xe9\xc0\x13\xea\x6e\xce\x24\x77\x31\ -\x10\x75\x4c\x68\xaf\x3a\xab\x7e\x2f\x6b\xaa\xe4\x33\x43\x45\xbf\ -\xd0\xa0\x6a\x26\xbd\x55\x27\x5b\x19\x47\x78\xb4\x0d\xba\xff\xfe\ -\x67\xc9\x8f\x51\x04\x2a\x06\xa7\x5a\xcb\xbc\xe7\xce\x40\x08\x5f\ -\x41\xc5\x0e\x48\xe2\x97\x33\x15\xa1\x0b\x30\xe2\x37\xf9\xa8\x94\ -\x15\x47\x10\xc0\x4e\x32\x2e\x74\x34\x63\x01\x60\x0d\xdb\x9e\x1e\ -\x04\x2c\x02\xb0\x86\x69\xe5\x78\xe8\x8a\xe6\x5f\x06\x6c\x9d\x18\ -\xcf\x68\xe5\x1b\x4a\x5e\xdc\x33\x9b\x5e\xfd\x87\x09\xd3\xc2\x0b\ -\x5a\x47\x8e\x90\x76\x03\x83\xb4\x5e\x75\x4c\x0d\x28\x71\x22\x4a\ -\x70\xd9\xf1\xba\x01\xa5\xa2\xa8\x12\x0a\xac\x90\x29\xf2\x50\xfb\ -\xac\xe4\xdc\x20\x64\x6a\xe0\x36\xc0\x48\xf6\xaf\x24\x19\x8c\x01\ -\x2a\x28\xaf\xa6\x05\x52\xb4\x4e\x15\x29\x03\x07\x65\x31\xd5\xed\ -\x27\x89\x59\x51\x34\x2b\x5c\x1f\xf6\xe4\xaf\x4a\xaa\x69\xb9\x2a\ -\x33\x78\x57\x9e\xef\xc8\x60\x42\x89\x2e\x01\x45\x83\x9b\xfc\xaa\ -\xa4\x5a\x51\x14\x50\x61\x72\xe6\xdb\x04\x2b\xa5\x58\x71\x52\xac\ -\x8a\x69\xe3\x65\x67\x75\x4b\x1f\xd9\x38\x47\xa1\x08\x14\x58\x81\ -\x92\xac\xfb\x7c\x1c\xf5\x7f\x00\xb7\x99\xbc\x16\x52\x9d\xee\x48\ -\xc4\x55\x50\xae\xbb\x6c\xf4\x82\xbd\xe8\x43\xe6\xa8\x10\x18\x07\ -\x52\xcf\xbc\x95\xe1\x8c\xc3\x7a\x01\xa4\x89\x59\x25\x05\x21\xa0\ -\xe5\x6f\x64\x47\x13\xda\xab\xa5\xbe\x55\x33\x7a\x11\x97\xaa\xcc\ -\x06\x12\xbd\x18\x98\x46\xaf\x46\x3a\xed\x5c\x77\x69\xf7\x85\x7c\ -\x1a\xc8\x57\x45\xe2\x54\xcd\xac\x74\xe6\x4c\x20\xf8\x02\x54\x2d\ -\xd9\xbe\x48\x7c\xaa\x18\x0f\x5e\x9d\x59\xd4\x78\x11\x9f\xa6\x00\ -\x30\x05\x1f\xfa\xc2\xf4\x66\x74\xbf\x79\x73\x08\xed\x86\xa6\x0d\ -\x49\x38\x9f\x4c\xee\xee\xce\x93\xa4\x78\x2a\x96\xe5\x74\xba\x23\ -\xc9\x5d\xfd\x3a\x43\x92\x5f\xfe\xa0\xbb\x9f\xda\x61\xbd\x9d\x08\ -\xc6\x1f\xf8\x4d\x9b\x89\x13\x5d\xb0\x3a\xe3\xb0\x1f\xd8\x4e\xb7\ -\xd3\x91\x38\x3f\xa5\x60\x2a\xbd\xf6\x66\xe0\x6b\xd7\x99\x55\x3c\ -\x75\x2f\x3f\xaa\xba\x75\x8d\x96\xe9\xa5\xf6\x14\xfc\x06\xe1\xf2\ -\x7c\xaa\xdf\x19\xe1\x0e\x92\x27\xbf\x91\x74\x86\x59\x58\xaa\x59\ -\xeb\xf9\xbb\xa3\xda\x41\x31\xdd\x6f\xa4\x5b\x88\x2e\x86\x3d\x6c\ -\x66\xf5\xfd\x4c\xb9\x83\xdc\x4e\x3f\x93\x8e\x5f\xfb\x64\xbb\x9c\ -\x4d\xbb\xa6\x5b\x7f\x64\x7b\x87\x2a\xe1\x72\x0e\xed\x52\x0a\x42\ -\x32\xdf\x13\xd5\xee\xa6\x77\x96\xbf\xc7\xc9\x76\x31\xe1\x5a\xdc\ -\xd9\x23\xcd\xf2\xbb\x3c\xbc\x4b\x9a\x65\x17\x9b\x20\x5d\x0c\xda\ -\x23\xe5\xde\x27\x8f\xf2\xcb\x55\x41\x17\x97\x7a\x66\xea\x83\xd7\ -\xce\xaa\xfa\x20\x3c\xdc\x0f\xaf\x7e\x2f\x94\x8b\x1a\xf5\xc0\x6d\ -\xec\x91\x65\xfb\x26\x60\x32\x48\xde\x1f\x01\xb9\x82\x60\xdb\xd3\ -\x83\xd7\x48\x3b\x71\x10\x55\xec\x87\x69\xbf\x17\xba\x1d\x26\x38\ -\x7b\x64\xd9\xbe\xc9\xa7\xb5\x31\xef\x8f\x7c\xfc\x72\xe2\x75\x1a\ -\xc4\x8e\xf1\xe3\xda\xce\x6b\x24\x9e\x38\x6a\x22\xd1\x93\x59\xfc\ -\x9d\x50\xae\x56\xb5\x20\xba\xb6\x6f\x0a\xde\x4e\xa6\xca\xbc\x3b\ -\x1b\x39\x79\x64\xbd\x87\xe9\x4e\xe9\x79\xa5\xa4\xcb\x02\x90\xd2\ -\xe8\x99\x80\xde\xe7\xf9\xfb\xe3\x5e\x7e\xb4\x0f\x5f\x9f\xa6\xde\ -\xe1\x7c\xbc\x46\xca\xd5\xce\xd9\xe5\x53\xaf\xcd\xb6\xd7\x4f\xb6\ -\x5a\x5d\x1c\xa4\x69\xfb\xe4\xd9\xfe\xa8\x97\xa4\xdd\xbb\x94\x77\ -\x89\x7c\x30\xce\x59\xcf\x02\xef\xee\x8e\xbf\x43\x27\xe3\x62\x23\ -\xaf\x8b\x74\xbf\x32\xce\xbe\x2e\x5e\x76\x24\x7b\x59\xcc\xc7\xab\ -\x78\xcb\x91\x6c\x0f\x55\xb1\x2a\xaa\xa7\x62\xd8\x26\x67\xb9\x5c\ -\x67\xf5\xfb\xf8\xa0\xd5\x22\x9f\x7f\xac\x8f\x3c\xd7\xb7\x79\x74\ -\x68\x35\xfb\xb9\x18\xa7\x98\x62\x9d\xa5\x16\xe1\xe1\xe5\x63\xca\ -\x3f\x67\xcd\x13\x8d\xf9\x3f\x36\xa7\xdd\xe5\x8b\xd9\xfc\x75\xbc\ -\xca\x97\xab\x2c\xfe\xe2\xec\xee\xe3\xbc\x58\x47\xfa\x66\xe9\x46\ -\x66\xcb\xfb\x31\x8f\x17\x3e\x97\xd5\xf4\xe8\xc0\x36\xcc\xd8\x85\ -\xea\x06\xc3\x43\x1c\x1a\x00\x45\x63\xc0\x59\x27\x0f\x89\x28\x38\ -\x33\xdc\xd9\x83\x26\x53\x4d\xa9\x9e\x74\x4a\x1b\x79\x04\x5c\xa2\ -\x95\x16\xca\x0e\x3f\xdf\xac\xe3\xdd\x2c\xb7\x63\x91\x3a\xe5\x74\ -\xf6\x10\xff\x8d\xab\x32\x51\x29\x3d\xe8\x70\x3f\x5a\x5f\x9b\x2e\ -\x88\x17\xb7\x1a\xe7\x9c\xfe\xfa\x99\xdf\x6f\x21\x90\x88\xab\x65\ -\xb3\xd2\xcd\x05\xdd\x22\x6e\x5a\x21\x73\x8e\xbc\xe7\x48\xf2\xf9\ -\xff\xfe\xf7\x66\x54\xdf\xe5\xe7\xf8\x37\x3e\x69\x9a\x20\x75\x8a\ -\xfe\x66\xb4\x7a\x8a\x7f\xfe\x1f\x17\xb6\xc9\x26\ -\x00\x00\x08\xfd\ -\x00\ -\x00\x20\xe8\x78\x9c\xd5\x58\x5b\x73\xda\x48\x16\x7e\xf7\xaf\xd0\ -\xe2\x97\xb8\x16\x35\x7d\xbf\x10\xe3\x79\x48\x6a\xa6\xa6\x6a\xa6\ -\xb6\x6a\x27\xa9\x7d\x9c\x12\x52\x03\xda\x08\x89\x92\x84\x81\xfc\ -\xfa\x3d\x2d\xd0\x0d\x44\x6c\xc7\xde\xcc\x2e\x54\x1c\xfa\x9c\xd3\ -\xb7\xef\xdc\xfb\xfe\xa7\xfd\x3a\xf1\x1e\x6d\x5e\xc4\x59\x3a\x1b\ -\x11\x84\x47\x9e\x4d\xc3\x2c\x8a\xd3\xe5\x6c\xf4\xf9\xd3\xcf\xbe\ -\x1e\x79\x45\x19\xa4\x51\x90\x64\xa9\x9d\x8d\xd2\x6c\xf4\xd3\xc3\ -\xcd\xfd\xdf\x7c\xdf\xfb\x90\xdb\xa0\xb4\x91\xb7\x8b\xcb\x95\xf7\ -\x6b\xfa\xa5\x08\x83\x8d\xf5\xde\xad\xca\x72\x33\x9d\x4c\x76\xbb\ -\x1d\x8a\x4f\x44\x94\xe5\xcb\xc9\x9d\xe7\xfb\x0f\x37\x37\xf7\xc5\ -\xe3\xf2\xc6\xf3\x3c\xd8\x37\x2d\xa6\x59\x31\x9f\x8d\x3a\x33\xb2\ -\x8d\x4d\x8b\x5d\x50\x86\xab\x79\x96\x7d\xa9\xe6\x6d\xf3\x78\x42\ -\x31\x36\x13\x90\x1d\xb5\x33\xa3\xb0\x99\xb8\xd9\xe6\x49\x25\x1a\ -\x85\x13\x9b\xd8\xb5\x4d\xcb\x62\x42\x10\x99\x74\xc4\xc3\x56\x3c\ -\x74\xe7\x8e\x1f\x6d\x98\xad\xd7\x59\x5a\x54\x33\xd3\xe2\xb6\x23\ -\x9c\x47\x8b\xde\xa9\x76\xac\x12\x22\xc6\x98\x09\xa6\x13\x4a\x7d\ -\x90\xf0\x8b\x43\x5a\x06\x7b\xbf\x3f\x15\x6e\x37\x34\x15\x2e\x80\ -\x27\xc0\x6b\x25\x9f\x27\x35\xdd\x27\x00\xe2\xd5\xc3\x54\xdc\xee\ -\xee\xa0\xb8\x0d\xfc\x6b\x26\xd4\x04\x54\x64\xdb\x3c\xb4\x0b\x98\ -\x69\x51\x6a\xcb\xc9\xc7\x4f\x1f\x1b\xa6\x8f\x51\x54\x46\x9d\x65\ -\x6a\xbd\xf5\xf6\xed\x29\x33\x0d\xd6\xb6\xd8\x04\xa1\x2d\x26\x35\ -\xbd\x9a\xbf\x8b\xa3\x72\x35\x1b\x31\x8e\x08\x83\x8f\xa8\x88\x2b\ -\x1b\x2f\x57\xe5\x39\x35\x8e\x66\x23\xb8\x2b\x35\x46\x55\xe3\x8e\ -\x11\x92\xa3\xc0\x69\xe1\x69\xc3\xc1\xc8\x50\x44\xbc\x9c\x08\xa6\ -\x8e\x32\xf5\x15\xa6\x51\x16\xba\x33\xc1\x92\x76\x1d\x07\xdb\x32\ -\x5b\x83\x8e\xc3\x30\x09\x8a\x22\x5e\xc4\x21\x0c\xb2\x74\x93\x6c\ -\x97\x71\xfa\x67\x01\xf6\x11\xa7\x36\xf9\xb3\xcc\xb2\x04\xd5\x70\ -\x37\xbb\xd9\xfd\x26\xcb\x4b\x7f\x1f\x6d\x00\x46\xa9\x06\x99\x87\ -\x9a\xf9\x00\xdc\xfb\xe6\x10\xee\x04\xd1\x63\x6c\x77\x6e\xce\xf1\ -\x86\xf3\xa0\x38\x22\xe3\x79\x9b\x60\x09\x36\x97\x64\xf9\x6c\x74\ -\xbb\xa8\x3e\x27\xc6\x3c\xcb\x23\x9b\xd7\x2c\x59\x7d\x7a\xac\x0c\ -\x90\x8e\xcb\xc3\xd1\x3f\x4f\x6b\xd7\x27\x72\xab\x36\x7c\x3c\xcc\ -\x2f\x56\x41\x94\xed\x66\x23\x7a\xce\xfc\x9a\x65\xeb\xd9\x48\x21\ -\x43\x34\xe6\x44\x9d\xb3\xc3\xfd\x6c\xe4\x13\x82\x34\x33\x5c\x98\ -\x0b\x2e\x6c\x48\x15\x62\x18\x53\xc5\x2e\x98\xdb\x3c\x07\x9c\xfd\ -\x24\x38\x58\xb8\x55\xf5\x1f\x39\x09\x15\xab\x6c\xb7\xcc\x1d\x3a\ -\x65\xbe\xb5\xe7\x33\x1d\xc7\x9f\xcf\xb3\xfd\x30\x1b\x14\xbd\x75\ -\x1e\xee\x6f\xd3\xb8\x04\x2f\xda\xec\xbb\xab\x6e\xe3\xc8\x16\xc3\ -\x13\x8b\x34\xd8\xf8\xcb\x24\x9b\x07\xc9\xb0\xc0\x2e\x4e\x01\x25\ -\xff\x64\xc2\x84\x35\x4a\x38\x97\xa8\xed\x59\x61\x7d\x45\x02\xce\ -\x7e\xa1\x88\x13\xeb\x70\x9d\xb5\x0e\xf6\xf1\x3a\xfe\x6a\x01\x18\ -\x52\x59\x16\xd8\x56\x0f\x96\xe3\xb4\xa3\x61\xb9\x31\x40\x2f\x46\ -\x35\xb1\x3c\x38\x87\xdd\x1f\x1c\xa3\x21\x66\x79\x0c\x26\xdf\x39\ -\x4e\x4d\x3a\x74\x49\xce\x93\x21\xe0\xef\x2b\x03\xab\xcc\x4f\x9d\ -\xf3\x0e\x5d\x9e\x37\xa9\xec\x7e\x72\x69\xf8\x15\x3d\xb2\x8b\xa2\ -\xf5\x00\x37\x02\x27\x37\xf5\x8d\x20\x64\xd9\x20\xff\x25\x0f\xa2\ -\x18\xd4\xd8\xbd\x52\x9f\x23\xb4\xa8\xe7\x38\x1f\x2b\xb3\x4d\x2d\ -\x0b\x87\x2a\x0f\x89\xf3\x75\x20\xfa\x95\xdf\x4c\x6f\x4d\x18\x04\ -\x18\xbf\xaf\x48\x27\x7f\x98\x92\xf7\xa3\x76\x4e\xb6\x58\x14\xb6\ -\xec\x5e\xfb\x14\x83\x60\x86\xd0\x92\x9c\x6e\xf5\xcc\xdd\x08\x8b\ -\xc8\xfc\x19\xbb\x91\xe1\xdd\x58\xb3\xdb\xfd\xa4\x7f\xed\x17\xa3\ -\x44\xdb\x2d\x20\x43\x82\xbf\xc7\x29\xec\x5b\x64\x09\x98\xc1\xf3\ -\x2f\xb4\x90\x90\x7b\xce\xe0\xc3\x48\x69\x4d\x99\x60\x2f\xc0\x91\ -\xbe\xe1\xcd\x88\x78\x93\x9b\x2d\xe6\x6a\xae\xbe\xdb\x30\x88\x7a\ -\xb3\x0b\x29\x22\x5f\x70\x6e\x4c\x08\xe5\xe4\x7b\xcf\xad\x88\xbe\ -\x6e\xd0\xad\x14\xd5\x43\x0b\x22\x69\xc0\x44\x71\x07\xff\xc1\x13\ -\x92\x79\x28\x43\x79\x71\xc2\x97\xf8\x91\x90\x5c\x07\xfa\x7b\xfd\ -\x48\x51\xfc\x86\x7e\xa4\x7c\xec\x5f\x8d\x38\x1d\x0b\x37\xbe\xf2\ -\xc9\x13\x7a\x18\xd2\x27\x0e\x95\x59\x3c\x1f\xad\x76\x47\x46\xe0\ -\x64\x43\x8a\x22\xdf\xde\x71\x21\x17\x8b\x0b\x9f\x7e\xff\x14\x62\ -\x6e\x14\x24\x17\x88\x35\x89\x3d\x4b\x12\x1b\xc2\xe6\x41\xb2\x0b\ -\x0e\x45\x73\x82\xaa\x14\x9d\xae\x72\x0b\xa5\xf3\xed\x15\x6c\xbb\ -\xf0\xf7\xb7\x61\x5a\xb4\x29\x67\x79\x22\x7e\x3e\x66\xf8\x6d\x61\ -\xf3\x3f\x5c\xad\xf9\x8f\xf4\x73\x53\x4c\xb5\x52\x9f\xf2\x20\x2d\ -\xa0\xb0\x85\x42\x06\x6a\xbe\x3c\xde\xbf\xf3\x19\xa2\xac\xfa\x8e\ -\x29\xe2\x84\x71\xa9\xc7\x50\xe3\x6a\x82\xa5\xa1\xd4\xfd\x84\x72\ -\x46\x63\x25\xcc\x58\x71\x24\x25\x16\x54\x8e\x7d\x8d\x34\xe7\x5a\ -\x31\x7e\xd7\x6c\xe1\xea\x1f\x22\x50\xeb\x06\xae\xe4\x21\x0a\x29\ -\xc3\xb5\x69\xcf\xbb\x38\x17\x5b\x0c\x8a\x41\x19\x44\x34\x12\x92\ -\x8a\x56\x05\x57\xcc\xf3\x35\x60\xbb\x28\x73\xdd\xce\x99\xe6\xf4\ -\x85\x40\x17\x1b\x68\x98\xa2\xdf\x6d\xb9\xca\x60\xb9\x4d\xd0\x56\ -\x17\x7b\x32\x1b\x69\x44\xa9\xd6\x12\xb7\xda\x3d\x00\x95\x18\x64\ -\xa4\x51\xed\xe5\xf7\x14\x8a\x45\x8e\x20\x99\xb8\x54\xdb\x88\xd2\ -\x01\xd1\xeb\x8a\x25\x08\x74\x29\xb8\xe1\x63\x0c\x5f\x82\x28\x87\ -\x20\xc9\xd8\x58\x22\xc1\x29\x66\x8c\x8c\x7d\x2a\x11\x31\x4a\x13\ -\xd0\xe2\x7f\x13\x64\x2d\xcc\xb7\x41\xe6\x6f\x66\xcd\x60\xb8\x8c\ -\x72\x25\x8d\x33\x5c\x2a\x95\x6b\x12\x45\x65\xcf\x94\x48\x6a\x44\ -\x45\x87\xaa\x4c\x6b\xa5\xe0\x37\x47\x5a\x72\x21\xd9\x98\x48\xa4\ -\x35\x93\x44\xdf\xf5\xf4\x05\xe5\xbc\x22\x5c\x76\x0a\x47\xa7\x2f\ -\x68\x1c\x88\x20\x18\x73\x23\x7b\x2a\x63\x50\xfc\x43\x7d\x8f\x59\ -\x4f\x65\x5d\xe9\xa7\x50\x1e\x4c\x83\xbe\xf8\x91\x89\xd0\xc7\xcf\ -\x4b\x85\x3e\x1f\x5a\xf4\xff\x28\x19\xfa\xe2\xfb\xd2\xe1\xa0\x1b\ -\x5e\xf1\xd8\x41\xe7\x1e\x8c\x03\xd7\xe3\xc6\xcb\x3d\xdc\x40\x1c\ -\x17\xa0\xcb\xb1\xcf\x18\x38\xb8\x50\x9c\xdc\xbd\xd0\xc3\x86\xdc\ -\xd4\x90\xe7\x86\x54\xbf\x55\xff\xd5\xc0\x51\xb7\x45\xae\xe3\xa9\ -\x7e\xad\x6d\x19\x44\x41\x19\xb4\xcd\x50\x4d\x71\x4d\x73\xdd\x10\ -\xe5\xd1\x62\xfa\xcf\x8f\x3f\x37\x76\x12\x86\xd3\x7f\x65\xf9\x97\ -\x56\xc5\x4e\x20\x98\x67\x5b\xd8\xa9\x71\x1b\xd7\x66\x85\x53\x87\ -\x5d\x50\x3e\xc4\x6b\x68\xf2\xdd\xc3\xd1\xdf\xf7\xeb\x04\xf6\x6f\ -\x18\x3d\x61\xd7\x20\xb6\x8b\x1e\x97\xcd\xed\xf1\x61\x68\xf0\x2d\ -\x2d\x0a\xd7\xb1\x9b\x34\xf9\xa3\x8c\x93\xe4\x57\xb7\x49\xc7\x9e\ -\x4f\x8b\xc6\x65\x62\x3b\x46\x3e\x39\x9d\xbe\xb6\xc2\xce\xe5\xee\ -\x27\xf5\xed\xab\xd1\xf2\xa6\x8f\xe6\x32\xcf\xb6\x9b\x75\x16\xd9\ -\xd3\x6b\xc1\x79\x93\x9c\x04\x73\x0b\x9d\xfb\x6f\x8e\xe7\xd5\x7a\ -\xab\x94\x7a\x7c\x5b\x38\xed\x68\x93\x24\xde\x14\xcd\x45\x4f\x6e\ -\xb6\x80\x0b\x4c\xe1\x6a\xef\x6e\x2f\xeb\x8e\xbb\xf7\x8e\xdb\xf1\ -\xb8\x6a\x98\x6f\x13\x3b\xb5\x8f\x36\xcd\xa2\x08\x5c\x32\xcf\xbe\ -\x58\x57\xc3\x9d\xba\x24\x37\x3c\xbe\x14\x4c\x9b\x21\x80\x65\xf3\ -\x04\x3a\xf8\x72\xca\x6b\x5a\x14\x14\xab\x20\xcf\x83\xc3\x34\xcd\ -\x52\x5b\x53\x9b\xad\x7a\xc6\xb9\x09\xca\x95\x94\xac\x4d\xcf\x55\ -\xf9\x81\x8f\x6f\x66\x6d\x00\xae\x6a\x10\x08\xe2\x8e\xd8\x06\xac\ -\x7c\xef\xbc\xb5\x1d\xba\xb7\x19\x28\x7e\xda\x78\xe0\x56\xbf\x0a\ -\xca\x65\xfa\x7a\x2d\x28\x08\x2b\xca\x08\x13\xfc\x5b\xe8\x5c\xe2\ -\x00\x30\xfc\xee\x11\x06\x39\xcc\x3d\x34\x8c\xa1\xaa\x32\xe0\xed\ -\x84\x7b\x54\x38\x1c\x94\xa1\x63\x42\x11\x33\x12\x52\x92\xf7\xc1\ -\x73\xd9\x9e\x48\x26\xa5\xa3\x62\xad\x0d\xa7\x1e\x5c\x5b\x00\x05\ -\x73\x08\x1a\x82\x28\x48\x5e\xda\xa3\x04\x49\xce\x29\x93\x63\xed\ -\xc2\x39\x21\x82\x7a\xbf\x79\x10\xc7\xc0\xb5\x29\x26\x50\x40\x28\ -\x88\x29\x4c\x69\x58\x13\x6a\x34\x97\x4c\xa9\x19\xc3\xe6\x4a\x42\ -\xf2\x65\x1e\xe4\x52\x08\x6e\x42\x29\xa0\x61\x2a\xa1\x74\x04\x9a\ -\x40\x0c\x0b\x63\x9c\x1c\x3b\x7e\x60\x4d\x8e\x30\x83\x4c\x0c\xa5\ -\x08\xd4\x93\x42\x42\x2a\xae\xce\x09\x9d\xb4\x84\x98\x69\xe0\x4c\ -\x94\x6b\x42\x99\x02\x1a\x87\x44\xcc\xe1\xe8\x18\x0e\x2c\x88\x30\ -\x1e\x43\x4c\x61\x85\xb9\x18\x83\x82\x5d\x67\x0f\x4b\x86\x1e\x44\ -\x42\x0f\x52\x3c\x68\x1b\x6b\x0e\x79\x1d\x31\x49\x15\x67\x20\xad\ -\x24\xc7\x8a\xd3\x31\x43\x02\x4b\xb8\x12\x6c\x0e\x97\x13\x86\x41\ -\xdd\x4b\x38\x53\x4a\x78\x02\x41\xaa\x27\xca\xd5\x03\x88\x40\x27\ -\x61\x88\x07\x97\x65\x44\x43\x6d\x30\x76\xa5\x05\x86\xe8\xee\x7d\ -\xed\x97\xe6\x10\xd4\x38\xe5\x83\x11\x2f\x4d\x81\x99\xe5\x7e\xb8\ -\xcd\x1f\x83\x72\x9b\xdb\xde\x3b\x52\xf3\x1e\x04\x6e\xec\x22\x07\ -\x44\xe3\xa2\xfa\x84\x5f\x8b\xa7\x4d\xb1\xe3\x22\xd7\xac\x8a\x0b\ -\x87\xa9\x6e\x2c\xc8\x19\x2e\x9c\x6c\x3a\xdf\x96\x65\x97\xf6\xef\ -\x2c\x4e\xa7\x95\xc9\xbd\x85\x77\xba\xc0\x0d\x70\x13\x46\x25\x87\ -\x64\xa4\x10\x3f\x3e\x84\x55\xca\xd1\xe8\x78\x54\x06\xbf\x5b\x4b\ -\xe8\xfc\xbe\x70\x72\xf0\x2f\xf9\x6c\x6c\xdf\x02\x35\x41\x95\x51\ -\x0c\xcb\xbf\x00\x35\x68\x78\x8e\x28\x38\x33\xef\xa2\xd6\x41\xa8\ -\xf3\x73\x10\x2b\xff\xc7\xa2\xa5\x4e\xda\xfd\xe1\x68\x41\xe4\x93\ -\x1d\x13\xfa\xe0\x86\x10\xb9\x4e\x43\x18\x10\x79\xfc\x3b\x8c\x12\ -\x7f\x39\x4a\xce\xd3\x9f\x9f\x14\xe8\xab\x93\x02\xa1\xd0\x80\x33\ -\xf9\x56\x19\xf3\x18\xa8\x44\x1b\x80\x4e\x6f\xf7\x00\x9a\xe0\x5c\ -\xb5\xa5\x68\xfd\x62\x0f\xa1\x1d\xfa\x7e\xd3\x79\xf5\xda\x1f\x3b\ -\x75\x2c\x55\x8b\x2a\xe4\x4e\x5f\x20\xa5\x18\x38\x3b\xed\xa5\x54\ -\x08\xb9\x90\x78\xfa\x59\xb7\x29\x59\xdb\x97\xf8\x81\x1e\x4e\x42\ -\xdf\xef\xf2\x0f\x98\x97\xe0\x2e\x86\x55\x6d\x9b\x12\x5a\x11\xa5\ -\xe8\xd8\x09\x10\x0e\xa9\xae\x2a\x7c\xef\x9e\xd6\xd0\xad\x0d\xdd\ -\xf7\xd5\x59\x5a\x82\x5a\x55\xd5\x5d\xbd\x99\x46\x98\x56\xec\x5c\ -\x23\x06\x32\x13\x95\xd0\xc6\x5e\xa8\x04\xb2\xb5\xe2\x4a\x0b\xda\ -\x55\x09\xc0\x8f\x21\x67\x71\xcd\x7a\x4a\x21\x1c\x11\x09\x89\x8d\ -\x9e\x29\x80\xc0\x02\xbc\x5f\xfc\xb8\x60\x63\x04\x60\x6a\xbe\xa1\ -\x16\xf7\x12\xc4\xc0\x50\x20\x9d\x83\x06\x98\x90\x98\x52\x42\x2a\ -\xc5\x68\x03\x25\xba\xae\x1e\x8b\x60\x47\x0c\xf6\xf1\x4c\xc5\x0c\ -\xba\x8e\x21\xff\xab\xae\xe3\xd3\xd7\x39\x0f\x85\xec\xa2\x31\x35\ -\xa6\xaf\x28\x28\x78\x14\x54\x7f\xe6\xaf\xf4\x9e\xfb\xc9\xf2\xe1\ -\xe6\xde\xb5\x45\x0f\x37\xff\x01\x38\xd8\x1b\xbe\ -\x00\x00\x0d\x7d\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x73\x65\x74\ -\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ -\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ -\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ -\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ -\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ -\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ -\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ -\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ -\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ -\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ -\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ -\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\ -\x36\x35\x2e\x31\x37\x35\x34\x33\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x2e\x31\ -\x38\x33\x33\x38\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ -\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\ -\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\ -\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\ -\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ -\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ -\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ -\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ -\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ -\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ -\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ -\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ -\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ -\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ -\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ -\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ -\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x64\ -\x35\x66\x66\x64\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ -\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ -\x22\x37\x34\x2e\x36\x36\x36\x36\x36\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x38\x2e\x36\x36\ -\x36\x36\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ -\x2d\x32\x31\x2e\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x79\x3d\x22\x2d\x33\x2e\x32\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\x33\x38\x32\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x23\x66\x32\x66\x32\x66\x32\x3b\x73\x74\x72\x6f\x6b\x65\ -\x3a\x23\x32\x65\x32\x65\x32\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x77\x69\x64\x74\x68\x3a\x33\x2e\x32\x35\x31\x38\x32\x35\x38\x31\ -\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ -\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ -\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ -\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ -\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\x48\ -\x20\x33\x32\x20\x56\x20\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\ -\x48\x20\x30\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x38\x2d\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ -\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ -\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ -\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\ -\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ -\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ -\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x65\x39\x63\x36\x61\x66\x3b\x66\ -\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ -\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\ -\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x30\x30\x31\x33\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ -\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ -\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\ -\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ -\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\ -\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\ -\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x38\x35\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ -\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x37\ -\x2e\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x79\x3d\x22\x31\x39\x2e\x34\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x72\x79\x3d\x22\x37\x2e\x31\x36\x38\x38\x33\x30\x39\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ -\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ -\x66\x30\x30\x31\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x31\x2e\x38\x33\x39\x39\x39\x39\x39\x31\x3b\x73\x74\ -\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ -\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ -\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ -\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ -\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\ -\x32\x31\x2e\x33\x33\x33\x33\x33\x33\x2c\x32\x33\x2e\x34\x36\x36\ -\x36\x36\x37\x20\x38\x2c\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x35\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ -\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ -\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ -\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ -\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ -\x65\x3a\x23\x66\x66\x30\x30\x31\x33\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x38\x33\x39\x39\x39\x39\x39\ -\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ -\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ -\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ -\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ -\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ -\x3d\x22\x6d\x20\x32\x39\x2e\x33\x33\x33\x33\x33\x33\x2c\x32\x33\ -\x2e\x34\x36\x36\x36\x36\x37\x20\x2d\x38\x2c\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ -\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x06\x94\ -\x00\ -\x00\x25\x7d\x78\x9c\xe5\x59\xdb\x6e\xdb\x38\x10\x7d\xcf\x57\x68\ -\x9d\x97\x16\x6b\x51\x22\x75\x57\xec\xf4\xa1\x45\x17\x05\x76\xb1\ -\xc0\x36\xc5\x3e\x16\xb4\x44\xdb\xda\xca\xa2\x41\x51\xb1\xdd\xaf\ -\xdf\xa1\xee\xb2\xe5\x36\x6d\xd2\x36\x41\x14\xc4\x91\x66\x86\x97\ -\x39\x3c\x73\x91\x33\x7b\xb5\xdf\xa4\xda\x2d\x13\x79\xc2\xb3\xf9\ -\x04\x23\x73\xa2\xb1\x2c\xe2\x71\x92\xad\xe6\x93\x0f\x37\x6f\x75\ -\x7f\xa2\xe5\x92\x66\x31\x4d\x79\xc6\xe6\x93\x8c\x4f\x5e\x5d\x5f\ -\xcc\x7e\xd3\x75\xed\xb5\x60\x54\xb2\x58\xdb\x25\x72\xad\xbd\xcb\ -\x3e\xe5\x11\xdd\x32\xed\xc5\x5a\xca\x6d\x68\x18\xbb\xdd\x0e\x25\ -\xb5\x10\x71\xb1\x32\x5e\x6a\xba\x7e\x7d\x71\x31\xcb\x6f\x57\x17\ -\x9a\xa6\xc1\xba\x59\x1e\xc6\xd1\x7c\x52\x0f\xd8\x16\x22\x2d\x0d\ -\xe3\xc8\x60\x29\xdb\xb0\x4c\xe6\x06\x46\xd8\x98\x74\xe6\x51\x67\ -\x1e\xa9\xd5\x93\x5b\x16\xf1\xcd\x86\x67\x79\x39\x32\xcb\x2f\x7b\ -\xc6\x22\x5e\xb6\xd6\x6a\x37\x3b\xab\x34\xc2\x41\x10\x18\x26\x31\ -\x08\xd1\xc1\x42\xcf\x0f\x99\xa4\x7b\x7d\x38\x14\xf6\x38\x36\x94\ -\x98\xa6\x69\x80\xae\xb3\xbc\x9b\x55\xb8\x4f\x01\x8a\xb3\x9b\x29\ -\xb5\xfd\xd5\x01\xfe\x2d\xfc\xb6\x03\x1a\x01\xca\x79\x21\x22\xb6\ -\x84\x91\x0c\x65\x4c\x1a\x6f\x6e\xde\xb4\x4a\xdd\x44\xb1\x8c\x7b\ -\xd3\x34\xe8\x0f\xd6\x1d\x1c\x49\x46\x37\x2c\xdf\xd2\x88\xe5\x46\ -\x23\x2f\xc7\xef\x92\x58\xae\xe7\x13\xcb\x46\xd8\x82\xcb\x29\x85\ -\x6b\x96\xac\xd6\xf2\x58\x9a\xc4\xf3\x09\xf8\x4a\x02\xbf\x7a\xee\ -\x51\x09\x57\x06\xf5\xc4\x61\xab\x31\x51\x40\x10\xd6\x04\x76\x2c\ -\xaf\xb2\x69\x5c\x08\x63\x1e\xa9\x3d\xc1\x94\x6c\x93\xd0\x42\xf2\ -\x0d\x9c\x71\x14\xa5\x34\xcf\x93\x65\x12\xc1\x03\xcf\xb6\x69\xb1\ -\x4a\xb2\x8f\x82\x27\x1f\x37\x45\x2a\x93\x6d\xca\x50\x83\x76\xbb\ -\x18\xdb\x6f\xb9\x90\xfa\x3e\xde\x02\x8a\xae\x37\xaa\x3c\x34\xca\ -\x6b\xd0\xce\x62\xb6\xcc\x95\x55\xe5\x92\x7a\x02\x9f\x2a\x1d\x68\ -\xe1\x84\x18\x15\x7f\x08\x1a\x27\xc0\xcb\xca\xae\xb2\x1c\x6a\x1c\ -\xcf\x6b\xc6\xc0\xa8\x5c\xf2\x6d\x63\x0b\x5e\xca\x43\xaa\x5c\x03\ -\xa1\x1e\xf1\x94\x8b\xf0\xd2\x34\xf1\xc2\x71\xaf\x4a\x11\x87\x83\ -\x48\xe4\x21\xc4\x57\x93\x6e\x0c\x5f\x2e\x73\x06\xa0\x9b\x3d\x59\ -\x09\x39\x8c\x80\xb5\x82\x89\x66\x9c\x59\xad\xb3\xf2\xbd\xb1\x09\ -\x91\x6b\x7b\xa6\xe3\xfb\xf6\xe4\x8b\x3b\xb4\x5d\x0f\x7b\xcb\xe1\ -\x0e\x4d\x64\x07\xbe\x69\x05\x84\x5c\x9d\x5f\x7f\x64\x2e\x1c\x7b\ -\x96\x7f\x3c\xd7\x98\xb7\x78\xd4\x5b\x1f\xb7\xab\xcd\x8c\x21\xec\ -\x5f\x3e\xa5\xe6\xdc\x61\x1b\x29\x8b\x60\x7e\x9a\xee\xe8\x21\x6f\ -\x17\x29\xe3\x2f\x5c\x0b\x06\xf9\xe2\x72\xe4\x3c\xbf\x74\xdc\x35\ -\xed\xcb\x69\x70\xff\x9c\x0e\xf0\x64\x91\x4e\x49\x54\xe4\x74\x5a\ -\xd2\xb7\x5d\xd5\xd3\x7d\xc8\x12\x09\x29\xa5\xc8\x99\x78\xaf\xc2\ -\xf2\xef\xec\x43\xce\x4e\xac\x6e\x04\xcd\x72\xc8\x01\x1b\x00\x26\ -\xa2\x29\x7b\x01\x59\xdb\x55\x97\xf7\xb2\x03\xe8\x17\x40\x11\x1c\ -\x41\x81\x88\x33\x40\x03\xbb\x43\x34\x30\xf2\x9c\x01\x20\x3d\x83\ -\x87\x46\x64\x66\xa8\x88\x2e\xef\xda\x64\xa3\x32\x4d\x7c\x9b\xb0\ -\x5d\x17\xf6\x0b\xda\xce\xbe\xa5\x2b\x56\xf2\x16\x80\x58\x96\x57\ -\xad\x58\x70\x11\x33\xd1\xa8\xca\x65\xdc\x81\xaa\xa6\x76\x55\x4d\ -\x2f\x86\xb8\xab\x59\x5b\xbd\x39\xae\xcf\xd7\x34\xe6\xbb\xf9\x84\ -\x1c\x2b\x3f\x73\x0e\x1e\x62\xc8\xac\x81\xe7\x9b\x27\xea\x68\x3f\ -\x9f\xe8\xd8\x45\x41\x80\xcd\x96\x6a\x9d\x16\x16\x24\x04\x79\x6a\ -\xa8\x7f\xa2\x2c\x84\x00\x1c\xf5\x94\x1e\x18\x78\x55\xfe\x69\x82\ -\x30\x5f\xf3\xdd\x4a\x28\x74\xa4\x28\xd8\xf1\x48\xa5\xd1\x17\x0b\ -\xbe\x1f\x57\x43\x42\x2f\x54\x25\xd7\x8b\xea\x20\xb7\xfb\xfe\xac\ -\x45\x12\xb3\x7c\x7c\x60\x9e\xd1\xad\xbe\x4a\xf9\x82\xa6\xe3\x06\ -\xbb\x24\x03\x94\xf4\xba\x54\x61\xab\x3d\x84\x63\x8b\xa6\x6e\x79\ -\xa7\x6e\xd7\x16\xfb\x2e\x16\x8f\x55\x87\xf3\xaa\x0d\xdd\x27\x9b\ -\xe4\x33\x8b\x55\xbe\xaa\xa3\x6e\x00\x4b\xc3\x52\x79\x50\x35\x78\ -\x7f\x50\xb2\x41\x00\x29\x01\x09\x82\x2e\xaa\xb8\x48\xa0\xb4\xed\ -\xfb\xa9\xa1\x12\x1d\xfa\x22\x55\xb1\xa1\x3d\xdb\x97\x04\xab\x68\ -\x7e\xac\x3b\xf4\x75\x4d\x04\x9c\x12\xbf\x94\x6f\x98\xa4\x31\x95\ -\xb4\x8b\x82\x46\x02\x7b\x33\x1b\xcf\xa0\x55\x0a\xff\x79\xf3\xb6\ -\x4d\xf6\x51\x14\xfe\xcb\xc5\xa7\x2e\x4f\x2b\x03\xba\xe0\x05\x20\ -\xdd\x16\x40\x55\x56\xa3\x50\x05\x26\x95\xd7\xc9\x06\xb8\xad\xfa\ -\xa2\xdf\xa1\x3d\x81\x78\x6c\x15\x03\x63\x05\x56\x37\x69\x35\xad\ -\x60\x55\xdf\x33\xda\x2a\xc6\xd1\x26\x51\x83\x8c\xf7\x32\x49\xd3\ -\x77\x6a\x91\x5e\x51\xaa\x27\x4d\x64\xca\x7a\x95\xca\xa8\x77\xdf\ -\x14\x93\x9e\x73\x33\xa3\xf1\xbe\x7c\x5a\x75\xa8\x0c\x82\xa2\x3d\ -\xe8\x94\x2e\x18\x30\xf4\x4f\xa5\xd4\x4e\xb4\x2b\xc1\x8b\xed\x86\ -\xc7\xac\x1e\xde\xa2\x09\xb9\xb7\x3d\xb2\xaa\x50\x2e\x61\xf7\x21\ -\xf8\xf5\xe2\x24\xed\xfa\xce\xcb\x2b\xa5\xed\x75\x08\xe5\xa3\x28\ -\x52\xe8\x65\x6e\x59\xc6\xe3\x18\x8a\xaa\xe0\x9f\xd8\xf8\x04\x01\ -\x4c\x50\xe9\xab\x70\x09\x31\x72\xcd\xf2\x22\x8d\x1c\x30\x64\x22\ -\x05\x3e\xcb\xd0\x6e\x64\x31\x85\x4c\x24\x04\x3d\x84\x19\xb4\xfe\ -\x8d\xb4\xdd\xc4\x80\xca\xca\x21\xa0\x4b\xd0\x0a\x9b\x16\xb2\xab\ -\x80\x6d\xff\xd8\x2b\x8a\x63\x14\x3e\x8c\x09\x05\x98\x3a\xc8\xb2\ -\x4c\xcb\xed\xd6\x10\x60\x6a\x21\xdf\xb4\x7d\x55\x86\xdb\xd2\xb7\ -\xa5\x72\x3d\x06\xee\x65\x50\x5e\x0d\x54\x97\x15\x04\x43\x64\x08\ -\x22\xbe\xe9\x92\x00\xbb\x8d\x5c\x81\x09\x67\x19\x2e\x0a\x29\xfb\ -\xb2\xff\x78\x92\x85\x25\x6c\xdf\x8f\x21\x74\xc2\x81\x6b\x7a\xbe\ -\x6d\xb5\x3e\xa9\xf0\xd3\x88\x87\x3c\xd5\x62\x5b\x53\xe5\x73\x79\ -\x69\x91\x66\x4e\x7d\xe4\x94\x0f\xde\xb9\xfb\xc1\x99\x28\x1c\x2c\ -\xcf\x0d\x74\x57\xef\x20\xef\x75\x00\x19\x38\x26\xb9\xd0\x21\xf9\ -\xdf\x52\x59\x08\xa6\x92\xcc\xd7\x51\x84\xf2\x01\x3f\x5f\x41\xd1\ -\xc6\x7e\xe0\x11\x3b\xf8\xa5\x28\x12\x14\x54\x28\x06\xc8\x05\xfc\ -\xe0\x73\x6a\xf6\x3f\x4f\xd1\xf2\x6d\x4f\x77\xac\x07\x04\xeb\xc9\ -\x50\xae\xa1\x90\x35\x25\x18\x9d\x52\xce\x1e\xbf\x3d\xc7\x37\x4f\ -\xf7\x9e\x23\xe3\xac\x3a\x6c\x01\x44\xa7\xa6\x9c\x53\x12\xc0\x2b\ -\x29\x37\x7a\x3f\x4e\x42\xff\x41\x43\xf6\xc9\xb0\x50\x85\x25\xa9\ -\xbe\x5e\xb0\xc8\x20\xe5\xf9\xe7\xee\xcf\x51\xd0\xd6\x9d\xe7\x48\ -\x41\x1b\xf9\x53\x17\x59\xd5\x89\xdf\x3d\xe9\xe1\x07\x45\x6b\xb9\ -\xf4\x96\x84\x3e\x32\xbe\x55\xdf\x58\x1c\x95\x08\x17\x55\x8d\xc6\ -\x14\x7b\x55\xcf\xe1\x0d\x58\x37\x7e\x7b\x8e\x72\x81\xee\xff\x6c\ -\x10\x7f\x36\xe5\x46\x41\xc4\xc8\xaf\x40\xec\x97\x8e\x3b\x12\xcf\ -\x7c\x50\xe2\x3d\x99\x44\x87\x1d\x64\xd7\xc4\x33\x6b\x0a\xde\x83\ -\x78\x5e\xf0\x3c\xeb\x6d\x8b\xdd\x14\xdb\x75\xaf\xf7\x0d\x7d\xde\ -\x83\x62\x76\xc4\xbc\xe5\x92\x2e\x89\xf5\x18\x99\xd7\xa5\x3c\x17\ -\xd9\xdf\xcf\xb9\x1f\x47\xb7\x71\xe8\x1e\x03\xdd\xba\x44\xd7\x0f\ -\xda\xbb\xd1\xed\x39\x52\xcd\xab\x72\x9c\x2a\x0c\xe4\x3e\x5c\xfb\ -\x91\xc9\xed\x11\xb3\xad\xa2\x98\x42\xcf\x1d\xb0\xad\x4c\xc7\x56\ -\xc5\xb6\xb1\xfb\x33\x6f\x14\xcf\x91\x81\xdd\x5b\xad\x85\x70\xdb\ -\x13\x77\x84\xc3\xe7\xee\xcf\xbe\x55\x3c\x47\x26\x76\xaf\xb5\x4d\ -\x44\xdf\xeb\xdd\x16\xff\xb8\x26\xf9\xd7\x33\x11\x1f\x05\xb1\x03\ -\x15\x01\xfb\xf5\x2b\xed\x3d\xbe\x51\x09\x7e\x36\x68\x8f\x81\x78\ -\xc4\x84\xb7\xd9\xba\x76\xdc\xf5\x7d\xe2\x39\xa6\x39\xe8\x7e\xed\ -\x29\xc6\x75\x98\xde\xe7\x7b\xbb\x87\xa4\xd9\x13\xc9\x6f\x7f\xb5\ -\xb5\x13\x30\x74\xb5\xd7\x1a\x0e\x10\x51\x77\x47\x7f\xcf\xbc\x45\ -\x7c\x23\x60\x33\x63\x75\x7d\x31\x53\xff\x06\xbb\xbe\xf8\x1f\xbe\ -\x4f\x01\xc4\ -\x00\x00\x07\x56\ -\x00\ -\x00\x62\xc2\x78\x9c\xed\x5c\xdd\x8f\x9b\x38\x10\x7f\xdf\xbf\x82\ -\xa3\x2f\xad\xee\x0c\x18\x08\x5f\x4d\xb6\x0f\x57\x55\xaa\x74\x4f\ -\x77\x3d\xdd\x63\xe5\x05\x27\x8b\x4a\x20\x02\xb2\x49\xfa\xd7\xdf\ -\x98\xaf\x40\xc2\x56\x6d\x6d\xee\xdc\x12\xa4\x6a\x8b\x67\x0c\xe6\ -\x37\xbf\xb1\x67\x3c\x84\xe5\x9b\xe3\x36\x51\x9e\x68\x5e\xc4\x59\ -\xba\x52\xb1\x66\xa8\x0a\x4d\xc3\x2c\x8a\xd3\xcd\x4a\xfd\xfb\xc3\ -\x3b\xe4\xa9\x4a\x51\x92\x34\x22\x49\x96\xd2\x95\x9a\x66\xea\x9b\ -\xfb\xbb\xe5\x2f\x08\x29\xbf\xe7\x94\x94\x34\x52\x0e\x71\xf9\xa8\ -\xbc\x4f\x3f\x15\x21\xd9\x51\xe5\xe5\x63\x59\xee\x02\x5d\x3f\x1c\ -\x0e\x5a\xdc\x34\x6a\x59\xbe\xd1\x5f\x29\x08\xdd\xdf\xdd\x2d\x8b\ -\xa7\xcd\x9d\xa2\x28\x70\xdf\xb4\x08\xa2\x70\xa5\x36\x1d\x76\xfb\ -\x3c\xa9\x14\xa3\x50\xa7\x09\xdd\xd2\xb4\x2c\x74\xac\x61\x5d\x3d\ -\xab\x87\x67\xf5\x90\xdd\x3d\x7e\xa2\x61\xb6\xdd\x66\x69\x51\xf5\ -\x4c\x8b\x17\x3d\xe5\x3c\x5a\x77\xda\x6c\x34\x07\xab\x52\xc2\xbe\ -\xef\xeb\x86\xa9\x9b\x26\x02\x0d\x54\x9c\xd2\x92\x1c\xd1\xb0\x2b\ -\x8c\x71\xac\xab\x69\x18\x86\x0e\xb2\xb3\xe6\xd7\x69\x05\x05\x00\ -\xba\x83\x7f\x9d\x7a\xdb\xa0\x15\xd9\x3e\x0f\xe9\x1a\xfa\x51\x2d\ -\xa5\xa5\xfe\xf6\xc3\xdb\x4e\x88\x0c\x2d\x2a\xa3\xde\x65\x5a\x3c\ -\x07\x77\x1d\x80\x9c\x92\x2d\x2d\x76\x24\xa4\x85\xde\xb6\x57\xfd\ -\x0f\x71\x54\x3e\xae\x54\xcb\xd6\xb0\x05\xc7\xa2\x6a\x7c\xa4\xf1\ -\xe6\xb1\xbc\x6c\x8d\xa3\x95\x0a\xa3\x37\x7d\xaf\x3e\xef\x91\x03\ -\xd7\x0a\xcd\x85\x83\x4e\x62\x68\xbe\xa9\x61\x25\xc7\x0b\xcb\xad\ -\x75\xda\x47\x08\xa2\x2c\x64\x63\x82\x4b\xd2\x6d\x4c\xf6\x65\xb6\ -\x05\xab\x85\x61\x42\x8a\x22\x5e\xc7\x21\x9c\x64\xe9\x2e\xd9\x6f\ -\xe2\xf4\x23\x8d\xe2\xf2\x63\x4e\x8a\x92\xe6\x5a\x0b\x5f\x77\x2f\ -\x7a\xdc\x65\x79\x89\x8e\xd1\x0e\x40\x74\xdc\x51\xe1\xa9\x15\xde\ -\x83\x74\x19\xd1\x75\xc1\xb4\xea\x27\x62\x67\xf0\x48\xae\xaa\xe8\ -\x95\xb4\x1b\x20\x1b\x5d\xf4\x14\xd3\xc3\x59\xf7\x81\x14\x35\x6a\ -\x8a\xb2\x23\x1b\x60\x58\x92\xe5\x2b\xf5\xc5\xba\x3a\x1a\xc1\x43\ -\x96\x47\x34\x6f\x45\x4e\x75\x0c\x44\x19\x58\x21\x2e\x4f\xb5\x4f\ -\x35\xd7\x6e\xc7\xcb\xae\xda\xc9\x8d\x71\x79\xf1\x48\xa2\xec\xb0\ -\x52\xcd\x4b\xe1\xe7\x2c\xdb\xae\x54\x57\xf3\xb1\x67\xd8\xd8\xbd\ -\x14\x87\xc7\x95\x8a\xb0\xab\x99\x9e\xe3\x76\x43\x3a\x4b\xe1\x86\ -\x0b\xcd\xf6\x1d\xc3\xc7\xf8\x4a\xb8\xcf\x73\xf0\x3a\x94\x90\x13\ -\x85\xa7\xaa\xfe\xb4\x4a\xc5\x63\x76\xd8\xe4\x0c\x9d\x32\xdf\xd3\ -\xcb\x9e\x4c\x82\x1e\x1e\xb2\xe3\xb8\x18\x48\xb0\x67\xfe\x8c\xf6\ -\x69\x5c\x82\xcf\xec\x8e\xfd\xab\xee\xe3\x88\x16\xe3\x1d\x8b\x94\ -\xec\xd0\x26\xc9\x1e\x48\x32\xae\x70\x88\x53\x40\x09\x35\xf4\xc6\ -\xd6\xf5\x13\x37\x1a\x2d\xd7\x5d\xc3\x7b\x46\x03\xc6\x7e\x65\x88\ -\x46\x74\x7a\x5e\xb4\x25\xc7\x78\x1b\x7f\xa6\x00\x0c\xae\x78\x07\ -\xdc\x1a\xc0\x52\x77\x53\x94\xf2\xc4\xfc\xf6\x78\x62\x6d\x6a\xdb\ -\xc8\xf0\x64\x0d\xa6\xef\xbb\x5d\x63\x96\xc7\xe0\x0e\xbd\xe1\xb4\ -\x4d\xa7\x7e\x13\xf3\x72\x98\xa4\x8f\x15\xc1\x2a\xfa\xb9\x97\xb2\ -\x53\x5f\xd6\xf0\x5e\xbf\x26\x7e\xd5\xbe\xa5\x25\x89\x48\x49\xce\ -\x5e\xd0\xb6\xc0\xd8\x8c\xf6\xc9\x60\xc2\x0c\xfe\x7c\xfb\xee\xbe\ -\xb9\xd1\x32\x0c\x83\x7f\xb2\xfc\x53\x7b\x5f\x45\x61\x0a\xe4\x21\ -\xdb\x03\xd2\xea\x7d\xd7\xbc\x8c\xc2\x00\xa6\x38\x70\xfd\xfb\x78\ -\x0b\xdc\x66\xb3\xe3\xaf\x30\xa5\x2d\xf5\xb3\x60\xa0\xcc\xc0\x3a\ -\x5f\xb4\xbe\x6c\x4e\xeb\xb9\x72\x74\xc1\x88\xc2\x6d\xcc\x3a\xe9\ -\x7f\x95\x71\x92\xbc\x67\x37\x69\x9e\xb8\x77\xd1\xb8\x4c\xe8\xb9\ -\x71\xa9\x37\xa3\x6f\x9e\x4d\xef\x3d\xdc\x52\x6f\x9f\xbe\x3a\xdb\ -\x9c\x51\x19\x38\x45\x67\xe8\x84\x3c\x50\x60\xe8\x1f\x4c\xa8\x5c\ -\x49\x37\x79\xb6\xdf\x6d\xb3\x88\x36\xdd\x3b\x34\x69\x58\x76\x26\ -\x2b\x4f\x09\xc8\xd7\x30\xfa\xe0\x85\x61\x10\xe2\x79\xaf\xd9\x09\ -\x6a\xe6\x89\x00\xd7\xa7\xf9\x3e\x81\xf9\xee\x89\xa6\x59\x14\xbd\ -\x2e\xca\x3c\xfb\x44\x03\x98\x99\x1c\x62\x18\xcd\x69\xed\x0c\x81\ -\xa1\x59\x6c\x21\x32\x0c\xb3\x6d\x07\x84\x68\x9e\x00\x5b\xcb\xc0\ -\x6e\xdb\x22\x02\xf3\x4c\x9e\x93\x53\x90\xc2\xf2\xde\xb6\x76\xf7\ -\x1c\x10\x95\x0d\x77\xe1\x59\x3e\xc2\xc8\xeb\x04\x8d\xe7\x2d\x34\ -\xcb\x3a\x2f\x21\xec\x68\x1d\xce\xd6\xfc\x4a\x62\x77\x12\x46\x59\ -\x43\xbb\xa0\x2c\x70\xd5\xd2\xbc\xc1\x3c\x0a\x66\x1f\x38\x41\x5e\ -\xf1\xd9\xb1\xd9\xe1\x74\xd6\xfd\x91\x51\x44\x78\x0a\x1c\xd1\xf5\ -\x84\xf0\xd3\x03\xe9\x4f\x01\x24\xb6\x34\x77\xa8\xf9\xd3\xe3\x88\ -\xd1\x62\x0a\x24\x3d\xcd\xab\x07\x3d\x1f\x24\xdd\x29\x70\x34\x2d\ -\x6d\x4e\xb3\x23\x5a\x4c\xc2\x46\xec\x69\x73\x5b\x68\xfc\x69\xf8\ -\x68\x59\x9a\x3d\xb3\x95\x06\x48\x89\x8c\x49\x7c\xdb\xd3\x16\x95\ -\xaa\x30\x2c\xd7\xeb\x30\x94\x15\x4b\x4e\x04\x8d\x01\x0b\x85\x07\ -\x8e\x91\x4d\x88\xac\xc8\x71\x07\x8d\xd7\xea\x33\xc4\x10\xd9\x53\ -\xa0\x38\x41\xe8\x2d\xb3\x13\x73\xe7\x81\x03\x37\x16\x1f\x6e\x4b\ -\x4e\x41\x8f\x17\xbe\x51\x0e\x8a\x87\x51\x6a\x0a\x1a\xdc\x9e\x3c\ -\x20\xa1\xf8\x4c\x45\x72\x12\xda\xc8\x9c\x82\x85\xe2\x71\x94\x9b\ -\x85\x96\x48\x12\x0a\x4d\xf3\x24\xe7\x9f\x33\x05\xfb\x84\x02\x28\ -\x37\xf1\xb8\x13\xbb\xe1\x1a\x2c\x3c\x35\x96\x9c\x7e\xf6\x34\x04\ -\x9c\x1d\x8e\x1e\xff\x66\xf6\x78\x5e\x22\x7c\x87\x41\x72\x77\xb6\ -\xb9\x71\x1c\x2e\x25\xc2\x77\x15\x24\x27\x22\xc4\x33\xdc\x53\xe2\ -\xf8\x9a\x32\xab\xfd\x99\x9a\x89\x62\x63\xeb\x39\xfa\x32\x77\x74\ -\x3d\x40\x70\x82\xfd\x05\x0f\x2e\x28\x2d\x84\x6c\xc3\xd5\xe6\xe5\ -\xa0\xe9\x5c\xae\xc5\xd5\x7e\x97\x6b\x89\xf5\x66\xe9\x81\xc4\xdc\ -\xf3\xe2\x28\x92\xc0\x49\x71\x49\x9e\xf4\x20\xfa\xdc\x9b\xff\xa3\ -\x20\x62\x91\x09\x8b\xf4\x20\xb2\x1a\x0a\x6f\x65\x6f\x14\x46\xef\ -\xb2\xae\xf2\xd3\x43\xe9\x72\x2f\x30\xa3\x40\x9a\xc2\x97\x6a\xe9\ -\x91\x64\xd5\x66\x64\xf0\x66\x83\xe3\xde\x2d\x3c\x74\x94\x1e\x4d\ -\x7f\x2a\x66\x42\x10\x59\x69\xce\x68\xcd\xa9\x4a\xce\xdc\xa1\xf8\ -\xb8\x9f\x7b\x9a\xb8\x3a\x81\xd4\x40\x72\xbf\xff\x30\x71\xf8\xb8\ -\x58\xd8\xb6\xb4\xe0\xf1\xa7\x31\x26\xd6\x2e\x1a\xe7\x88\xa2\x8d\ -\x4c\xde\x9a\xdf\x28\x90\xf3\x89\xc1\x3d\xc4\x5b\x69\xc1\xd3\x05\ -\xde\x92\xb3\xcf\xe3\x07\x6f\x94\x7d\xf3\x49\x5e\xaa\x2d\x1d\x9b\ -\xfb\xed\xf7\x69\x73\x16\xc9\x59\xc8\x36\x68\x27\x99\x04\xe7\x95\ -\xfc\x19\x96\xe0\x90\x46\x7c\xca\x27\x39\x11\x1d\xfe\x3d\x88\x31\ -\x1a\xce\x2c\x75\x36\x20\xd1\x13\x3b\x21\x8a\xcf\x96\x25\x27\xa2\ -\x0d\x54\xb4\x78\xab\x7e\xe3\x2b\xf3\xdc\xa0\x64\x65\x68\xe4\x73\ -\x6f\xd1\x8e\x26\x2b\xf3\xda\x78\xa8\xab\x57\x9e\xd8\x68\x5b\xe8\ -\x76\x83\xe4\x54\xac\x0a\xd1\xdc\xc5\xfc\xf1\x25\x66\x36\xbb\x36\ -\x4d\x15\x9a\xff\x57\x69\x73\xde\x43\x6c\x0a\xd1\xc8\xe7\xdd\xdc\ -\xc6\xd3\x15\xfe\xa4\xff\xdd\x8f\xcd\xff\xa2\x6c\x8f\x6f\x93\x6c\ -\x7e\x49\x8f\x21\x86\x09\x91\x97\x83\x43\x10\xe7\xc5\x41\xe6\xca\ -\xbc\xb1\xf6\x10\x3f\xa1\x5b\x37\xd2\xe3\x57\xd5\x9d\xb9\x97\xe4\ -\x21\x82\xc2\x77\x1d\xa4\x47\xd1\x15\xf0\x86\xdd\x10\x43\xf1\x29\ -\xb3\xf4\x20\x36\xd5\x66\xc1\x6b\x8a\xf8\x7c\x4f\x7a\x20\xab\x42\ -\x33\xf7\xbe\xf6\xc5\xd2\x2c\x3c\x3e\x94\x1e\xc6\xa6\xc6\xcc\x5d\ -\x65\xbe\x70\xec\x6f\x4e\x54\x36\xfd\x11\x6e\x2c\x13\x9f\x7f\x29\ -\x5c\xe6\x24\x2d\xd8\xd7\x82\xd8\xa7\xa0\xe0\xbf\x09\x29\xe9\x4b\ -\x30\x55\xf5\x46\xa4\xfb\x5b\x93\x28\x59\xd6\x2b\x75\xd4\x08\x00\ -\xaa\xd3\x81\x1a\x34\x5f\xf3\xba\x46\xa8\xfb\x3c\x50\xdf\x9a\x5f\ -\xf8\xd6\xd8\xf3\x2a\xc7\x6b\x95\xe1\x43\xf7\xda\x07\xd0\xd4\xae\ -\x8c\xeb\x5f\xe4\xf6\xbb\x57\x9f\xf6\xc2\x97\x3f\xef\xfb\x92\x45\ -\xbe\x60\xc6\xd1\x99\xbd\xdf\x73\x0c\xbd\x6f\xa0\x70\x1f\xde\x96\ -\xc2\x5e\x3d\x3b\x2d\x78\x28\xdc\xfb\x82\xd3\xff\x6c\x22\x67\x04\ -\xee\xa9\x4d\x54\xaf\x1b\x37\x2b\x7d\xbd\x95\xcc\x11\x6b\x4c\x6d\ -\x25\xff\xe6\x4a\xdf\x66\x24\xec\x68\xae\xcf\x8e\xff\xd6\x95\x60\ -\xc9\xf3\x6f\x66\xe2\x5f\x94\x4c\x53\x13\x6d\x21\xc3\xea\xa5\xba\ -\x37\xd3\x7c\x7f\xbc\xe0\xd6\x01\x92\x27\xdc\x83\x1c\xe4\xdc\x0c\ -\xc4\x1f\x2d\x4c\xe1\x3b\x83\x97\x6f\x6f\xb6\xf9\xfe\x48\x6e\x32\ -\xe7\xa9\x6a\xbe\x37\x13\x09\x08\xe3\x26\x33\x51\x5d\x4b\xbe\xd9\ -\x88\x3f\x8a\x9b\x64\x8a\xb3\x07\xdf\xa1\xbd\x59\xe7\xfb\x63\xec\ -\x09\x27\x39\x56\x02\x77\x6f\x46\xe2\x9f\xe6\x26\x73\x21\xfb\x47\ -\x72\xa2\xa5\xbe\xa9\x3f\xcf\x0d\x7f\x96\xec\x2b\xe2\xf7\x77\xff\ -\x02\x60\x10\xdc\xe1\ -\x00\x00\x17\xb0\ -\x00\ -\x00\xbf\x45\x78\x9c\xed\x5d\x5b\x6f\x23\x47\x76\x7e\xf7\xaf\x60\ -\xb4\x2f\x6b\x44\x4d\xd5\xfd\x22\xcf\x78\xb1\xc8\x62\x81\x05\x92\ -\x97\x64\x83\x3c\x1a\x14\xc9\x99\x61\x4c\x91\x02\x49\xcd\xc5\xbf\ -\x7e\xbf\x73\x4e\x35\xbb\x9b\xdd\x1a\x51\x63\x2a\xb0\xb3\x2d\xc1\ -\x9e\x66\x75\x5d\xcf\xfd\xab\x3a\x45\xbd\xf9\xd3\xe7\xfb\xf5\xe4\ -\xe3\x72\xb7\x5f\x6d\x37\x6f\xaf\xf4\x54\x5d\x4d\x96\x9b\xf9\x76\ -\xb1\xda\xbc\x7f\x7b\xf5\xdf\x7f\xff\x6b\x95\xae\x26\xfb\xc3\x6c\ -\xb3\x98\xad\xb7\x9b\xe5\xdb\xab\xcd\xf6\xea\x4f\x3f\x7e\xf7\xe6\ -\x5f\xaa\x6a\xf2\x6f\xbb\xe5\xec\xb0\x5c\x4c\x3e\xad\x0e\x1f\x26\ -\x7f\xdb\xfc\xbc\x9f\xcf\x1e\x96\x93\x3f\x7e\x38\x1c\x1e\x6e\x6f\ -\x6e\x3e\x7d\xfa\x34\x5d\x95\xc2\xe9\x76\xf7\xfe\xe6\xfb\x49\x55\ -\xfd\xf8\xdd\x77\x6f\xf6\x1f\xdf\x7f\x37\x99\x4c\x30\xee\x66\x7f\ -\xbb\x98\xbf\xbd\x2a\x0d\x1e\x1e\x77\x6b\xae\xb8\x98\xdf\x2c\xd7\ -\xcb\xfb\xe5\xe6\xb0\xbf\xd1\x53\x7d\x73\xd5\x54\x9f\x37\xd5\xe7\ -\x34\xfa\xea\xe3\x72\xbe\xbd\xbf\xdf\x6e\xf6\xdc\x72\xb3\xff\x43\ -\xab\xf2\x6e\xf1\xee\x58\x9b\x66\xf3\xc9\x72\x25\x9d\x73\xbe\x51\ -\xe6\xc6\x98\x0a\x35\xaa\xfd\x97\xcd\x61\xf6\xb9\xea\x36\xc5\x1c\ -\x87\x9a\x1a\xa5\xd4\x0d\xde\x35\x35\xcf\xab\x75\xbb\x07\x41\x1f\ -\xf0\xdf\xb1\x7a\x5d\x30\xdd\x6f\x1f\x77\xf3\xe5\x3b\xb4\x5b\x4e\ -\x37\xcb\xc3\xcd\x5f\xfe\xfe\x97\xe3\xcb\x4a\x4d\x17\x87\x45\xab\ -\x9b\x9a\x9e\x9d\x51\x3b\x44\xde\xcc\xee\x97\xfb\x87\xd9\x7c\xb9\ -\xbf\xa9\xcb\xb9\xfd\xa7\xd5\xe2\xf0\xe1\xed\x95\x75\x53\x6d\xf1\ -\xe3\xb9\xf0\xc3\x72\xf5\xfe\xc3\xe1\xb4\x74\xb5\x78\x7b\x85\xd9\ -\x9b\x9c\xe4\x73\x4b\x38\xb4\x54\x28\x1d\xdf\x1e\xdf\xa8\x69\x36\ -\x53\x3d\xd9\x69\x6f\xa3\xd4\xa9\x97\x70\xbb\xd8\xce\x69\x4e\xe8\ -\x72\x79\xbf\x9a\x3d\x1e\xb6\xf7\xe0\xda\x7c\xbe\x9e\xed\xf7\xab\ -\x77\xab\x39\x3e\x6c\x37\x0f\xeb\xc7\xf7\xab\xcd\x4f\x6b\x48\xd9\ -\x4f\xf3\x2d\x7a\xfd\x69\xfe\x61\xb6\x01\x41\x6a\x22\x1e\x47\x5c\ -\x7e\x7e\xd8\xee\x0e\xd5\xe7\xc5\x03\x48\x19\xe2\xe0\xcb\x2f\xf5\ -\xcb\x1f\xf1\xf6\xcd\x62\xf9\x6e\x4f\xb5\x64\x5d\xf4\x09\x0b\x8b\ -\x57\x93\x1b\x7e\x7b\x9c\x26\xcd\x71\xf1\x71\xb5\xfc\xd4\xd4\xbd\ -\x9b\xed\x85\x76\x93\xc9\xc3\xec\x3d\xe4\x6c\xbd\xdd\xbd\xbd\xfa\ -\xc3\x3b\xfe\x29\x2f\xee\xb6\xbb\xc5\x72\x57\xbf\x0a\xfc\xd3\x79\ -\xb5\x05\x2f\x56\x87\x2f\xa2\x59\xa5\xef\x7a\xbe\xd4\xeb\xf1\xbd\ -\x1a\x7e\xbf\xff\x30\x5b\x6c\x3f\xbd\xbd\x32\xa7\x2f\x7f\xd9\x6e\ -\xef\xa9\xd7\x1c\xb3\xd7\xca\x9d\xbe\x9e\x7f\x7e\x7b\x55\x59\x35\ -\x4d\xc6\xda\xa0\x7b\x6f\x31\x60\xa5\xd3\x54\xa3\xb5\xce\xbd\xb7\ -\x8f\xbb\x1d\x94\xaf\x5a\xcf\xbe\x2c\xb1\x2c\xfe\xa7\xee\x62\xff\ -\x61\xfb\xe9\xfd\x8e\xc8\x73\xd8\x3d\x2e\x4f\x5b\xd2\x9b\xea\xee\ -\x6e\xfb\x79\xf8\x35\x64\xe1\x91\xd4\xba\x7a\xdc\xac\x0e\x50\x9d\ -\x87\xcf\xed\x5e\x1f\x57\x8b\xe5\x7e\xb8\xe1\x7e\x33\x7b\xa8\xde\ -\xaf\xb7\x77\xb3\xf5\x70\x85\x4f\xab\x0d\xc8\x54\x15\x29\xd7\xf6\ -\xc8\x85\xd3\x1a\xb5\xc8\x47\x95\x9e\xa8\x81\xb9\xf7\x38\x51\x5e\ -\x7d\x79\xfa\xd5\xfd\xec\xf3\xea\x7e\xf5\xcb\x12\x84\xd1\x2c\x78\ -\x10\xae\x0e\x59\xa4\xd9\x64\x72\xf8\x42\xea\xfb\xf9\x0b\x95\x5d\ -\xd5\x85\x44\x4f\x2a\x30\x39\xc7\x63\xe1\x76\xb7\x82\x56\xb4\xa6\ -\x53\x17\x7d\x69\x17\x91\xb2\xc3\x56\x7f\x66\x09\x63\xf9\x8b\xa7\ -\xef\xbe\xb4\xdf\x15\xc1\xbf\xe9\x4b\x3e\x97\xdf\x2f\x0f\xb3\xc5\ -\xec\x30\x6b\xd4\xa0\x2e\xc1\xdc\x54\xbd\x32\xd8\xcd\xdb\xff\xfc\ -\xcb\x5f\x7f\x2c\x03\xbd\x99\xcf\x6f\xff\x67\xbb\xfb\xb9\x1e\x77\ -\x32\xa1\x0a\xb3\xbb\xed\x23\x28\x7d\xf5\xe3\xb1\xf8\xcd\x62\x7e\ -\x0b\x4b\x07\x0b\xf0\xe3\xea\x1e\xc2\x4d\x46\xf2\x5f\x61\xd9\xde\ -\xdc\x34\x2f\x3a\x95\x89\x58\x4d\xa7\xd2\xed\x6e\x29\x26\x73\xd0\ -\x6f\x2c\xe6\xf7\x2b\x6a\x74\xf3\x5f\x87\xd5\x7a\xfd\x37\x1a\xa4\ -\xac\xb8\xd5\xe9\xea\xb0\x5e\x36\x85\x6f\x6e\xca\xec\xcb\xda\x6e\ -\x5a\x8b\x7b\x73\x53\xaf\x9e\x3f\xbd\x6f\xa8\xd2\x51\x8a\x23\xa3\ -\xd7\xb3\xbb\x25\x24\xf4\xdf\xe9\xe5\xa4\xf7\xf6\xfd\x6e\xfb\xf8\ -\x70\xbf\x5d\x2c\x4b\xf3\x9a\x9a\xef\x3b\x62\x60\x55\x8b\x83\x87\ -\xdd\x6c\xb3\x27\xca\x80\x0f\xb3\xc3\x6e\xf5\xf9\x8f\x76\xaa\x4d\ -\xd0\x21\xfb\x6b\x33\x45\x55\xa5\xc2\x75\x85\x27\x67\x52\x8e\xe1\ -\xda\x32\x9f\xb5\x75\xd7\x26\x4d\x9d\x35\x5e\xc7\xeb\xca\xc7\xa9\ -\x71\x39\x9a\xf0\x7d\x23\x19\x87\x2f\x6b\x4c\xe3\x1d\x88\x74\x0b\ -\x8b\x76\x77\xe7\xe2\x0f\xf4\xa1\x2a\xf6\xe8\x56\x1f\xd9\xd6\x4c\ -\xaf\x4c\x30\x58\xef\xae\x9a\xb2\x17\x74\x45\x92\xb3\x9c\x1f\xda\ -\x1c\x7d\xbe\xb5\x7c\xdc\x3d\xae\x61\xe0\x3f\x2e\x37\xdb\xc5\xe2\ -\x87\xfd\x61\xb7\xfd\x79\x79\x5b\x4c\x71\xf9\x28\xca\x7f\xab\xea\ -\x8f\x10\x84\xe5\x6e\x0d\xa5\x3c\xdc\xba\xba\x6c\x31\x83\x3d\xdd\ -\xed\x66\x5f\x6e\x37\x08\x66\xea\xd2\x66\xa2\xed\x99\xd1\x5a\x69\ -\xb6\x3e\xd9\x5c\xa9\xca\x55\x1a\xbf\xa1\xea\x56\x2a\x06\xc7\x4d\ -\x0d\xab\x57\xee\xbc\xac\x6d\xcd\xf0\x5b\x36\xd0\x7e\xaa\xb2\x8d\ -\xc9\x75\xde\x40\x5f\x4d\x86\x61\x0f\x26\x85\xce\x8b\x5d\xc7\x18\ -\x70\x09\xeb\xb6\x33\xf4\x63\x3b\x6f\x5a\x92\xb3\xdb\x1e\x10\xa7\ -\xfd\xb1\x4a\x79\x1a\x33\xa4\xe3\xfb\xae\x4a\xfc\xce\x59\x92\xaa\ -\x58\xf9\x0b\x33\x45\xab\x94\x4d\xee\x31\xc5\x4f\xa3\xca\xc1\x8d\ -\x4c\x79\x9e\x29\xb1\xb2\x55\x7c\x05\xae\x78\xdf\xe3\x0a\x91\x3a\ -\x26\x6b\x46\xae\x3c\xc7\x95\x0c\x55\x71\x97\x66\x8a\x45\x04\xd9\ -\xb3\x5f\x3a\x22\xb6\xd4\x5e\xfb\x91\x29\xcf\x31\x25\x55\xa6\xf2\ -\x97\xd7\x15\xef\xac\xed\x59\x30\x6d\x00\xd4\x5c\x8a\xa3\x05\x3b\ -\xc7\x82\x45\xb8\x7b\xf3\x0a\x7c\x09\xe1\x94\x2f\x69\x1a\x1c\x82\ -\x39\x3d\xf2\xe5\x59\xbe\x58\x28\x4b\xb8\x34\x53\x10\x4e\xf7\x4c\ -\x98\x9b\x02\x38\x9b\x68\xd3\xc8\x93\xe7\x78\x02\x13\x66\x5f\x43\ -\x57\x92\x0b\xa9\xe7\xef\x15\x42\x66\x17\xac\xcb\xce\x8e\x9c\x79\ -\x86\x33\x17\x65\x08\x6d\x26\x45\xad\xd3\x29\x43\x46\xac\x72\xbe\ -\xa2\x5c\x9a\x21\xa0\x66\x30\x3d\x86\x14\x9c\x32\x5a\xae\x33\xbc\ -\xfc\x2b\x70\x24\xeb\x1e\x47\x0a\x46\x71\x23\x47\x9e\xe3\x48\xbe\ -\x34\x43\xa2\xf1\xa6\x67\xb3\x46\x7c\xf2\x12\xe7\x7e\x69\x96\x00\ -\x80\xc4\x9e\xd5\xaa\xb1\xc9\x68\xb5\xce\xc2\x26\x97\xe7\x49\x54\ -\x3d\xbb\x55\x70\x89\x1d\xd5\xe4\x79\x5c\x72\x61\x86\x64\x65\x52\ -\x7c\x0a\x94\xb8\x38\x32\xe4\x39\x86\x10\x28\xb9\x34\x4f\x74\x52\ -\x3d\xbb\x55\xf0\x48\x08\x7e\x0c\x80\x9f\x65\xca\x45\x91\xbb\x09\ -\x53\xef\xbc\xed\x43\x44\x42\x24\x56\xa5\x71\x47\xf8\x0c\x25\xb9\ -\xa8\x23\x21\x8e\x04\xe5\x6d\x8f\x21\x7e\x1a\x82\xd3\x69\x44\xec\ -\xe7\xf8\xf6\x8b\x9a\xad\xc2\x12\xdf\x87\xed\x7a\x6a\x93\xb1\x61\ -\x8c\xb7\x9e\xc7\x24\x97\xd7\x92\xac\x40\xa7\x21\x54\xe2\x82\x72\ -\x79\x64\xc9\x73\x2c\xe1\x53\x93\x0b\x33\x05\x6a\x32\x70\x92\x65\ -\x00\x21\xb3\xd3\xa3\xe9\x3a\x0b\x96\x5c\xdc\xc3\x13\x53\x42\xcf\ -\x78\x25\x68\x50\xf4\x39\xe9\x91\x2b\xcf\x71\xc5\x5e\x5e\x4f\x8c\ -\xd6\xae\xe7\xe3\x01\x4d\xb4\x4f\x5a\x8d\x51\xd7\x59\xd0\xe4\xf2\ -\x8a\x62\x83\x49\x3d\x45\x01\x3a\x71\x59\x47\xfd\xfa\xc1\xf0\x9b\ -\x9b\xf7\x43\x29\x63\xad\xd6\xfc\xb8\xa6\x0e\x30\x2b\xed\xb5\x8e\ -\x26\x5f\xe7\x69\xc0\x23\x9e\xbe\x6f\x0d\x5a\xf2\xcc\x3a\xfb\x76\ -\xff\x64\x79\x66\x0a\xff\xbf\xa8\xe2\x3a\xc4\x16\xde\x9b\xd4\x0f\ -\xce\xf3\x34\x79\x6d\xf2\x18\x75\x9c\x03\x97\x10\x77\x5c\x38\x42\ -\x07\x63\x82\x0a\xd1\xf5\x4f\x0d\xfc\xd4\x27\x17\xc2\xe8\xe4\xce\ -\x42\x4d\xc4\x97\xcb\x1e\x1f\x30\x67\xa2\xd2\x7d\x95\x01\x76\x52\ -\x06\x5a\x33\x72\xe6\x39\xce\x50\xce\x99\xbf\xf4\x3e\x03\x18\x93\ -\x55\x1e\xd8\xf9\x01\x82\x52\x21\xf8\x31\x58\x3f\x0f\x40\xe1\x39\ -\x5f\xf6\x50\x1a\x6f\x54\x50\xc9\xf6\x54\x06\x38\x2a\xe6\x9c\xf2\ -\x18\x1e\x9e\x89\xa3\xf0\xfb\x1a\xbc\xd1\x88\xdd\x07\xd0\x94\x4e\ -\x0a\x78\x6a\xe4\xcd\x73\xbc\xb1\xac\x34\xca\x5c\x3a\x04\x30\x46\ -\x9b\x74\xb2\xf1\xc3\xa0\xca\x50\x58\x3f\x26\x6c\x9e\x0b\xaa\x38\ -\x08\x50\x17\xe6\x8d\x0d\xce\xe4\x78\xca\x9b\x0a\x28\xc6\x2a\x4a\ -\x44\x1b\x33\xd1\xce\x44\x34\x97\xe4\x0b\x1c\x4a\x40\x08\x90\x07\ -\xf3\xd1\xb4\x06\xe8\x1d\x99\xf2\x1c\x53\x0a\x9e\xb9\x30\x5b\xa2\ -\xca\xca\xf5\xaf\x34\xf9\x69\x70\xde\xc4\x91\x2d\x67\xa3\x99\x57\ -\xe0\x4b\x3f\xef\x86\xb0\x4c\xb0\x2e\x8c\x2e\xe6\x5c\x2c\x73\x69\ -\xb6\x58\x3a\xac\x1e\x40\x32\xda\x44\x3d\x5e\x36\x7b\x01\x94\xb9\ -\x34\x63\xbc\x73\xfd\x7b\x01\x74\x20\x14\x94\x57\xe3\xb9\xe9\x0b\ -\x80\xcc\x2b\x70\x26\xf5\x2c\x19\x60\x4c\x4c\x21\x8f\x49\x9d\xe7\ -\xc3\x98\x4b\xf3\x25\xe4\xd0\xbf\xa1\x89\x26\x39\x20\x24\x18\x4d\ -\xd9\x0b\x40\xcc\xa5\x39\x93\x5c\xea\xe7\x77\x32\x82\x41\x2b\xaf\ -\xc7\xcc\xf4\xb3\x10\x8c\xbf\x6c\x32\x74\xa2\x6b\x01\x26\xf9\x7e\ -\x50\x96\xa7\x29\xe9\x60\x46\x95\x39\x13\xc3\x5c\x38\x1b\x04\x8c\ -\x71\xc6\x59\xd5\x4f\x2d\x04\x8a\xd1\x2e\xa7\xd1\xfb\x9f\x8b\x62\ -\xdc\x65\x61\xbf\x70\xc6\xf7\xbd\x3f\xe1\x18\x6b\x75\x1c\x37\x98\ -\xcf\xc4\x31\xe6\xb2\x29\x08\x60\x4c\x34\x43\x17\x69\xe9\x4c\x26\ -\x87\xe4\xc7\xb0\xec\x6c\x24\x63\x2f\xfb\x35\x0d\x60\x4d\x42\x00\ -\xa0\x7a\x5b\x98\x84\x65\x10\x00\x8c\x11\xf3\x0b\xb0\xcc\xe5\xed\ -\x19\x78\x13\xfa\x69\x19\x40\x33\x0e\x3c\x53\xe3\xa1\xcc\xb9\x68\ -\xe6\xb2\x41\x33\xe8\x8f\xe0\x18\x74\x1d\x80\x33\x68\xa0\xcd\xa8\ -\x34\xe7\xc3\x19\x75\xd9\x2d\x00\x3e\xb0\xd4\xa9\xff\x45\x1a\x95\ -\x99\x7a\x63\x5d\xf6\x69\x59\xa9\x57\x67\xd0\x31\xe5\xad\x79\xe8\ -\x7e\x97\x9b\x4f\xba\xfd\x6d\x15\xfd\x6f\x73\xd3\x94\xf0\xed\x7d\ -\x0c\xd7\x6a\x1a\x80\x92\xb5\x75\xfa\xba\x52\x50\x7d\x1d\x6c\xb4\ -\x28\xcd\xb0\x0d\xd1\xe8\x74\x5d\xc1\x8f\x66\xa3\x72\x32\xd7\x94\ -\xee\x17\xa3\x52\x56\x3f\xf1\x8d\x6e\x8a\x7f\x4e\x25\xa3\x96\x83\ -\xf2\xb6\xc7\xce\xe3\xb2\x1e\x66\x87\x0f\x0d\x39\x8e\xdf\x14\xb8\ -\xdc\x60\x4d\x16\x33\xce\xd9\x77\xc2\xac\x63\x8d\xfd\x61\xb6\x3b\ -\x74\xc9\x8c\x26\xff\x31\xf1\x7e\xea\x88\x93\x91\xd2\xfd\x78\x74\ -\x37\xf9\xf3\x04\x5c\xa4\x6f\x1d\x35\xe9\x3a\xca\xeb\x10\x27\x0a\ -\xbf\x7a\xe2\x41\x97\x98\x6d\xcc\xd7\x3a\x4c\x55\x0c\x51\xc5\xaf\ -\xd4\x76\x06\xb4\xf3\xde\x78\xae\xed\xbc\x53\xfe\x2b\xb5\x2d\x2c\ -\x2e\x48\x87\x99\x78\x1b\x3d\x22\xc9\xc9\x5a\x6a\x2b\xeb\x40\x6f\ -\x15\x10\x5d\xfa\xc9\x2f\x43\xcb\x23\x81\x39\x76\x37\x58\xe1\x33\ -\xdb\x6d\x19\x79\xa8\x02\x7d\xf1\xe6\x91\x04\x83\x15\xd0\x83\x0b\ -\xd3\x4c\x5d\xb4\x2b\x90\x38\x11\x5b\x6c\x76\x8c\x44\xdb\x6d\x85\ -\xf3\xfc\x25\xa4\x47\xe6\x2e\x56\xfb\x87\x35\x14\x77\xb5\x59\xaf\ -\xa0\xba\xf4\xa5\xaa\xef\xd6\xdb\x4f\xb7\x1f\x57\xfb\xd5\xdd\x7a\ -\xf9\x03\xff\xbb\x5a\x13\xe3\xeb\xa2\xaf\x89\x4e\x63\x54\x60\x09\ -\x7e\x59\xee\xb6\x4f\x08\xd3\x89\x51\xa1\xb1\xe7\xb3\x87\xdb\xbb\ -\xc7\xc3\xa1\x5d\xf6\xbf\xdb\xd5\xe6\x96\x2d\xce\xcb\xcd\x0f\x95\ -\x6e\xdf\xbd\xdb\x2f\x0f\xb7\x7d\x19\xfe\xe1\x7e\xb6\xfb\x79\xb9\ -\x93\x06\xcb\xcd\x0c\xeb\xaa\xee\x66\xf3\x9f\xe9\xab\x17\x37\x8b\ -\xdb\xd9\x7c\xfe\x78\xff\x48\x29\xa8\x43\xb4\x97\xaf\xe6\x9c\xed\ -\xe6\x6d\x15\xef\xea\x42\xf3\x1d\xa9\xdb\x0d\x96\x76\xd8\xee\xaa\ -\xf9\xe3\xee\xe3\xec\xf0\xb8\x5b\x76\xe5\xbe\x66\x98\x8f\x29\x77\ -\x22\x06\xfa\x4a\xcd\x89\xcd\xb4\x27\x66\x52\xba\x06\xd2\x87\xc4\ -\x46\x1f\x26\xf3\x09\x25\xeb\x26\x13\xc9\x00\x00\x7a\x6a\x67\xa8\ -\xc4\x07\x67\xa9\x24\x18\xab\xa2\x46\x89\xa6\xbd\x4f\xb6\x12\x59\ -\x7b\x67\x02\x55\x32\x4a\x73\x25\x4a\x7e\xa2\x02\xad\xa2\xca\x51\ -\x4a\xac\xe1\x56\x01\x4f\x52\x92\xd1\x9e\x7b\xb6\x3e\x70\x81\xd5\ -\x81\xab\x28\x9b\x3c\x77\xac\xa2\x71\xa1\x6e\x94\x3b\x8d\x8c\x77\ -\xfc\x59\x43\x87\xb8\x93\xa4\x58\x6d\x34\x74\x89\x3e\x27\x65\xcd\ -\xb5\xe2\xde\x52\x54\x32\x29\x0f\xa9\xe5\x89\x07\xe7\x3c\x95\x18\ -\xb4\x76\x09\x45\xc6\xa9\x2c\x93\x30\xc9\x39\x9d\x4f\xa7\x55\x96\ -\x92\xfc\x33\x4b\x31\x21\x46\x1e\x15\xe4\xc2\x2b\x9a\x8f\xd3\xba\ -\x33\x1f\x65\x6d\x92\x46\x3a\xe7\x24\xb4\x26\x5b\x4a\xab\x2d\x6b\ -\xe1\xba\xed\x6e\x01\xf4\x65\x26\x99\x3e\x6a\xba\x79\x2b\xd4\xf0\ -\x86\x99\x33\x40\x1f\x25\xac\x51\x8a\x17\x63\x15\x1d\x44\x33\x43\ -\xad\x85\x5d\xa0\x22\x43\xdf\x2a\xc4\x45\x31\x1b\xc3\x4b\xd6\x3a\ -\xcb\x92\x0d\xd8\x3f\xa9\xda\x25\x60\x28\x68\xd7\x19\x02\x8e\x8f\ -\x3f\x3b\x4b\x8d\x31\x27\x65\xb9\xc0\xc2\xf3\x85\x54\x0f\x11\x8e\ -\x43\xc8\x62\xa3\x29\xcc\xf0\x31\x4e\x98\xde\x2a\xf1\x54\x2d\x8c\ -\x79\x0c\x75\x33\xdf\x6d\x66\x6c\x16\xda\xd7\xf4\x7c\x01\x7d\x8f\ -\x8c\x2c\x7c\xeb\xd3\xb7\x57\x23\xc7\xc0\xb3\xd4\x64\xa2\x8f\x14\ -\x66\x26\xe8\x04\xf7\xc8\x22\x66\x6b\xd1\x36\xce\xd2\x40\x20\x95\ -\x31\x41\x84\x30\xd4\x42\xe5\x6b\x71\x88\xc2\x1f\xb8\x78\xf7\xcd\ -\x32\xee\xac\xa7\xee\x15\x53\xae\xb5\x64\xe8\xa1\x2b\x33\x31\xdc\ -\xbb\x4f\x45\x35\x21\x53\xfe\x38\x97\xae\xac\x46\xef\x8f\x53\x12\ -\x71\xf6\x36\xe8\xeb\xa6\xa0\x28\x85\x2a\xea\x25\x22\xa8\xa3\xb6\ -\x65\xfe\xae\x37\xfd\xd0\xa5\x2a\xa4\x53\x06\xd0\x91\x67\x95\x41\ -\xe6\xc4\x03\xc4\x1c\x9b\x49\xf1\x00\x50\x1c\x53\x64\x5c\xb8\x96\ -\x4d\x16\x0e\xe4\xd0\xc8\x78\xec\x72\xc0\xd8\x94\xda\x52\x01\x8b\ -\x84\x78\x98\x3b\xc4\x53\xd6\x5a\x2c\x00\x24\x22\xc8\x3a\x48\x3f\ -\xad\xbc\x57\xda\x67\x57\x16\x67\xcb\x32\x35\xc2\x1a\xc7\x24\x2e\ -\xb2\x53\xd8\xfe\x12\x16\xc6\xaf\xb3\xf0\x05\x66\x21\x88\x91\x52\ -\xd1\xa5\x61\xb3\x00\xa5\x08\xe7\x2a\x85\x71\x65\x22\x30\xd6\xa4\ -\x63\x3a\x21\xa0\x13\x1d\xc3\x0a\x63\x5f\xed\xba\x36\xb0\x36\x79\ -\xd0\xf9\xc2\x17\xed\x4f\x17\xcd\x7c\xf1\xb2\x16\x23\x33\xf5\x29\ -\x72\x3f\xce\x49\x3c\x09\x56\x40\xdb\xdb\x8b\x69\x98\x09\xf7\x53\ -\x24\x4a\x7b\xdd\xf1\x1d\xda\x04\xa7\xc3\x64\x58\x0b\xd9\xe4\x36\ -\x66\x1a\x15\xa4\x06\xb4\xe5\x09\xb2\xbd\xcc\xca\x91\xf0\xc8\xb4\ -\x10\x6e\x4e\x78\x32\x51\xc8\x04\x69\x09\x5d\xd1\xe7\x59\x3d\x35\ -\x86\xab\xbd\x47\xa2\xe5\x75\xc7\xc8\x45\x15\xa3\x62\xc6\xc1\x21\ -\x8b\xea\xc0\x6e\x1b\xb6\xae\x27\xa6\x74\xc0\x5a\xab\x16\x9f\xfa\ -\x3e\xa9\x6d\xdc\x3a\xcc\x30\x3d\x66\xf8\x27\x99\x11\x8e\xcc\xf0\ -\xfd\x65\x7f\x23\x33\x6c\x2c\x62\x9f\xb2\x15\x51\x81\x58\x71\xa7\ -\x19\xb8\x37\xb4\xdb\x90\x6b\x16\xe2\x86\x6c\x6b\x5b\xc1\x96\xd0\ -\xe7\xd2\x2b\x10\x8c\x19\x1e\xa6\x27\x91\x51\x17\x22\x40\x20\xfd\ -\x13\x12\x59\xdc\x72\x31\xef\xb4\x38\x77\x64\x7c\x37\x02\x68\x28\ -\xf7\x42\x1f\x7a\xba\x94\x90\xac\x6b\xbb\xf6\x01\xf1\x0d\xb9\x2c\ -\x85\x9b\xb4\x79\xd2\x9e\x7e\x99\x68\xb4\x5e\x26\x11\xa5\x95\x25\ -\x3a\x5b\x79\xed\xc8\x65\xf3\x4a\xb5\xf3\xa6\x16\x4e\x5e\x05\x10\ -\xa0\xa8\xb9\x31\x3e\xda\x61\x19\xa9\xc3\x21\xc3\x06\x6b\x58\xfc\ -\xb8\x05\x9c\x87\x2e\xcf\x90\x0b\x98\xad\xd6\xf0\x65\xd6\x7c\xcc\ -\x51\xea\xa4\xe4\x12\x29\x16\xa0\x26\xe4\x3e\xa2\xfb\xd6\xca\x4a\ -\xfd\x3a\x32\xa0\x67\x38\x95\xe4\x4c\x7b\xd8\xaa\xb1\xbc\x3a\x3b\ -\x57\xea\xb1\xfc\xe8\x0e\x8f\xc4\x5d\x9e\x11\x21\x64\x2d\xe4\x50\ -\x09\x31\xb2\xc4\x60\x58\x93\x18\x42\x23\xfa\xd8\x38\x70\x1e\xc8\ -\xb6\xcd\x7f\xca\x88\x3c\x99\x0d\xbe\x88\x50\xa6\x5b\x50\xbd\x79\ -\x85\xe2\x41\x63\x16\xf3\x9b\x63\xb1\x76\xd1\x85\x7c\xaa\x0b\x12\ -\xa6\x6a\x53\x82\x43\xb0\x4c\xb7\xc4\x21\xf4\x89\x46\xc9\xbd\x3a\ -\xb6\x08\x5e\x18\x11\xa0\xc7\xa5\x8a\x27\x1f\x92\x84\xf6\x8a\x02\ -\x4d\x2f\xcf\x1e\x52\xa7\x9f\xe2\xa7\x6b\xf1\xb3\x63\x88\xaa\xd6\ -\xfc\x34\xf4\x21\x9b\xd6\xa4\x98\x40\xd1\x8a\xc1\xb0\xb0\x0f\x5d\ -\x79\x37\x8a\x04\xbc\x5d\xd2\xef\x7f\x58\xf8\xcb\xaa\xd8\x06\x55\ -\x6d\xa3\xd4\x88\x64\x2f\x60\xbf\x6e\xba\x6c\x2a\xb6\xfa\x6b\x49\ -\x5c\x4b\xe0\x14\x61\x77\xe3\xa8\x95\x26\x3b\xc1\x92\xa6\xa7\x81\ -\xae\x14\xea\xe3\x7b\xb2\x6b\xfd\xf7\xfc\x9a\xbe\x13\x4c\x97\x4e\ -\xd9\x7b\xf3\x63\xf4\x88\x42\x62\x99\x54\x6d\xec\x3d\xc4\x0d\x0d\ -\x10\x74\xca\x7c\x8a\xd4\x30\x89\x53\x36\x5c\x37\x2a\x91\x32\xd6\ -\xde\xa2\xbc\xa2\x0d\x12\x09\xd4\xc6\x41\x24\x31\x71\xb0\x87\x28\ -\xd0\x71\x87\xe8\x0d\x24\x90\xc7\x5a\x33\xd5\x11\x94\x89\xff\x6a\ -\xdc\x57\x5b\xd5\x1c\x8f\xce\x66\xb2\x3a\xda\xc9\xda\x3f\x56\x4d\ -\x14\xd5\x1e\x5e\x65\x27\xa1\x26\x2d\xef\x9a\x05\x29\xbb\xd8\x50\ -\x5a\x4a\x61\x9b\xa5\x53\x4c\x37\x50\x68\xe3\xe1\xb4\xa2\x6e\xb8\ -\xd0\xa8\x73\xa3\xcd\xec\x74\x4e\x7d\xce\xa9\xff\x6f\xdc\xe6\x00\ -\xe7\x6b\xb9\x68\x56\xff\x5c\x9f\x1c\x8a\xd1\xfb\xe0\x85\x26\x6c\ -\xd8\x89\x18\x39\xf8\xdc\xc8\x92\x93\xd0\xd6\x10\x7b\xac\x09\x2d\ -\xf7\xcb\xde\xdf\xb4\x3b\x67\x0e\xd7\x72\x18\x93\x11\x69\x56\x81\ -\xd8\x00\x3d\x4e\x3e\xb4\x2a\xd7\x2c\x23\x46\x29\xa1\x06\x42\xe7\ -\x17\x93\xa3\x19\x41\x15\xad\x6a\x2f\x12\x86\x92\x3f\x87\xcc\x43\ -\x03\xb8\x32\x57\xb3\x0e\xd6\x0d\x4c\xbc\x21\x63\x6d\x57\x25\xd2\ -\x6e\x62\x88\x13\xb9\xec\x12\xfe\x9b\xe8\xce\x40\xb1\x89\x6d\xae\ -\xdb\x0e\x8b\x00\xab\xea\xe0\xd5\x78\x7d\x0a\x57\x7d\x2d\x80\x71\ -\x60\xb8\xe2\xef\x5b\x7d\xd6\x10\xa6\x65\xc4\x4f\x56\xc0\xe8\x5e\ -\x9d\x80\xfb\xd6\x0a\x08\xdb\xab\x06\xda\x13\x96\x13\xb5\x6c\x05\ -\xbc\x6d\x47\x64\x58\x0f\x00\x39\xa4\x01\x8a\x13\xcb\x03\xb8\x6d\ -\x26\x0d\x68\x6b\xdb\x07\xc5\xe6\x01\x11\x00\x7a\x9b\x88\x37\x51\ -\xa9\xc5\x96\x1a\xa8\x9e\x04\xbd\xea\x04\x42\x9f\xfa\xc7\xf6\xac\ -\x68\x43\x82\x41\x81\x92\x90\x38\x46\xe6\x0b\x62\x18\x6d\xdb\xa4\ -\x3d\x92\xc9\xc3\xb3\xd3\x4a\xd8\x3e\x68\xeb\xcb\x16\x88\x13\x3f\ -\x77\x24\x6b\x33\xa3\x10\x65\x7f\xc7\x39\x89\x90\xbd\xb7\x35\xba\ -\xd4\x93\xe3\x76\x06\xa3\x38\x47\xe9\x77\x6c\x3d\xa2\xb0\x11\xaf\ -\x98\x6b\x39\x36\x91\x6b\xea\x30\x0d\x18\x93\x17\x48\xac\xe7\xf9\ -\xc3\x96\x16\x3c\x1a\x1b\xba\xc6\x16\x54\x7b\x01\x75\x4e\xf1\x65\ -\xd5\xb4\xad\x25\x8a\xbb\xf5\x59\xb7\xd1\x1b\x03\x40\x36\xac\x5d\ -\x33\x71\x2a\xfb\x1d\xf4\x57\xb5\x0a\x1a\xf8\x97\x8b\x14\xc1\x66\ -\x72\xa8\xe2\xe0\x5f\x68\x2c\x88\xb9\xb7\xb1\x2d\x02\x2d\x39\x16\ -\x4d\x3a\xa7\xfb\x53\x82\x5c\x70\xe6\x2f\xa5\xf5\x90\xc6\x1e\x5d\ -\x8f\xed\x69\xec\x90\xad\x07\x3e\x62\xe1\x51\x61\xc8\x06\x50\xca\ -\x6d\x7b\x87\x40\x50\xaa\x3a\xe1\xe5\xc9\x46\xe0\x93\x6b\x0b\xbf\ -\x8a\x6c\xb5\x5c\xb5\xfa\x3c\xa5\x0f\xef\x64\x95\x8d\x2c\x57\x4f\ -\x32\x74\x4c\xae\x75\x5a\x76\x65\x58\xf5\x10\x86\x1b\xab\x4b\x60\ -\xcf\x7b\x5f\xbc\x95\x62\x5f\x7b\xca\xb5\x7a\x84\x9e\x7a\xa4\xa3\ -\x7a\x98\x5f\xa5\x1e\xae\xe0\x26\xdd\xb1\xc4\xc2\xa3\x98\x25\x1a\ -\x39\xee\xec\x38\x31\xb2\xed\x2d\x8e\xa7\x65\xa0\xde\x38\x29\x21\ -\x45\x67\xda\xce\x48\xd7\x5e\x36\xd9\x72\x0a\xa2\x79\xd6\x79\x75\ -\x34\x75\x47\x83\x2d\x2b\x89\x1c\x51\x61\x1a\x9a\xd5\xd5\x80\x51\ -\x8a\x95\x33\x82\x39\x6e\xd8\x55\x99\xcc\x33\xf4\x25\x4c\xe0\xb0\ -\xbb\x44\xdd\xf6\x24\xfe\xe8\xf9\x71\xc3\x94\x64\xc4\x9d\x06\xfd\ -\xb8\x63\x1f\x06\x3b\x1d\x05\xfd\x64\x18\x6f\x6e\x12\x15\x39\xde\ -\xc1\x55\xf4\xe2\x8a\xba\xa0\xc0\xe0\x16\x39\x29\xf6\x13\x27\x28\ -\x52\x05\xaf\x9f\x5f\x14\xb2\x7c\xb5\x6b\x5b\xba\xae\xf1\xb5\x15\ -\x3a\xb9\x41\xa9\xa9\xeb\x17\x70\xdd\x02\x53\x2d\x2c\xd5\x47\xd6\ -\x2d\x60\x5d\x62\xb1\xd6\xf1\x47\x03\xab\x7a\x60\xe4\xc4\x1c\x99\ -\xc2\x49\x5d\xb3\xf2\x84\x93\x1d\x54\xc2\x83\x5b\x09\x1f\x10\x64\ -\x4a\x9c\x9c\x4b\x7c\xe8\xac\xd6\xa9\x13\x7c\xb7\x02\x82\x8e\x6a\ -\x54\x8d\x0a\x36\x48\xa1\x01\x4e\xea\xe9\x0a\xb5\x2d\xa1\xe7\x5a\ -\x22\xe9\x99\x0d\x46\xa9\x13\x40\x4f\x43\xc6\x83\xc0\x3c\x8c\x07\ -\xd9\xd6\x49\x65\x68\x13\x3b\x87\xd2\xf6\xb8\xd1\x5c\xb5\x8c\x0d\ -\x9e\x23\x00\x17\x39\xf2\xde\xb0\x16\xc6\x40\xf4\xcd\x1e\xdb\x97\ -\xb1\x9b\x40\x41\x09\x41\x9c\xf0\x97\xee\x4a\xb4\x91\xd0\x11\xbd\ -\x68\x28\xb3\x16\x2c\xe2\x62\xe6\xee\x40\x96\xe4\xfa\xcb\x2a\x7b\ -\x60\x6a\xb0\x4e\x5d\x9e\xa1\xd6\x5a\x9e\x7d\xca\x74\xc0\xcb\xcf\ -\x29\x59\xaf\x4a\x3f\xe0\x63\xf6\x49\x48\x02\xbe\x65\x9d\x84\x24\ -\x2e\x65\x84\xf9\xa5\x1f\xda\x0f\x2f\xcf\xa0\xbd\xf3\x85\x11\x89\ -\x6c\xc2\x13\x9c\xc8\x2d\x6a\xc6\x01\x16\x76\x1c\xd1\x09\xab\x53\ -\x90\x53\x67\xd8\x24\x26\x93\xf6\x2e\x68\x8e\x99\xc0\x33\xaf\xdb\ -\x54\x6e\xa3\xb8\x0b\x09\xd2\xe9\x4a\x62\x5f\x2e\x28\x68\x2d\x74\ -\xb5\x91\xcd\x11\x93\x26\xb0\xb3\x3a\x79\xd6\x50\x16\x04\x92\xe5\ -\x39\xa4\x40\x3b\x66\x22\x8d\xce\x88\xa0\x68\x8a\x20\x55\x2e\x5c\ -\x20\x73\xe6\x62\x7f\x02\x6d\xce\xb6\x05\x53\xd1\xd7\x3e\x94\x2a\ -\x98\xb9\xa8\xab\xa6\x78\xe1\xa4\xd1\xc9\xae\xbe\x44\xb8\x65\x4b\ -\xa8\x54\x3f\xd9\x6b\xaa\x8a\x77\x69\xb7\xe1\xa3\x47\xd7\xd7\xb9\ -\x1e\x77\x9f\x60\xee\xc0\x24\x5a\x67\x0b\xe6\x89\x59\x74\x4f\x17\ -\x5e\x3e\x86\x57\x4a\x97\x3d\x45\xf5\xc4\x18\xda\xc0\x29\xcb\xfe\ -\x29\xd4\xd5\xb3\xe7\xa2\x2d\x0b\x39\x69\x46\x60\x4f\x27\x13\x44\ -\xd2\xe4\x53\x39\x5b\x84\xc7\x89\xb1\x9b\x16\xf1\xad\x19\x27\xff\ -\x07\x49\x02\x4d\x52\xcb\x93\x47\xf9\xbf\x3a\xad\xe5\x7e\xe2\x83\ -\xe4\x7a\xf8\x6b\x4f\xe7\xbb\x16\x41\xcc\x6c\x72\x4c\xef\xb8\xd6\ -\x7a\x1a\xb9\xb8\x64\x9e\x54\x8e\xfe\x1c\xab\xb9\xd6\x8c\xd3\x68\ -\x0f\xe2\x2b\x75\x33\x1f\xf8\x17\xde\xba\xac\xf3\xe4\xcf\x5f\xa9\ -\x6e\x23\x4d\x00\xb8\xce\x23\xc0\xf1\x74\x02\x37\x59\xa3\x3a\x8c\ -\x5c\x08\x6c\x5f\x72\xd2\xce\x3e\x9d\xd5\x72\xec\xef\xa9\xac\x96\ -\xaf\x27\xad\xa0\x87\x9a\x02\xdf\x9c\xd4\x32\xf4\x47\x25\x7f\x43\ -\x39\x2d\xf0\xa2\x0e\xb1\x0c\x94\xec\xff\x6d\x72\xcb\xaf\xd3\x88\ -\x7e\xce\x1c\x02\x34\xe8\x47\xd2\xfa\xfb\x53\xc5\xa9\x2c\xe5\x84\ -\x6b\x08\x32\x7d\xad\x36\x7c\x86\x72\xf1\x0c\xd5\x81\x89\xfb\x56\ -\xe5\xf9\x6a\xd7\xc0\xe2\x94\x6b\x56\x69\x02\xe6\x81\xf6\xd4\x8e\ -\xca\xe3\x6b\xe5\x79\x4d\xdd\x69\x88\xf0\x94\xf6\x54\x50\x9f\x90\ -\xb5\x7a\x5a\x7b\x7e\xe3\x29\x61\xff\x04\xea\x73\x7e\x6e\x98\x38\ -\x0f\x07\xc8\xef\x02\x42\x8e\x8c\x60\x0f\x41\x54\xd6\x93\xb9\x44\ -\x1d\x99\xb3\x35\x80\x85\x15\x80\xa7\x44\xbd\x90\x40\x2a\x8b\x21\ -\x04\xa0\x65\xf6\xcd\x8c\x76\xae\x35\xe7\x83\x45\x93\x65\x43\x0f\ -\x38\x4c\xda\x5a\x23\x01\xa5\xa5\x6f\xf6\x21\x50\x47\x97\x33\x42\ -\x96\xb8\x36\xc3\x29\x68\x3a\xb5\xa5\x2d\xd9\x8a\x0f\xa8\x3c\xe3\ -\x25\x44\x55\x99\x47\x74\xce\x1b\x8e\xd7\x83\x8a\x40\xa7\x1c\xc3\ -\x01\x13\x70\x1e\x4c\x42\x14\xed\x64\x0e\x84\xc6\x18\x55\x83\xb3\ -\xce\x09\xee\x40\xa0\x40\x48\x0e\xb1\xb3\xa6\x63\x11\x8c\x83\xe0\ -\x93\x67\x05\x53\xa0\x25\xd4\xb7\x86\xfe\x8a\x30\xe3\x25\x45\x87\ -\x09\xd4\xd0\xd2\xb9\x33\x63\x36\x4a\x9a\xa0\x22\xc4\xf4\x82\x2f\ -\x11\x25\x22\xca\xab\xe3\x7f\xd9\xe0\x0f\xf4\x87\xcf\xeb\x28\x4d\ -\x71\x24\x98\x5c\x4c\x25\x12\xf4\x82\xed\x5c\xf6\x7c\xea\x29\x91\ -\x27\xd4\x94\x03\x69\xaf\x22\x1d\xb7\x0e\x14\x7d\x84\x49\xa0\x3c\ -\x3c\xa3\xad\x91\x53\x56\x1d\x4c\xd2\x72\x12\x1f\x72\x92\x6c\x81\ -\xa4\xf9\x2c\x9b\x72\x39\x24\x85\x8a\xae\x8a\x05\x27\x45\x26\x48\ -\x8a\x9b\x8f\x9e\xce\x55\x60\x89\x94\x95\x14\x1b\x84\xe0\x96\x37\ -\x82\x11\xce\x27\x49\xab\x8a\x11\xa1\x16\x37\xb4\x40\x94\x6c\xaf\ -\x00\x7b\x15\x1d\x4d\x4d\x43\xb4\x46\xa2\x45\x0f\xdf\x8d\x80\x8c\ -\x28\x89\x00\x9b\x47\x8c\x40\xe0\xdc\x17\xed\x6f\x64\x39\xfd\x8c\ -\xde\xf0\x91\xb1\x03\xa7\xe4\x40\x14\x7c\xb2\xbc\xfd\x01\x9c\xaf\ -\xc5\x1c\x52\x82\x12\x6f\x3c\x5a\xca\x1f\x2e\xa1\x1d\x43\x74\x18\ -\xa0\x18\xb8\x59\x00\x02\xe6\x13\x11\x8f\x70\x95\xce\x4d\x35\xa5\ -\x0e\x25\xce\x08\xd3\xa8\x5e\xb2\x55\x42\xe4\x33\x6b\xe3\x21\x17\ -\x1c\x5b\x47\x8b\x68\x9e\x53\x5a\x68\xab\xc7\x5f\x33\x20\xf0\xb4\ -\x01\xc4\x2c\x20\x72\xbb\x20\xf9\x51\x80\xcd\x41\x0f\x94\xfc\x32\ -\x98\x42\x99\x63\x27\x7f\x7c\x34\x6f\xbf\xca\xbc\x5d\xcc\x82\x59\ -\xd6\xf6\x4c\x7f\x6b\x1c\xd2\xe4\x83\x96\x1c\x56\xca\x1d\x10\x15\ -\x48\xf0\xfe\xe5\x14\xd1\x97\x53\x6e\x4a\x13\x65\x70\x52\xf6\xf9\ -\x23\x04\x4c\x0b\x4c\x29\x52\x04\x43\x68\xe5\x50\x89\xb6\xbd\x42\ -\x14\xe1\x80\x48\x89\xb6\x8b\x0e\xa6\x4c\xb2\x26\x78\xc7\x49\x9a\ -\xa9\x41\x84\x50\x20\x10\x2c\x55\x90\x0c\x05\x28\x91\x34\x83\xb1\ -\x94\x4c\x14\x98\x1b\x27\xdb\x17\x04\x73\x24\x29\x12\x4e\x3f\x1d\ -\xc1\x76\x92\x14\x44\xfa\xaa\x9a\xc0\xf5\x2c\xf4\x41\x94\x27\xa6\ -\x9c\x52\x28\x08\x4a\xd5\xab\x0c\xba\xb6\x86\x30\x96\x5a\x4e\xcc\ -\x11\xa1\x88\x1d\x85\x89\x95\x9c\xd1\xa8\x7c\xd9\x35\xd3\x74\x49\ -\x5e\xec\x86\x95\xbd\x2c\x98\x7f\xa7\x79\xc6\x14\xac\xc8\x66\x91\ -\x4b\xa9\x60\x34\x18\x7d\x2d\x69\x0c\xda\xf0\x86\x24\x2b\xbb\xd6\ -\x42\x49\x93\x61\xe9\x45\x83\xe8\x18\x28\x4a\x5b\x18\xf2\x24\x2a\ -\x19\x93\xec\x47\x51\xba\x48\x9d\x20\x23\x46\x98\xf6\xda\xea\xf4\ -\x1d\x5f\x08\x77\x34\x71\xe5\x4c\x1c\x2a\x4a\xf7\x2c\xa4\x14\x2e\ -\x04\x56\xae\x5f\x52\x5b\x4d\x18\x14\xc3\x01\x13\x19\x4f\xde\xf4\ -\x33\x5e\xcb\x2e\x19\xef\x01\x66\xcb\x17\x1d\x10\x4f\x79\xd9\xcd\ -\x74\xc6\xb0\x13\xb0\x21\xf3\x16\x1c\x4c\x8a\x9c\x20\x61\xf1\x34\ -\x25\xa2\x07\x82\x50\xf6\x00\xb0\xb5\xb1\xd8\x1f\x76\x00\xb0\x93\ -\xce\x48\x26\xab\x1c\x82\x79\xed\xe5\xe4\x15\x5e\x20\x51\x0a\xe2\ -\x14\x92\x25\x29\x76\x1a\x44\x70\x32\x12\xcc\x20\xe7\xba\xc2\x38\ -\x27\x1e\x89\x0e\xcd\x79\x24\x38\x51\x3e\xc0\x8d\x44\x4f\x2b\x43\ -\x59\x71\x23\x81\x3c\x25\x9b\x3a\x6f\x03\xfb\x28\x80\x2c\x49\xde\ -\x8b\x1a\x64\x24\xdf\xa6\xc8\xcf\xf2\x2a\xb1\x2a\xde\x33\xce\x49\ -\x95\x43\x9f\xac\xd9\xc7\x04\x0f\xba\x52\x49\xf2\x59\x1c\x22\x4c\ -\xa7\x50\x8a\x3a\x66\x3f\x9a\x6c\x49\x32\x0d\xec\x6b\x03\x25\x20\ -\x64\x69\x13\xf8\x44\x21\x65\x45\xc9\x05\xdc\x46\x73\x1b\xef\x03\ -\x3b\x1f\x0d\xcf\x28\xae\x17\x82\x28\x69\x83\x94\x0b\x2a\x0e\x34\ -\xe7\x18\x8e\x8e\xd0\x27\xde\x33\x86\xd0\x99\x90\x06\x4a\x06\xad\ -\x70\xd2\xb6\x73\xc3\x6a\xb4\xc2\x17\xb1\xc2\x5f\xbb\x3b\xf4\xd5\ -\x9b\x43\x00\x38\xb0\x7d\xb0\x06\x69\x1a\x35\x9d\xa3\xda\x65\xe5\ -\x10\x4c\xe2\x43\xd0\x26\xd1\x07\xba\x46\x63\x1d\x2c\x74\xe5\x1c\ -\x1d\x6f\x68\x31\x28\x78\xf0\x11\xb1\xdb\xf7\xe3\x95\x9f\xdf\xcd\ -\x95\x9f\x57\x53\xbc\x85\xbf\x9b\xf9\xaf\xdc\x22\x3c\x55\x3c\x97\ -\xee\xdc\x5d\x1e\x2f\xfc\x7c\xed\xc2\xcf\x78\xdd\x87\x27\x3e\x5e\ -\xf7\x19\xaf\xfb\x0c\x4a\xe0\x78\xdd\xe7\xba\x29\x18\xaf\xfb\x8c\ -\xd7\x7d\xc6\xeb\x3e\xe3\x75\x9f\xf1\xba\xcf\x78\xdd\x67\xbc\xee\ -\x33\x5e\xf7\x19\xaf\xfb\x8c\xd7\x7d\xc6\xeb\x3e\xe3\x75\x9f\xf1\ -\xba\xcf\x78\xdd\x67\xbc\xee\xf3\x02\xea\x8c\xd7\x7d\xc6\xeb\x3e\ -\xe3\x75\x9f\xf1\xba\x0f\xbd\x19\xaf\xfb\x8c\xd7\x7d\xda\x08\x64\ -\xbc\xee\x33\x5e\xf7\x19\xaf\xfb\x8c\xd7\x7d\x5a\x12\x39\x5e\xf7\ -\xf9\xf6\xeb\x3e\xc3\x49\x03\xe3\x75\x9f\xf1\xba\xcf\x99\x09\x2d\ -\xaf\x96\xce\x02\xe4\x05\xc7\xde\x95\x4c\xca\x7f\x86\xc2\x04\x95\ -\x5e\x98\xd7\xf2\xbb\x4a\x28\x1b\x2f\xfd\xfc\xd3\x5d\xfa\x19\xb5\ -\xe8\x37\xa2\x45\xe3\xdd\x1f\x01\x21\xe3\xdd\x9f\xeb\x6a\xbc\xfb\ -\x73\xe1\xbb\x3f\xbf\x99\xd4\xd7\xa1\x3f\xa0\xf1\xbb\x32\x6e\xe3\ -\xcd\x9f\xf1\xe6\x8f\x50\x6e\xbc\xf9\x33\xde\xfc\x79\xc9\xcd\x9f\ -\xd1\x06\xbf\xde\xbd\x9f\xe5\x7a\xbd\x7a\xd8\x2f\xbf\x7b\x15\xfa\ -\x2a\x45\xf2\xf9\x2b\xff\x9e\xcb\x94\xd2\x51\x09\xcd\xff\x0e\xe8\ -\xfb\xdd\x89\xf4\x86\xf6\x1f\x57\x27\x58\xa5\xe3\xe9\xde\x05\xc1\ -\x31\x3b\x6d\x30\x2f\xe1\x37\x6d\x64\xb3\xa7\x91\xfc\x5d\xa9\x25\ -\x0c\x64\xf6\xbd\xb9\xd9\x7f\xc4\x3f\xff\x00\xaa\x5d\xac\xfa\ -\x00\x00\x16\x70\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x73\ -\x65\x74\x5f\x73\x74\x64\x5f\x64\x65\x76\x5f\x73\x74\x72\x65\x74\ -\x63\x68\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ -\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ -\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ -\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ -\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ -\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ -\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ -\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ -\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ -\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ -\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x78\x3d\x22\x2d\x31\x37\x2e\x36\x32\x38\x30\x38\x34\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x79\x3d\x22\x31\x37\x2e\x39\x39\x37\x31\x35\x36\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ -\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ -\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ -\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ -\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ -\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ -\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ -\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\ -\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ -\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ -\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ -\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ -\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ -\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ -\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ -\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ -\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ -\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ -\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ -\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ -\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ -\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ -\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ -\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ -\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ -\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ -\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ -\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ -\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x66\x3b\x66\x69\x6c\ -\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ -\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ -\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x38\x33\x37\ -\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ -\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ -\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ -\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\ -\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\x2e\x34\x35\x31\x31\x34\ -\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ -\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ -\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\ -\x34\x33\x36\x37\x38\x34\x38\x2c\x30\x2e\x35\x33\x36\x38\x34\x38\ -\x37\x39\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ -\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ -\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ -\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x38\x39\x33\x37\x32\x39\x33\ -\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\x39\x38\x2c\x30\x2c\x30\x29\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\ -\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ -\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x37\x2e\x37\x39\x39\x37\x36\ -\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x35\x2e\ -\x39\x38\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ -\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ -\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ -\x6c\x6c\x3a\x23\x38\x66\x66\x66\x38\x66\x3b\x66\x69\x6c\x6c\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ -\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ -\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ -\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\ -\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ -\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ -\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\ -\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ -\x66\x66\x61\x33\x61\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ -\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ -\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ -\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ -\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\x39\x3b\x73\ -\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ -\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ -\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ -\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ -\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\ -\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x33\x2e\ -\x33\x32\x30\x36\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ -\x3d\x22\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\ -\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ -\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ -\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\x35\x30\x38\ -\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\x30\x2c\x30\ -\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ -\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\ -\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\x30\x33\x34\x38\ -\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x72\x79\x3d\x22\x33\x2e\x32\x31\x31\x37\x36\x34\x36\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ -\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ -\x2d\x34\x2e\x30\x34\x30\x31\x33\x38\x34\x65\x2d\x31\x35\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x33\x2e\x38\x36\x36\ -\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\x36\x39\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\ -\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ -\x23\x65\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ -\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ -\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ -\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ -\x69\x64\x74\x68\x3a\x31\x2e\x39\x30\x37\x36\x32\x34\x39\x36\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ -\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ -\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ -\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ -\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\ -\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\ -\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\ -\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\ -\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ -\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\ -\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\ -\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\ -\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\ -\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\ -\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\ -\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\ -\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\ -\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\ -\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\ -\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\ -\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\ -\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\ -\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ -\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\ -\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\ -\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x38\x30\x30\x30\x30\ -\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\ -\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\ -\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\ -\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ -\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x20\x63\x20\ -\x2d\x34\x2e\x30\x37\x34\x32\x30\x34\x2c\x30\x2e\x30\x30\x31\x34\ -\x20\x2d\x38\x2e\x33\x37\x31\x35\x35\x35\x35\x2c\x33\x2e\x39\x39\ -\x32\x38\x32\x33\x36\x20\x2d\x39\x2e\x36\x2c\x36\x2e\x34\x20\x43\ -\x20\x35\x2e\x31\x37\x31\x35\x35\x35\x35\x2c\x39\x2e\x38\x37\x33\ -\x38\x34\x33\x20\x33\x2e\x30\x38\x34\x32\x38\x33\x2c\x31\x38\x2e\ -\x39\x31\x31\x35\x36\x34\x20\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ -\x2c\x32\x35\x2e\x36\x20\x30\x2e\x30\x35\x37\x38\x35\x38\x36\x37\ -\x2c\x32\x38\x2e\x39\x34\x34\x32\x31\x38\x20\x2d\x31\x2e\x38\x30\ -\x38\x38\x30\x38\x2c\x33\x30\x2e\x32\x37\x37\x35\x35\x31\x20\x2d\ -\x32\x2e\x33\x35\x36\x36\x30\x36\x2c\x33\x30\x2e\x37\x37\x34\x38\ -\x33\x20\x2d\x32\x2e\x39\x30\x34\x34\x30\x34\x31\x2c\x33\x31\x2e\ -\x32\x37\x32\x31\x30\x39\x20\x2d\x33\x2e\x32\x2c\x33\x30\x2e\x39\ -\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x32\x2c\x33\x30\x2e\x39\x33\ -\x33\x33\x33\x33\x20\x63\x20\x30\x2e\x37\x30\x36\x38\x37\x35\x37\ -\x2c\x30\x2e\x31\x35\x38\x36\x32\x39\x20\x30\x2e\x34\x34\x30\x34\ -\x38\x31\x33\x2c\x31\x2e\x30\x31\x35\x33\x37\x32\x20\x30\x2e\x31\ -\x33\x30\x35\x36\x35\x31\x2c\x31\x2e\x38\x30\x34\x30\x38\x37\x20\ -\x2d\x30\x2e\x33\x30\x39\x39\x31\x36\x32\x2c\x30\x2e\x37\x38\x38\ -\x37\x31\x33\x20\x2d\x30\x2e\x36\x36\x33\x33\x35\x34\x31\x2c\x31\ -\x2e\x35\x30\x39\x33\x39\x39\x20\x2d\x30\x2e\x31\x33\x30\x35\x36\ -\x35\x31\x2c\x31\x2e\x33\x39\x35\x39\x31\x33\x20\x30\x2c\x30\x20\ -\x30\x2e\x32\x36\x30\x34\x35\x35\x36\x2c\x31\x2e\x35\x33\x32\x30\ -\x34\x31\x20\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x2c\x30\x20\x31\ -\x2e\x38\x37\x32\x38\x37\x37\x37\x36\x2c\x2d\x31\x2e\x35\x33\x32\ -\x30\x34\x20\x35\x2e\x33\x35\x38\x31\x37\x37\x36\x2c\x2d\x33\x2e\ -\x39\x39\x34\x38\x32\x37\x20\x36\x2e\x34\x2c\x2d\x38\x2e\x35\x33\ -\x33\x33\x33\x33\x20\x43\x20\x37\x2e\x34\x31\x36\x39\x37\x38\x31\ -\x2c\x31\x36\x2e\x35\x32\x32\x39\x38\x38\x20\x39\x2e\x35\x37\x36\ -\x37\x38\x34\x2c\x35\x2e\x32\x38\x32\x39\x30\x35\x31\x20\x31\x36\ -\x2e\x31\x37\x35\x35\x34\x39\x2c\x35\x2e\x33\x32\x34\x32\x38\x35\ -\x20\x32\x32\x2e\x34\x2c\x36\x2e\x34\x20\x32\x31\x2e\x33\x33\x33\ -\x33\x33\x33\x2c\x39\x2e\x36\x20\x32\x36\x2e\x36\x36\x36\x36\x36\ -\x37\x2c\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\x63\x20\x32\x2e\ -\x34\x31\x37\x33\x38\x34\x2c\x36\x2e\x32\x38\x35\x32\x20\x36\x2e\ -\x34\x2c\x39\x2e\x36\x20\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x2c\ -\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x20\x36\x2e\x34\x2c\x31\x2e\ -\x30\x36\x36\x36\x36\x37\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\ -\x30\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\x30\x20\x43\x20\x34\ -\x34\x2e\x38\x2c\x33\x32\x20\x34\x33\x2e\x37\x33\x33\x33\x33\x33\ -\x2c\x33\x35\x2e\x32\x20\x34\x32\x2e\x36\x36\x36\x36\x36\x37\x2c\ -\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x34\x31\x2e\x39\x32\x34\ -\x35\x30\x33\x2c\x33\x31\x2e\x31\x38\x30\x37\x32\x31\x20\x33\x35\ -\x2e\x30\x35\x38\x33\x34\x37\x2c\x33\x32\x2e\x33\x32\x36\x32\x35\ -\x32\x20\x33\x32\x2c\x32\x35\x2e\x36\x20\x32\x38\x2e\x39\x34\x31\ -\x36\x35\x33\x2c\x31\x38\x2e\x38\x37\x33\x37\x34\x38\x20\x32\x37\ -\x2e\x34\x38\x30\x35\x39\x35\x2c\x31\x31\x2e\x33\x30\x39\x36\x35\ -\x33\x20\x32\x35\x2e\x36\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\ -\x20\x32\x33\x2e\x37\x31\x39\x34\x30\x35\x2c\x33\x2e\x36\x32\x33\ -\x36\x38\x20\x32\x31\x2e\x37\x35\x39\x31\x38\x37\x2c\x31\x2e\x31\ -\x31\x34\x34\x33\x35\x35\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\ -\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ -\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ -\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\ -\x7a\x73\x73\x63\x73\x63\x73\x73\x63\x73\x63\x63\x63\x73\x7a\x63\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\ -\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\ -\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ -\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\ -\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\x30\x30\x30\x30\x31\ -\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\ -\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\ -\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\ -\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\ -\x64\x27\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\ -\x67\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\ -\x6e\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\ -\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ -\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ -\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ -\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x39\x33\ -\x33\x33\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ -\x22\x74\x65\x78\x74\x33\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\ -\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\ -\x61\x6e\x33\x37\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ -\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x39\x33\ -\x33\x33\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ -\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\ -\x32\x35\x2e\x36\x30\x30\x30\x30\x30\x33\x38\x70\x78\x3b\x6c\x69\ -\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\x32\x35\x3b\x66\ -\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\ -\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ -\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x22\x3e\xcf\ -\x83\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\ -\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x0b\x1c\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ -\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ -\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ -\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ -\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ -\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ -\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ -\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ -\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ -\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ -\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ -\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ -\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ -\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ -\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ -\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ -\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ -\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ -\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ -\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ -\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ -\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ -\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ -\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ -\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ -\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ -\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ -\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ -\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ -\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ -\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ -\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x63\x6c\x61\x73\x73\ -\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ -\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ -\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\ -\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\ -\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\ -\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\ -\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\ -\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ -\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ -\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\ -\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\ -\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x2e\ -\x39\x37\x39\x35\x31\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x32\x35\x34\x2e\ -\x30\x36\x30\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x37\x31\x2e\x36\x30\x37\x38\ -\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\ -\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ -\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ -\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ -\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ -\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\ -\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\ -\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ -\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ -\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ -\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ -\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ -\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ -\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ -\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ -\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ -\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\ -\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ -\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\ -\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ -\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ -\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\ -\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ -\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ -\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ -\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ -\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ -\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ -\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ -\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ -\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ -\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ -\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ -\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ -\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ -\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ -\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ -\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ -\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x66\x32\ -\x32\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ -\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x66\x32\ -\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ -\x2e\x36\x31\x33\x39\x36\x38\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ -\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ -\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ -\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ -\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ -\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ -\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ -\x4d\x20\x31\x31\x2e\x31\x33\x39\x38\x35\x32\x2c\x31\x35\x2e\x34\ -\x30\x33\x31\x34\x32\x20\x48\x20\x31\x39\x20\x76\x20\x2d\x32\x2e\ -\x39\x39\x37\x33\x38\x20\x6c\x20\x36\x2e\x38\x37\x37\x36\x33\x2c\ -\x34\x2e\x37\x39\x35\x38\x31\x20\x4c\x20\x31\x39\x2c\x32\x31\x2e\ -\x39\x39\x37\x33\x38\x31\x20\x56\x20\x31\x39\x20\x68\x20\x2d\x37\ -\x2e\x38\x36\x30\x31\x34\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x38\x31\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ -\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\ -\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\ -\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ -\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\ -\x30\x66\x32\x32\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ -\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\ -\x20\x2d\x31\x38\x2e\x34\x30\x36\x32\x35\x2c\x2d\x31\x33\x20\x43\ -\x20\x2d\x31\x39\x2e\x32\x39\x37\x36\x30\x39\x2c\x2d\x31\x33\x20\ -\x2d\x32\x30\x2c\x2d\x31\x32\x2e\x34\x38\x30\x30\x31\x32\x20\x2d\ -\x32\x30\x2c\x2d\x31\x31\x2e\x38\x34\x33\x37\x35\x20\x76\x20\x34\ -\x37\x2e\x36\x38\x37\x35\x20\x43\x20\x2d\x32\x30\x2c\x33\x36\x2e\ -\x34\x38\x30\x30\x31\x32\x20\x2d\x31\x39\x2e\x32\x39\x37\x36\x30\ -\x39\x2c\x33\x37\x20\x2d\x31\x38\x2e\x34\x30\x36\x32\x35\x2c\x33\ -\x37\x20\x68\x20\x33\x36\x2e\x38\x31\x32\x35\x20\x43\x20\x31\x39\ -\x2e\x32\x39\x37\x36\x30\x39\x2c\x33\x37\x20\x32\x30\x2c\x33\x36\ -\x2e\x34\x38\x30\x30\x31\x32\x20\x32\x30\x2c\x33\x35\x2e\x38\x34\ -\x33\x37\x35\x20\x76\x20\x2d\x31\x2e\x39\x33\x37\x35\x20\x43\x20\ -\x31\x32\x2e\x36\x30\x30\x39\x31\x2c\x33\x30\x2e\x36\x33\x30\x36\ -\x30\x36\x20\x37\x2e\x35\x2c\x32\x33\x2e\x38\x34\x36\x35\x31\x37\ -\x20\x37\x2e\x35\x2c\x31\x36\x20\x37\x2e\x35\x2c\x38\x2e\x31\x35\ -\x33\x34\x38\x32\x38\x20\x31\x32\x2e\x36\x30\x30\x39\x31\x2c\x31\ -\x2e\x33\x36\x39\x33\x39\x34\x35\x20\x32\x30\x2c\x2d\x31\x2e\x39\ -\x30\x36\x32\x35\x20\x76\x20\x2d\x39\x2e\x39\x33\x37\x35\x20\x43\ -\x20\x32\x30\x2c\x2d\x31\x32\x2e\x34\x38\x30\x30\x31\x32\x20\x31\ -\x39\x2e\x32\x39\x37\x36\x30\x39\x2c\x2d\x31\x33\x20\x31\x38\x2e\ -\x34\x30\x36\x32\x35\x2c\x2d\x31\x33\x20\x5a\x22\x0a\x20\x20\x20\ -\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x39\x32\ -\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ -\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ -\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x16\xb0\ -\x00\ -\x01\xff\x66\x78\x9c\xed\x5d\x59\x73\xe3\xc8\x91\x7e\x9f\x5f\x41\ -\x73\x5e\x3c\x61\xa1\x84\x2a\xa0\x80\x02\x5b\x6a\x3f\x78\xc2\xb1\ -\x13\x61\xc7\x46\xd8\x5e\xef\xe3\x04\x45\x42\x12\xb7\x49\x42\x01\ -\x42\x57\xff\xfa\xad\xc2\x41\xf0\x48\xb5\xc5\x49\x30\xd1\x1a\x24\ -\x67\x3a\x28\xe2\x46\x7e\x95\x59\x79\x55\xe6\xd5\x9f\x5f\x56\xcb\ -\xd1\x53\x9a\x6f\x16\xd9\xfa\x7a\x2c\x85\x3f\x1e\xa5\xeb\x59\x36\ -\x5f\xac\xef\xae\xc7\xff\xf3\xaf\xbf\x7a\x66\x3c\xda\x14\xd3\xf5\ -\x7c\xba\xcc\xd6\xe9\xf5\x78\x9d\x8d\xff\xfc\xf9\x87\xab\x3f\x78\ -\xde\xe8\x2f\x79\x3a\x2d\xd2\xf9\xe8\x79\x51\xdc\x8f\x7e\x59\x7f\ -\xd9\xcc\xa6\x0f\xe9\xe8\x8f\xf7\x45\xf1\x30\xb9\xbc\x7c\x7e\x7e\ -\x16\x8b\x7a\xa3\xc8\xf2\xbb\xcb\x9f\x46\x9e\xf7\xf9\x87\x1f\xae\ -\x36\x4f\x77\x3f\x8c\x46\x23\x7b\xdf\xf5\x66\x32\x9f\x5d\x8f\xeb\ -\x13\x1e\x1e\xf3\x65\x79\xe0\x7c\x76\x99\x2e\xd3\x55\xba\x2e\x36\ -\x97\x52\xc8\xcb\x71\x7b\xf8\xac\x3d\x7c\xe6\xee\xbe\x78\x4a\x67\ -\xd9\x6a\x95\xad\x37\xe5\x99\xeb\xcd\x8f\x3b\x07\xe7\xf3\xdb\xed\ -\xd1\xee\x69\x9e\x83\xf2\x20\x99\x24\xc9\xa5\xaf\x2e\x95\xf2\xec\ -\x11\xde\xe6\x75\x5d\x4c\x5f\xbc\xfd\x53\xed\x33\x42\xa7\x2a\xdf\ -\xf7\x2f\xed\xbe\xf6\xc8\xf7\x1d\x35\xd9\x58\x82\x3e\xd8\x7f\xdb\ -\xc3\x9b\x0d\x62\x93\x3d\xe6\xb3\xf4\xd6\x9e\x97\x8a\x75\x5a\x5c\ -\xfe\xfc\xaf\x9f\xb7\x3b\x3d\x5f\xcc\x8b\xf9\xce\x65\x1a\x7a\xee\ -\xdd\x75\x8f\xc8\xeb\xe9\x2a\xdd\x3c\x4c\x67\xe9\xe6\xb2\xd9\x5e\ -\x9e\xff\xbc\x98\x17\xf7\xd7\xe3\x20\x14\x32\xb0\x1f\x5d\x6e\xbc\ -\x4f\x17\x77\xf7\xc5\xe1\xd6\xc5\xfc\x7a\x6c\x9f\x5e\x07\xca\x2f\ -\x7f\xef\x0c\x0e\x59\x1d\x50\x5f\x78\xb2\xdd\xe3\x8b\x44\x09\x39\ -\xca\xa5\x0e\xe2\xea\x98\xe6\x15\x26\xf3\x6c\xe6\x9e\xc9\x5e\x32\ -\x5d\x2d\xa6\x8f\x45\xb6\xb2\xa8\xcd\x66\xcb\xe9\x66\xb3\xb8\x5d\ -\xcc\xec\x8f\x6c\xfd\xb0\x7c\xbc\x5b\xac\x7f\xb5\x17\x2d\x8a\x34\ -\xff\x35\x9f\x6e\xdc\x57\x91\xae\x1e\x7e\xfd\xc7\x7f\xff\x22\x1a\ -\x52\x6e\xef\x9b\xbe\x3c\x64\x79\xe1\xbd\xcc\x1f\x2c\x41\xa3\x58\ -\x68\x70\xf7\x6b\xbb\xfb\xb3\xdd\x7f\x35\x4f\x6f\x37\xee\xb8\xea\ -\x0d\xdd\x2f\xfb\x8a\x6a\x3c\xba\x2c\xf7\x6e\x1f\xd8\x3d\xed\xfc\ -\x69\x91\x3e\xb7\xc7\xde\x4c\x37\x15\x15\x47\xa3\x87\xe9\x9d\x1d\ -\x71\xcb\x2c\xbf\x1e\xff\x78\x5b\x7e\xea\x1d\x37\x59\x3e\x4f\xf3\ -\x66\x57\x54\x7e\xf6\x76\x65\x16\x95\x45\xf1\x5a\xf1\x58\x7d\xed\ -\xe6\x89\xdd\x55\xb7\xfb\x7d\x78\xff\xe6\x7e\x3a\xcf\x9e\xaf\xc7\ -\xea\x70\xe7\xd7\x2c\x5b\x5d\x8f\x63\x91\x48\xe3\x87\x32\x3e\xdc\ -\x3d\x7b\xb9\x1e\x7b\x81\x14\x71\x12\x18\x63\x8e\xf6\xba\x07\x4a\ -\x84\x09\x74\x54\x23\xb7\xbb\xf3\x31\xcf\x2d\x17\x7a\xcb\xe9\x6b\ -\x6a\xdf\xaa\xfc\x0a\xea\x83\x36\xf7\xd9\xf3\x5d\xee\xa8\x53\xe4\ -\x8f\xe9\xe1\x99\x6e\x8f\x77\x73\x93\xbd\xc0\xbb\xed\xa0\x78\x74\ -\xfc\xed\x3d\xae\x17\x85\xe5\xa1\x87\x97\xdd\xab\x3e\x2e\xe6\xe9\ -\xe6\x8d\xeb\xba\x7d\xdf\xb8\xf0\xf3\x62\x6d\x89\xe4\xd5\xa3\x5d\ -\x06\x5b\x0c\x0e\x8f\x68\x86\x7e\xec\x1f\x91\xa4\x3e\xc2\xde\xe1\ -\x08\x87\x7a\xd7\xeb\xdb\xbb\x56\xd3\x97\xc5\x6a\xf1\x35\xb5\x74\ -\x91\xe5\xb0\xb3\x43\x6b\x8f\x2a\xd5\x69\xa3\x51\xf1\xea\xd8\xf8\ -\xe5\xd5\x6d\x1b\x37\x1b\x1d\x39\xdd\x06\x1d\x84\xd1\x76\x63\x96\ -\x2f\x2c\x77\xec\x3c\x4e\xb3\xe9\x75\x77\x93\x63\x7a\x2b\xb3\x5f\ -\xca\xf1\x55\x8e\xbe\xf8\x70\xdf\xeb\xee\xbe\x7a\xd8\x5f\x1e\x8f\ -\xfb\x72\xfb\x2a\x2d\xa6\xf3\x69\x31\x6d\x99\xa0\xd9\x62\x99\x46\ -\x37\x6f\x66\xe5\xe7\xe4\x1f\x3f\xff\xf5\x73\x7d\xa3\xab\xd9\x6c\ -\xf2\xbf\x59\xfe\xa5\xb9\xef\x68\xe4\x0e\x98\xde\x64\x8f\x96\xd2\ -\xe3\xcf\xdb\xcd\x57\xf3\xd9\xc4\x4a\x3c\x2b\x09\x3e\x2f\x56\x76\ -\x68\x3b\x61\xf9\x27\x2b\xe1\xae\x2e\xdb\x1d\x7b\x07\x3b\x62\xb5\ -\x17\xad\x2e\x9b\xa7\x95\xe8\x04\xe7\x8f\xf9\x6c\xb5\x70\x27\x5d\ -\xfe\xb3\x58\x2c\x97\xbf\xb8\x9b\xd4\x6f\xbc\x73\xd1\x45\xb1\x4c\ -\xdb\x8d\x57\x97\xf5\xd3\xd7\xef\x76\xb9\xf3\x72\x57\x97\xcd\xdb\ -\x97\xbf\xee\x5a\xaa\x94\x3c\x71\xc4\x38\xcb\xe9\x4d\xba\xbc\x1e\ -\xff\xcd\xed\x1c\x1d\xed\xbd\xcb\xb3\xc7\x87\x55\x36\x4f\xeb\xd3\ -\x1b\x2c\xee\xfe\xd3\x71\x07\xb7\x0d\xde\xba\xad\x9d\x15\x97\xcb\ -\x6c\x0b\x52\x3a\x2b\xb6\x23\xa1\x78\x5d\xda\xcb\x95\x62\x6a\xf2\ -\xa3\x5f\x7e\x3e\xcd\x17\x9b\x07\x7b\x41\x3b\xbb\x2c\x17\xeb\xf4\ -\x53\x66\xc5\xfa\xed\x32\x7b\x9e\x3c\x2d\x36\x8b\x9b\x65\xfa\xa9\ -\xfc\x5e\x2c\x2d\x41\xb7\x9b\x6a\x61\x35\xb1\x82\xdf\x24\xe5\xe7\ -\xd3\xad\x25\xf4\xa4\x96\x89\xe5\x0f\xaf\x39\x48\x56\x3f\xf3\xc7\ -\x65\x3a\x59\x67\xeb\xaf\x56\x16\x7e\xda\x14\x79\xf6\x25\x75\xc7\ -\x1b\x6d\x1f\xa1\xfa\x59\xf1\xed\x44\x0b\x99\xc8\x30\x8a\x8c\x6c\ -\xb6\xbb\xe7\xb2\x6f\x38\xb9\x79\x2c\x8a\xdd\x6d\xff\x97\x2d\xd6\ -\x13\x8b\x74\x9a\x37\x5b\xcb\x1f\x4b\xcb\x82\xc5\x24\x6c\xb6\xcd\ -\xa7\x56\x76\xe6\xb9\x7d\x43\x7b\xf7\x74\x77\x6b\x76\x7b\xbb\x49\ -\x8b\x89\xb2\xf2\x4f\x19\x5f\x6a\xd3\xec\x6c\x1f\x7d\x35\xcd\xbf\ -\xa4\x79\x75\x66\xba\x9e\xda\x97\xf7\x6e\xa6\xb3\x2f\x0e\x9b\xf5\ -\x7c\x32\x9d\x59\x41\xf6\xb8\xb4\x6a\xd0\x1e\x0f\x3b\x92\x07\x41\ -\xdc\x72\x67\x2d\x90\xa2\x44\xb8\x79\x36\x68\x99\xbb\x91\x43\xda\ -\x88\x92\x31\xcd\x76\x8f\x13\xdb\x2a\x12\x7b\x33\xc9\x68\x64\x79\ -\xd8\x93\x81\x30\xbb\x4c\x6c\x31\x7e\x98\x16\xf7\x07\x18\x97\x78\ -\xec\xbc\xf0\x16\xee\x3d\x5a\xab\x6a\xe6\x0f\xc2\xf0\x9c\xb4\xde\ -\x92\x73\xfb\x1e\x96\x48\x7f\x1f\x6d\xa5\xd1\x85\xb7\xfd\x73\xf4\ -\xef\x51\x10\x54\x3f\xe2\x3d\x9a\xba\x57\x54\x49\xd2\x92\xa2\x9d\ -\xa6\xb2\xb5\x7d\xe4\x22\xcb\x3d\x3b\x61\x3d\x4d\x8b\xc7\x3c\xdd\ -\x93\x8c\x5b\x09\x67\x59\xc9\x09\x05\x3b\xb7\xcc\x66\x1f\x9d\x76\ -\x81\x16\xea\x62\x4b\xa9\xd1\x7f\x8d\x8e\xc5\xfe\x0e\xd5\xcc\xf7\ -\x43\x35\x29\x2c\x88\xbe\xd2\xe6\xe1\xe5\x74\xb2\x81\xc4\x58\x8d\ -\x1a\x24\x82\x0b\x15\x8b\xb8\xfc\x6b\x34\xdb\x6e\x0d\x2f\xfc\xb7\ -\xfe\x3e\xa2\x55\x10\xc7\xca\xf3\xdf\x4d\xad\x4e\x06\x91\x8c\x75\ -\x28\xb5\xee\x90\x1e\x91\x08\x2f\x1a\xa5\xde\x51\xc2\xbf\xf0\x42\ -\xa1\xca\xe1\xf1\xd6\xdf\xc7\x94\x30\xe1\x87\xa7\x83\x94\xf5\x68\ -\xe8\x84\x1a\xde\xfb\xb9\xe8\x3b\xa5\x87\x52\x1d\x0d\x0c\x2f\xf9\ -\xf0\xa4\x88\x3b\x1d\x1a\x1f\x9e\x55\xb6\x53\x49\x37\xf4\x08\x3e\ -\x3a\x3d\x64\xdc\x29\x3d\xde\xaf\xb6\xfc\x47\x7a\x94\x3a\xf6\x96\ -\x06\xbd\x4c\xb2\x56\x8c\xa0\xe6\x57\x4f\xfd\x9e\xc8\xb1\x1d\x2a\ -\x38\x9a\x48\x42\x96\x39\x33\x41\x64\x17\x4a\x18\xa9\x0c\x39\x2f\ -\x41\x22\x2c\xbf\x84\xbf\x1b\x52\xb4\x86\x1e\x8a\x20\xbf\x41\xff\ -\x38\x87\x1f\xa4\x91\x40\xe5\xf9\xef\x76\x7a\x40\x54\xf7\x4f\xa7\ -\xf5\x6f\xf2\x75\xf8\x47\x48\x21\x5c\x1c\xc6\x6f\x05\x79\xe3\x73\ -\x15\xed\xa6\xc6\xb9\xe1\x8b\x44\x86\xca\xe8\xb8\xdd\xe5\xfc\x94\ -\x81\x08\x8f\x9c\x1b\x8d\xe8\xd0\x8c\xdb\x79\x71\xdb\x11\x29\xa7\ -\x23\xa7\x1b\x07\x14\x23\xd7\x03\x72\x09\x02\xb9\x50\x44\xc7\xc8\ -\x69\x11\x24\x7e\x18\x47\x8c\xdc\xb9\x79\x6e\xc7\x85\x70\x3a\x76\ -\xb5\x9a\x69\x18\xbb\x3e\xb0\xc3\xcc\x74\x10\xd7\x25\xa2\xc4\x2d\ -\x50\x8c\xdc\xd9\xb9\x2e\xea\x98\xeb\x18\x3b\xb2\xb9\x6e\xc7\x0a\ -\xec\x48\x4f\x09\x84\x8e\x64\xe2\xb3\x9e\x42\x30\xdb\xa1\x74\x15\ -\x73\xe8\x51\x63\xf4\x28\xe7\xbb\xae\x19\xcf\x08\x3f\xb6\xd0\xc9\ -\x84\xa1\x3b\x3b\xe3\x75\xcd\x76\x8c\x1d\xdd\x84\x87\x50\x34\x95\ -\x0f\xe4\x8b\xb0\x61\x4e\x3a\xe1\xc9\xae\x67\x3c\x86\x8f\x08\x3e\ -\x8c\x95\x00\xfa\x32\x59\x57\x21\x63\x3c\x84\xb2\x02\x0b\x4d\xc6\ -\x8e\x6c\xc2\xc3\x48\xcc\xa4\xe2\x3b\xf6\xac\xf4\x36\xe1\x21\xa4\ -\xa6\x92\x80\x99\x40\x8a\x9e\x3b\xdb\x0c\x15\xbd\x04\x10\x9a\x87\ -\x39\xa4\x0d\x80\xc7\x7b\x2a\xfc\xaa\x38\xed\x9e\xe4\xf4\x1b\x67\ -\x27\xe3\x77\xf6\x59\x0f\x8d\x60\x00\xc8\x4f\x46\x90\x6e\xee\x03\ -\xa4\xe7\x69\x00\x2a\xb1\xcf\x7d\xa1\x48\x4a\x9e\x64\xec\x08\xe6\ -\x3e\x8d\x45\x2f\x14\xba\x42\x8b\x21\xec\xc3\xc5\x09\x99\x0d\x28\ -\xf6\x33\x35\x9e\x86\xb1\x3b\x7f\x50\x0f\x32\x1c\xf0\xec\xc7\x10\ -\x12\xc6\xf6\xf0\x12\x14\x54\x60\x94\x60\xf4\x48\x9c\x9d\x50\xa0\ -\xe1\x34\xfc\xb4\x88\x18\x3a\xf2\xd0\x1e\x1e\x37\x88\xef\x22\x11\ -\x96\x64\x92\x8c\xe0\xf9\x23\x7c\x78\xd3\xe1\x80\xf5\x18\x3d\xc2\ -\x18\x1f\x1e\xbd\x7a\xfd\x1a\xfb\x5e\x7a\x0c\xf5\xe1\x35\xd0\xc3\ -\xe9\x8f\x01\xa4\x0a\xf6\xe1\x6d\x3f\xd0\xfb\xc9\xfa\x0b\x89\xe3\ -\xd3\x8b\xcf\x22\x3f\x19\x3d\x92\x80\x1f\x5e\xfd\x84\x0a\xa3\xb0\ -\xe5\x4e\x1a\xf7\xc3\xdb\xee\x46\xc4\x65\xed\x20\x06\xb1\x0f\x10\ -\xb1\xf3\x5f\xab\xab\xec\x4a\xd0\x44\x28\x36\x22\x88\x26\x41\x60\ -\x09\xdf\x69\x08\xba\xe9\x8e\xc1\xeb\x65\x0e\xc4\xea\x2f\x4d\x5a\ -\xe0\x9e\xfe\xd2\x7a\x65\x18\x40\x82\x19\x10\x3b\x01\xb6\x85\xdc\ -\x18\xc3\x5e\xc2\x7f\x40\xaa\x35\x9e\x09\xdb\x15\x63\x0c\xe0\xf9\ -\x63\x80\x68\x39\x0a\xf1\x20\x43\x48\x19\x03\xc4\xba\x42\x0f\xd5\ -\x98\xd6\x31\xc3\xe8\x51\xc4\x00\x8f\xca\x9c\x9e\x8a\xdf\x36\xe1\ -\x85\x41\xec\x27\x1a\x88\x46\xf0\xd0\x90\xe0\x14\x26\xc2\x40\xe0\ -\x59\xf8\x8f\x21\xa4\x8c\x06\xa2\xb5\x18\xb0\x36\x08\x9b\xf3\xb4\ -\xd1\x40\xb4\x39\x01\x32\x22\xa3\x48\x17\x12\x44\x8b\x52\xc8\x27\ -\xca\xaa\x0c\x65\x60\x10\xed\x94\x81\x44\x29\x43\x48\x1a\x1d\x44\ -\x63\xb8\x9f\x54\xc1\xd6\x3c\x69\x5c\x10\x2d\x44\x4d\x5d\xff\x93\ -\x41\xec\x69\x51\x12\x3a\xaf\x09\x86\x90\xa4\x48\xdd\xa0\xb1\x2b\ -\x17\x25\xa1\xf5\x50\xe5\x43\x75\x28\x18\x3d\x0a\x67\xa8\x46\xe7\ -\xc6\xb4\x06\xc3\x2e\x7a\xc7\x3d\x83\x18\xc4\x73\xae\x8b\xc0\x33\ -\x21\x98\x5e\xc8\x30\xd2\x19\x83\x78\x4e\x04\xbd\x32\x0c\x21\x65\ -\x9a\x28\x3e\x51\x14\x5c\x61\xc6\x20\x12\x6a\xa3\xe8\x4c\x35\x5e\ -\x62\xd6\x93\x22\x8a\x36\xe4\x41\x3b\x82\x01\xa4\x53\x63\xce\xa3\ -\x8d\xf2\x32\x17\x42\x35\x06\xeb\x8f\x01\xf3\xb4\x75\xa5\x9d\xd2\ -\x94\x25\x1c\x34\x84\xb5\x1a\x83\xce\xb6\xff\x0e\x8a\x35\x9d\xd6\ -\x1b\xf8\x77\x85\x62\x12\x40\xbd\x1f\x42\xed\xfe\xd3\x00\x82\x81\ -\x1f\xc4\xf6\xff\x03\xb7\x4c\xe2\x0e\xdf\xd7\x66\xb4\x88\x23\x95\ -\x44\x44\x91\x89\x01\x23\xe8\xca\x6d\x41\xb9\x6a\xa7\x61\x68\x0d\ -\x07\x77\x3c\x63\xd8\x9b\x35\x01\xac\x9a\x38\x0d\xc2\x83\x9a\x3f\ -\x8e\x2d\x63\xfb\x21\xa9\x8d\x3d\x68\xf4\x2a\xa3\x02\xd0\x48\x4f\ -\xc3\xcf\xaa\x2e\x7e\xe2\x27\x8a\x41\xec\xa9\xe8\x16\x14\xa3\x47\ -\xb1\xa0\x0c\x84\xd4\xf6\xc3\x6a\xcc\xf9\x59\x30\xf2\xc0\xb2\x07\ -\x78\x16\x64\x10\x89\xe3\x4c\x80\x5b\xad\x03\x5d\xc6\x08\x77\x60\ -\xc4\x82\x94\xca\x43\x83\x66\xc6\xc8\x6a\x9f\x41\x14\x18\x86\xb1\ -\xaf\x62\x5c\x90\x87\xbb\x03\x56\xf4\x85\x0e\x8d\x0c\x89\x9c\xa5\ -\x03\xc6\xb0\x2c\xc7\x85\xb7\xef\x41\x46\x64\x10\x89\x4b\x3a\x9d\ -\x49\xa0\xb2\x8d\x4f\xe8\xf2\x46\x1b\x18\xa0\xab\x8d\xe7\x44\xca\ -\x55\x4d\xe8\x49\x51\x2a\xa1\xa4\xb1\xff\xed\x81\x98\x88\x28\x0e\ -\xfd\x98\xa8\xbd\xc4\x80\x41\x2c\xf3\x48\xa1\xe0\xd3\x69\x20\x46\ -\x42\x5b\x0c\xd9\x59\xd3\x67\x18\x1f\x4a\xa2\x39\x0d\xc5\x44\x84\ -\xd6\xde\x97\x8c\x62\x8f\xf6\x3e\x5e\xa0\x1a\x61\xa7\xbf\x20\xe2\ -\x59\xb1\x57\x83\x1f\x2c\x1e\xdb\x81\x7a\xc3\x33\x23\x65\x6e\x29\ -\xda\xcc\xb0\x16\x85\x54\xb1\x8a\x25\x73\x63\x8f\x69\x19\xf8\x70\ -\x14\xe8\xba\x61\x5e\xa4\xcc\x2f\x45\x83\x28\x03\x8b\x97\x65\xc6\ -\x3e\xd7\x1d\x0e\x18\xc4\x26\xdb\xf4\x2c\xd6\x06\xc3\x48\xab\xa7\ -\x2a\x74\x86\x06\x3c\x33\x86\xf6\x22\x89\x8a\x88\xea\x28\x0c\x18\ -\xc6\x6d\xea\x30\xda\x23\x0e\x1b\x1c\x0c\x24\x71\xe6\x29\x3e\x65\ -\xea\x3b\xc8\x5c\x1c\x70\x06\xb1\xcb\x3d\x45\xf7\x1b\xe1\x86\x3f\ -\xbd\x27\x9f\xa2\x97\x94\x72\xc7\x9f\x9e\xe0\x2b\x93\xde\x80\xd9\ -\x10\xdf\xae\x30\xac\x97\xea\x13\x19\xfc\x03\xc6\xb0\x4a\x7d\x43\ -\x2f\xc3\x80\x3a\x57\x30\x88\xb4\x26\x06\x9a\x13\x0f\x04\x29\x37\ -\xad\xa0\xb6\x2d\xd0\x08\x42\xed\x7f\x18\x46\xd2\xa4\xb7\xae\x9b\ -\xa7\xa9\x7a\xad\x30\x1b\x14\xe7\xe7\x42\xe7\x36\x3d\x4b\x0b\x43\ -\x06\x91\x6e\x2a\xec\xa4\x0b\x5e\x02\xd4\xcf\x67\xc3\x82\x3c\x69\ -\x11\xbd\xc8\x1b\x62\x46\xc6\x91\x32\x24\x7c\x96\x4a\x35\xac\xd3\ -\xd0\x7a\x4b\xd1\x93\x22\x24\x4f\x19\x44\xba\x49\x51\x76\xd0\x9c\ -\x0b\xac\x98\xc1\x46\x3e\xe5\xa4\x18\x75\x50\x07\x33\xf0\xab\x7a\ -\xec\x8a\x61\xec\x37\x8e\x88\x6d\x74\x08\xd6\x3e\x61\xe5\x86\xb4\ -\x08\x11\x7a\x66\x04\xb9\xb1\x3d\x92\x41\x24\x0a\x06\xa3\x3d\xe0\ -\x1c\x49\xec\x39\x18\x8c\x46\xf0\xc0\xf1\xc6\xe5\xdc\x48\xc3\xc0\ -\xe8\xe6\xe9\x90\xa9\xcf\x18\x92\xc6\x82\xd1\x18\x42\x61\x44\x36\ -\x13\x69\x63\xc1\x68\x10\x21\x33\x91\x41\xa4\x8d\x05\xa3\x6d\x0b\ -\x50\x9a\x72\x89\x5a\x3a\xfb\x10\xad\xce\x40\x2e\x37\x46\x90\x62\ -\x2a\x2c\xc3\xc0\x67\xe1\x40\x36\x28\x88\x8b\x9f\x9c\xc5\xf1\xcd\ -\x28\xd2\x46\x83\xd1\x3e\x9a\x7d\xe7\x0c\xdb\x14\xd4\x61\x60\x74\ -\x5e\x14\x38\x17\x32\x8e\x84\x9e\xd2\xae\xb3\xbc\x59\x93\x21\xf3\ -\x8e\x62\x93\x30\x0e\xc4\x27\x03\x47\x31\xef\xb9\x80\xef\x59\x62\ -\x13\x6c\xc9\x93\x07\x7c\xd1\x38\x06\xf5\x56\xc6\xb1\xdf\x88\xef\ -\x59\x96\xab\xb1\x1e\x43\x1b\xf1\xc5\x26\x78\x83\xdc\xc8\x8d\x67\ -\xc8\x23\xbe\x68\x3f\x37\xc7\x0b\xfb\xd2\x6e\xf0\xd1\xc2\x44\x44\ -\x25\x45\xf6\xfd\xdb\xdb\xae\x5e\x04\x08\xde\xde\x96\xe7\x0f\x13\ -\xc1\x32\xe2\x8b\x6e\xa3\x27\xa1\x18\x05\x25\x86\x83\xe6\x42\x17\ -\xf1\x45\xf7\xb0\xdc\xca\xcc\x5d\x08\x69\x4b\xd3\x0c\x18\xc2\x2a\ -\xe0\x8b\xf5\xae\x95\x16\x3d\xe3\xd7\xdf\xba\x5f\x34\x17\x42\x82\ -\xb4\xcd\x2e\x65\x14\x69\xec\x43\xac\x9f\xad\x6d\xdf\xcc\x30\xf6\ -\x15\xf6\xc5\x46\x7d\x61\x9d\x26\xac\xfc\x70\x01\x63\x48\x12\xf5\ -\x45\x2b\xa6\x10\x23\x32\x88\xb4\x41\x5f\x6c\xc0\x49\x1e\x96\x2e\ -\x65\xb3\x82\xb8\x61\x09\x5a\x96\x82\x6c\xc8\x40\x12\x7a\x4b\xb1\ -\xa6\x05\xe8\xa6\x61\x95\x86\xd6\x57\xda\xad\x24\x65\xf4\x68\x83\ -\xc0\xd8\x70\x45\xab\xb7\xb0\x89\xdf\x63\x10\x18\xeb\xf0\x6e\x11\ -\x63\x18\x7b\x8d\x01\x63\x81\x6c\xe3\xf6\xbb\x42\xd5\xaf\xd7\x6f\ -\x33\x90\x24\x31\xe0\xf3\x70\xe3\x56\x5f\x65\x10\x89\x62\xc0\xd8\ -\x92\x18\xdf\x83\xe7\x74\xc0\xa5\xbc\x5d\x09\x68\x74\xdb\xa0\xfe\ -\xcb\xb1\x73\x28\xb8\x83\x36\xb3\x60\x31\x76\x2e\xaa\x4f\xd8\x70\ -\x26\x84\x2c\x45\x74\x43\x3d\x6e\x1a\x44\xa9\xa3\x6a\x58\x43\x3d\ -\x8d\x15\x95\x38\x4c\xc9\x60\x04\xe9\x16\xe1\xe3\xdb\x05\x41\x5c\ -\x28\x85\xd1\xd2\x68\xa2\xe8\xc5\x80\x31\xac\x72\x32\xc0\x65\xf8\ -\x38\x2e\x64\x04\x49\xb3\x32\x12\x70\xcd\x53\x07\x3a\x0d\x37\xee\ -\x22\xf6\xd9\x74\xc0\x8b\x60\x37\x44\x06\x92\x32\x33\x23\x38\x4f\ -\x7f\xd9\x44\xa8\xd0\x7e\x34\xa3\x78\x7e\x76\x2c\x57\xe4\xe3\x61\ -\x84\x98\x91\x61\xa4\x8f\xef\xa3\x7b\x05\xc3\x62\x95\x6d\x7e\x42\ -\x57\x38\xbe\x8b\x1e\xec\x7e\xa3\x9c\x1b\x07\xed\x7e\x4b\x4a\x73\ -\xc3\x87\x3c\xe1\x1d\xf4\x0a\x66\xcb\x9f\xd4\x77\xa3\xbc\x18\xdf\ -\x9d\x14\x6a\x16\xcc\x38\xd2\xda\x8e\x5d\x34\xef\x06\xdb\x05\xb3\ -\xcd\x41\x6c\x3c\x2a\x38\x9f\xb8\x83\x29\xd2\x08\x77\x20\x55\xc5\ -\xf6\x01\x43\xe9\xf4\x1c\xe7\x05\x40\x07\x1a\x95\x50\xd2\x8a\x56\ -\xe6\xc8\x3e\x83\xfe\x8e\x27\xcf\xe2\x97\x63\x7e\xa4\xd5\x75\xb4\ -\xd5\x5a\xd1\xca\x0e\xa8\xb5\xd2\xb6\xf0\x1e\x30\x92\x95\xb6\x53\ -\xb2\xe6\x59\x64\x6b\x20\xa4\xb6\x1f\xa2\x84\xaa\x01\x03\xd9\xa6\ -\x37\x9a\x33\x29\xae\x0c\x25\x75\x6e\x5c\x88\x0f\x24\x73\x66\x55\ -\xaf\x48\x02\x42\x55\x1d\x21\x67\x75\x19\x19\x2a\xa3\x63\xb5\x07\ -\x5d\x08\x15\x66\x50\x22\x0a\xe3\x48\x92\xa8\x38\xc3\x86\xce\x33\ -\x80\x43\xee\xdd\xe0\x81\xd9\xc5\x0c\x1e\x59\x16\x0e\x60\x29\xbe\ -\x1b\x3b\x0d\x97\xaa\x35\x32\xf1\x49\x8a\x83\x0d\x1a\x3a\x97\x7c\ -\x03\xe8\x2f\xef\x06\xcf\x34\xcb\x30\x18\xbc\x7e\xd6\x7d\x03\x06\ -\xe1\x7b\xc1\x53\x12\x6e\x98\xc0\x52\x93\x32\x2e\x8c\x99\xf6\x12\ -\xa8\x3a\x26\x03\x48\xb8\xdc\x14\x31\xf1\x29\x1f\xe8\xfd\xc4\xb2\ -\x93\x74\x99\x29\x10\xcb\x7f\x37\x7c\x01\xa4\x73\x32\x7c\x44\x2a\ -\x27\x46\x6c\x82\xa6\x5e\x2c\x12\xe3\x27\x21\x8b\x4d\x02\xce\xc3\ -\x98\x0b\x6f\x2c\xeb\x66\xf0\x88\xe6\xbc\x18\xc3\x79\x90\xad\x67\ -\xd5\xd0\x28\x70\xe8\x31\x78\x04\x73\x1e\x10\x0a\x44\x19\x7b\x8c\ -\x1e\x9d\x97\x05\x61\xeb\xc1\x5e\x96\x48\x48\xad\x68\x1a\x22\x0c\ -\x1a\xba\x10\xa7\x6a\xc2\x5e\x16\x06\x8f\x2e\x66\x1b\x61\x7c\x64\ -\xa0\xc6\x92\x08\x2b\x34\xb5\xe2\xa0\x10\x89\x9b\xa5\x7b\x2f\x0b\ -\xe3\x47\xb7\x96\x09\xa3\xb3\x80\xcc\x17\x8a\xc0\x4a\x4e\xc6\xee\ -\xfc\xbc\x07\x2e\xae\xc7\x71\x1e\x83\x47\x17\x5d\x00\x16\x2c\xe1\ -\xa2\x0b\x6c\xa8\xd3\x46\x17\x30\x9e\x16\x90\xfb\x18\x40\xb2\x24\ -\xec\xce\x5d\x9c\xac\xb3\x10\xa6\x94\x75\x1e\x98\x65\xf4\x08\xe3\ -\x7a\x08\x95\x13\x8e\xeb\xb1\xb5\x4e\x19\xd7\xf3\x11\x99\x80\x70\ -\x60\x8f\xf1\xa3\xca\xe1\x44\xcd\x7b\xa0\x9b\xd3\x08\x63\x05\x67\ -\xc0\x3a\x0b\x01\xf3\xc5\xd0\xe2\x3f\x9c\xa3\x93\xe1\xa3\xcb\xe3\ -\x44\x99\xeb\xdf\xaa\xb8\xcd\xf1\x21\x8a\x20\x03\xd8\x71\x19\x6b\ -\xf0\x31\x7e\x74\xd9\x9c\x98\xc9\x0f\x56\x5c\x58\x7a\x12\xe7\x73\ -\x76\x6f\x3b\x30\x84\x94\x19\x9d\xd0\xd2\x4c\xac\xd3\x93\x45\x28\ -\x65\x52\x27\x4a\x88\x86\x90\x0a\x4a\x89\xa0\x3b\x7b\xc0\x8d\x0a\ -\xaa\x75\xb5\x80\x1a\x83\x6b\xd1\xcb\xcd\x08\x49\xab\x16\x6a\x74\ -\x6f\xd7\x03\x00\xdb\x2e\x30\x0c\xe0\xf9\xf5\x50\x30\x5d\xa9\x83\ -\x2e\x5a\x0e\x54\xc6\x8f\xa8\xde\x24\xba\x4b\xf6\xa1\x0c\x65\xf4\ -\x68\x42\x47\x60\x4d\xbb\x0e\xb8\x8f\xe7\x40\xda\x46\x84\x68\x06\ -\x04\xfb\xb9\xfa\x4d\x68\x97\x51\xa4\xe9\x44\x88\x56\x65\x0e\x57\ -\xf8\x31\x7e\x84\x9d\xeb\xba\x6d\xe6\x1a\x57\x2e\x52\x2a\xf4\x06\ -\x5d\x96\xa7\x6e\x0b\x82\x2e\xd4\xab\x84\xf6\x13\x3f\xd9\x63\x42\ -\x2d\x94\x31\x86\x4b\xd7\xd1\x58\x83\x06\x5d\xf9\xdc\x4e\x85\x49\ -\x14\x44\x81\x3e\x50\x48\x23\x23\x43\x43\x54\xa5\x77\xc0\xa2\xb4\ -\xec\x59\xa7\xf0\x5d\x40\xd9\xa8\xef\x55\x9a\x6a\x7c\x73\x6c\x48\ -\x25\x8d\x44\x58\xd2\x8a\xa8\x03\xc1\x80\x61\xac\xea\x47\x82\xab\ -\x38\x71\xa6\x3d\x2b\xa5\xc4\x0e\x6e\x83\x37\x2b\x40\x1b\x9f\x81\ -\xa4\xec\xb1\x04\x76\xca\x3a\x09\xc5\xb6\x91\xf9\x0e\x8a\xba\xea\ -\xa7\x1c\x90\xd4\x11\x19\x34\x8a\x95\x7e\x1a\xe1\x99\x31\x11\xaa\ -\x9a\x02\x19\xc6\xde\x62\x16\x60\xd2\x3d\xbe\x4d\x3d\x6b\xa9\xe4\ -\xa1\x0b\x1f\xaf\xa8\x42\xb3\x23\x23\x49\x1b\xc6\x88\xf0\x8a\x2a\ -\x98\x53\xca\x4a\x0e\x69\x20\x23\xc6\x87\x12\xf7\xd4\x1b\xb6\x17\ -\xa9\x43\x18\x0a\xaf\xe0\x18\x21\x8f\xe4\x29\x03\x49\x1b\xcb\x00\ -\xd3\xf3\x4f\x33\x37\x0e\x9a\x64\x07\x82\x9d\xa7\x67\x17\xa2\x65\ -\xcf\x0f\x4e\xc6\xf8\x78\xc8\x95\x6e\xef\x0e\x92\x11\x39\x17\xaa\ -\x2f\x27\x8d\xf3\x97\x26\x78\xb3\x90\x13\x31\xfa\x0f\x5e\x74\xc0\ -\x87\x9c\x88\xd1\x63\xd4\x22\x3c\x8f\x4d\xcf\x59\x6d\xd4\xa1\x0b\ -\x8d\x67\xc4\x37\xaa\x72\x31\x90\x84\xa1\x0b\xb0\x07\x1d\xfb\xd8\ -\x3e\x0e\x8c\x75\x6e\x4d\x74\x1e\x76\x24\xc5\x71\xd0\xab\xd6\xaa\ -\xe0\x45\x84\xd7\x52\xa1\x18\x14\x9b\x19\x94\x71\x0b\x70\xfd\x76\ -\x07\x53\x23\x83\x48\xe3\x62\x53\xdd\xfb\x69\x28\xb5\x9a\x41\x8b\ -\xd1\x2a\xe4\xe4\xe3\x67\x43\x50\x8c\xb2\x72\x4a\x1a\x72\xea\x20\ -\x23\x03\x0a\x58\xb0\xcd\x4f\x1e\x79\x02\xeb\x58\xe2\x53\xa4\x18\ -\x49\xda\xd0\x93\x44\xab\xa7\x20\x8c\xc4\xeb\x69\x06\x0c\xe3\xb6\ -\xcd\x75\xc2\xb1\xa8\x8f\x88\x5f\x80\x76\x9f\xb6\x16\xfd\x0e\x76\ -\x2a\x68\x8a\x7e\x31\x80\x67\x67\x40\xb0\xc3\xfc\x69\xac\xe7\x03\ -\x85\x9d\x19\x43\x3a\xe5\x14\x9f\x0b\x95\x88\xa8\x24\xc9\x5e\x1e\ -\x86\x8a\x45\xec\x78\x93\x2b\x0c\x91\x28\xa6\x1a\xaa\x52\x7a\x1a\ -\x23\xca\x06\x30\x46\xb1\xaf\xa6\x4c\x78\x8f\x29\x28\x4d\xb5\x88\ -\x18\x3f\x92\x58\xa2\x8f\x2f\x33\x74\xa0\x8a\x32\x78\x44\x01\x0b\ -\xb0\xcc\x25\x3e\x7a\xc8\xaa\x0c\x71\xcc\x42\x75\x5e\x6a\x8f\x21\ -\x24\xf4\xcc\xf8\xe8\x39\x10\xb6\x0a\x59\x8c\xd2\x78\x64\x3a\xa8\ -\x2e\x04\x8a\x51\x32\xfc\x06\x5c\xdb\x24\x29\x6b\xcd\x02\xe2\xf3\ -\xa4\xca\x26\xa0\x5b\xd4\xe2\xa7\x42\xfb\x61\x10\x29\xa6\x41\x0d\ -\xe7\x96\x9e\x06\x63\x20\x64\xac\x63\x7d\x28\x46\x19\x46\xb2\x5c\ -\x28\xdf\xd9\x84\x48\x18\xad\x45\xe8\x9b\xd0\x84\x87\xfe\xb5\x24\ -\xf4\x63\x9a\x02\xec\x83\x86\x31\x29\x33\xbd\xc1\x18\xfe\x69\x30\ -\x86\x22\xb4\x28\x9a\xc3\x49\x91\xb9\x91\x50\xa8\x3a\x23\x11\x5d\ -\xbc\x2d\x16\x81\x95\xaa\x31\xcf\x8e\x3d\xba\x69\xea\xea\x0a\x58\ -\x28\x8d\x30\x52\x49\xa5\x58\xb4\xf6\x18\xff\xf5\xc0\xd5\x50\xa7\ -\xa9\x3a\x52\xc4\xca\x21\xd9\x23\x90\x03\x36\x1b\x93\x00\xee\xaa\ -\x7d\x92\xd5\xd8\xe6\x5d\xb0\xe7\xa6\xaf\x85\xa5\xf8\x6a\x7c\x30\ -\x8a\x1c\x84\xa2\xad\xc6\x17\xa0\x7d\x38\x70\x48\x98\x7d\x70\x74\ -\x0a\x4e\x07\x69\xc3\x60\x40\x98\x31\xa4\x09\x47\x45\xf6\xdf\x59\ -\x6a\x9b\xf2\x9c\x48\xbe\x88\xa6\x8b\x95\x89\x20\x33\x32\x94\x84\ -\x29\xc3\x60\xcd\xef\x0e\xb4\x1b\x96\xa8\x54\xb6\xa2\xc2\x67\x67\ -\x80\x12\x95\x11\x24\xb3\xf6\xb5\x2b\xc2\xf7\xb1\x95\xd3\x01\xbb\ -\x6c\xaa\x00\xa3\x82\x72\x15\x3b\x70\xa2\xb2\xe7\x8d\x38\xc4\xd8\ -\x41\x90\x11\x8c\x15\x33\x90\xc4\xd1\xa9\x18\x32\xf8\x4f\xe3\x48\ -\x29\x74\x90\x04\x09\xfb\xc2\x7b\x8e\x4f\x81\x0b\xf6\x3b\x08\x35\ -\x52\x42\x39\xe8\x55\xdf\x89\x17\xa3\x3a\xae\x5b\x15\x15\x74\xdb\ -\x24\x7e\x18\x93\x68\x38\x83\x46\xcf\x31\xa2\xc2\x34\x5c\x97\x11\ -\xb0\xca\x9b\xe1\xa3\x5c\x85\x91\x60\xda\xad\xc3\xd9\x8b\xa1\xf0\ -\xe3\x48\xd2\xb4\x67\x1b\x34\x80\x95\xfb\x1b\xb4\x11\xdf\x8d\x60\ -\x5c\x75\xb9\x08\x19\xc1\x7e\x5c\x6d\xa0\x36\xfa\x6e\xf4\x54\x95\ -\xfe\xcd\xe8\xf5\xe6\xa6\x31\x90\x7d\xff\x6e\xfc\x12\x48\x7d\x39\ -\xc6\xef\x6e\xf7\xf6\x77\x41\xa0\xdb\x31\x53\xe4\xd3\xf5\xe6\x36\ -\xcb\x57\xd7\xe3\xd5\xb4\xc8\x17\x2f\x7f\xf4\x85\x36\xb1\xbe\xf0\ -\xdd\x7f\x22\x0e\xc3\x38\x91\x51\x7c\xa1\x13\x61\x94\x8c\x4d\x74\ -\x61\x84\x7d\x0a\xad\x13\xfd\xd3\xf8\x73\x7d\x95\xbd\x01\x02\x5f\ -\x33\xd6\x26\x49\x4c\xa4\xec\x35\x23\x2d\xfd\x44\xa9\xe0\xc2\xb3\ -\x9b\xe3\xd8\x6a\xd5\x52\xba\xcd\x2a\x91\x2a\x52\xc6\xdd\xf7\xa7\ -\x71\x7b\xb5\xfc\xb5\x74\x4d\xd9\x81\x1a\x05\xc9\xee\x76\x67\x12\ -\x5b\xed\x3b\x8a\x64\x2c\x77\xb6\xbb\xba\xe6\x46\x84\xbe\x4a\x76\ -\x0c\xac\x92\x5c\x9e\x53\x0d\xb4\x8c\x77\x9c\x59\x2d\x85\x8d\x30\ -\x3a\xf1\xb5\xd9\xdd\xd7\x00\x12\x8a\xc8\xd8\x57\xd7\x3b\xbb\x1a\ -\x20\xed\x5d\x5c\x3b\xaf\x60\x67\x57\xcd\x21\xd5\x00\x4f\x93\xe9\ -\x8d\x8c\xde\x1e\xe0\xe9\x53\xba\xce\xe6\xf3\xed\x00\x97\x66\x1e\ -\x59\xcb\x0c\x1e\xe0\xef\x1f\xb6\xdb\x5b\x6d\x07\xc1\xbb\x50\x4a\ -\x54\x28\x75\x94\xc4\x16\x8e\xc0\x28\x5f\xaa\x44\x97\x28\x39\xbc\ -\xa4\x31\x6e\x40\xf8\x61\x62\x74\x10\xc2\x28\xc5\x46\x6b\x65\xcc\ -\x01\x4a\xd2\x5e\xd7\xb7\xdb\x93\x7d\x94\x12\x11\xd9\xa1\x28\x75\ -\x78\x80\x52\xa8\xed\x5d\x7c\x3b\xda\x01\x94\xa4\x16\xbe\x1d\x8e\ -\x3a\x00\x50\xb2\x56\xb5\x7d\x5e\x23\xdf\x46\x29\xfe\x80\x30\x39\ -\xc2\x5a\x96\xb4\xe6\xa4\x1d\xe6\x87\xe3\xdf\x0e\x4c\x99\x44\x3a\ -\x50\xfb\x94\x3d\xae\x7e\x54\x51\x36\xd2\xb5\x8b\x17\xa0\x6c\x58\ -\x3b\x97\x92\x63\xca\xb6\x39\x25\x6f\x53\xd6\x33\xc3\x20\xad\x77\ -\xec\x10\x3f\x3b\x6d\x3f\x26\x65\x03\x61\xfc\xd0\x8a\x4d\x7d\x40\ -\xd8\x40\x68\x1d\xe8\x38\x89\xde\x4b\x58\x53\x52\x2f\x06\xe8\xba\ -\x07\x4e\x43\x50\x79\xa8\x91\x1e\x12\xf4\x23\x90\xf3\x61\x5a\xdc\ -\xef\x3c\x66\x36\x5f\x3c\xd8\x7f\xf6\xbc\x79\x5a\xbc\x3e\xa4\x1b\ -\xab\x80\xbd\xf1\xd9\x7d\xed\xf5\x97\x8d\xd5\x87\xd2\xc9\x2c\x5b\ -\x5b\xcd\xa8\xc8\x72\x6f\xf6\x98\x3f\x4d\x8b\xc7\xdc\xbe\xb4\xff\ -\x06\x81\x76\x36\xdb\xad\xab\x91\xb5\xf1\x44\x50\xc6\x85\x2e\x3c\ -\x69\x27\x80\xd1\xd3\x48\x0a\x39\x0a\x54\xf9\x75\xbf\xfb\xe3\xdf\ -\x23\xd7\x61\x64\xf4\xb7\x91\x17\x68\xa1\x2e\x1a\x87\x75\x3c\x72\ -\x32\xbd\x8a\x05\x5e\x34\x2b\x0e\x03\x7b\x1d\x2f\xda\x39\xda\xdb\ -\x46\x7c\xcb\x0d\xb2\xbe\xa5\x1d\x16\xee\xc8\xea\x5e\xe5\x97\x67\ -\xef\xf6\x75\xb4\x1a\x29\x77\x0b\xa1\xec\x66\x65\x95\x13\x77\x9d\ -\xd0\x5c\x6c\x83\x58\xf6\x61\xdc\xa9\xcb\x91\x5b\xe6\x5f\xde\xf0\ -\xc2\xe5\x05\xb8\x8b\x94\x87\x7f\x3d\x1e\x06\xfb\x3a\xed\x6d\xb6\ -\x2e\xbc\x72\x8f\x25\x7b\xbe\x9a\x2e\xab\x2d\x4f\xd3\x7c\x31\x5d\ -\x17\x7b\xdb\x9e\xcb\xf1\xb8\xb7\xc9\x82\x9b\x16\xb3\xfb\xfd\x6d\ -\x8b\xaf\xe9\x64\x95\xce\x17\x8f\xab\x4f\x4e\x2f\xf5\xee\x8f\xcf\ -\xbb\x9d\xae\x16\xcb\xd7\xc9\x3f\xed\xdc\xfc\xc9\x6b\x00\xf4\xaa\ -\xd3\x1f\xd2\xd9\xe2\x76\x31\x9b\x16\x8b\x6c\x5d\x1d\x51\xa4\x2f\ -\x85\x3d\x6a\x9e\xae\x9d\x7a\x5a\xfe\x9a\x2e\x17\x77\xeb\xc9\xa6\ -\x98\xe6\x45\xb5\x61\x9e\xce\xb2\xbc\x3a\xa7\x1c\x76\x07\x1b\x4b\ -\x0d\xb9\xda\xb3\x4c\x0b\x3b\x68\xed\x7d\xec\x80\x5c\xdf\x35\x8f\ -\xf5\x9c\xe5\xf3\xc3\x6d\xe5\x35\xb6\x0a\x44\x75\xf6\x73\xbe\x28\ -\xec\x21\xde\xca\x8e\xd1\xc9\x32\xf7\x8a\x1b\x6b\x16\xb8\x41\xe5\ -\xee\xbc\x2c\xf2\x4f\x37\xd3\x4d\x5a\xbe\xf6\xe6\x7e\x71\x5b\x4c\ -\x9a\x9f\xf5\x63\xaf\x67\xf7\x96\xf8\xd5\x73\xff\x66\x73\xa2\x66\ -\xc9\xf7\xb2\xf0\x2e\x1b\x56\xfc\xab\xdc\x3a\x2e\xab\xf7\x98\xe0\ -\xfd\xba\xfd\x9b\x6c\x7b\x1a\xff\xb9\x73\x83\x64\x4f\xfc\x55\xfc\ -\x17\x26\xd5\x98\x8e\x2f\x5a\x0e\x99\x8d\x2c\xeb\x5c\x34\x1d\x98\ -\x82\x6f\xfd\x7a\x4b\xdc\x19\x30\x42\xde\x08\xb7\x5b\xc0\xd0\x92\ -\xc2\x84\xb1\x56\xbe\x09\x1e\x5e\x4e\xb7\xb9\xde\x21\xe7\x7e\x13\ -\xc1\xa2\x63\x82\xa9\xba\xb0\xc7\x1e\xc1\xbc\x7d\x1a\x7d\xf3\xe7\ -\x5b\x34\xf3\xfd\x28\x90\x47\xe3\xeb\x5b\x34\x53\xb5\x26\x16\x86\ -\xdf\x13\xcd\x42\x4f\x7d\x63\x98\x79\x81\x95\xaa\xdb\x11\x76\xf8\ -\xfd\xbb\x1f\x4f\x9e\xfc\xc6\x88\xaa\x69\xd3\x0c\x97\xe3\x3f\x06\ -\x30\x74\x00\x02\x05\x49\x9d\x5d\x67\x75\x84\x3a\xfb\x2e\xd8\x0e\ -\xa1\x20\x71\x9f\xf8\x5b\xbf\x06\x30\xa8\x20\xaa\x05\x5b\x96\xdb\ -\xa5\x9a\xb7\x4f\xa8\x6f\xfe\x1c\xc2\x70\x8b\x8f\x08\x17\xcb\x76\ -\xb8\x29\xab\xcc\x0d\x59\x58\x79\x80\xc6\xae\xdb\x71\x55\x91\x67\ -\xd8\xf2\xea\x98\x42\xb1\x6f\xdf\xde\xd5\xfa\x1e\xf6\xd0\x39\x56\ -\x36\xa3\x2d\x59\x86\x3d\x64\x8e\xf5\xa3\x76\x8a\xdb\xba\xd7\x86\ -\x3d\x78\x8e\x15\xef\x76\x3e\xdb\x25\xd1\x47\x1c\x48\x57\x97\x77\ -\xee\x8f\xf2\xeb\xea\x72\xf3\x64\xbf\xfe\x1f\x0e\xa2\x7a\x19\ -\x00\x00\x08\xff\ -\x00\ -\x00\x32\x47\x78\x9c\xe5\x5a\x59\x8f\xe3\x36\x12\x7e\xef\x5f\xc1\ -\x75\xbf\x64\xb0\x2d\x99\x87\x0e\x4a\x76\x77\x1e\x32\x08\x12\x20\ -\x79\xd9\x64\x13\x60\x5f\x06\xb2\x44\xdb\xdc\x96\x25\x83\xa2\xdb\ -\xf6\xfc\xfa\x2d\xea\x96\x6c\x27\x3d\xd3\x93\x60\xbc\x56\xa3\x61\ -\xb1\xaa\x78\x7d\x75\xb0\x48\x71\xfe\xed\x61\x93\xa2\x17\xa1\x0a\ -\x99\x67\x8f\x13\x62\xe3\x09\x12\x59\x9c\x27\x32\x5b\x3d\x4e\xfe\ -\xfd\xeb\xf7\x16\x9f\xa0\x42\x47\x59\x12\xa5\x79\x26\x1e\x27\x59\ -\x3e\xf9\xf6\xe9\x6e\xfe\x0f\xcb\x42\xdf\x29\x11\x69\x91\xa0\xbd\ -\xd4\x6b\xf4\x63\xf6\x5c\xc4\xd1\x56\xa0\x6f\xd6\x5a\x6f\xc3\xe9\ -\x74\xbf\xdf\xdb\xb2\x26\xda\xb9\x5a\x4d\xdf\x21\xcb\x7a\xba\xbb\ -\x9b\x17\x2f\xab\x3b\x84\x10\xf4\x9b\x15\x61\x12\x3f\x4e\xea\x0a\ -\xdb\x9d\x4a\x4b\xc1\x24\x9e\x8a\x54\x6c\x44\xa6\x8b\x29\xb1\xc9\ -\x74\xd2\x89\xc7\x9d\x78\x6c\x7a\x97\x2f\x22\xce\x37\x9b\x3c\x2b\ -\xca\x9a\x59\x71\xdf\x13\x56\xc9\xb2\x95\x36\xa3\xd9\xb3\x52\x88\ -\x04\x41\x30\xc5\x74\x4a\xa9\x05\x12\x56\x71\xcc\x74\x74\xb0\x86\ -\x55\x61\x8c\xe7\xaa\x52\x8c\xf1\x14\x78\x9d\xe4\xeb\xa4\xc2\x02\ -\x00\xdd\xc2\x7f\x2b\xde\x10\xec\x22\xdf\xa9\x58\x2c\xa1\x9e\xb0\ -\x33\xa1\xa7\xef\x7f\x7d\xdf\x32\x2d\x6c\x27\x3a\xe9\x35\xd3\xe0\ -\x39\xe8\x75\x00\x72\x16\x6d\x44\xb1\x8d\x62\x51\x4c\x1b\x7a\x59\ -\x7f\x2f\x13\xbd\x7e\x9c\x30\xc7\x26\x0c\x1e\xb7\x24\xae\x85\x5c\ -\xad\xf5\x98\x2a\x93\xc7\x09\x8c\x9e\x06\xbc\x2a\xf7\x8c\x83\x54\ -\x02\x75\xc3\x61\xcb\xc1\x76\x40\x6d\x82\x14\x71\x99\x5f\xc9\x34\ -\x53\x08\x93\x3c\x36\x63\x82\x26\xc5\x46\x46\x3b\x9d\x6f\x40\x6b\ -\x71\x9c\x46\x45\x21\x97\x32\x86\x42\x9e\x6d\xd3\xdd\x4a\x66\x1f\ -\xa0\x51\xad\x85\xfa\x20\x12\xa9\x3f\x6c\xf3\xf4\xb8\xca\x33\xbb\ -\xc1\xb1\xed\x54\x1c\xb6\xb9\xd2\xd6\x21\xd9\x02\x9a\x9e\x7f\x96\ -\x79\x6c\x98\x4f\xc0\x9d\x27\x62\x59\x18\xa9\x6a\x6a\xa6\x04\x73\ -\xf3\x27\x68\x5a\x72\xdb\x91\x9a\x61\x26\x2f\x52\xec\x3b\xd9\x45\ -\x54\x54\xf0\x21\xb4\x8d\x56\x60\x6a\x69\xae\x1e\x27\xf7\xcb\xf2\ -\xa9\x19\x8b\x5c\x25\x42\x35\x2c\xaf\x7c\x06\xac\x1c\xd4\x21\xf5\ -\xb1\x72\xae\xba\xed\x66\xbc\xa6\xd5\x96\x8f\xcf\xf3\x8b\x75\x94\ -\xe4\xfb\xc7\x09\x1d\x33\x3f\xe6\xf9\x06\x94\x67\x07\x6e\x80\x29\ -\x0e\xc6\xec\xf8\xf0\x38\xb1\x08\x61\x36\xc1\x7e\x3b\xa4\x8e\x0b\ -\x1d\x52\xd0\x1b\xa1\xe4\x0c\x73\xa7\x14\xb8\x9f\x95\x46\x47\x01\ -\xb3\x2a\x7f\x48\x2d\x54\xac\xf3\xfd\x4a\x19\x74\xb4\xda\x89\x71\ -\x4d\xc3\xb1\x16\x8b\xfc\x70\x9e\x0d\xd6\xb0\x33\x8e\x6d\xed\x32\ -\xa9\xc1\x79\xb6\x87\x7e\xab\x3b\x99\x88\xe2\x7c\xc5\xbd\xcc\x00\ -\x04\xab\x36\x63\xc2\x4e\xc7\x5c\x4b\x34\x36\xed\x63\x7e\x41\x02\ -\x86\x76\x82\x73\xcd\x3a\x5e\x66\x6d\xa2\x83\xdc\xc8\x8f\x02\xe6\ -\x4d\xc6\x22\x45\x16\x6d\xad\x55\x9a\x2f\xa2\xb4\x1e\xfd\x53\x29\ -\x31\x1f\xc0\x52\x55\x42\x48\x1f\x8d\x03\x1f\x8e\x86\x36\x69\x88\ -\x06\x4f\x43\x60\xbe\xe7\xb6\xc4\x5c\x49\xf0\x8b\xde\x78\x1b\xd2\ -\xb1\x4f\x32\xee\x0e\xd1\xfa\x50\x1a\x58\x69\x7e\xfe\x98\x77\xec\ -\xf3\x6a\xbb\x9f\x9e\x1a\x7e\x49\xdf\x08\x1d\x25\x91\x8e\x3a\x2f\ -\x68\x28\x34\x08\x70\x33\x33\x88\x9c\xe1\xbf\xde\x7f\xff\x54\x77\ -\x34\x8f\xe3\xf0\xf7\x5c\x3d\x37\xfd\x22\x64\x04\xa2\x45\xbe\x03\ -\x55\x4c\x9e\x5a\xf2\x3c\x89\x43\x88\x75\x10\x03\x9e\xe4\x06\x6c\ -\xdb\x84\xc9\x7f\x42\x6c\x9b\x4f\x3b\xc6\x40\xd8\x80\xd5\x35\x5a\ -\x35\xab\x44\x15\x34\xcf\xae\x1c\x49\xbc\x91\xa6\xd2\xf4\x17\x2d\ -\xd3\xf4\x47\xd3\x49\x3d\xe3\x5e\xa3\x52\xa7\xa2\x23\xce\xa7\xf5\ -\xe8\xeb\xb9\x4d\x7b\x93\x9b\x4f\x9b\xd9\x97\xa5\x55\x87\xca\xc0\ -\x29\x5a\x45\xa7\xd1\x42\x80\x11\xfc\x64\x98\xe8\x84\xbb\x52\xf9\ -\x6e\xbb\xc9\x13\x51\x57\x6f\xd0\x5c\x0d\xcc\x80\x61\x97\xb5\x1a\ -\xd4\x2a\xca\x0a\x83\x0c\xe8\x21\xd2\x4a\x1e\xbe\xc1\x36\xf7\x48\ -\xf9\x3c\x60\xf3\xd7\x15\x89\x0d\x31\x9b\x70\x97\x3e\x50\xdb\x77\ -\xcb\xe7\x5d\x0b\xfe\x5c\x89\x58\x77\x50\x9e\x6b\xd7\x77\x79\x10\ -\x70\x8f\x42\x9b\x9e\x4b\x70\x40\x29\x7b\x80\x35\xc8\xf7\x7d\x86\ -\x99\xe9\xce\xf6\x28\x04\x0c\x8f\x72\xd3\xef\xbb\x49\x4f\xdb\x95\ -\x85\xb9\x8c\x79\x2c\xe8\xd3\xc1\x2a\xa9\xed\x38\x9e\x47\x7c\xd2\ -\xa3\x83\xb8\x69\xd8\xc4\x2d\x0f\xfb\x3d\x86\x91\xf7\x6c\xcf\x63\ -\x1e\x77\x7b\xe4\xc6\xab\xb9\xcd\x21\xd8\xb9\xdc\xe9\xf1\x9a\x98\ -\xe0\xd8\x1e\xf7\xb9\xd7\xaf\x66\xe0\x34\xd3\x06\xcb\x0d\x2c\x6e\ -\xb1\x1e\xab\xd0\xc7\x14\xd4\xb0\x04\x23\x09\xef\x45\x10\x2d\x88\ -\x37\x33\x05\xab\x0e\xc7\x21\xa9\x8a\x6a\x97\xc2\xb2\xf2\x22\xb2\ -\x3c\x49\x66\x85\x56\xf9\xb3\x08\xef\x09\x4f\xbc\xe5\xb2\x2e\x56\ -\x41\x29\xc4\x4d\x11\xec\x4f\xa8\x14\x82\x85\x0e\x9d\x86\x96\x44\ -\x10\xc5\x95\x8a\x8e\x61\x06\x59\x54\x43\x6d\xbb\xea\x59\xe8\x2b\ -\xd4\x14\x50\x87\xb8\x5e\xe0\x83\x3e\x18\xa7\x98\xd0\xc0\x2d\xd5\ -\x64\x14\x46\x38\xe8\x06\x5e\x1d\xb0\x04\xe6\x9c\x57\x93\xcf\x5d\ -\x97\x72\x3e\x52\x13\x18\x0f\xc5\x40\x0f\x46\x6a\x0a\xec\x00\x33\ -\x16\x38\x23\x2d\x11\xd7\x76\x38\x0b\xf8\x19\x25\x01\x0b\x13\xcf\ -\x77\xd9\x19\x25\x11\xdb\x85\xe1\x72\x72\x59\x49\xfe\x15\x6a\x49\ -\x95\xab\xb7\x8b\x7d\x06\x66\x3e\xb6\x7f\xb0\x4b\x12\x78\x2e\xa3\ -\x43\x60\xa9\x6f\xfb\x26\xe9\x72\x86\xb8\xba\x36\x63\x5d\x2e\x36\ -\x04\xd6\xb1\x69\x19\xc3\x83\x53\x60\xcf\xb5\x36\x06\xd6\xe2\xb7\ -\x81\x2c\xfe\xdb\x10\xbd\x4e\x3c\x99\xcd\xb1\x03\xa1\xd2\x1d\xc1\ -\xc9\x6c\xd7\x65\xae\x1f\x78\x7f\x08\x27\xad\xf6\x0a\x03\x5c\xda\ -\x8d\x04\x3d\x83\x23\xb1\x4f\xe4\x87\x38\x5e\x03\x8a\xdb\x48\xaf\ -\x7b\xc3\x6c\x53\x27\x58\xcb\x4d\xb6\x01\x59\x6b\x7c\xe1\xe9\x4f\ -\xbb\xcd\xaf\xf3\x2c\x83\xe9\xe7\xca\x82\x4c\xfb\x25\xd2\x3b\x25\ -\x86\x38\x0f\x00\xea\x1b\x27\xd0\x7f\x46\xb0\xd2\x56\x26\xfd\x60\ -\xc1\x9e\x0c\xfd\x86\x30\x62\x14\x31\xc8\xf4\xd1\x1a\x19\x0a\x83\ -\x60\x5e\x3e\x3e\xaa\x04\x80\xfd\x13\x62\xae\x0d\x99\x41\x00\xf9\ -\x82\xc9\x03\x11\x75\x6c\xb7\x6a\x85\xf0\x5a\xa7\xe8\x05\x59\x9e\ -\xed\xb4\xb2\x35\x99\x95\xc5\x4a\x16\x1b\x19\x52\xf6\x54\xfe\x58\ -\xbd\xbe\x3e\xa2\x0d\xa2\x65\x3d\x8a\x7e\x30\xe3\xa9\x86\x09\xcd\ -\x51\x48\x02\x1e\x08\xe4\x0f\x55\xd7\xbf\x21\x12\xd8\xe5\x90\x1a\ -\x99\x07\x06\xeb\x9a\xa9\x54\xf7\xc3\xd0\x7f\x4e\xcd\xa2\xdc\x64\ -\x85\xf7\xb8\x7c\x66\xcb\x1c\xf6\x11\x25\x07\xd4\x00\x99\x63\x5a\ -\x51\x5e\x22\x25\xa3\x4c\x0f\x68\xfb\xd2\x3e\x07\x24\x50\xb6\xd0\ -\xf1\x7a\x48\x83\xfc\x3e\x84\x5c\x58\xee\x36\xb3\x54\x66\xa2\xde\ -\x4c\x0c\x64\x96\xd1\x46\xa6\xc7\xf0\x17\x58\x96\x67\x56\xa3\x50\ -\xab\xaa\xbe\x15\x71\xbb\xa7\xad\x24\xb4\x38\x68\x90\x4a\x60\xcb\ -\x03\xa6\x58\x96\xa2\x54\xae\xb2\xb0\xd0\x91\xd2\x15\x21\x81\x7d\ -\xa5\xaa\xea\x94\x66\x38\x22\x5a\x66\x24\x15\x27\x15\x66\x7f\x6c\ -\xd5\x49\x7d\x33\xac\x3d\xec\x32\xc7\xb4\xb2\x8d\x36\x77\xa8\x6a\ -\xef\x95\xd4\x20\x62\x99\xfc\x33\x4c\x95\xa5\x17\xb3\x44\x1a\x23\ -\x33\x3d\xa7\x5a\xcd\xcc\x6e\xb7\x9c\x76\xb1\x96\x4b\x1d\x36\xc5\ -\x7a\xd8\x59\xbc\x06\xf0\xab\x71\x27\xb2\xd8\x42\x02\x1b\xca\xac\ -\x14\xc8\x5f\x84\x5a\xa6\xf9\x3e\x7c\x91\x85\x5c\xa4\x62\x56\xfe\ -\xca\xd4\x78\x51\x43\xaa\x5c\xba\x76\xd1\xd7\xba\x74\xdf\x2d\x2b\ -\x7f\x06\x93\xf4\x5d\x48\x79\x38\x9b\x6d\x22\xf5\x2c\x54\x25\x23\ -\xb2\x08\x3a\xb1\x16\x51\xfc\x6c\x72\xec\x2c\x09\xa3\x18\x76\x9a\ -\xbb\x34\xd2\xe2\xb2\x1b\x7f\x9a\x3f\x9a\xba\x2c\xc0\xce\xd0\x1b\ -\xc1\xe2\xeb\x00\x07\x7e\xe4\x57\x9b\x2c\x1f\xc5\x08\xdc\xe8\xc1\ -\xb8\xd2\xe8\xf7\x52\xac\xe3\x60\xd1\x1c\x8f\x81\x69\x22\xdb\xb2\ -\xb2\xf8\x01\x12\xc4\xe6\x8e\xef\x52\xcc\xd9\xf6\xd0\x70\x8c\x36\ -\x60\x42\xe1\x62\xa7\x75\x9f\xf6\xdf\x5c\x66\x61\x19\x01\x3f\x21\ -\xc8\x7d\x16\x3a\xde\x09\x3a\xf5\x32\x3a\x44\xc7\x6a\x60\x39\x79\ -\xb9\x04\x10\xc6\x1e\x23\x27\x96\xf3\x47\x00\xb5\x0b\x95\xf3\x35\ -\x01\xe4\x58\xf4\xb2\x01\x19\x20\x6e\xd7\x74\x2c\x72\xd9\x78\x2a\ -\x64\x6e\xda\x6c\x4e\xe1\x31\x6b\x66\x9d\x07\x74\x4b\xf5\x2d\xdb\ -\xcf\x19\x88\xfc\xc6\xb7\x06\x10\xdd\xb6\x21\xf9\x63\x94\xac\xf6\ -\x74\xf0\xc1\x82\x0c\xec\xb6\x6d\x28\x18\xa3\xd3\x6c\x20\x59\x03\ -\xce\x6d\x5b\xcf\x09\x3e\xf8\x81\x72\x9b\xdf\xb6\xd1\x38\xe3\x3d\ -\x9a\x99\x7b\x09\xcb\x77\x80\x8f\xd9\x3e\x0d\x7f\x6e\xc1\x50\x4e\ -\x12\x9d\x6e\xbd\x6a\x17\xf6\xdb\xb6\x9a\x93\x6c\xb9\x5b\xae\xfa\ -\x08\x5d\x63\xbc\x99\x4f\x57\xf5\x4b\x1f\xab\xfe\x20\x7b\x9b\xbb\ -\x76\x4f\x7f\x61\x48\x9f\x3e\xa0\xcf\x39\xee\xb9\xeb\x34\xf1\x33\ -\xb8\x29\x36\xe7\x26\xf5\x97\xf1\xee\x4c\xba\xd1\x20\x0d\x7a\xe7\ -\x64\xaf\x35\x80\xf3\xe7\x46\x1d\x66\xd7\x09\x55\x0b\xd2\x43\xfb\ -\x86\x7e\x40\xf8\x1c\x64\xfc\xeb\x81\xcc\x1c\x5b\x79\x98\xba\xfc\ -\x6d\xf6\x3e\x40\xa2\x4b\xa3\xea\xd0\xcf\xcc\x69\x98\x79\x3d\x79\ -\x39\x41\x87\xf9\x3e\xb5\xf0\xab\xf1\xf9\x22\x36\x43\x7c\xd7\x21\ -\xae\xfb\xc5\x10\xe8\xe7\x4a\xe5\x62\x17\x83\x1f\x59\xf5\x21\xbb\ -\x7f\xe9\xfd\x14\x0a\xee\x5c\x3d\x10\xed\x61\xe7\x5b\x81\xb0\x5e\ -\xef\x33\x5f\x29\x14\xdd\xf9\xc6\x5b\xa1\x08\xae\x1e\x0a\xef\x4b\ -\x59\xc5\xd5\x3b\x08\xa3\x6f\xc6\x80\x5d\x3b\x06\xc4\x7b\x33\x06\ -\xaf\x4f\x42\xbe\xc6\x25\x73\xd3\x5f\x32\x99\xed\x34\xe7\xc3\xed\ -\x59\x0d\x64\x61\x17\xde\x2f\x2c\xa0\xbd\x5d\xc7\xb5\x03\xd2\x7d\ -\x96\x7b\x13\x20\xe4\xaa\x01\xe9\x27\x55\x84\xb6\x49\x55\xf9\x7a\ -\xf2\x72\x09\x82\xbf\x33\x50\xfc\xb5\x36\xe1\x57\x3e\xf2\x56\x27\ -\x71\xfe\x6f\x00\xe9\x9f\xea\xbe\x01\x90\xcf\xc8\x2c\xfa\x17\x2b\ -\x06\x9b\x6f\x8f\x72\x4f\xc4\xc3\xcd\xb7\xb9\xaa\x05\x20\x04\x0e\ -\xf9\xb3\x55\xa6\xf9\xbc\xf9\x05\x76\x67\xfd\x5b\x04\x2d\xb1\xb9\ -\x09\xde\xc5\xc9\x33\xb7\x37\xce\x5e\x26\x3d\x9e\x23\xaa\xfa\x86\ -\x0d\x66\xbd\x4b\x34\xc3\x5b\x26\x2d\x62\xb1\x54\x71\x2a\x46\x98\ -\x0d\x3f\xea\x7f\xc6\x97\xe5\x0e\xe2\x80\x57\x37\x11\x66\xcd\x21\ -\xc8\x72\x89\xf1\x58\x0f\xae\xe3\xe2\x00\x86\xd6\xfb\xea\x0c\x28\ -\x7e\x14\x2a\x1f\x68\xc6\xf1\x87\x9a\x81\x9d\xad\xe7\x31\x68\xdc\ -\xfb\x2b\x77\xd8\x86\x9a\x2f\x97\x85\xd0\x60\x0a\x9c\x51\x8e\x89\ -\xcb\x4f\x14\xfc\xfa\x4f\xdf\x67\x52\x86\xce\xf5\xcd\x05\xf1\xe6\ -\xa3\x6c\x17\x3a\xcd\xc5\xf0\x53\xaa\xea\x5f\xfc\x69\x6e\x10\xaf\ -\x9e\xee\xe6\xe6\x06\xef\xd3\xdd\xff\x00\x1d\x74\x75\x40\ -\x00\x00\x15\x35\ +\x00\x00\x15\x35\ \x00\ \x02\x08\xb4\x78\x9c\xed\x5d\x49\x73\xe3\x46\x96\xbe\xd7\xaf\xc0\ \xd0\x17\x3b\x46\x48\xe6\xbe\xa8\xa4\xea\x83\x1d\x1d\xdd\x11\xd3\ @@ -23098,121 +482,15086 @@ \xe8\x64\xe8\xac\x18\xd7\x32\xd4\xf7\xcc\x51\xe1\xab\x12\x67\x73\ \xef\xdf\x1a\x7d\xd6\xc1\x86\xe6\xcf\xcd\x70\xf5\x14\xff\xfc\x2f\ \x9c\x72\x9b\x2c\ -\x00\x00\x06\xfc\ +\x00\x00\x0e\x4f\ +\x00\ +\x00\x78\xbb\x78\x9c\xdd\x5d\xed\x6f\xa3\x38\x1a\xff\x3e\x7f\x45\ +\x94\xd1\x49\x33\xba\x98\xf8\x0d\x6c\xb2\xed\xac\xb4\x37\xda\xbd\ +\x93\x4e\xba\xd3\xee\x8e\xee\x33\x4d\x48\x8a\x36\x09\x11\xa1\x6d\ +\x32\x7f\xfd\xd9\xbc\xda\x60\x08\x69\xa1\xa5\x93\x68\x34\xc1\x36\ +\xe0\xe7\xf7\x3c\x7e\x5e\x0d\xbd\xf9\xf9\xb4\xdb\x4e\x1e\xfd\xe8\ +\x18\x84\xfb\xdb\x29\xb2\xe0\x74\xe2\xef\x97\xe1\x2a\xd8\x6f\x6e\ +\xa7\xdf\xfe\xfc\x15\xf0\xe9\xe4\x18\x7b\xfb\x95\xb7\x0d\xf7\xfe\ +\xed\x74\x1f\x4e\x7f\xfe\xf2\xe1\xe6\xf8\xb8\xf9\x30\x99\x4c\xc4\ +\xc9\xfb\xe3\x62\xb5\xbc\x9d\xde\xc7\xf1\x61\x31\x9f\x1f\x1e\xa2\ +\xad\x15\x46\x9b\xf9\x6a\x39\xf7\xb7\xfe\xce\xdf\xc7\xc7\x39\xb2\ +\xd0\x7c\x5a\x0e\x5f\x96\xc3\x97\x91\xef\xc5\xc1\xa3\xbf\x0c\x77\ +\xbb\x70\x7f\x4c\xce\xdc\x1f\x3f\x2a\x83\xa3\xd5\xba\x18\xfd\xf4\ +\xf4\x64\x3d\x91\x64\x10\x72\x5d\x77\x0e\xf1\x1c\x63\x20\x46\x80\ +\xe3\x79\x1f\x7b\x27\xa0\x9f\x2a\xe6\x68\x3a\x15\x43\x08\xe7\xa2\ +\xaf\x1c\xd9\x6d\xd4\xe2\xb4\x0d\xf6\x7f\x35\x4e\x26\xe9\x55\xef\ +\x2e\x30\x3c\x88\x7f\xc5\x09\x79\x83\x75\x0c\x1f\xa2\xa5\xbf\x16\ +\x67\xfa\xd6\xde\x8f\xe7\x5f\xff\xfc\x5a\x74\x02\x68\xad\xe2\x95\ +\x72\x19\x71\xd1\xe3\xd2\x3b\xf8\xda\x7d\xf3\xc6\x14\x2f\x6f\xe7\ +\x1f\x0f\xde\xd2\x3f\xce\xf3\xf6\xe4\xfc\xa7\x60\x15\xdf\xdf\x4e\ +\x09\xb5\x10\x11\x1f\x3b\x69\xbc\xf7\x83\xcd\x7d\x5c\x6d\x0d\x56\ +\xb7\x53\x41\x2b\x76\x79\x7a\xac\xc8\x03\x4a\x07\x64\x17\x5e\xa8\ +\x92\x62\xe1\xc9\x27\x9f\x3b\x4b\xce\x20\x67\xee\x6c\x82\x21\x46\ +\x00\x22\x80\xec\xcf\xc9\x49\x39\x4d\x8b\x55\xb8\x94\x93\x14\xf7\ +\xf0\x77\x81\xf7\x10\x87\x3b\xc1\xf4\xe5\x72\xeb\x1d\x8f\xc1\x3a\ +\x58\x8a\x83\x70\x7f\xd8\x3e\x6c\x82\xbd\x95\x23\x5e\xdc\xd0\x3f\ +\x1d\xc2\x28\x06\xa7\xd5\x41\x20\x69\x53\x68\xec\x3d\x17\xbd\x5f\ +\x44\xf7\xcd\xca\x5f\x1f\xe5\xb0\x94\x30\x79\x24\x28\x63\x49\x9f\ +\xe8\x5d\x07\xdb\xd8\x8f\xd2\x7e\xe5\x52\xcb\x70\xbb\xf5\x97\x02\ +\x1a\x6f\xfb\xe4\x9d\x8f\xd3\x7c\xc0\x31\x3e\x6f\xc5\xd4\x45\x77\ +\x18\x81\x60\x2f\x4e\x3d\x84\xdb\x64\xca\x20\xbd\x92\x60\xf5\xef\ +\xbf\xfd\x52\x8c\x97\xb7\x4c\x3b\x1c\x9b\xa3\xa2\xf9\x74\x3b\x15\ +\xbc\x85\xc4\x29\x5a\x32\xfe\x08\x20\x19\x2e\x1a\xcf\xb5\x61\x39\ +\xc7\xd2\x71\x5f\xb2\xe6\x9b\xb5\xff\x9b\xf7\x20\xf0\xf3\xf6\xbf\ +\x6c\x1f\x0a\x6a\x3a\xd0\x23\x29\x5a\x7d\xf5\x1f\x83\x84\x86\xdb\ +\x29\xb4\x90\xed\x26\x1f\x65\x48\x42\x84\x76\x07\x41\x0c\x99\x4e\ +\xe6\x19\x86\xf3\x94\xc2\xec\x68\xb9\x0d\x0e\xff\xf5\xe2\xfb\xfc\ +\xfc\xfc\xf8\xdb\x3e\x88\xc5\xe2\x7a\x38\xfa\xd1\x1f\x52\x40\xff\ +\xb3\xff\x76\xf4\x35\xa0\xf2\x91\x88\x8b\x85\xec\x88\xaf\x42\xa1\ +\x38\xad\x9c\x90\x80\x0f\x2a\xf3\x3b\xeb\x87\xc9\xda\x5b\xdc\x47\ +\xbe\xd0\x15\x1f\x37\x88\x23\x0e\x38\x02\xe2\x92\xbc\x42\x93\xb8\ +\xa6\xb8\x15\x05\x36\x04\x42\x4e\x95\xce\x9c\x19\x10\xfe\x4d\x69\ +\x2d\xb0\x97\xcd\x25\xf1\xf9\xac\x7b\x27\xbf\x57\xe2\x5b\x48\x1f\ +\x19\xe1\xfd\x91\xdd\x48\xf3\xc8\x28\x06\xa4\x4f\x56\x37\x73\xda\ +\xed\x89\xee\x57\xd3\x99\x14\x3b\xa4\xa2\x33\x71\xa6\x9f\xea\x8a\ +\x93\x92\x9a\xe2\x64\xd2\x6e\x43\x88\x0c\xea\x13\x51\x3a\x8c\xfa\ +\x74\xab\x0c\xd0\x2f\x2e\x48\xb2\x9b\x34\xe7\xeb\xe1\x4a\x98\x5d\ +\xc1\x15\x41\x2e\xa1\xc2\x75\x5c\x31\x72\x2a\xb8\x22\xc8\x24\x0b\ +\xb8\x01\x56\x39\x78\x20\x58\xe5\xf4\x68\x3b\xb6\x84\xb1\xb7\xc7\ +\x96\xda\x6e\x05\x5b\xc8\xec\x44\x68\x59\x1d\x5c\x64\xa3\xaa\xd4\ +\x22\xee\xea\x9c\x28\xd1\x25\x8c\x0f\x83\xae\x93\x30\x9f\xb4\xa3\ +\x4b\x1d\x34\x02\x74\x0d\x92\x5b\x91\xc6\x56\xc9\xe5\x4d\xd8\xbe\ +\xad\xe4\xd2\x31\x48\xae\x5d\xc7\x56\xa8\x5b\x03\xae\x94\x54\x70\ +\x15\x2d\x4d\xb8\x52\x3e\x0c\xae\x82\x5f\x1d\x64\xd6\x1e\x07\xae\ +\x55\x8d\x50\xc3\xab\xb4\x62\xbc\x26\xb3\x2a\x0f\x14\x79\xa5\xe4\ +\x2d\x71\xe5\x23\xd0\x05\x32\x08\xf9\x01\x75\x81\xcd\x47\xe0\x21\ +\x38\xb0\x8a\xad\xb0\x62\x89\x64\x18\xc0\x35\x5a\x31\x2e\x39\x61\ +\x92\x5c\x61\xa5\x13\x0f\x6e\x18\x4b\x96\x5c\xdb\x69\x47\xd8\x81\ +\xa3\x40\x98\x19\x10\xee\xea\x22\xbc\xbe\x77\x50\x0d\xa7\x6a\x98\ +\xba\x23\xc0\x14\xd5\x72\x2c\xef\x1a\x53\xd4\x98\x65\x79\x4d\x4c\ +\x0d\xb1\x42\x47\x05\xfb\xaa\xba\x15\x5d\xce\x5b\x09\x62\x46\xe0\ +\x0f\x38\xa8\xe6\x0f\xbc\xf7\xa8\xd6\xc1\x23\xf0\x07\x1c\xb7\x21\ +\x36\x30\x68\x80\x0c\x71\xb3\x4f\x40\xcd\x72\x9b\x80\x3e\x88\xcf\ +\xc5\x99\x6e\x2c\xcd\x18\xbb\x23\x90\x5d\x66\x57\x35\xec\xfb\xf0\ +\xb9\x2e\xc8\x2f\xb3\xcd\x9a\xf6\x66\x2e\x0b\x06\xc9\xaf\xa2\x80\ +\x21\xab\x17\xab\xc7\xc0\x7f\xfa\x50\x5c\xed\xce\x2b\x12\x7c\x07\ +\x6f\xe3\x27\xc0\xde\x4e\x3f\xae\x93\x4f\xd6\x71\x17\x46\x2b\x3f\ +\xca\xbb\x9c\xe4\xa3\x75\x85\x07\x6f\x19\xc4\xe7\xb4\xee\xf6\x41\ +\xa7\x57\x5e\xb5\xe8\x87\xe6\xfe\xe3\xbd\xb7\x0a\x9f\x6e\xa7\xb8\ +\xda\xf9\x3d\x0c\x77\x32\xa7\x67\x51\x2a\xd6\x82\x5b\xed\x5e\x0a\ +\x3e\x62\x6a\x51\xdb\xa6\x0e\xaf\x75\x8a\xfb\x61\x6c\x11\x61\x59\ +\x0b\x8d\x53\x76\x3e\x44\x91\xbf\x8f\xc1\xd6\x3b\xfb\x82\xa8\xe4\ +\xbf\x7c\xd0\xf1\x3e\x7c\xda\x44\x12\x9c\x38\x7a\xf0\xab\x67\xca\ +\x1e\x70\x77\x17\x9e\xcc\xdd\xab\x70\xf9\x20\xab\x85\xe0\x21\x4d\ +\xa5\x1e\x4e\xea\x55\x1f\x82\x95\x2f\x1a\xd7\xde\xf6\x58\x3b\xf3\ +\xb8\xf7\x0e\x60\xb3\x0d\xef\xbc\xad\xf9\xd2\x4f\xc1\x5e\xa0\x04\ +\x72\x21\x25\x05\x13\xaa\x23\x72\xd1\x64\xb0\x69\x84\x92\x9e\xad\ +\x76\x9d\x9b\xbb\x76\xde\x29\xd8\x05\xdf\x7d\x81\x4c\x0d\xd0\x84\ +\xb4\x2e\xb8\x44\x61\x9c\x4b\x78\x5e\xc9\xd2\xb0\xcd\x85\x3d\x3e\ +\xcb\x62\xe1\xe9\x2c\xdb\xb4\xe5\x2c\x1b\xb0\x9a\x92\x0a\xa3\x60\ +\x13\xec\xb5\x8c\x73\xda\xa4\x65\x9d\x65\x69\x31\xd8\x6f\x4e\x89\ +\x90\x26\x22\xcc\xaa\x7d\x67\xb5\x2f\x5d\x53\x37\xf3\xfa\xe2\x49\ +\xda\x77\x7e\xec\xad\xbc\xd8\x2b\x57\x52\xde\x22\xe6\x56\x50\x16\ +\xad\xd6\x8b\xdf\xbf\xfe\x5a\x68\x87\xe5\x72\xf1\xbf\x30\xfa\xab\ +\x5c\xd0\x72\x80\x77\x17\x3e\x08\x6e\x15\x3a\x44\x56\xfe\x96\x8b\ +\x75\x18\xed\xbc\xf8\x4b\xb0\x13\xeb\x43\x16\x70\xff\x7e\xda\x6d\ +\xc5\x9a\x2e\x3a\xb4\xc1\x12\xac\xf2\xa2\xe9\x65\x23\x3f\x2d\xd0\ +\x1a\x6b\xda\xab\xe5\x2e\x90\x27\xcd\xff\x88\x83\xed\xf6\x5f\xf2\ +\x26\x85\x16\x29\x2e\x1a\xc4\x5b\xbf\x6c\xbc\x99\x67\xb3\xcf\x75\ +\x8d\x42\xdc\xcd\x3c\xa7\x3e\x39\xda\x94\xa8\x68\x2b\xab\x60\xf4\ +\xd6\xbb\xf3\x85\x94\xff\x5b\x76\x4e\xea\xb2\x14\x85\x0f\x87\x5d\ +\xb8\xf2\xb3\xd3\x0b\x34\x85\xde\xac\x18\x02\xa1\xef\xb6\x8b\x8f\ +\xd8\xbe\x5b\x43\xf7\x27\x79\x00\x32\x5d\xb3\x40\x3f\x1d\xe3\x28\ +\xfc\xcb\x4f\xd7\xcb\x02\x5a\x04\xdb\x84\x20\x4d\x94\xe4\x05\x5d\ +\x47\x56\x31\x2a\x16\x80\x60\x0b\x36\x99\xd3\xaa\xf0\x18\x25\x4a\ +\x88\x12\xb1\x52\x6f\x47\x51\xcf\x8d\x04\xf8\xde\x1d\xa4\x9e\x99\ +\x80\xc5\x3e\xdc\xfb\x55\x62\x30\x16\x96\x97\xe5\xad\x82\x97\x7e\ +\xb4\x15\x6b\x33\x5e\xd0\xbc\x6d\xe5\x09\xad\x1a\x45\xde\x59\x3b\ +\xbf\xb8\x78\x0d\x07\xdb\x76\x6d\x20\x8b\x58\x55\x63\x88\x2c\x56\ +\x56\xd8\x35\x28\xb0\xc5\x55\x14\x84\xb2\xa5\x2a\x00\xb6\x25\xcf\ +\x23\xc2\xb1\x1b\x02\x00\x0e\x29\xe5\xfd\x03\xd0\x9d\x7c\x2c\x26\ +\xa1\x9a\xc2\x54\x12\x78\xba\x1f\x81\x98\x80\x70\x87\x00\x82\x62\ +\xe6\xd8\xbd\x03\x51\x83\xc1\x4d\xa5\xb9\xee\xba\x63\x6e\x55\x52\ +\xf0\x27\x29\xfb\x36\xa7\x2e\x81\xc4\x07\x90\x19\xa0\x20\x4a\x16\ +\x63\xa3\x29\x77\x61\xab\x39\x56\xea\x7d\x71\xe4\xed\x8f\x52\xe5\ +\x49\xb3\x22\x7e\x0a\x67\xcf\xff\x94\x2f\x4f\x34\x03\x52\xe8\x08\ +\x75\x88\xf3\xb9\xea\x23\xa6\x78\x52\x4c\x84\x7f\x56\xc5\x33\x75\ +\x93\x16\x42\x21\x7e\xfa\x58\x6e\x72\xf8\x5c\xba\x71\x2a\x7f\x92\ +\x89\x53\x68\xd9\x72\xe2\x25\x35\xa9\x17\xa9\x09\xbd\x82\x4a\x26\ +\x06\x6a\x5f\x06\xa5\xa9\x2b\x87\x9e\x73\x0e\x1c\x04\x5c\x81\x80\ +\x56\xdd\xee\x40\x52\xa3\x88\x10\xcb\x7d\x89\x74\x28\x06\xa0\x06\ +\x0a\x71\x92\x25\x60\xc2\xa4\xea\xb9\xf6\x03\x0c\x07\x04\xb0\x77\ +\x80\x0b\xaf\x03\x30\x9c\xb0\x08\x54\xe0\xf8\x31\x69\x5c\x40\x8e\ +\x95\x68\x51\xde\x2f\x30\x08\x50\xc0\x80\xf3\x8e\x71\xa1\x69\xbb\ +\xdd\xb3\xc0\x00\x28\xfe\xb9\xef\x5a\x62\x32\xc3\xdb\xb3\xc4\x38\ +\x40\xfa\x3f\x44\xdb\x6b\xf5\xce\x90\xc9\xbd\x8f\x9e\x65\x46\xea\ +\x18\xca\x04\x38\xf6\x3b\x80\x06\xd7\xd5\xc9\x60\xaa\x57\x7e\xc9\ +\x3b\xc0\x84\x56\x5d\xb4\x01\x31\x91\xca\x85\x69\x1b\xb6\x46\x80\ +\xca\xcd\x7c\x63\xf4\x36\xa9\x9a\x61\x35\xba\x9a\xa0\x20\x79\x96\ +\x6c\x68\x15\xae\x26\xe1\xb6\xe2\x29\x6e\x1a\x08\x5d\x13\xf9\xad\ +\x10\xaa\xa0\x62\xbc\x5b\x7a\x33\xec\xda\x33\x4c\x2c\x2a\xe5\x18\ +\x7d\xae\x40\x2d\x3c\x64\x9b\x20\x35\x59\x70\x50\x36\xf2\x75\x9b\ +\xc6\x60\x78\xab\xd3\x90\x29\x91\x09\x82\x72\x39\x42\xe4\xcc\x64\ +\xb4\x08\x21\xe3\x68\xf2\x38\x91\x64\x62\x8e\x48\xfe\x03\x4f\xfe\ +\x39\xe1\x52\xa5\x61\x48\xd0\xc4\x91\xce\x13\x71\xa1\xa3\x8e\xbc\ +\x2f\xc6\xda\xc5\x2f\x37\x1b\x40\x45\x04\x54\x1d\x99\xb4\x3d\x4e\ +\x40\xd1\x0c\x8a\xd6\x7b\xc3\xfd\xd5\x91\xf7\xc5\x6f\xac\xb4\x3e\ +\x1a\x5b\xbf\x6b\x24\xb7\x49\x90\x64\x2a\x30\x72\xd5\xbc\x84\xd4\ +\x15\x5d\x48\x6f\x83\x18\x23\x44\x09\xb8\x20\xc8\x79\x8e\x42\x70\ +\x22\xfd\xc5\xf9\x0b\x43\x26\xb9\x17\xaf\x31\x64\x7a\xc9\xa2\x17\ +\xf6\x9d\x51\xc7\x46\x6d\xf2\x95\x43\x86\x10\x72\xb5\x90\xa0\x45\ +\x53\xe5\x0a\x8e\x66\x81\x3b\xad\xe8\x43\x6e\xb9\x48\x88\x1d\xe3\ +\x22\x6a\x55\xed\xc7\x39\x89\x72\x59\x5a\xe7\x6a\x54\xb4\x2f\xa3\ +\x18\xb9\x14\x43\xde\x99\x62\xa2\xd9\xe2\x0a\xcd\xac\x59\xa9\xdb\ +\x48\xa7\x39\x3f\x05\xeb\xe4\x12\x68\xb9\x69\xf3\x25\x0d\x2a\x45\ +\xaf\x93\x0c\xd8\x77\xfe\x6a\xbd\x1e\x4c\x06\x46\x27\x01\x57\xd3\ +\x7b\xad\x04\xbc\x15\xff\x1b\x53\x57\x57\xcb\x3c\x21\x4e\x8d\xdc\ +\x2b\xac\x8f\x41\x23\x61\x87\x94\x4a\x4d\x57\x11\xa0\x56\xa2\xae\ +\x0b\x48\x0e\x96\x93\x86\xef\x50\x2b\x18\x16\x0a\x54\xcd\x67\x61\ +\x94\xe5\xf6\x3a\xa4\xf6\xae\x96\x08\x81\x0f\x29\x93\xbc\xcd\x09\ +\xbb\x84\xc0\x5a\xca\xee\x32\x79\x5a\xe6\x12\x48\x4a\x18\x77\x20\ +\xae\xe6\xec\xca\x44\xe7\x65\x1a\x9f\x23\x03\x26\x1a\x4d\xcc\x75\ +\x90\xdb\xcc\xdc\x7a\xe6\xb6\x0f\xf6\x26\x29\xee\x37\xe7\x2c\xa8\ +\x6d\xbf\xbe\x96\xb7\xb2\x46\xea\x4a\xff\x4a\xd3\x6b\xe7\x32\xbd\ +\x4d\x1a\xf3\xb1\x44\x79\x02\xc7\xec\xdf\xe4\xc8\x91\x59\xee\x2c\ +\xdb\xc4\xe4\x5a\xd4\xf9\x39\x16\xf7\x01\x18\x9e\xab\x79\x86\xf9\ +\x30\x9d\x22\x30\xe6\x69\xb0\x4e\xf8\x78\x7c\x07\x2d\x31\xf6\x7c\ +\xeb\x61\xc2\xc1\x48\x70\xa3\xf7\x40\x30\x33\x86\x52\x69\x2f\xe6\ +\x5c\x0d\x74\x74\xcc\x86\xb7\xb7\x35\xdc\x88\xd6\xd9\x82\x5b\x3b\ +\x72\x8d\xc2\xd2\x50\x22\x51\xf0\x7b\x53\x1f\xcb\xf4\x18\xd6\x33\ +\x96\x89\xd0\x17\x22\x8a\xc6\xb6\xa3\x19\x1a\x8d\xf6\x61\xdd\x0e\ +\xc8\xa0\xe3\x76\x34\x39\xa8\xcd\xe4\x5c\x63\x74\x4a\xb6\x2a\x8a\ +\xb9\x6e\x89\xe4\x6e\x23\xad\xb0\xaa\xe8\xdc\x64\xeb\x84\xff\xc9\ +\x85\x9f\x07\xb1\x49\x66\x58\x1a\x6d\x52\xbd\x54\x7c\x99\x78\x95\ +\xf6\x5a\x5b\x42\x7a\x66\x8f\xe8\x8b\xe9\x1f\x54\x2c\x20\x6b\x17\ +\x0b\xa5\x78\xd7\xa7\x60\xd4\x4b\xce\x23\x96\x0e\x50\xdb\x57\xd7\ +\x87\x7c\xd4\xea\xd0\x17\x10\xa8\xe4\xfb\x18\x2d\x75\x58\xb3\x67\ +\xc2\xec\xe6\x5a\x70\x0f\x9e\x49\x5d\xc6\x9a\x3d\x93\x4c\x9c\x9e\ +\x99\xe2\x60\x95\x34\x78\x26\x56\x48\xd7\xba\x40\x7f\x8b\x42\x17\ +\x5c\x87\xf0\x60\x0c\x51\x40\x07\x5c\xae\x45\xc6\x64\xae\x4f\xaa\ +\xcf\xf2\x52\x68\x3a\x98\xac\xde\x7d\x15\xdd\x4a\xd7\xf7\x33\x35\ +\xaf\xbc\xbc\x47\x5d\x79\x79\xf4\xaf\xed\xe6\x61\x69\xe6\xd2\x61\ +\x8d\x91\x02\xe5\xc6\x48\x61\xe7\xc5\x51\x70\xfa\x04\xd3\xba\x8c\ +\xc3\xc8\x0c\x8a\x2f\x9a\x21\x62\x21\x5b\x7e\x66\xb0\xdb\x62\xeb\ +\x3d\xca\x32\x6b\xad\x6b\xbd\x9c\x7a\xc4\xa5\xa9\x2f\xbb\x22\x50\ +\xd8\xb5\xb8\xbe\x57\xac\x07\x81\x1a\xd2\xd8\x89\xc8\xf1\x82\xb1\ +\xbb\x22\xb3\x52\xee\x09\x53\xe5\x4d\x7f\x50\xe0\xbd\xb8\x3f\xd7\ +\x84\xe5\x39\xdd\x17\x97\xd9\xf5\x1e\x90\xa9\x14\x00\x8c\x2b\x31\ +\x3b\x1b\xb8\x62\xf9\xc1\x74\xaa\x74\x86\xe9\x4b\xcb\x00\x74\x34\ +\x65\x00\xe0\xb6\x64\x45\x7f\xdc\x4a\x80\xe9\x45\x28\x6f\x55\x0b\ +\x50\x6c\x8f\x59\xf2\xdc\x34\x5b\xc4\x78\x22\x79\x63\x88\x6a\x5b\ +\x72\x21\x3f\x6a\xed\xe0\xed\x24\xa6\x3f\x13\xd6\xc0\x65\x93\x86\ +\xb2\x59\x9b\x09\xbb\x22\x73\x9e\xbb\xd5\x9a\x1e\x47\x2c\x2b\xa8\ +\x6a\x49\xf3\xac\xd2\xcb\x86\xb0\x55\x97\x04\xbc\xe2\x0e\x5e\x61\ +\xa7\xea\xc2\x2d\x09\xd4\x4b\x1e\xc5\xee\xce\xa1\x82\xf0\xba\x20\ +\x9b\x83\xf0\x96\x5a\x4f\x16\x1d\xc0\xee\x94\x67\x16\x1a\x69\x89\ +\xf3\x86\x30\x9c\xbd\xcc\x44\x0b\x47\x59\xe1\x89\xc9\x55\xe6\xe9\ +\x24\xed\xdc\x55\xb6\x98\xfc\xd8\x58\x66\xd8\xc5\x7f\x2e\x76\x99\ +\x0f\xd8\xc8\xdc\x66\xd0\x71\xc3\xd0\x1b\x38\xce\x66\x1f\xc9\xcc\ +\x04\xd5\x4b\x42\x59\xb6\x61\x86\xa8\x45\x12\x0d\xfe\x52\x67\xc9\ +\xe6\x64\x3c\xce\x92\xb6\xd7\x71\x1c\xa6\xef\x55\xdc\xa5\x9e\xca\ +\x1f\x3d\x39\x4c\xa0\x2d\xda\xd1\x9d\x75\x45\x0c\x47\xe1\x39\x8d\ +\x50\x80\x5e\xc1\x77\x6a\x53\x74\xaf\x29\x3e\xd4\x51\xe2\x9d\x96\ +\x3a\xab\xfb\xca\xf1\xd9\x85\xb4\x5d\xcb\xce\xa5\x36\x99\x71\x75\ +\xf4\xaa\xb0\x69\xa5\x7a\x53\x31\x31\x55\xfa\x54\x2b\xe2\x99\xec\ +\xc7\x4c\x38\x38\x09\x03\xec\x19\x61\xa9\xc9\xb1\xd5\xed\x7a\x1d\ +\x20\xeb\x5c\xb4\x1c\x40\xc9\xd7\x20\xd7\xc3\xc3\x56\xc8\xdb\x17\ +\x6a\xfb\x52\x6d\x5c\xac\xbd\x63\xf0\x8c\xc2\xad\xdc\xd9\x4f\xdb\ +\x50\x78\x66\xf1\x16\x57\x01\xa8\x2f\xde\x2e\xdb\x37\x09\x96\x2e\ +\xd4\x85\x87\xde\xf2\x07\x65\xd8\x2c\xcb\x55\x23\xd7\xbc\x0d\xb9\ +\xa8\x9d\x27\xbb\x62\x46\x55\x3f\x17\x5f\x38\x00\x1b\xde\x55\x0d\ +\xbd\xf2\x58\xd2\x68\xea\xe8\xc3\x46\xa1\xf6\x75\x3b\xf0\x8c\x71\ +\x68\xb9\xb8\x94\x68\xac\xcc\x97\x0e\x10\x8e\x5e\x95\x63\xb0\xdb\ +\x72\x0c\xd7\x54\x43\x8d\x59\x86\x32\xa1\xa0\x85\xa2\xb5\x47\x2d\ +\xcd\x21\x51\x31\xb1\xfc\x19\xfb\x62\x18\x58\xfa\xf2\x35\x2a\xc9\ +\x2b\x21\x84\xb5\xa3\x0c\x41\x45\x9a\x9a\xc7\x9f\x13\x0a\xb8\x0d\ +\x39\x6f\xde\x3c\x96\x28\xa1\x96\x48\x17\x59\xe9\x2b\xbb\x59\x59\ +\x13\x4a\x63\xbc\x59\x91\x54\x19\xc8\xd3\xbd\xda\xeb\x23\x3d\xef\ +\xb8\xa5\xe6\x15\x6b\x77\x08\x1a\x90\xb1\xfe\x5f\x24\x0f\x18\x87\ +\xae\x8b\x1c\x27\xc1\x54\x1c\x32\x2c\xbe\xc8\x99\x11\x5b\xa0\x4d\ +\x08\x97\x99\x57\xd1\x6a\x33\x07\xb5\x19\x10\x8e\xeb\x4f\x0a\xca\ +\xd7\x29\x03\xf9\xbc\xc9\xed\x34\x91\xfd\xfa\x7b\xcf\x1b\x3d\x25\ +\x08\xc5\xad\x61\x03\x87\x3e\xae\x57\xf2\xab\x33\x09\x5f\xb1\x17\ +\xb8\x85\x8f\xe6\x4d\x8b\xf9\x73\x62\xee\x0c\xe4\x6a\x45\x09\xcc\ +\x75\x3c\xea\x2f\xae\xf8\x87\xa0\xbb\x66\xe8\x9a\x5e\xd8\xfe\xb6\ +\x40\x7c\x51\x26\x52\xf3\x00\xc6\xc2\xa3\x1c\x42\x39\x3f\x66\xcb\ +\x67\x77\xab\xfe\x5a\xb1\xe4\x32\xe7\x87\xb2\x4a\x77\xbe\xec\x4c\ +\x85\x7c\xf9\x91\x4b\xcf\xb6\x9c\x4a\xeb\xb9\x4c\xdf\x3a\x9a\xcf\ +\xfa\x8e\xc0\xc2\xc2\xc2\x50\x80\x07\x81\xab\xfa\x14\x7b\x86\x59\ +\x82\xe4\xbb\x85\x0b\xca\x2d\x12\xa0\x2a\x0a\x2f\x07\xac\x5e\x08\ +\x68\x06\x4c\xf5\x46\x95\x9f\x4d\x5a\xf8\x0a\x1d\xdc\x1c\xab\x52\ +\xc6\x31\x1a\x8d\x06\x26\x6e\xea\xd0\x08\x0d\x5c\x24\xd4\xfb\xd3\ +\xc0\xcd\xfa\xf7\x95\x61\xb8\x66\x8d\xbc\x19\x87\x72\x00\x15\xfd\ +\x3b\x72\xed\x3b\x1a\xa8\x12\xed\x3b\x72\xdd\x3b\x22\xb0\x20\x70\ +\x2b\xdb\xe8\x47\xad\x79\x3b\xeb\xdd\x46\xad\xeb\x79\x92\x8f\x0d\ +\x60\x5f\xa1\x2d\x9d\x2c\x28\x9c\x95\x6f\x06\xe9\x49\x5b\x36\xab\ +\xca\x8e\x73\xbf\x46\x14\x5b\x2f\x99\xca\x9e\x7c\x9e\xc8\x85\xf4\ +\x2a\x7d\x35\x72\x6d\x35\x0c\xd5\x18\x54\x09\x1b\x9b\xe2\x19\x8a\ +\x6e\xfd\x2f\x02\xf5\x43\xf9\x70\xde\x5b\x77\x2d\x02\xc8\xf3\xf4\ +\xc8\x6b\xb8\x6b\xc3\x29\x20\xd0\xe2\xad\x0d\x4d\x76\xcf\xd2\x3c\ +\x98\x3f\xf6\x03\x68\xb8\x01\x1d\x30\xfb\xfd\xeb\xc1\x41\x3d\x2e\ +\x38\x3a\x6d\xd9\xa1\x20\x91\xbd\xd5\xb5\xbe\x3b\xa9\xe9\xa5\x3a\ +\xca\x2b\x5d\xab\xc9\xf6\xfa\x63\x1c\xad\x2f\x74\x2d\xf1\x3a\xab\ +\x05\xe8\xcb\x15\x86\x6e\x6f\xa2\x45\xca\x9f\x21\xd2\xde\x43\x6b\ +\x78\xa6\x2e\xdb\xf5\x64\xfa\x13\x0f\x86\x89\xd7\xb3\xcb\x67\xb5\ +\xb1\x2f\x02\x20\xe6\xca\x7d\x75\x12\xea\xbb\x0d\xb3\xe8\xde\xf4\ +\xee\x74\x03\x09\xc4\xd2\xeb\x3b\xd9\x98\x2e\xcf\xe1\x77\x9a\x3c\ +\x76\x61\xfe\xf7\x61\xeb\x93\xaf\xef\x05\xcd\xf4\x40\xc7\x37\x01\ +\x67\xb2\xa2\xc1\xef\x5a\x8e\x8b\x90\x93\x3e\x7b\x9f\xbf\x56\x5a\ +\x48\xff\x8d\x7c\xad\xf3\x97\x0f\xff\x07\x8a\x92\x51\xeb\ +\x00\x00\x12\x2a\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x34\x20\x28\x35\x64\x61\ +\x36\x38\x39\x63\x33\x31\x33\x2c\x20\x32\x30\x31\x39\x2d\x30\x31\ +\x2d\x31\x34\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\ +\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\ +\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x64\ +\x6f\x5f\x73\x61\x76\x65\x5f\x72\x6f\x69\x2e\x73\x76\x67\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ +\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x36\x2e\x33\x38\x30\x33\ +\x31\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x31\x36\x2e\x31\x30\x34\x39\x38\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ +\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ +\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x37\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ +\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ +\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ +\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ +\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ +\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ +\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x32\ +\x34\x37\x35\x31\x33\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ +\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ +\x65\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x33\x32\x35\x36\x36\x65\ +\x2d\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\ +\x35\x2e\x32\x31\x30\x36\x34\x36\x38\x65\x2d\x31\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\ +\x34\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ +\x33\x2e\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\ +\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\ +\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ +\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\ +\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\ +\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\ +\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ +\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\ +\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\ +\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\ +\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\ +\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\ +\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\ +\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ +\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\ +\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\ +\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\ +\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\ +\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\ +\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\ +\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\ +\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ +\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ +\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ +\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\ +\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\ +\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\ +\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x2e\x35\x35\x32\x32\x36\x39\ +\x35\x2c\x31\x31\x2e\x36\x39\x35\x31\x30\x38\x20\x43\x20\x36\x2e\ +\x39\x35\x35\x30\x32\x35\x35\x2c\x33\x2e\x33\x31\x30\x30\x37\x35\ +\x38\x20\x31\x33\x2e\x35\x39\x30\x30\x36\x35\x2c\x34\x2e\x35\x32\ +\x38\x36\x37\x30\x31\x20\x32\x32\x2e\x32\x39\x32\x35\x35\x36\x2c\ +\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x4c\x20\x32\x34\x2e\x32\ +\x39\x33\x32\x31\x33\x2c\x31\x2e\x39\x34\x31\x30\x36\x32\x34\x20\ +\x33\x30\x2e\x37\x34\x39\x37\x31\x36\x2c\x31\x35\x2e\x39\x30\x32\ +\x37\x20\x32\x39\x2e\x33\x32\x39\x36\x30\x37\x2c\x31\x36\x2e\x34\ +\x39\x37\x36\x33\x35\x20\x31\x36\x2e\x30\x33\x31\x37\x37\x31\x2c\ +\x31\x37\x2e\x30\x36\x38\x36\x35\x31\x20\x31\x39\x2e\x33\x34\x33\ +\x36\x35\x34\x2c\x31\x31\x2e\x35\x31\x34\x35\x34\x38\x20\x43\x20\ +\x31\x33\x2e\x35\x33\x39\x36\x35\x35\x2c\x31\x30\x2e\x32\x32\x38\ +\x34\x34\x33\x20\x37\x2e\x37\x33\x33\x37\x30\x36\x35\x2c\x38\x2e\ +\x39\x32\x32\x37\x33\x39\x32\x20\x34\x2e\x39\x35\x39\x33\x39\x30\ +\x35\x2c\x31\x34\x2e\x32\x30\x36\x34\x31\x34\x20\x63\x20\x2d\x32\ +\x2e\x35\x32\x34\x36\x31\x33\x2c\x32\x2e\x32\x38\x32\x34\x32\x38\ +\x20\x2d\x33\x2e\x39\x39\x32\x33\x38\x34\x30\x33\x2c\x31\x2e\x37\ +\x33\x34\x33\x39\x32\x20\x2d\x32\x2e\x34\x30\x37\x31\x32\x36\x2c\ +\x2d\x32\x2e\x35\x31\x31\x33\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\ +\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\ +\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\ +\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\ +\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\ +\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\ +\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\ +\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ +\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\ +\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\ +\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\ +\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\ +\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\ +\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\ +\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\ +\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\ +\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\ +\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\ +\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\ +\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\ +\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\ +\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\ +\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\ +\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\ +\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\ +\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\ +\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\ +\x34\x31\x33\x33\x33\x33\x34\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\ +\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\ +\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\ +\x2e\x38\x36\x37\x31\x38\x37\x35\x2c\x39\x2e\x33\x38\x30\x39\x31\ +\x34\x31\x20\x43\x20\x37\x2e\x32\x36\x39\x39\x34\x31\x35\x2c\x30\ +\x2e\x39\x39\x35\x38\x38\x31\x30\x37\x20\x31\x33\x2e\x39\x30\x34\ +\x39\x38\x32\x2c\x32\x2e\x32\x31\x34\x34\x37\x35\x36\x20\x32\x32\ +\x2e\x36\x30\x37\x34\x37\x34\x2c\x35\x2e\x31\x35\x32\x34\x37\x32\ +\x32\x20\x4c\x20\x32\x34\x2e\x36\x30\x38\x31\x33\x2c\x2d\x30\x2e\ +\x33\x37\x33\x31\x33\x32\x36\x39\x20\x33\x31\x2e\x30\x36\x34\x36\ +\x33\x33\x2c\x31\x33\x2e\x35\x38\x38\x35\x30\x35\x20\x32\x39\x2e\ +\x36\x34\x34\x35\x32\x32\x2c\x31\x34\x2e\x31\x38\x33\x34\x34\x32\ +\x20\x31\x36\x2e\x33\x34\x36\x36\x38\x39\x2c\x31\x34\x2e\x37\x35\ +\x34\x34\x35\x38\x20\x31\x39\x2e\x36\x35\x38\x35\x37\x31\x2c\x39\ +\x2e\x32\x30\x30\x33\x35\x34\x31\x20\x43\x20\x31\x33\x2e\x38\x35\ +\x34\x35\x37\x32\x2c\x37\x2e\x39\x31\x34\x32\x34\x39\x36\x20\x38\ +\x2e\x30\x34\x38\x36\x32\x34\x35\x2c\x36\x2e\x36\x30\x38\x35\x34\ +\x34\x35\x20\x35\x2e\x32\x37\x34\x33\x30\x38\x35\x2c\x31\x31\x2e\ +\x38\x39\x32\x32\x31\x38\x20\x32\x2e\x37\x34\x39\x36\x39\x36\x35\ +\x2c\x31\x34\x2e\x31\x37\x34\x36\x34\x36\x20\x31\x2e\x32\x38\x31\ +\x39\x32\x35\x35\x2c\x31\x33\x2e\x36\x32\x36\x36\x31\x20\x32\x2e\ +\x38\x36\x37\x31\x38\x31\x35\x2c\x39\x2e\x33\x38\x30\x39\x31\x38\ +\x34\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\ +\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x38\x30\x30\ +\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ +\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ +\x2e\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ +\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\ +\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x34\x2e\ +\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x3d\x22\x31\x38\x2e\x31\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x79\x3d\x22\x31\x39\x2e\x32\x30\x30\x30\x30\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\ +\x34\x34\x34\x34\x34\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ +\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\x98\ +\x00\ +\x00\x1d\x2e\x78\x9c\xed\x58\x5b\x6f\xeb\x36\x12\x7e\x3f\xbf\x42\ +\x50\x5e\x5a\xd4\xa2\x78\x11\x29\x52\xb1\x53\x60\x71\x50\xb4\x40\ +\xf7\x65\xdb\xee\x3e\x16\xb4\x44\x3b\xda\x48\xa2\x57\x97\xd8\xee\ +\xaf\xef\x50\xb6\x2e\x8e\xe3\xed\xc1\x36\x3d\x67\x0f\x5a\x39\x81\ +\xcd\x99\xe1\x65\x3e\x7e\x33\x1c\x6a\xf9\xf5\xa1\x2c\xbc\x67\x53\ +\x37\xb9\xad\x56\x3e\x41\xd8\xf7\x4c\x95\xda\x2c\xaf\xb6\x2b\xff\ +\xa7\x1f\xbf\x09\xa4\xef\x35\xad\xae\x32\x5d\xd8\xca\xac\xfc\xca\ +\xfa\x5f\x3f\xbc\x5b\x36\xcf\xdb\x77\x9e\xe7\x41\xe7\xaa\x49\xb2\ +\x74\xe5\x3f\xb6\xed\x2e\x09\xc3\x5d\x57\x17\xc8\xd6\xdb\x30\x4b\ +\x43\x53\x98\xd2\x54\x6d\x13\x12\x44\x42\x7f\x32\x4f\x27\xf3\xb4\ +\x36\xba\xcd\x9f\x4d\x6a\xcb\xd2\x56\x4d\xdf\xb3\x6a\xee\x66\xc6\ +\x75\xb6\x19\xad\xf7\xfb\x3d\xda\xb3\xde\x88\x28\xa5\x42\x4c\x43\ +\x4a\x03\xb0\x08\x9a\x63\xd5\xea\x43\x70\xd9\x15\xd6\xf8\x5a\x57\ +\x8a\x31\x0e\x41\x37\x59\x7e\x98\x55\xd2\x00\x2a\x3b\xf8\x1f\xcd\ +\x07\x01\x6a\x6c\x57\xa7\x66\x03\xfd\x0c\xaa\x4c\x1b\xbe\xff\xf1\ +\xfd\xa8\x0c\x30\xca\xda\x6c\x36\x4c\x5e\x3d\x35\xa9\xde\x99\x8b\ +\x59\x07\xe1\x09\x01\x5d\x9a\x66\xa7\x53\xd3\x84\x83\xbc\xef\xbf\ +\xcf\xb3\xf6\x71\xe5\xb3\x08\x11\x06\x0f\xef\x85\x8f\x26\xdf\x3e\ +\xb6\x2f\xa5\x79\xb6\xf2\x61\xf5\x54\xc9\x53\x7b\xb6\xc3\xe4\x64\ +\x70\x1e\x38\x99\xef\x3d\xa2\xde\x17\x46\x8a\x54\xc6\x58\xc6\x6a\ +\xe1\x51\x4c\x49\x80\x49\x40\xf8\x97\x7d\xa7\xc1\xa7\x24\xb3\xa9\ +\x5b\x24\xcc\x61\xca\x5c\x77\xad\x2d\x61\x1b\xd3\xb4\xd0\x4d\x93\ +\x6f\xf2\x14\x1a\xb6\xda\x15\xdd\x36\xaf\x7e\xae\x6d\xfe\x73\x6b\ +\x6d\x81\x06\x30\xc7\x99\xcd\x61\x67\xeb\x36\x38\x64\x3b\x80\x54\ +\xc4\xaf\x2a\x8f\x73\xe5\x73\x6e\xf6\x7f\xb3\x87\x95\x8f\x3d\xec\ +\x31\x0a\x7f\xfe\x03\xc8\x97\x99\xd9\x34\x4e\x7f\x72\xdb\xb5\xc0\ +\xef\xd8\xf7\xc2\x5e\x3b\x2e\xda\xad\x38\x73\x63\x4c\xb6\x6b\xdd\ +\x9c\xa0\xf5\xbc\x9d\xde\x02\x0d\x0b\x5b\xaf\xfc\xbb\x4d\xff\x9c\ +\x15\x6b\x5b\x67\xa6\x1e\x54\xa2\x7f\x2e\x54\x16\xb6\x2a\x6f\x8f\ +\xa7\xe8\x39\x8f\x3d\xb8\xe1\x46\x1d\xf5\xf8\x75\x7d\xf3\xa8\x33\ +\xbb\x5f\xf9\xf4\xa5\xf2\x17\x6b\x4b\xd8\x58\xa4\xb8\xc2\x14\xab\ +\x97\xea\x14\x90\x08\x18\x45\x54\x4a\xce\xc8\x95\x16\x26\xa4\x31\ +\x8a\x24\x17\x5c\x5e\x29\xbb\xba\x86\xd0\x0c\x0a\x7d\x34\xe0\x55\ +\xff\x35\x8c\xd0\x3c\xda\xfd\xb6\x76\xe8\x6c\x74\x31\xc2\x33\x76\ +\x75\xaa\x60\xbd\x76\xdb\xd0\xd6\xdd\x95\x1a\x98\xd1\xb9\xa8\x0f\ +\xba\x2a\x6f\x21\xb2\x76\x87\xf9\xb0\x5d\x9e\x99\xe6\xc6\xc0\xfb\ +\xbc\x02\x18\x82\x33\xc9\x09\x1b\x51\x7e\x69\x31\x30\x3e\xc6\xb7\ +\x2c\x1c\x45\x6e\xa8\x8e\xb7\x55\xa5\x3e\xe4\x65\xfe\x8b\x01\xcf\ +\xaf\xd0\x1c\xdd\xaa\x6d\xdb\xb3\xdb\x0d\xf3\xd0\x1b\x2d\x2f\xa0\ +\x39\xf5\xf3\xbc\xf6\xe8\x22\xfc\x70\x74\x32\x7f\x10\x3a\x50\x9d\ +\x80\xc5\x82\x8f\x42\x5b\xe7\x10\x27\xb3\x25\x0f\xa2\xe3\x5c\xe4\ +\xf2\x01\xe4\xe4\xc3\xb4\xb6\x51\xe6\x98\x37\x90\x3d\xbc\x66\x7b\ +\x2f\x2f\x4d\xab\x33\xdd\xea\x89\xfa\x83\x84\x2a\x35\x7a\x02\xa9\ +\x34\xf9\xc7\xfb\x6f\x1e\xce\x13\x2c\xd3\x34\xf9\x97\xad\x9f\x86\ +\xf9\x3c\xcf\x19\xe8\xb5\xed\x00\x7d\xff\x61\x14\x2f\xb3\x34\x81\ +\xe4\x07\x39\xe0\x21\x2f\x81\xd0\x2e\x6f\x7e\x05\xc9\x6e\x19\x4e\ +\x8a\x0b\x63\x07\xce\x34\xe8\x69\xd8\xda\x9c\xb2\xe8\xab\x47\x49\ +\x96\x96\xb9\xeb\x14\xfe\xd0\xe6\x45\xf1\x9d\x9b\xe4\xec\xf1\x6c\ +\xd0\xbc\x2d\xcc\x24\x5c\x86\xe7\xd5\x9f\x7d\x0b\x67\xce\x2d\xc3\ +\xc1\xfb\xbe\xb5\x9d\x50\xb9\x88\x84\x71\x63\x0b\xbd\x36\xc5\xca\ +\xff\xde\x29\xbd\x2b\xed\xb6\xb6\xdd\xae\xb4\x99\x39\x77\x1f\xd1\ +\x34\x69\x3b\x6e\x55\x7b\x2c\x40\xbf\x81\xd5\x27\x77\x1b\xb5\x59\ +\x6f\xcc\xbd\x6b\x04\xe7\xe4\x90\x90\x53\xb3\xee\x0a\xc8\x7d\xcf\ +\xa6\xb2\x59\x76\xdf\xb4\xb5\x7d\x32\xc9\x9d\x24\x9a\x68\x75\x6e\ +\x9e\x02\x24\xc1\x43\xb3\xc8\x2b\x03\xcb\x48\x9a\xff\x74\xba\x36\ +\x73\xe9\xbf\x6d\x5e\x25\x80\x9b\xa9\x07\x69\xdf\x28\x80\xe4\x6d\ +\x12\x0d\xb2\x4c\x43\xfe\xa9\x6b\x7d\x4c\x2a\x38\xe0\xe7\x52\xbb\ +\xd9\x34\xa6\x9d\x66\x1a\x97\x7a\xc1\x67\xe7\x25\x53\x6a\x12\x9e\ +\x03\x98\x72\xa4\xdc\x23\x47\xc5\x10\xb7\x44\x20\x26\x08\x16\x6c\ +\xd4\x1c\xfa\x2c\x27\x79\x1c\x4f\x61\xe1\x58\x1d\x21\x0a\x8f\x98\ +\x86\xa8\x0f\x7d\x96\x65\x02\x4f\x19\x0f\xa4\xc7\xb9\x74\xa0\xc0\ +\x72\xa7\xdb\xc7\xd7\xf0\x9f\xf9\x99\xdc\x45\x4a\x44\x62\x7d\x89\ +\x2d\x41\x11\x13\x6e\xe9\x2f\x31\x5e\x77\x6d\xfb\x56\x08\x5f\xa3\ +\x09\x60\xfe\xdd\x3b\xe3\xc0\xd4\x62\xf4\xde\xfb\xa7\xc7\x30\xe2\ +\xd2\x9d\xee\x17\xd0\x3b\x07\x21\x7c\xc5\x24\x1c\xf3\xbb\xad\x60\ +\xc5\xad\xad\x03\xc8\xf4\xcf\xba\xed\x6a\x73\x91\x4c\xc6\x24\x01\ +\xac\x75\x71\x05\x39\x39\x4d\x7f\x1b\xb9\x3b\x89\xd7\x6c\xb3\xf9\ +\x0d\xf0\x14\x87\x45\xc1\x99\xf5\x09\xd0\xa3\x12\xa8\x85\xe3\x98\ +\x2e\xa8\x42\x1c\x7e\x89\xd8\xfb\x76\xc2\xf4\x35\xf4\xe4\x5f\xe8\ +\x9d\xd0\x2b\xbd\x08\x31\x2e\x95\x8a\xc8\x82\x0a\x14\x29\x86\x01\ +\xbd\xd4\x23\x88\x72\x12\xc7\x4a\x2d\xf0\xad\xdf\x57\xb8\x32\xd8\ +\x82\x00\x7f\x30\xb2\x6f\x11\xb2\x9c\xd1\x3e\xdf\x7c\x02\xd6\x71\ +\x44\x59\xcc\x39\x66\x0b\x0a\x54\x83\xc2\x85\x7b\x31\x22\x84\x53\ +\x22\xb9\x13\x45\x94\x33\x08\x63\x82\x11\x14\xd6\x9c\x47\x0b\xa2\ +\x10\x14\xea\x04\x13\x8f\x40\x43\x22\x49\x99\x24\xd2\x2b\x80\xa9\ +\x84\xaa\x28\x8a\x16\x11\x12\x98\x70\x3e\x08\xf8\x02\xf2\x1b\xa5\ +\x5c\x08\xb7\x49\x92\x50\x2a\x17\x14\xe1\x88\x43\xc9\x0f\xd3\x63\ +\x1c\x13\xc2\x16\x0e\x04\x26\xf9\xd5\x6e\x44\x98\xc5\x6f\xb7\x17\ +\xff\xf7\x34\x56\x08\x90\x95\x92\xb8\x1c\x00\x85\x16\x95\x40\x62\ +\xbc\x08\x46\xbc\x6e\xfc\xbe\x26\xb1\x8c\x70\xf0\xe1\xe9\xe1\xf3\ +\x07\x8e\xf0\x53\xf6\x8c\xde\x04\x39\xf5\x27\x42\x8e\x12\x24\x88\ +\x82\x8b\xe1\x9b\x20\xc7\x3e\x6a\xe2\xfc\x54\xb5\x8e\x3b\x6f\x04\ +\x21\x42\x50\x88\x54\x0c\x47\x4f\x2c\x84\x9c\x9d\x37\x7c\x76\xc6\ +\xbc\xf8\x7d\xe3\xbc\xf9\x13\x02\x07\x21\x4b\xa3\x48\x32\xfe\xfb\ +\x80\xfb\x1f\x62\xf5\x95\xdb\x4d\xff\x8e\x24\xb9\xc3\xfd\x73\x9f\ +\xe5\xcd\x0e\xee\x43\x49\x5e\x39\x14\xee\xed\xb3\xa9\x37\x85\xdd\ +\x27\xcf\x79\x93\xaf\x0b\x73\xdf\x7f\xe7\x85\x73\x6f\x10\x9d\x82\ +\x1d\x4a\x8a\xb5\x8e\x3e\xfc\x7a\x64\xf8\x06\x8f\xc9\x61\xb8\x1e\ +\x21\xc1\x05\x27\x7f\x68\x2e\xf8\xaf\x77\xa4\xfb\x52\xd7\x4f\xa6\ +\x3e\x75\x30\x95\x06\xf7\x82\xb5\x4e\x9f\xdc\x65\xb1\xca\x12\x9d\ +\xa6\x5d\xd9\x15\xba\x35\x17\x5b\xe2\x40\x75\x49\x2c\xe0\xf0\x11\ +\xc1\x54\xd9\x9f\x2f\x55\x0a\xdc\x52\x38\x66\xd7\x97\xaa\x6b\x0d\ +\x5c\x95\x28\x92\x8a\x4a\x11\x4f\x71\xd1\xbf\x85\x72\xf5\x00\xa5\ +\x53\x49\x70\xba\x55\x09\x2c\x15\x27\x74\x92\xf6\xb7\x2a\x12\xc9\ +\x48\xc6\xd3\xa8\x6d\xad\xab\xc6\xdd\xe9\x61\xb1\xee\x55\x88\xf9\ +\x22\xc0\x88\xc6\xf0\xe1\x9c\x7d\xf9\x31\xe8\xc1\x0d\xd4\x4a\xfa\ +\x4d\xe8\x21\x55\xf4\x99\x13\x24\x88\x6f\x50\x84\xaa\x5b\x14\x99\ +\x69\x60\xdf\x25\x14\xaa\x34\x62\x8a\xbe\xa0\x08\x8d\x85\x22\xd1\ +\x67\x4a\x91\x73\xbe\xfe\x8b\x22\x3d\x45\xf8\xef\xa4\x08\x89\xdc\ +\x25\x44\xf1\xf8\x65\x16\x11\x14\x2a\x1d\xf6\x99\x72\x84\x71\x58\ +\x52\xf6\x36\x1c\x91\x7f\x68\x11\xf0\x51\x38\x32\xab\x9d\x2e\x59\ +\x42\x6e\xb2\x84\x5c\xb2\x04\x0a\x5f\x25\x60\xf7\x2e\x59\xc2\x04\ +\x14\x1e\x74\x46\xa8\x37\x64\xc9\x55\xcd\x32\xda\x07\xa9\xa9\x00\ +\xde\xa0\x3f\x03\xa1\xf8\x89\x22\xf2\xca\x5b\xb2\x2b\x73\x58\x44\ +\x40\x90\x64\x4c\xc1\xfa\xc6\x57\xea\xdb\x87\x77\x4b\xf7\x4a\xfb\ +\xe1\xdd\xaf\xcc\x66\xba\x05\ +\x00\x00\x05\x90\ +\x00\ +\x00\x1b\xc7\x78\x9c\xed\x58\xdb\x8e\x9b\x48\x10\x7d\x9f\xaf\x60\ +\xc9\x4b\xa2\x1d\xa0\xaf\xd0\xed\xd8\x8e\xb4\x1b\x45\x8a\xb4\x4f\ +\xbb\x59\xed\x63\x84\xa1\x6d\xa3\x00\x6d\x01\x1e\xdb\xf9\xfa\xad\ +\xe6\x66\x98\x61\x2e\x89\x93\x87\x48\x46\x33\xca\x74\x55\x75\x77\ +\xf5\xa9\x73\xaa\x21\xf3\x77\xc7\x2c\xb5\xee\x54\x51\x26\x3a\x5f\ +\xd8\xd8\x45\xb6\xa5\xf2\x48\xc7\x49\xbe\x59\xd8\xff\x7e\xfa\xe0\ +\x08\xdb\x2a\xab\x30\x8f\xc3\x54\xe7\x6a\x61\xe7\xda\x7e\xb7\xbc\ +\x99\xff\xe6\x38\xd6\x9f\x85\x0a\x2b\x15\x5b\x87\xa4\xda\x5a\x1f\ +\xf3\x2f\x65\x14\xee\x94\xf5\x7a\x5b\x55\xbb\x99\xe7\x1d\x0e\x07\ +\x37\x69\x8d\xae\x2e\x36\xde\x1b\xcb\x71\x96\x37\x37\xf3\xf2\x6e\ +\x73\x63\x59\x16\xec\x9b\x97\xb3\x38\x5a\xd8\xed\x84\xdd\xbe\x48\ +\xeb\xc0\x38\xf2\x54\xaa\x32\x95\x57\xa5\x87\x5d\xec\xd9\xe7\xf0\ +\xe8\x1c\x1e\x99\xdd\x93\x3b\x15\xe9\x2c\xd3\x79\x59\xcf\xcc\xcb\ +\x57\x83\xe0\x22\x5e\xf7\xd1\x26\x9b\x03\xad\x83\xb0\x94\xd2\x43\ +\xc4\x23\xc4\x81\x08\xa7\x3c\xe5\x55\x78\x74\xc6\x53\x21\xc7\xa9\ +\xa9\x04\x21\xe4\x81\xef\x1c\xf9\xb2\xa8\x59\x09\x80\xee\xe0\xb7\ +\x0f\xef\x0c\x6e\xa9\xf7\x45\xa4\xd6\x30\x4f\xb9\xb9\xaa\xbc\xf7\ +\x9f\xde\xf7\x4e\x07\xb9\x71\x15\x0f\x96\xe9\xf0\x1c\xed\x3a\x02\ +\x39\x0f\x33\x55\xee\xc2\x48\x95\x5e\x67\xaf\xe7\x1f\x92\xb8\xda\ +\x2e\x6c\xca\x5c\x4c\xe1\xe1\xb5\x71\xab\x92\xcd\xb6\xba\x6f\x4d\ +\xe2\x85\x0d\xd9\x13\x29\x9a\xf1\x80\x1c\xb8\x09\x68\x17\x9e\xf5\ +\x1e\xe4\x4a\xe2\x62\xab\xc0\x9c\x06\x4d\x4c\x77\x84\x59\xac\x23\ +\x93\x13\x2c\xa9\xb2\x24\xdc\x57\x3a\x83\xaa\x45\x51\x1a\x96\x65\ +\xb2\x4e\x22\x18\xe8\x7c\x97\xee\x37\x49\xfe\x39\xd3\x65\x98\x44\ +\x9f\x2b\xad\x53\xb7\x83\xaf\xdf\x4b\x1d\x77\xba\xa8\x9c\x63\xbc\ +\x03\x10\xfd\x60\xd2\x79\x1a\x3a\xef\x12\x75\xf8\x43\x1f\x21\x39\ +\x0b\x59\x94\xc0\x8f\xbd\x04\xfb\x3c\x56\xeb\xd2\xf8\x9b\x83\x9a\ +\x11\x9c\x34\xb0\x2d\xaf\xf6\xf6\x79\x9b\xa4\x63\xb3\xc6\x39\x76\ +\x15\x96\x0d\x98\x96\xb5\x0b\x37\x40\xbc\x54\x17\x0b\xfb\xd5\xba\ +\x7e\x5a\xc7\x4a\x17\xb1\x2a\x3a\x97\x5f\x3f\x23\x97\x86\xe2\x24\ +\xd5\xa9\x91\x5a\xbb\x76\x77\x0c\xb3\x6a\xef\x47\xd3\xfe\x72\x1b\ +\xc6\xfa\xb0\xb0\xc9\x7d\xe7\x57\xad\x33\x58\x15\x8a\x24\x03\x81\ +\x1e\xb8\x23\x40\xc2\xc1\xc8\xc5\x08\xf9\x3e\x7b\xe0\x35\x09\xf9\ +\x6e\x40\x19\x97\xfc\x81\x73\x5f\x14\x20\x46\x27\x0d\x4f\x0a\x4e\ +\x55\xff\x83\xdb\xa0\x72\xab\x0f\x9b\xc2\xa0\x53\x15\x7b\x75\x7f\ +\xa6\xf1\x38\xab\x95\xa9\xc2\x94\x1b\xb8\xb1\x37\x32\x77\xf6\x79\ +\x52\x81\x94\x76\xc7\xe1\xaa\xfb\x24\x56\xe5\xf4\xc4\x32\x0f\x77\ +\xce\x26\xd5\xab\x30\x9d\x0e\x38\x24\x39\xa0\xe4\xb4\xac\xc7\xb4\ +\x2f\xc2\xfd\x88\x4e\x02\x01\x12\x8f\x44\x18\x06\x3d\xe2\x3a\x3d\ +\xee\xca\xc2\x63\x92\x25\x5f\x15\x00\x83\x1f\xa0\x62\x4e\x36\x84\ +\x65\x59\x07\xcc\x47\xb0\x35\x73\x2c\xab\x3a\x19\xb9\x1f\x4f\xc6\ +\x66\x77\x46\x83\xb7\x31\x10\x29\x83\xde\xa8\x8b\x04\x54\x34\x48\ +\xb7\x33\x9d\x86\x26\xd3\x1c\xa0\xb7\x1f\xcf\x79\xf5\x36\xc3\x81\ +\x4e\x07\xde\x43\x21\xd4\xf6\x4c\x55\x61\x1c\x56\xe1\x59\x15\x9d\ +\x05\x72\x41\xdd\x49\xa0\xaf\xce\xfe\x7e\xff\x61\xd9\x6e\x30\x8f\ +\xa2\xd9\x7f\xba\xf8\xd2\xed\x67\x59\x26\x20\x5c\xe9\x3d\x20\x6f\ +\x2f\x7b\xf3\x3c\x8e\x66\xd0\x09\xa1\x43\x2c\x93\x0c\xb8\x6e\x9a\ +\xe8\xef\xd0\xf9\xe6\xde\xd9\x31\x0a\x36\xe0\x9c\x17\x6d\x96\x2d\ +\x54\xd3\x52\x27\xef\x95\x38\xca\x12\x33\xc9\xfb\xa7\x4a\xd2\xf4\ +\xa3\xd9\xa4\x3d\xf1\x60\xd1\xa4\x4a\xd5\xd9\x38\xf7\xda\xec\xdb\ +\xb3\x79\x83\xc3\xcd\xbd\xee\xf4\xf5\x68\x73\x46\x65\x24\x92\xbe\ +\xb0\x69\xb8\x52\xc0\xd8\xbf\x8c\xd3\x7a\xc8\x8b\x42\xef\x77\x99\ +\x8e\x55\x3b\xbd\x47\x53\x45\x55\x5f\xaa\xea\x94\x82\x7f\x0d\xd9\ +\xcf\x5e\x21\xc4\x79\xcc\xde\x9a\x81\xd3\xf6\x8d\x19\x6e\x86\xc5\ +\x3e\x85\xb6\x78\xa7\x72\x1d\xc7\x6f\xcb\xaa\xd0\x5f\x94\x89\x37\ +\x4f\x3b\x6c\xc4\x31\x83\x7e\x41\x7c\xe9\x0b\xcc\x3b\x3b\x20\xa4\ +\x8a\x14\xd8\x5b\xcd\x58\x67\x8b\x43\xe8\x3b\x45\x11\x9e\x66\x39\ +\xbc\x05\x74\xd6\x7e\xcf\x11\x31\x4d\xba\x40\x06\xda\x1b\x3b\x15\ +\x42\xc7\x13\x34\x90\xa2\x77\x74\xe2\x93\x2e\xe6\x52\x62\x4c\x7a\ +\xcf\xb1\xbe\x94\x90\xa4\x18\x9f\x09\x0e\xfc\xe4\xd0\x15\xb9\x4f\ +\xb8\xec\x8d\x85\x61\xb2\x4b\x09\x46\x94\x9f\xf3\x28\xea\x06\x4b\ +\x05\x97\xe8\x6c\xac\x8a\x30\x2f\x0d\x8d\x80\xb4\x61\x55\x24\xc7\ +\xd7\xb0\x1a\x65\x02\x21\x2a\x6f\xe1\xae\x85\xf7\x02\x2a\x19\x11\ +\xb7\xc8\x65\xc2\x27\x84\x0b\x1f\xfe\x14\x01\x15\x94\xe2\xe0\x16\ +\xdd\xa2\x37\xe7\x83\x3e\x75\x2f\x4d\x05\xf4\x77\x53\xc7\xac\x51\ +\x59\xbf\x21\x35\xee\x43\x72\x70\x32\x93\x1a\xe1\x58\x30\x4c\xc6\ +\xa9\x35\x67\x67\x01\xa3\x98\x06\xcf\xe0\x04\xa1\x24\x70\x03\x22\ +\x98\xc4\x43\xf0\x31\x71\x05\x27\x80\xc1\x44\xad\x02\xc6\xc0\x13\ +\x3c\x5f\xde\x8e\x0c\x34\x18\xe0\x72\x8f\xc0\x61\x08\x84\xbc\x90\ +\xc0\x88\x63\x2a\x69\x70\x11\x81\x27\xab\xf2\x0b\x89\xcd\xb9\x54\ +\x6e\x98\xbb\x12\xc2\x7d\x3a\xe4\x06\x93\xf0\x62\x27\xc5\xb4\xda\ +\xae\x62\x7b\x91\xd8\xee\x69\x4d\x0a\x41\x30\x1b\x22\xef\x70\x60\ +\x30\x1c\x9b\xb3\x1f\x25\x36\xc7\xbf\xca\xed\x27\xcb\x8d\x5f\x28\ +\x37\x60\x02\x61\xe6\xbb\x63\xa8\x36\xec\x06\x82\x8b\xa1\xb2\xae\ +\x72\xbb\x48\x6e\x60\xe4\xe6\x19\x22\x2f\x00\x00\x22\xc8\xe0\xbe\ +\xbb\x54\x6d\xf4\xaa\xb6\x9f\x7d\xb9\x0d\x3a\xda\xf7\xe9\x4d\xba\ +\x94\x49\x8e\xe5\x58\x70\xc4\xc5\x82\xa2\x60\x52\x70\x4c\x5e\x15\ +\xf7\x12\xc5\x0d\x70\x6a\x24\x47\x18\xe7\xfe\xf8\x86\x93\x00\x01\ +\x16\x1c\xf9\x3f\x4c\x73\xbe\x43\x7e\x7d\xd5\xad\xd7\xf5\xde\x17\ +\xe5\x5a\x57\x93\xf8\x98\xfc\x48\xd1\x01\xc4\xf2\xe5\x82\xc3\xc0\ +\x70\x44\x08\x1b\x09\xce\x01\x6d\x31\xe0\x1c\x1b\x7d\x6c\x48\xd7\ +\x27\x82\x0a\xc9\x26\x7b\xf7\xfd\xef\x37\x0e\x62\xf1\x7d\xfe\x3d\ +\x92\xf3\x29\xc2\x18\x9b\xbf\x82\xc0\xe7\x88\x31\xda\xd0\xfa\x17\ +\x2f\x8a\xf3\x02\x9d\x3c\x5d\x16\x2c\xe1\xb3\x9a\x71\x46\xc7\x65\ +\xe1\x44\x42\x01\xfc\xc9\xb2\x5c\xab\xf2\x5c\x55\xbe\xe1\x6d\x70\ +\xba\x2a\xf0\x0d\x4e\x7d\x86\x25\x19\x56\x85\xba\x9c\x06\x02\x07\ +\xcf\xbc\xe8\x5c\xab\xf2\x98\x56\x9c\xcb\x9b\x18\x75\x7d\x11\xc0\ +\xe5\x35\xae\x0b\xa3\x82\xf9\x83\xd0\xa7\x5e\x1b\x7e\x5a\x61\xe6\ +\xde\x66\x79\x33\x37\xff\x47\xba\xbc\xf9\x1f\xda\xce\x98\x81\ +\x00\x00\x09\x06\ +\x00\ +\x00\x5f\x8b\x78\x9c\xe5\x5c\x5b\x8f\xa3\x38\x16\x7e\xaf\x5f\x91\ +\x4d\xbd\x74\x6b\x0b\x62\x8c\x09\x76\xba\x52\xf3\xb0\xad\x19\x8d\ +\xb4\xd2\x4a\x3b\xdd\xda\xc7\x96\x03\x26\xc5\x36\x81\x08\x48\x25\ +\x99\x5f\xbf\xc7\x04\x02\x04\x8c\x7a\xb5\xb1\xb4\xe5\x4e\xab\x55\ +\x85\x8f\xaf\x9f\xcf\xe5\xe3\xc4\xe5\xe7\x5f\x4e\xbb\x64\xf6\x26\ +\xf2\x22\xce\xd2\xf5\xdc\xb1\xd1\x7c\x26\xd2\x20\x0b\xe3\x74\xbb\ +\x9e\x7f\xfd\xf2\xab\x45\xe7\xb3\xa2\xe4\x69\xc8\x93\x2c\x15\xeb\ +\x79\x9a\xcd\x7f\x79\x79\x78\xfe\x8b\x65\xcd\xfe\x96\x0b\x5e\x8a\ +\x70\x76\x8c\xcb\xd7\xd9\xef\xe9\xf7\x22\xe0\x7b\x31\xfb\xf0\x5a\ +\x96\xfb\xd5\x62\x71\x3c\x1e\xed\xb8\x2e\xb4\xb3\x7c\xbb\xf8\x38\ +\xb3\xac\x97\x87\x87\xe7\xe2\x6d\xfb\x30\x9b\xcd\x60\xdc\xb4\x58\ +\x85\xc1\x7a\x5e\x37\xd8\x1f\xf2\xa4\xaa\x18\x06\x0b\x91\x88\x9d\ +\x48\xcb\x62\xe1\xd8\xce\x62\xde\x56\x0f\xda\xea\x81\x1c\x3d\x7e\ +\x13\x41\xb6\xdb\x65\x69\x51\xb5\x4c\x8b\xc7\x4e\xe5\x3c\x8c\xae\ +\xb5\xe5\x6c\x8e\x6e\x55\xc9\x61\x8c\x2d\x10\x5e\x60\x6c\x41\x0d\ +\xab\x38\xa7\x25\x3f\x59\xfd\xa6\x30\xc7\xb1\xa6\x18\x21\xb4\x00\ +\x59\x5b\xf3\xc7\x6a\xad\x4e\x09\x40\xa1\x9c\x4c\x25\xed\x8e\x0e\ +\xf0\xef\xe1\xff\xb5\x41\x53\x60\x17\xd9\x21\x0f\x44\x04\x2d\x85\ +\x9d\x8a\x72\xf1\xf9\xcb\xe7\xab\xd0\x42\x76\x58\x86\x9d\x6e\x1a\ +\xf4\x7b\xe3\xf6\xb6\x24\xe5\x3b\x51\xec\x79\x20\x8a\x45\x53\x5e\ +\xb5\x3f\xc6\x61\xf9\xba\x9e\xbb\xc4\x76\x5c\xf8\x78\x55\xe1\xab\ +\x88\xb7\xaf\xe5\x6d\x69\x1c\xae\xe7\xb0\x56\xcc\xe8\xe5\xb9\xa3\ +\x4a\xce\xa5\x42\xdd\xf1\xea\x2a\x41\x36\xc3\xb6\x33\xcb\x1d\xcf\ +\xf5\x2f\x75\x9a\x25\xac\xc2\x2c\x90\x73\x82\x2e\xc5\x2e\xe6\x87\ +\x32\xdb\xc1\x1e\x07\x41\xc2\x8b\x22\x8e\xe2\x00\x1e\xb2\x74\x9f\ +\x1c\xb6\x71\xfa\xed\xcf\x2c\xdb\x7d\x2b\xb3\x6f\xfb\x5c\xbc\xc5\ +\xe2\x68\x37\x80\x5f\xc7\x13\xa7\x7d\x96\x97\xd6\x29\xdc\x03\x90\ +\x4b\x7f\x54\x78\x6e\x84\x2f\x20\x7d\x0e\x45\x54\xc8\x5a\x97\x55\ +\xc9\x27\x58\xd6\x45\x06\x52\xd8\x24\xc1\xf3\xdf\x72\x1e\xc6\xa0\ +\x9a\x97\x7a\x97\x9a\x7d\x89\xeb\xfb\xac\x6e\x03\xad\x8a\x32\xdb\ +\x37\x75\x61\xa1\xe5\x39\x91\xab\x83\x42\x2b\xc8\x92\x2c\x5f\x3d\ +\x46\x28\x12\x51\xf4\xa9\x2a\xca\x60\x2f\xe2\xf2\xbc\x42\x9f\xe6\ +\x6d\x9b\x2c\x8a\x0a\x01\xb8\xa3\x4e\x59\x85\x3a\xb4\x70\x7d\xea\ +\xce\x67\x0b\xc5\x68\x9d\x5a\xfe\x58\x87\x36\x61\xae\xe3\xa1\x25\ +\x9d\x4f\xce\x70\xb3\x89\xf8\x60\x86\x36\xf1\x91\x47\x29\x26\x9f\ +\x7e\x68\x7c\x6f\x64\x7c\x67\x7a\x58\xea\x47\xcb\xe1\xb0\x8c\x22\ +\x97\x61\x67\xd9\x0e\xfb\xbc\xe8\xe3\x5f\x97\xca\x27\x9e\x0c\xb6\ +\xab\x51\x00\x18\x24\x11\x01\xcc\x82\x27\x47\x7e\x2e\xae\x53\xa9\ +\x6c\x71\xf5\x9a\x0b\xf0\x1d\x8f\x23\x1b\xdb\xdd\xf7\xfe\x10\x20\ +\x6e\x57\x19\x9c\xd6\x73\x62\xbb\xbe\x47\x01\xa4\xb6\xf4\xbc\x9e\ +\x7b\xf6\xd2\xf3\x3c\x42\xdc\x6b\x69\x34\x5a\x37\x1a\xad\x9b\x03\ +\x6c\xc4\x86\xf5\x77\x6a\x6e\xeb\x09\x7c\xc9\x79\x5a\x80\x6f\xd8\ +\xad\xe7\x60\x36\x79\x7c\xfa\x00\xee\x1c\x23\x4c\x08\x7b\x42\xf0\ +\x0f\x9e\x1c\x86\x29\x7d\x82\x1e\xd8\xd2\x67\x2e\x7d\xa2\xb6\x4f\ +\x3c\x8a\x96\xe4\xe3\xa0\xb7\xaf\x69\x5c\x82\x7b\x3b\x14\x22\xff\ +\x43\xba\x88\x7f\xa4\x5f\x0b\x51\x83\xfe\xbc\x90\xc6\x51\xfd\x76\ +\x35\x5d\x69\xb7\xa1\xb4\xc4\xd6\x82\x36\xbc\x10\x75\xbf\x7b\xbe\ +\x15\xd5\xbe\x02\xaa\x51\xf5\xa9\x05\x9b\x2c\x0f\x45\xde\x88\x96\ +\xd5\xa7\x27\xaa\xb7\xfe\x12\x9b\x1e\xfa\x9b\x28\x7b\xbd\xca\xd1\ +\xb8\xbc\x78\xe5\x61\x76\x5c\xcf\xf1\xad\x50\x3a\x10\xd9\x2b\xf3\ +\x99\xe7\x20\x72\x2b\x96\x3b\x68\x51\xd7\xc6\xd4\x63\xde\x72\x20\ +\x85\x01\x2d\x8c\x6c\x17\x13\x46\xfc\x81\xf4\x90\xe7\x00\xa1\x95\ +\xf0\xb3\x80\x65\x55\x3f\x1a\x6d\x2f\x5e\xb3\xe3\x36\x97\xf0\x94\ +\xf9\x41\xdc\xb6\x94\x12\x6b\xb3\xc9\x4e\xe3\x62\xf0\x8f\x07\x19\ +\x18\xad\xc3\x65\x77\xf6\xa7\x6e\xaf\x87\x38\x14\x50\x18\xf1\xa4\ +\x18\xb4\x2c\x52\xbe\xb7\xb6\x49\xb6\xe1\x89\xa2\xc6\x31\x4e\x01\ +\x28\xab\xf6\xfd\x8e\xbb\x1c\x2c\xba\xae\xd1\x04\x02\x1f\x51\x45\ +\x8d\x53\xeb\xad\x6e\x45\x67\xb5\x68\xc7\x4f\xf1\x2e\xfe\x53\x84\ +\xd2\x35\xd4\x56\xdc\x03\xa6\x51\xd1\xf2\x2c\x83\xda\xe9\x2c\xcb\ +\x7a\x06\x29\x0b\x30\x63\xad\xb3\xcb\xf2\x18\x62\xc5\xa9\xeb\x3c\ +\x2f\x45\xe7\x6e\x91\x0c\x81\xc0\x77\x4e\x95\x8e\x55\x1a\xe8\xdf\ +\xca\xce\x5d\x59\x63\x04\x43\xdd\xaf\xca\x77\xa2\xe4\x21\x2f\x79\ +\x6b\x08\x4d\x09\xcc\x0d\x35\x2b\x03\xee\xb1\xfa\xe7\xe7\x5f\xaf\ +\xae\x33\x08\x56\xff\xca\xf2\xef\xad\x4b\x94\x15\xf8\x26\x3b\x00\ +\xd2\xd7\x70\x22\x83\x54\xb0\x92\x36\xce\xcb\x97\x78\x07\xea\x2d\ +\x89\xc6\x5f\x21\xde\x83\x49\x5e\x05\xbd\xca\x12\xac\xb6\xd3\x4b\ +\xb7\xb9\xb8\x10\x89\x51\xee\x15\x06\xbb\x58\x36\x5a\xfc\x51\xc6\ +\x49\xf2\xbb\x1c\xa4\xe3\xe2\xeb\x4e\xe3\x32\x11\x1d\xbf\xbf\xa8\ +\x67\xdf\x78\xe4\xce\xe2\x9e\x17\xcd\xea\xab\xa7\x6d\x8b\x4a\xcf\ +\x2c\xae\x1b\x9d\xf0\x8d\x00\x15\xfd\xbb\x14\xce\x06\xd2\x6d\x9e\ +\x1d\xf6\xbb\x2c\x14\x75\xf3\x06\xcd\xed\xc0\xc1\x8f\xf6\xd3\x1d\ +\xd8\x6a\x15\xa0\x1c\x78\x4e\x64\x7b\x3e\xf2\x3d\xec\x56\x9e\xb3\ +\x7d\x62\xf6\x92\xb8\xd4\x43\xf4\x89\xd8\x10\x55\x99\x43\xdc\x8f\ +\x6d\xb0\xcf\x21\xa2\x74\x36\xb0\x52\x1a\x82\xe5\xa7\xf5\xe0\x50\ +\x7e\xea\x07\xf3\xb3\x74\xff\xb8\xd2\x2d\xd6\x29\xbe\xa9\xd5\x58\ +\xdd\x58\xd5\xda\x66\xc7\x44\x55\x9c\x82\x69\x79\xd4\xed\x16\xd7\ +\xf1\x36\x82\x1d\x5e\x3d\x22\x14\x04\x10\x69\xe5\xc3\x35\xd2\x3a\ +\x97\xc7\xfc\x90\x00\x59\x7a\x13\x69\x16\x86\x10\x8a\xf3\xec\xbb\ +\x58\xd5\x0e\xbc\x7e\xbc\x38\x0c\xa0\x2c\xf5\x23\x28\x8f\xc8\x13\ +\x30\xe4\x72\x45\x9a\xb2\x90\x83\x17\xce\x73\x7e\x5e\xa5\xf0\x12\ +\xd1\x94\x5e\x87\xea\x32\x88\x7b\x43\x38\x56\x7c\x07\x28\xad\x11\ +\xf2\xd2\x80\xc9\x79\x48\xcc\x04\x93\xda\x9e\x64\xfe\x2e\xbd\x37\ +\x98\xd6\x08\x05\x6d\xe0\x5c\x2e\x29\x32\x13\x4e\x07\xdb\xf7\x47\ +\x12\xa9\x91\x24\xc4\xf3\x0c\x45\xd2\xbf\x04\xe7\xbb\xc3\xe9\xaa\ +\xd0\x8c\x22\xcc\x31\x37\x13\x4d\xec\xd8\x95\x99\x93\xbb\x2b\xa7\ +\xff\x53\xc2\x09\xaf\x71\xf7\x77\x98\x96\xf7\x53\x62\xc9\x6c\xda\ +\x27\xe8\x77\xf3\x9b\x96\xd9\xb6\x8e\xfa\x40\x6a\xe3\x45\x16\x51\ +\xc1\x68\x04\x33\xba\x81\x51\x23\x23\x9a\xa2\x98\x06\x70\xa2\x1b\ +\x20\xf5\x70\x21\x75\xc0\x31\x82\x0d\xdd\x62\xa8\x8d\x05\x59\x4b\ +\xb5\x6f\x64\xcc\x34\x1c\x35\xf2\x1f\x0b\xff\x54\x40\x6a\x62\x3e\ +\x96\x32\x95\x61\x04\x8a\x37\xbe\xf0\xfe\x89\xa0\xa9\xd7\x6d\x03\ +\x52\x41\x43\xfc\xf4\xb1\x1d\x3a\x01\xa5\x01\x74\x67\x08\xa5\x4e\ +\xc6\x33\x91\xa1\x34\x80\xf1\x0c\xb1\xd4\x44\x7a\x94\xc1\xda\x08\ +\xd2\x33\x02\xa3\x3e\xde\xa3\x0c\xd7\x14\xc9\x8f\x71\x50\xea\xa4\ +\x3e\xca\xf7\x6b\x53\xb1\xd4\xc5\x7e\x94\x21\xc7\x54\x20\x75\x26\ +\x7d\xd4\xaf\x88\x46\xa0\x39\x16\xae\x35\x10\x4a\x34\x95\xf6\x31\ +\x80\x52\x2a\x60\xd4\x98\x45\x53\x87\x1e\x23\x88\xa5\x02\x50\xad\ +\xf9\x34\x75\xca\xdc\x08\x7e\xa9\x80\x54\x57\x66\x6d\x8a\xad\x1b\ +\x40\x33\x55\x68\x6a\xcc\xb1\xa9\x4d\x3e\x24\xe6\x86\x22\xad\xd9\ +\x36\x75\x74\x37\x1a\x52\x6d\x79\x37\xf5\xf1\x02\xa3\xf1\xd4\x4a\ +\x40\xb1\xfa\x9b\x1e\x23\x40\x1d\x33\x70\x1d\x14\x54\xf9\x7e\x29\ +\x63\xbb\xa9\x28\xea\x63\xa0\xca\x2c\x92\xc9\x70\xea\xe4\x9f\xca\ +\x50\x64\x32\xa0\x9a\xd8\xa7\x32\x05\x62\x34\x96\x1a\xf3\x9c\x13\ +\x5f\x94\x83\x35\x18\x0a\xa8\x4e\xea\x39\xf1\xae\x49\x08\x7f\xef\ +\xa7\x89\x54\x80\xea\x22\x9e\xca\xd8\x8e\xb9\x1f\xbd\xfb\xec\x92\ +\x0a\x4d\xbd\x79\x4f\x75\x3e\xde\xe7\x3c\x14\xef\x1c\xd3\x31\x67\ +\xa9\x25\xf1\xa9\xf4\x9c\x32\x09\xf2\xee\x43\x91\x02\x46\x9d\x89\ +\x4f\x25\xf1\x34\x19\x50\xcd\x89\x4f\x65\x34\x32\x19\x53\x6d\x99\ +\x4f\xe5\x77\x1d\x46\xa3\xa9\x33\xf3\x39\xc1\x96\x0c\xa0\x9f\x0a\ +\x44\xf5\x66\x3e\x27\x4f\x81\xbc\x7b\x02\xaa\x82\x54\x5f\xe6\xd3\ +\x6c\x0a\xaa\xc2\x53\x73\xe6\x53\x99\x4e\x36\x82\x83\x8e\xa1\xa7\ +\xf9\x34\xa2\x3a\x97\xbc\x09\x42\xd7\x7b\xef\x6a\xaa\x40\x54\xeb\ +\xa1\x44\x35\xc3\x37\x19\x52\x5d\x67\x13\xd5\x71\xc9\x68\x34\x35\ +\xa6\xee\x0c\x27\x4f\x0a\x44\xb5\x9e\x54\x9c\x3a\xcd\x64\x00\x79\ +\x52\x41\xaa\xed\xc0\xa2\x5a\x45\x8d\x20\x4f\x37\xc0\xe9\x39\x5f\ +\xa7\x8e\xec\x94\x72\xfe\xee\xdf\x3a\x87\x18\x6a\x3d\x5c\x37\x71\ +\xec\xd3\x4c\x34\x35\x27\x98\x26\x98\xbc\x99\x78\xea\x3b\x56\x37\ +\x71\x50\xde\x50\x28\xb5\x9e\xa9\x9b\xba\x11\xc5\x04\x7a\x34\x80\ +\x53\xf3\x81\xba\xe9\xbf\xa9\x7e\xff\xdc\x68\x88\xa7\xc6\xd3\x74\ +\x6a\xe5\x34\x94\x18\x69\x3f\x4a\x37\x41\x93\xfe\x8f\x52\x4a\x7b\ +\x5e\xbe\x76\x56\xd2\xde\x4a\x9a\xa6\xb0\xa2\x2c\xb7\x82\x43\xfe\ +\xc6\xcb\x43\x2e\x86\x17\xbf\xca\xb6\xae\xbf\x64\xbd\x37\x69\x79\ +\xcb\xe0\xac\x71\xa4\xfe\x13\xb5\x19\xf3\x7d\x07\xb1\x59\x30\x43\ +\x4f\x0e\xb3\x71\xf5\xc7\x2c\x8e\xfa\x41\x85\x5a\x7d\xf9\xc9\x14\ +\x28\xae\x8d\x09\x42\xde\x12\x91\xfd\xa9\x91\xc8\xab\x53\x61\x49\ +\xab\xcd\xa1\x2c\xbb\x65\xff\xce\xe2\x74\x55\x81\xa7\x17\x1f\x4a\ +\xfc\x5b\x74\x7c\x9b\x2c\x2f\xe8\x38\xf4\x72\x85\xb1\x0b\xe8\x5c\ +\x11\x70\x9f\x90\xfa\x41\x85\x4e\xfd\x85\xcf\x34\x3a\x1e\x65\x88\ +\x79\x0e\xbe\x1b\x3a\x43\x7b\x74\x6d\x8a\x08\xed\xdf\xb3\x2b\xed\ +\xd1\x83\x50\x80\xdc\x9e\xd9\xf4\xae\xb2\xec\xc7\xe1\x91\xe2\xeb\ +\xad\xcf\x78\x68\x94\xbd\xb2\xc6\x1a\x31\x63\xaa\x3f\x0c\xe8\x58\ +\x85\x0c\x16\xd5\xd1\xd6\x1e\x54\xd8\x76\x7c\x0f\x39\x98\xba\xf7\ +\x30\xb3\xe7\xc5\xb6\xfe\x45\x24\x49\xbc\x2f\xae\xd7\x60\x76\xe7\ +\x74\xc8\x93\x0f\x8f\xc3\x8b\x7c\x3f\xfe\xb8\x9b\x18\x5f\x08\xc2\ +\x4b\x4a\x10\xfb\x9f\x16\xf2\xd0\x81\x56\x2a\x35\x40\xdb\xfa\x5b\ +\x79\x3f\x2d\x68\x28\x71\xb1\x4b\x5b\x47\x20\xef\xa5\x75\x88\x2d\ +\x2f\xb4\x75\x5b\x5d\x90\x9a\xe0\xb8\x36\xa1\xa0\xae\x2d\x2b\xa8\ +\xfc\x78\x5d\xda\xde\x22\xdd\x53\xae\x9e\xae\x7b\x1e\xc6\xff\x0d\ +\xfb\x54\xec\xf0\x85\x9b\x90\x7b\x01\x23\xa7\x0b\xde\xb0\xd5\xd9\ +\xe6\x02\x5b\x66\x23\xcf\x71\xbd\x56\xd0\x86\x19\xe2\xfb\x68\x49\ +\x5b\x35\x3d\xc9\xcb\x7c\x7d\x1b\x7b\x3e\xed\x90\xd0\xcb\xc1\x1c\ +\xec\x53\x8c\x48\x1f\x4a\xdb\x01\x67\xe7\x7a\xac\x07\xa5\x6b\xfb\ +\x18\x75\x48\x57\xe7\x52\xd1\x3c\x2b\x79\x29\x3e\x58\x2e\xb3\x7d\ +\xe6\x53\xdf\xfd\x78\xbd\x43\x16\x54\xf4\x59\xde\xe1\xfa\xf2\xf0\ +\x1f\xe4\x46\xc2\x2a\ +\x00\x00\x05\xe1\ +\x00\ +\x00\x17\x33\x78\x9c\xed\x58\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ +\x14\x0c\x58\xb1\xea\x42\xdd\x2c\x29\xb6\xfb\xb0\xa2\x58\x81\xf5\ +\x65\xeb\xb6\xc7\x82\x96\x68\x9b\x8b\x24\x0a\x14\x15\xdb\xf9\xf5\ +\x3b\xa4\xee\xb6\x53\xa4\x18\x96\x3e\xb4\x02\x02\x45\xe7\x42\x9e\ +\xf3\x9d\xef\x1c\x32\x59\xbe\x39\x16\x39\x7a\xa0\xa2\x66\xbc\x5c\ +\x19\xd8\x72\x0c\x44\xcb\x94\x67\xac\xdc\xad\x8c\x3f\x3f\xbe\x33\ +\x23\x03\xd5\x92\x94\x19\xc9\x79\x49\x57\x46\xc9\x8d\x37\xeb\x9b\ +\xe5\x0f\xa6\x89\x7e\x11\x94\x48\x9a\xa1\x03\x93\x7b\xf4\xbe\xbc\ +\xaf\x53\x52\x51\xf4\xd3\x5e\xca\x2a\xb1\xed\xc3\xe1\x60\xb1\x4e\ +\x68\x71\xb1\xb3\x5f\x21\xd3\x5c\xdf\xdc\x2c\xeb\x87\xdd\x0d\x42\ +\x08\xf6\x2d\xeb\x24\x4b\x57\x46\xe7\x50\x35\x22\xd7\x86\x59\x6a\ +\xd3\x9c\x16\xb4\x94\xb5\x8d\x2d\x6c\x1b\xa3\x79\x3a\x9a\xa7\x6a\ +\x77\xf6\x40\x53\x5e\x14\xbc\xac\xb5\x67\x59\xdf\x4e\x8c\x45\xb6\ +\x1d\xac\x55\x34\x07\x4f\x1b\xe1\x38\x8e\x6d\xc7\xb5\x5d\xd7\x04\ +\x0b\xb3\x3e\x95\x92\x1c\xcd\xb9\x2b\xc4\x78\xcd\xd5\x75\x1c\xc7\ +\x06\xdd\x68\xf9\x3c\xab\xa4\x06\x40\x2b\xf8\x19\xcc\x7b\x81\x55\ +\xf3\x46\xa4\x74\x0b\x7e\xd4\x2a\xa9\xb4\xdf\x7e\x7c\x3b\x28\x4d\ +\xc7\xca\x64\x36\x59\xa6\xc7\x73\xb6\xeb\x0c\xe4\x92\x14\xb4\xae\ +\x48\x4a\x6b\xbb\x97\x6b\xff\x03\xcb\xe4\x7e\x65\x78\xbe\x85\x3d\ +\x78\x02\x2d\xdc\x53\xb6\xdb\xcb\x73\x29\xcb\x56\x06\x44\xef\xc6\ +\x51\xfb\x3d\x21\x07\x6e\x0d\xba\x85\x93\x41\xe3\x58\xb1\x6b\x61\ +\x24\x70\xe0\x2d\x5a\x9b\x3e\x85\x24\xe3\xa9\x8a\x09\x96\xa4\x05\ +\x23\x8d\xe4\x05\x54\x2d\x4d\x73\x52\xd7\x6c\xcb\x52\xf8\xe0\x65\ +\x95\x37\x3b\x56\x7e\x12\xb4\xe2\x42\x7e\x92\x9c\xe7\x56\x0f\xdf\ +\xb0\x17\x3d\x2a\xa5\x79\xcc\x2a\x00\x31\x5c\x5c\x55\x9e\x7a\xe5\ +\x1a\xb4\xcb\x8c\x6e\x6b\x65\xd5\x66\xa4\xbe\x20\xa5\x85\x81\x6c\ +\xad\x1d\x02\x54\xd1\x65\x0f\x8c\x1e\x46\xdb\x0d\xa9\x5b\xd4\x10\ +\xaa\xc8\x0e\x18\x96\x73\xb1\x32\x6e\xb7\xfa\xe9\x14\x1b\x2e\x32\ +\x2a\x7a\x55\xa8\x9f\x99\x8a\x43\x15\x98\x3c\xb5\x3d\xd5\xad\xdd\ +\xc7\xab\x56\x1d\xf4\xce\x75\x7d\xbd\x27\x19\x3f\xac\x0c\xf7\x5c\ +\xf9\xc8\x79\xb1\x32\x02\x2b\x88\xa3\xd8\xc1\xe7\xda\xf4\x08\x3b\ +\x42\xa5\x42\xd7\xc7\xde\x85\x52\x87\x13\xb8\x91\x87\xfd\xe8\x42\ +\xd9\x08\x01\x3d\x67\xe6\xe4\x44\x21\x27\xfd\xea\x97\xaf\xf7\xfc\ +\xb0\x13\x0a\x1b\x29\x1a\x7a\xee\xa9\x34\xe6\x66\xc3\x8f\xd7\xd5\ +\x40\x81\x46\x75\xb3\xd9\x94\x4c\x42\xc7\x54\xc7\xe9\xaa\x0d\xcb\ +\x68\x7d\xdd\xb1\x2e\x49\x65\xee\x72\xbe\x21\xf9\x75\x83\x03\x2b\ +\x01\x23\xb3\x23\x37\xf6\x86\x12\x9c\x5b\xf4\x4c\x5f\x38\x17\x69\ +\x77\x16\x10\xfb\x45\x19\x3a\xd5\xe9\x69\x55\x41\x8e\xac\x60\x8f\ +\x14\x80\xc1\x9a\x75\xc0\xac\x19\x2c\xad\x1b\x42\xf2\xa4\xba\xf6\ +\x78\x52\x32\xa3\x17\x2a\x3c\x95\xc0\x8d\xe3\xc5\x20\xe4\x82\x41\ +\x33\x4c\xc2\xe9\x45\xa7\xa9\x48\xf5\x38\x8c\xe8\xa3\xa6\x97\x26\ +\xdf\xe2\x5c\x77\x9a\xea\x3a\xd6\xdb\x97\xb4\xd7\xf2\x82\x4a\x92\ +\x11\x49\xc6\x1e\xe8\x25\x10\x9b\xd3\x67\x06\xe3\x32\xf9\xfd\xed\ +\xbb\x75\xb7\xd1\x32\x4d\x93\xbf\xb9\xb8\xef\xf7\x45\x48\x19\x90\ +\x0d\x6f\x00\x69\x63\x3d\x88\x97\x59\x9a\xc0\x80\x83\xc6\x5f\xb3\ +\x02\x98\xad\x66\xe3\xcf\x30\xd0\x96\xf6\xa8\x98\x19\x2b\xb0\xc6\ +\x45\xdb\x65\x05\x6d\x27\xe5\xd5\xe3\x22\x4b\x0b\xa6\x9c\xec\x3f\ +\x24\xcb\xf3\xf7\x6a\x93\x2e\xe3\xc9\xa2\x4c\xe6\x74\x14\x2e\xed\ +\x2e\xfa\x2e\x37\x7b\x92\xdc\xd2\xee\xb3\xd7\x5f\xbb\x11\x95\x59\ +\x53\x0c\x85\xce\xc9\x86\x02\x43\x7f\x53\x4a\x74\xa1\xdd\x09\xde\ +\x54\x05\xcf\x68\xe7\x3e\xa0\x49\x53\x39\x94\x4c\x9e\x72\xd0\xeb\ +\x71\x92\xdc\x3a\xfa\xb9\xcb\x58\x5d\x81\x07\x4c\xfd\x9c\x95\xf4\ +\x8e\xc3\xb8\xdd\xe6\xfc\x90\x3c\xb0\x9a\x6d\x72\x7a\xa7\xdf\x2c\ +\x87\xcc\x07\xd1\x16\xd2\x4f\x6e\xb7\xd1\x36\x4e\x1d\xfd\x61\x76\ +\x63\x26\xc1\xed\xa7\x68\x72\x9a\x94\xbc\x7c\x84\x01\x75\x57\x4b\ +\xc1\xef\x69\xd2\x0d\xb6\xee\xb3\xed\xa6\xc4\x6d\x8f\x04\xcf\xf7\ +\x7b\xb9\x0a\x02\x12\x4a\x36\x8d\x94\x53\xd9\x3f\x9c\x95\x09\xe0\ +\x4f\x45\x2f\xd5\x1f\x39\x34\x86\x4c\x06\xef\x8c\xc0\x40\x13\x02\ +\xd2\x81\xdd\xe9\x54\xca\xb7\xdb\x9a\xca\xc4\xe9\x65\x63\xc4\x05\ +\x11\xf7\x54\xb4\x0e\xb4\x24\x90\xa0\xb9\x21\xe9\xbd\x02\xb4\xcc\ +\x12\x92\xc2\x58\x69\x72\xb8\x82\xcc\x1a\x4a\xc1\xea\xc1\x80\x1b\ +\x84\xfd\xd1\x17\x58\xea\x60\x76\x46\xc5\x70\xfc\x5d\x68\xa0\xad\ +\x4c\x6c\x79\xae\x1b\x86\xb1\x3f\x48\xf5\xac\x6e\x51\x89\xdd\x41\ +\x2a\xc0\xd8\xb7\x22\x2f\x8c\x70\xe8\x8d\x52\x30\xf6\xac\x28\x76\ +\xe3\xc0\x0f\x07\x2e\x2e\x2b\x22\xf7\x67\x35\xd7\x25\x9b\x60\x32\ +\x94\x7f\x56\x8e\xd0\xf2\xda\x4e\x8e\xff\xcf\x72\x0c\xd0\x0f\x79\ +\xa8\x49\x80\xe0\x1e\xe2\x06\xe1\x6b\xdc\xc2\xe4\x2c\xd0\x1e\x79\ +\x91\xe5\xa3\xbf\xd4\x2b\xd0\x2c\x01\x91\xa9\x65\x8f\xb3\x62\xa8\ +\x7c\xbd\x08\x8f\xb3\x69\x3c\x6d\x78\x09\xf1\x4b\x2e\x4c\x38\x77\ +\x1e\x88\x6c\x04\x55\xf3\xed\xbf\x23\x85\x2d\x3f\xf4\x17\xe1\x22\ +\xc2\x2f\x8e\xd4\x07\x84\x3d\x4b\x91\x26\x5c\xbc\x0e\x3b\x60\x30\ +\xa0\x14\xb8\x56\x1c\xbb\x41\xec\x5d\xc3\x26\xfe\x36\xb0\x01\x16\ +\x75\x1d\x35\xc5\x66\x8f\x7c\xcf\x0a\x87\xbb\xc8\x14\x18\xd7\xfb\ +\x36\x80\xf9\x80\x9c\xd7\xae\xda\x1f\x9e\x08\xfd\x8a\x7c\x17\x60\ +\x52\xf8\x5c\xc3\x24\xf8\x72\x4c\x24\x3d\x0e\xc7\x0c\x1c\xba\x89\ +\xfe\xeb\x00\x16\x84\x03\x95\x8a\x87\x71\x76\xf6\x78\x71\xb8\xa8\ +\xe9\xdf\x21\x74\x38\x9a\xf3\x3b\x2d\x39\xe8\x59\x39\x13\xd5\x70\ +\xef\x49\xb0\x6b\x45\x1a\x4f\x1c\x57\xc7\x3b\x05\x50\x77\xd7\x4a\ +\x9c\x1f\x5b\xb3\x2d\x29\x58\x7e\x4a\x6a\x52\xd6\x26\xec\xc8\xb6\ +\x77\x39\x95\x80\x98\xd9\x5d\x53\x12\x07\x1c\x0f\x70\x65\x9e\x09\ +\xda\x83\xac\x2b\xd5\xd9\x41\xd6\x15\x72\x8a\x6c\x5f\xc5\xee\xba\ +\xe3\x4e\x27\x39\x0e\x2d\x98\xc2\x8b\xc5\x6c\x90\xbb\x91\xe5\xc0\ +\x64\x0e\xf1\x0c\x65\x85\x15\x9c\x1d\x23\xf4\x52\x40\xd8\xea\x8a\ +\x02\x7f\xbf\xa4\x24\xa7\x3f\x39\x6a\xa6\x47\x6e\x14\x78\x30\x0e\ +\x31\xcc\x43\x2f\x88\x5f\x19\xeb\xa5\x84\xe0\xcb\xf1\xce\x32\x5c\ +\xb3\x04\x57\xa0\x2a\x5c\x8c\x51\xab\xb7\x52\x0e\xb0\x57\x30\x91\ +\x5f\x0d\xf6\x89\x70\xcf\x0a\xa6\x6a\x11\x59\x51\x14\x85\x4e\x80\ +\xdd\xb3\x52\xc0\xe0\x0e\x9e\x2a\xc6\x53\x00\xae\xb1\xeb\x2d\x6d\ +\x1d\xe5\x1a\xde\x00\xcc\x77\x3e\x7d\x86\x4f\xd8\xb7\x16\x2e\x5e\ +\x04\xde\x55\x3e\x99\xc1\x4b\x32\xca\x8c\x9f\xc5\xa9\xcb\x90\xbf\ +\x73\xea\x6b\x71\xca\xb7\x7c\xdf\xf7\x9c\x2f\xa1\x94\xf3\xa2\x94\ +\x0a\xe7\x94\xba\x88\xf7\xab\x31\xea\x3b\x9f\x9e\xcb\xa7\xcf\x1f\ +\x79\xa6\xf3\xc2\x43\x2a\x34\xfd\xe7\x70\xea\x6b\x9c\x7c\x97\x9c\ +\x5a\xda\xbb\xf5\xcd\x52\xfd\xe3\x62\x7d\xf3\x2f\x01\x81\xea\x10\ +\ +\x00\x00\x05\xe1\ +\x00\ +\x00\x17\x33\x78\x9c\xed\x58\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ +\x14\x0c\x58\xb1\xea\x42\xdd\x2c\x29\xb6\xfb\xb0\xa2\x58\x81\xf5\ +\x65\xeb\xb6\xc7\x82\x96\x68\x9b\x8b\x24\x0a\x14\x15\xdb\xf9\xf5\ +\x3b\xa4\xee\xb6\x53\xa4\x18\x96\x3e\xb4\x02\x02\x45\xe7\x42\x9e\ +\xf3\x9d\xef\x1c\x32\x59\xbe\x39\x16\x39\x7a\xa0\xa2\x66\xbc\x5c\ +\x19\xd8\x72\x0c\x44\xcb\x94\x67\xac\xdc\xad\x8c\x3f\x3f\xbe\x33\ +\x23\x03\xd5\x92\x94\x19\xc9\x79\x49\x57\x46\xc9\x8d\x37\xeb\x9b\ +\xe5\x0f\xa6\x89\x7e\x11\x94\x48\x9a\xa1\x03\x93\x7b\xf4\xbe\xbc\ +\xaf\x53\x52\x51\xf4\xd3\x5e\xca\x2a\xb1\xed\xc3\xe1\x60\xb1\x4e\ +\x68\x71\xb1\xb3\x5f\x21\xd3\x5c\xdf\xdc\x2c\xeb\x87\xdd\x0d\x42\ +\x08\xf6\x2d\xeb\x24\x4b\x57\x46\xe7\x50\x35\x22\xd7\x86\x59\x6a\ +\xd3\x9c\x16\xb4\x94\xb5\x8d\x2d\x6c\x1b\xa3\x79\x3a\x9a\xa7\x6a\ +\x77\xf6\x40\x53\x5e\x14\xbc\xac\xb5\x67\x59\xdf\x4e\x8c\x45\xb6\ +\x1d\xac\x55\x34\x07\x4f\x1b\xe1\x38\x8e\x6d\xc7\xb5\x5d\xd7\x04\ +\x0b\xb3\x3e\x95\x92\x1c\xcd\xb9\x2b\xc4\x78\xcd\xd5\x75\x1c\xc7\ +\x06\xdd\x68\xf9\x3c\xab\xa4\x06\x40\x2b\xf8\x19\xcc\x7b\x81\x55\ +\xf3\x46\xa4\x74\x0b\x7e\xd4\x2a\xa9\xb4\xdf\x7e\x7c\x3b\x28\x4d\ +\xc7\xca\x64\x36\x59\xa6\xc7\x73\xb6\xeb\x0c\xe4\x92\x14\xb4\xae\ +\x48\x4a\x6b\xbb\x97\x6b\xff\x03\xcb\xe4\x7e\x65\x78\xbe\x85\x3d\ +\x78\x02\x2d\xdc\x53\xb6\xdb\xcb\x73\x29\xcb\x56\x06\x44\xef\xc6\ +\x51\xfb\x3d\x21\x07\x6e\x0d\xba\x85\x93\x41\xe3\x58\xb1\x6b\x61\ +\x24\x70\xe0\x2d\x5a\x9b\x3e\x85\x24\xe3\xa9\x8a\x09\x96\xa4\x05\ +\x23\x8d\xe4\x05\x54\x2d\x4d\x73\x52\xd7\x6c\xcb\x52\xf8\xe0\x65\ +\x95\x37\x3b\x56\x7e\x12\xb4\xe2\x42\x7e\x92\x9c\xe7\x56\x0f\xdf\ +\xb0\x17\x3d\x2a\xa5\x79\xcc\x2a\x00\x31\x5c\x5c\x55\x9e\x7a\xe5\ +\x1a\xb4\xcb\x8c\x6e\x6b\x65\xd5\x66\xa4\xbe\x20\xa5\x85\x81\x6c\ +\xad\x1d\x02\x54\xd1\x65\x0f\x8c\x1e\x46\xdb\x0d\xa9\x5b\xd4\x10\ +\xaa\xc8\x0e\x18\x96\x73\xb1\x32\x6e\xb7\xfa\xe9\x14\x1b\x2e\x32\ +\x2a\x7a\x55\xa8\x9f\x99\x8a\x43\x15\x98\x3c\xb5\x3d\xd5\xad\xdd\ +\xc7\xab\x56\x1d\xf4\xce\x75\x7d\xbd\x27\x19\x3f\xac\x0c\xf7\x5c\ +\xf9\xc8\x79\xb1\x32\x02\x2b\x88\xa3\xd8\xc1\xe7\xda\xf4\x08\x3b\ +\x42\xa5\x42\xd7\xc7\xde\x85\x52\x87\x13\xb8\x91\x87\xfd\xe8\x42\ +\xd9\x08\x01\x3d\x67\xe6\xe4\x44\x21\x27\xfd\xea\x97\xaf\xf7\xfc\ +\xb0\x13\x0a\x1b\x29\x1a\x7a\xee\xa9\x34\xe6\x66\xc3\x8f\xd7\xd5\ +\x40\x81\x46\x75\xb3\xd9\x94\x4c\x42\xc7\x54\xc7\xe9\xaa\x0d\xcb\ +\x68\x7d\xdd\xb1\x2e\x49\x65\xee\x72\xbe\x21\xf9\x75\x83\x03\x2b\ +\x01\x23\xb3\x23\x37\xf6\x86\x12\x9c\x5b\xf4\x4c\x5f\x38\x17\x69\ +\x77\x16\x10\xfb\x45\x19\x3a\xd5\xe9\x69\x55\x41\x8e\xac\x60\x8f\ +\x14\x80\xc1\x9a\x75\xc0\xac\x19\x2c\xad\x1b\x42\xf2\xa4\xba\xf6\ +\x78\x52\x32\xa3\x17\x2a\x3c\x95\xc0\x8d\xe3\xc5\x20\xe4\x82\x41\ +\x33\x4c\xc2\xe9\x45\xa7\xa9\x48\xf5\x38\x8c\xe8\xa3\xa6\x97\x26\ +\xdf\xe2\x5c\x77\x9a\xea\x3a\xd6\xdb\x97\xb4\xd7\xf2\x82\x4a\x92\ +\x11\x49\xc6\x1e\xe8\x25\x10\x9b\xd3\x67\x06\xe3\x32\xf9\xfd\xed\ +\xbb\x75\xb7\xd1\x32\x4d\x93\xbf\xb9\xb8\xef\xf7\x45\x48\x19\x90\ +\x0d\x6f\x00\x69\x63\x3d\x88\x97\x59\x9a\xc0\x80\x83\xc6\x5f\xb3\ +\x02\x98\xad\x66\xe3\xcf\x30\xd0\x96\xf6\xa8\x98\x19\x2b\xb0\xc6\ +\x45\xdb\x65\x05\x6d\x27\xe5\xd5\xe3\x22\x4b\x0b\xa6\x9c\xec\x3f\ +\x24\xcb\xf3\xf7\x6a\x93\x2e\xe3\xc9\xa2\x4c\xe6\x74\x14\x2e\xed\ +\x2e\xfa\x2e\x37\x7b\x92\xdc\xd2\xee\xb3\xd7\x5f\xbb\x11\x95\x59\ +\x53\x0c\x85\xce\xc9\x86\x02\x43\x7f\x53\x4a\x74\xa1\xdd\x09\xde\ +\x54\x05\xcf\x68\xe7\x3e\xa0\x49\x53\x39\x94\x4c\x9e\x72\xd0\xeb\ +\x71\x92\xdc\x3a\xfa\xb9\xcb\x58\x5d\x81\x07\x4c\xfd\x9c\x95\xf4\ +\x8e\xc3\xb8\xdd\xe6\xfc\x90\x3c\xb0\x9a\x6d\x72\x7a\xa7\xdf\x2c\ +\x87\xcc\x07\xd1\x16\xd2\x4f\x6e\xb7\xd1\x36\x4e\x1d\xfd\x61\x76\ +\x63\x26\xc1\xed\xa7\x68\x72\x9a\x94\xbc\x7c\x84\x01\x75\x57\x4b\ +\xc1\xef\x69\xd2\x0d\xb6\xee\xb3\xed\xa6\xc4\x6d\x8f\x04\xcf\xf7\ +\x7b\xb9\x0a\x02\x12\x4a\x36\x8d\x94\x53\xd9\x3f\x9c\x95\x09\xe0\ +\x4f\x45\x2f\xd5\x1f\x39\x34\x86\x4c\x06\xef\x8c\xc0\x40\x13\x02\ +\xd2\x81\xdd\xe9\x54\xca\xb7\xdb\x9a\xca\xc4\xe9\x65\x63\xc4\x05\ +\x11\xf7\x54\xb4\x0e\xb4\x24\x90\xa0\xb9\x21\xe9\xbd\x02\xb4\xcc\ +\x12\x92\xc2\x58\x69\x72\xb8\x82\xcc\x1a\x4a\xc1\xea\xc1\x80\x1b\ +\x84\xfd\xd1\x17\x58\xea\x60\x76\x46\xc5\x70\xfc\x5d\x68\xa0\xad\ +\x4c\x6c\x79\xae\x1b\x86\xb1\x3f\x48\xf5\xac\x6e\x51\x89\xdd\x41\ +\x2a\xc0\xd8\xb7\x22\x2f\x8c\x70\xe8\x8d\x52\x30\xf6\xac\x28\x76\ +\xe3\xc0\x0f\x07\x2e\x2e\x2b\x22\xf7\x67\x35\xd7\x25\x9b\x60\x32\ +\x94\x7f\x56\x8e\xd0\xf2\xda\x4e\x8e\xff\xcf\x72\x0c\xd0\x0f\x79\ +\xa8\x49\x80\xe0\x1e\xe2\x06\xe1\x6b\xdc\xc2\xe4\x2c\xd0\x1e\x79\ +\x91\xe5\xa3\xbf\xd4\x2b\xd0\x2c\x01\x91\xa9\x65\x8f\xb3\x62\xa8\ +\x7c\xbd\x08\x8f\xb3\x69\x3c\x6d\x78\x09\xf1\x4b\x2e\x4c\x38\x77\ +\x1e\x88\x6c\x04\x55\xf3\xed\xbf\x23\x85\x2d\x3f\xf4\x17\xe1\x22\ +\xc2\x2f\x8e\xd4\x07\x84\x3d\x4b\x91\x26\x5c\xbc\x0e\x3b\x60\x30\ +\xa0\x14\xb8\x56\x1c\xbb\x41\xec\x5d\xc3\x26\xfe\x36\xb0\x01\x16\ +\x75\x1d\x35\xc5\x66\x8f\x7c\xcf\x0a\x87\xbb\xc8\x14\x18\xd7\xfb\ +\x36\x80\xf9\x80\x9c\xd7\xae\xda\x1f\x9e\x08\xfd\x8a\x7c\x17\x60\ +\x52\xf8\x5c\xc3\x24\xf8\x72\x4c\x24\x3d\x0e\xc7\x0c\x1c\xba\x89\ +\xfe\xeb\x00\x16\x84\x03\x95\x8a\x87\x71\x76\xf6\x78\x71\xb8\xa8\ +\xe9\xdf\x21\x74\x38\x9a\xf3\x3b\x2d\x39\xe8\x59\x39\x13\xd5\x70\ +\xef\x49\xb0\x6b\x45\x1a\x4f\x1c\x57\xc7\x3b\x05\x50\x77\xd7\x4a\ +\x9c\x1f\x5b\xb3\x2d\x29\x58\x7e\x4a\x6a\x52\xd6\x26\xec\xc8\xb6\ +\x77\x39\x95\x80\x98\xd9\x5d\x53\x12\x07\x1c\x0f\x70\x65\x9e\x09\ +\xda\x83\xac\x2b\xd5\xd9\x41\xd6\x15\x72\x8a\x6c\x5f\xc5\xee\xba\ +\xe3\x4e\x27\x39\x0e\x2d\x98\xc2\x8b\xc5\x6c\x90\xbb\x91\xe5\xc0\ +\x64\x0e\xf1\x0c\x65\x85\x15\x9c\x1d\x23\xf4\x52\x40\xd8\xea\x8a\ +\x02\x7f\xbf\xa4\x24\xa7\x3f\x39\x6a\xa6\x47\x6e\x14\x78\x30\x0e\ +\x31\xcc\x43\x2f\x88\x5f\x19\xeb\xa5\x84\xe0\xcb\xf1\xce\x32\x5c\ +\xb3\x04\x57\xa0\x2a\x5c\x8c\x51\xab\xb7\x52\x0e\xb0\x57\x30\x91\ +\x5f\x0d\xf6\x89\x70\xcf\x0a\xa6\x6a\x11\x59\x51\x14\x85\x4e\x80\ +\xdd\xb3\x52\xc0\xe0\x0e\x9e\x2a\xc6\x53\x00\xae\xb1\xeb\x2d\x6d\ +\x1d\xe5\x1a\xde\x00\xcc\x77\x3e\x7d\x86\x4f\xd8\xb7\x16\x2e\x5e\ +\x04\xde\x55\x3e\x99\xc1\x4b\x32\xca\x8c\x9f\xc5\xa9\xcb\x90\xbf\ +\x73\xea\x6b\x71\xca\xb7\x7c\xdf\xf7\x9c\x2f\xa1\x94\xf3\xa2\x94\ +\x0a\xe7\x94\xba\x88\xf7\xab\x31\xea\x3b\x9f\x9e\xcb\xa7\xcf\x1f\ +\x79\xa6\xf3\xc2\x43\x2a\x34\xfd\xe7\x70\xea\x6b\x9c\x7c\x97\x9c\ +\x5a\xda\xbb\xf5\xcd\x52\xfd\xe3\x62\x7d\xf3\x2f\x01\x81\xea\x10\ +\ +\x00\x00\x0b\x27\ +\x00\ +\x00\x5a\x95\x78\x9c\xed\x5c\x59\x8f\xdb\xc8\x11\x7e\xf7\xaf\x60\ +\x64\x04\xbb\x46\xd4\x14\xfb\x60\x1f\x1a\xcd\x2c\x10\x1b\x0b\x2c\ +\xb0\x79\xc9\x6e\x10\x20\x2f\x0b\x0e\x49\x69\x08\x53\xa4\x40\x52\ +\x23\x8d\x7f\x7d\xaa\x78\x89\xd4\xe1\x38\x96\xb4\xd6\x48\xa6\x31\ +\x9e\x51\x55\x1f\xd5\x5f\x57\x55\x7f\x4d\xb1\x39\xf9\x69\x3d\x8f\ +\xad\xe7\x30\xcb\xa3\x34\xb9\x1f\x50\xdb\x19\x58\x61\xe2\xa7\x41\ +\x94\xcc\xee\x07\xff\xfa\xfd\x67\xa2\x07\x56\x5e\x78\x49\xe0\xc5\ +\x69\x12\xde\x0f\x92\x74\xf0\xd3\xc3\x9b\xc9\x5f\x08\xb1\xde\x67\ +\xa1\x57\x84\x81\xb5\x8a\x8a\x27\xeb\x97\xe4\x63\xee\x7b\x8b\xd0\ +\xfa\xf1\xa9\x28\x16\xe3\xd1\x68\xb5\x5a\xd9\x51\x2d\xb4\xd3\x6c\ +\x36\x7a\x67\x11\xf2\xf0\xe6\xcd\x24\x7f\x9e\xbd\xb1\x2c\x0b\xfa\ +\x4d\xf2\x71\xe0\xdf\x0f\xea\x0a\x8b\x65\x16\x97\x05\x03\x7f\x14\ +\xc6\xe1\x3c\x4c\x8a\x7c\x44\x6d\x3a\x1a\x6c\x8a\xfb\x9b\xe2\x3e\ +\xf6\x1e\x3d\x87\x7e\x3a\x9f\xa7\x49\x5e\xd6\x4c\xf2\xb7\x9d\xc2\ +\x59\x30\x6d\x4b\xa3\x35\x2b\x5e\x16\xa2\xc6\x98\x91\xc3\x46\x8c\ +\x11\x28\x41\xf2\x97\xa4\xf0\xd6\xa4\x5f\x15\x6c\xdc\x57\x95\x39\ +\x8e\x33\x02\xdd\xa6\xe4\x97\x95\x1a\xe7\x00\xe8\x02\x7e\xda\xe2\ +\x8d\xc0\xce\xd3\x65\xe6\x87\x53\xa8\x17\xda\x49\x58\x8c\x3e\xfc\ +\xfe\xa1\x55\x12\xc7\x0e\x8a\xa0\xd3\x4c\x83\x67\xaf\xd7\x1e\xc8\ +\x89\x37\x0f\xf3\x85\xe7\x87\xf9\xa8\x91\x97\xf5\x57\x51\x50\x3c\ +\xdd\x0f\xb8\xb0\x29\x87\xcb\x2d\x85\x4f\x61\x34\x7b\x2a\xb6\xa5\ +\x51\x70\x3f\x00\xeb\x99\xd1\xd5\xe7\x8e\x73\xd0\xaa\x40\xdd\xf0\ +\xb8\xd5\x38\xb6\x61\x36\xb5\x32\xea\x72\x55\x95\x69\x86\x30\x0e\ +\x52\x1f\x6d\x82\x26\xc3\x79\xe4\x2d\x8b\x74\x0e\xb3\xe6\xfb\xb1\ +\x97\xe7\xd1\x34\xf2\xe1\x43\x9a\x2c\xe2\xe5\x2c\x4a\xfe\xc8\xc2\ +\xbe\xf8\x8f\x22\x4d\x63\xbb\x01\xb2\xed\x35\x5c\x2f\xd2\xac\x20\ +\xeb\x60\x01\x70\x4a\xb5\x57\xf9\xd2\x28\x1f\x40\x3b\x09\xc2\x69\ +\x8e\xa5\xaa\xb1\xe1\x27\x18\x9c\x1a\x58\xa3\x52\xdb\x9a\x8a\x76\ +\x06\xcf\x51\xb8\xda\x94\x7d\xf4\xf2\x0a\x3f\xcb\x5a\x78\x33\xf0\ +\xb5\x38\xcd\xee\x07\x6f\xa7\xe5\x55\x2b\x1e\xd3\x2c\x08\xb3\x46\ +\x25\xcb\xab\xa7\x4a\x61\x3e\xa2\xe2\xa5\x8a\xae\xba\xed\xc6\x5e\ +\x6c\xb5\xd5\x3b\xfb\xf5\xf9\x93\x17\xa4\xab\xfb\x01\xdb\x56\x7e\ +\x4a\xd3\x39\xb4\x0a\xf3\x62\x94\x76\x76\xd4\xfe\xfa\x7e\x40\xa8\ +\x6b\x1b\x18\xac\x31\x3b\x5a\x34\x48\xd8\x5a\x70\xc1\xc4\x8e\x72\ +\x99\x65\x10\x7f\x24\xf6\x5e\x42\x18\x55\xf9\x8b\xd6\x85\xf2\xa7\ +\x74\x35\xcb\x10\x9d\x22\x5b\x86\xdb\x35\x51\x43\x1e\x1f\xd3\xf5\ +\x7e\x35\xb8\xc3\x12\x23\x9b\x2c\x93\xa8\x80\xe8\x59\xac\xbb\xad\ +\x2e\xa3\x20\xcc\xf7\x57\xcc\x13\x6f\x41\x66\x71\xfa\xe8\xc5\xfb\ +\x0b\xac\xa2\x04\x50\x22\xb5\xa3\x53\xde\x4e\xc2\x76\x89\xc6\xeb\ +\x95\xa3\x0f\x94\x00\xdb\x77\x26\xa2\x56\xbd\x1c\x56\xcd\xbd\x75\ +\x34\x8f\x3e\x85\x00\x0c\x2d\xfd\x0e\x7c\xab\x07\x4b\x55\xcd\xb2\ +\x8a\x17\x8c\xe0\xf5\x0b\xca\x06\x8d\x10\xf1\x44\x01\x33\x46\xb5\ +\xc2\x34\x8b\x20\x30\x3a\xe6\x34\xa2\x97\xae\x08\xe3\x1d\xd2\xf5\ +\xba\x74\xb0\xd2\xfd\xd4\xb6\xee\xa5\xab\xab\xfd\x7e\xb4\xeb\xf8\ +\xa5\x7c\x1e\x16\x5e\xe0\x15\xde\x26\x0a\x1a\x09\xd8\xe6\x34\x23\ +\x83\xd4\x39\xfe\xe7\x87\x9f\x1f\xea\x8e\x26\xbe\x3f\xfe\x77\x9a\ +\x7d\x6c\xfa\xb5\x2c\x2c\xe0\x3d\xa6\x4b\x40\x7a\xf0\xd0\x8a\x27\ +\x81\x3f\x86\x64\x07\x49\xe0\x21\x9a\x83\x6f\x63\x9e\xfc\x1b\x24\ +\xb7\xc9\x68\xa3\xe8\x15\x46\xb0\x36\x8d\x56\xcd\x66\x61\x95\x35\ +\xf7\x2e\x1d\x81\x3f\x8f\xb0\xd2\xe8\xb7\x22\x8a\xe3\x5f\xb0\x93\ +\x7a\xc4\x9d\x46\xa3\x22\x0e\x37\xc2\xc9\xa8\xb6\xbe\x1e\xdb\xa8\ +\x33\xb8\xc9\xa8\x19\x7d\xf9\x69\xb6\x41\xa5\x17\x14\xed\x44\xc7\ +\xde\x63\x08\x1e\xfa\x2b\x2a\xad\x1d\xed\x2c\x4b\x97\x8b\x79\x1a\ +\x84\x75\xf5\x06\xcd\x85\x57\x3c\xb5\x53\x56\xbc\xc4\xa0\x2f\x13\ +\xca\xf8\xad\x53\x5e\x77\xd3\x14\x62\xa6\xd4\x8c\x13\x44\x29\xae\ +\x24\xcf\x5e\x16\x79\x49\xd1\x93\xad\x4a\xff\xee\x89\xf2\x22\x0b\ +\x0b\xff\xa9\x2f\x03\x57\x1d\xc3\xbc\x47\xcb\xf9\x5d\x1c\x25\x61\ +\x1d\x17\xbd\x32\x53\x6f\x1e\xc5\x2f\xe3\xdf\xbc\x24\xbf\x23\xcd\ +\x20\x48\x55\x7d\x11\xfa\x6d\xa6\xae\x4a\x14\xe1\xba\x80\x52\x01\ +\x84\xf7\xd8\xa9\x3e\x79\x71\x34\x4b\xc6\xc0\x1f\xb2\xa2\x12\x04\ +\x90\x43\xb3\xaa\x4e\x02\x7c\x62\x5b\x48\xd0\x92\x4a\x13\x87\x45\ +\x11\x66\xa4\x76\xe0\xc6\xac\x15\x64\xd4\x6d\x59\xd9\x46\x91\x81\ +\x09\xe8\x40\x55\xed\x55\x16\x15\x50\x84\x20\xd6\xe3\x38\x23\xc5\ +\xe3\x5d\x10\xc1\x02\x53\xf6\x1c\x17\xd9\x1d\x66\xf6\x72\xd8\xf9\ +\x53\x34\x2d\xc6\xcd\xc7\xda\xec\xc4\x7f\x02\xf0\x2b\xbb\x83\x28\ +\x5f\xc0\x64\xc1\xe2\x5b\x16\x48\x61\xd5\x9b\xc6\xe9\x6a\xfc\x1c\ +\xe5\xd1\x63\x1c\xde\x95\xbf\xa3\x18\x9c\xae\x15\x4d\xc1\xf3\x36\ +\x53\x07\x1f\x48\x9d\xe3\xc7\xf4\x0e\xe6\x22\xfd\x58\x8f\xb1\xfa\ +\xbb\xca\x59\x63\x6e\x8b\x72\x15\x16\xec\x6e\xee\x65\x1f\xc3\xac\ +\x2a\x13\x26\x1e\x34\x49\x1e\x3d\xff\x23\x7a\x4f\x12\x8c\x3d\x1f\ +\x72\xe8\x32\x06\xee\xd5\x86\x39\xb8\xe3\x3f\x2c\x48\xf5\x9a\x71\ +\x43\xd5\x90\x41\xac\x3b\x86\x31\x65\xbd\xb7\x28\xac\x2a\xda\x50\ +\xa1\x86\x40\x27\xb4\x96\x98\x60\x2c\x69\x6b\xe5\x30\x25\x39\x14\ +\xe5\xda\x28\x25\xb4\xc5\x6d\xaa\x98\x16\x54\x0e\x95\x2d\x38\x33\ +\x8e\xab\xad\x5f\x2d\xa8\x44\x1d\xe1\x2a\x6e\xd4\xd0\x05\x9a\xa0\ +\xa9\x2b\x85\x45\x6d\x25\x05\x93\xda\x1d\x42\xa7\x42\x30\x57\x18\ +\x8b\xd9\x4a\x6b\x6a\x04\x43\x19\xa3\xda\x11\x1c\x3b\x17\x54\x1b\ +\x57\x0d\xe1\x2f\xce\x1d\xa9\x24\xf4\x2d\x86\xda\x76\x79\x79\x59\ +\x3e\xd6\x63\xc6\xe5\xd4\x0c\x09\xb3\x8d\xd6\x5c\x6a\x65\x41\xab\ +\x2e\x13\x4a\x0f\x89\x8b\x32\x41\x0d\xb5\x0c\x66\x30\xb0\x60\x48\ +\x90\xaf\x50\xa6\xa9\x82\xca\x38\x1e\x4e\x87\x8e\xcd\x34\xa7\x94\ +\xa2\x1d\x06\x86\xa6\x0d\x8e\xd7\x35\x52\x51\xe9\x5a\xd0\xb9\xab\ +\x94\x16\xd8\x05\x17\x94\x32\x65\xac\x4f\xbd\xdc\x8b\x11\x08\xac\ +\x40\x13\x45\x36\x99\x75\xb3\x1e\xa6\x49\x02\xce\x93\x66\x04\x56\ +\xc6\x67\xaf\x58\x66\x61\x2f\x03\xb7\x99\x14\xdc\x0d\x93\x0f\x2c\ +\x62\x7e\x73\xb5\xd9\xe7\x7b\x94\x7f\x8f\xf2\x63\xa3\x7c\x6e\x51\ +\x0d\x01\x07\xdc\x5c\x0d\x39\xb5\x99\xe3\x4a\x2a\x21\x88\x5c\x5b\ +\x19\x88\x48\x03\xf1\xac\x99\x70\x18\xb5\xb4\x6d\x84\x70\x65\x15\ +\x06\xb0\x25\x51\xda\xa2\x0c\xc3\x4e\x38\x06\xa3\x4a\x0a\xea\xb8\ +\xca\x8a\x21\xee\x39\x83\x72\x1a\xaa\x32\x26\x98\x05\x21\xe2\x68\ +\x68\x1f\xe2\x0c\x82\x96\x49\x46\xa9\x45\x80\x3d\x50\x0d\x81\x8c\ +\x71\x26\x24\xe7\x20\x52\xd0\xac\x70\x8d\x81\xb4\xe0\x08\xc3\xb4\ +\xb1\x84\x0d\xe6\x08\x41\x87\x90\x1e\x28\x75\x20\x4f\xf8\xd8\x9a\ +\x94\xae\xe3\x9a\x21\x87\x62\x12\xec\xb0\xa0\x73\xce\x38\x83\xe4\ +\x21\x21\xb7\x70\xcc\x1d\x04\xac\x55\x2e\xb0\xd4\xa1\x00\x9d\x80\ +\x84\x83\x15\xb9\xe3\x32\xd7\xc5\x01\x30\x0e\x79\xad\x34\x0d\x8c\ +\xe0\x0a\xcd\x90\xae\x96\x0e\xc5\xfc\xc4\x1d\x25\x15\x26\x3d\x2e\ +\x20\xff\xe9\x43\x81\x7d\xb6\xb0\x9e\xf5\x38\x9c\x70\xa8\xdb\xe9\ +\xab\x8e\xf3\xae\xaf\xb4\xba\xd6\x9b\x91\xd1\xc2\x9f\x38\xd9\x3f\ +\x12\xa6\x6c\x55\xe6\xc6\x21\xcc\x97\x7e\xd7\x92\xa7\x09\x3a\x76\ +\x87\x5f\x95\x9c\x4e\x30\xbc\xf8\xa0\x23\xef\xd1\x45\xcb\x82\x62\ +\x0c\xa7\xb1\xb3\x2d\xc1\x0b\x4a\x31\x69\xcb\x6d\x71\x43\x8e\x45\ +\x5d\xc3\x74\x74\x35\xb5\xde\xa7\xc2\x91\xa3\x79\xae\xe6\x86\x50\ +\x4e\x18\x91\x84\x76\xf4\x7b\x50\xd8\x8e\x98\xf2\x63\xb6\x84\xd4\ +\x17\x3e\x87\x00\x78\xd0\xc4\x50\xbd\xdb\xea\x87\x91\xd3\x7c\x04\ +\xb2\x17\x66\x31\x10\xef\x62\x2c\x1a\x59\xe0\xc1\x96\x29\xcb\x20\ +\x9a\xbb\xf1\xd7\x76\xd5\xa1\x83\x27\xc7\x94\xc3\x56\x18\xe7\x8e\ +\x9d\x1a\x53\x58\x97\x38\x31\x44\xdc\x24\xa8\xc0\x27\x70\x74\xf4\ +\xe4\xa0\x6a\xe2\xc2\x0f\x27\xce\x4d\xc2\x6a\x6c\xd1\xdf\x2d\x9e\ +\x0a\x56\x07\x20\x55\xe0\xad\x97\x0f\xeb\x64\x34\xdb\x9b\xc5\xb9\ +\xd1\x8c\xf0\xcf\x67\x6a\x4c\xcf\x40\x28\x61\x29\x7d\xf7\xd9\x74\ +\x7f\x82\x09\xd4\xb0\xbc\xe3\xd5\x9f\x40\x6a\xce\x15\x17\x4e\x19\ +\x19\xec\xe2\xa7\xef\x28\x50\x45\xbd\x09\xf9\xf3\x40\x55\x44\x60\ +\x5c\x5c\x35\xac\x5c\xd9\x7c\x7b\x05\x3c\x33\xac\x12\xfe\x89\x57\ +\x90\x6c\x8e\x82\x95\xd7\xf7\xef\xfe\x4c\x6f\x35\x90\xc7\x25\x51\ +\x17\x0f\xec\xa1\x2c\x8e\x5c\xfc\x08\x26\xae\xaa\xf5\x51\xaa\xe1\ +\xe6\xcf\x57\xcb\xc7\x2f\x7e\x12\x5f\x1f\x1b\xbf\x49\x48\xcf\xcd\ +\xc5\x6f\x12\xd4\x73\x33\xf1\x8b\x07\xf5\x73\x3c\xfc\x7f\x64\x69\ +\xbc\x9f\x8c\xff\x5d\x27\x09\xbf\xf8\x99\x7b\x8d\x14\xfc\xaa\x41\ +\xfd\x56\x04\xfc\xba\x41\xfd\x66\xf4\xfb\xe2\x61\xdd\xa4\xee\x2e\ +\xba\x3d\x5b\xa7\x53\xe6\x31\xef\x1b\xda\xfa\x66\x2f\xc8\x9b\x39\ +\x3f\x38\x2f\x87\x27\x13\x67\x7f\x33\x39\xe8\x22\xf6\x26\xe2\xfa\ +\x1e\xd4\xf7\xb3\x16\xb7\xd7\x06\x57\x27\x6f\x7e\x1d\x5e\xbb\xec\ +\xe7\x26\x60\xeb\xae\xe2\x5f\x09\xdc\xce\x3a\x79\x13\xc0\x39\xe4\ +\xd8\x08\xdd\xe5\x6c\x27\x06\xce\x18\xd7\xbd\x38\xe0\xba\xab\xc6\ +\x29\x32\x1b\xd9\x7d\xae\xec\x2a\x71\x83\x25\x97\x9d\x23\xc5\xdd\ +\x0c\x7e\xb8\x85\x37\xe7\xc8\x75\x27\x47\x50\x7f\x6b\xf6\x74\x28\ +\x72\x8f\x75\xc0\x7e\xe4\x52\x5a\x3d\x4b\x20\xae\x1b\x36\xbc\x1d\ +\x77\x8e\xc0\xbd\x15\xf8\xca\x5b\x6f\xe7\x88\xdb\x5b\x01\xb0\xbc\ +\xcd\x76\x0e\xae\x72\x6a\x00\x03\x71\x91\x00\xe2\xd7\x4c\xa7\xcd\ +\x7c\xed\x17\x36\xd7\x0d\x1c\x52\x96\xf3\xec\xcb\x6e\x05\xc0\x92\ +\xb3\x74\xbe\x3c\x3e\x61\xf6\xbb\x15\x08\x31\xfb\xb1\xce\xf3\x7e\ +\x27\xcc\x7f\xa7\x86\x50\x08\xd7\xbd\x3c\x08\x9d\x63\xd9\xcb\x1e\ +\x7e\xbc\xf7\xdb\xa6\x6b\x04\x8f\x1e\xbd\xdb\xed\xde\x10\xb8\x21\ +\xd8\xf4\xd1\x0b\xc7\x6e\x74\xde\x10\x7c\xce\xd1\x94\x79\x97\xdc\ +\x9d\x01\x3e\xe6\x73\x75\x79\xf0\x39\x47\xfb\xde\xfe\x94\x47\xaf\ +\x1b\x36\x4a\xc4\xa9\xb3\xdd\xd5\x23\xa6\xe1\xc7\x3d\xf6\x0e\xfc\ +\xde\x4c\x77\xf5\xd0\x95\x5f\x97\x9f\x23\xc9\x9d\x0c\x39\xad\x3d\ +\xef\x12\x91\xd3\xfa\x68\x3e\xbc\xcd\x4a\x76\xe8\xf1\x95\x22\x07\ +\xbb\xb1\xf3\xf0\x92\x1b\x01\xb0\x7c\x1c\xe3\x2c\xcc\xe4\xc4\x00\ +\x4a\xa9\x2f\x70\x3b\xeb\xc0\x12\x7b\x6c\xe8\x1e\xd8\x8e\xed\xdc\ +\x23\xb8\x46\xfc\x90\xa2\x1c\x7f\x4b\x6a\x3b\xf9\xdd\x08\x74\x25\ +\x57\x39\xfa\x66\xd4\xfe\xf4\x77\x23\x10\xd6\x0f\x4e\x9d\x25\x01\ +\x7e\x1d\x84\xdf\x8f\xfd\x5f\xe1\xb1\x7f\xed\xec\x73\xff\xda\xd9\ +\xcf\x71\xec\x5f\xd9\x5c\xe3\x4b\x32\xb8\x83\x6f\xe1\x30\xc2\xec\ +\x39\xf5\xcf\xfe\xef\x53\xff\xa6\x3e\xf5\x8f\x27\xe9\xeb\x73\xff\ +\x66\x73\xee\x7f\x73\xf0\x5f\x34\x07\xff\x59\x7d\xf0\x5f\x36\xc7\ +\xfe\x75\x73\xec\x9f\x35\xc7\xfe\xdd\xcd\xb1\x7f\xd9\x9c\xfa\x97\ +\xed\xa9\x7f\xd9\x9c\xfa\xd7\xf5\xa9\x7f\xdd\x9c\xf9\x17\xed\x99\ +\x7f\x71\xa2\x33\xff\x1b\xe1\x69\x4f\xfc\xbf\x3a\x4e\x88\xdb\x91\ +\xa3\x73\xe2\x01\x56\x73\x62\x56\x78\xd1\xcf\xb6\x1c\xff\x74\xcb\ +\xbe\x2f\x39\xbe\xf6\xe9\x16\x4c\x67\x6d\xdb\xf3\x78\x5c\xbe\xf8\ +\x0f\xbc\x3f\x0b\xf3\x30\x7b\xde\x24\x90\x06\xdf\xfd\xcb\xcc\xbe\ +\x25\x05\x97\x0f\x3c\xde\x5c\xae\x4f\xd4\x2c\xd6\xbd\x55\xc4\xf9\ +\x6b\x6f\x05\xc9\x21\x39\x13\xe8\x31\x9a\x6e\xe7\x75\x07\x2a\xf6\ +\x92\x3a\x0a\x9a\x69\x2e\xa7\xed\x4b\xf3\x67\x8b\x10\xeb\xad\xd2\ +\x3b\x8f\x5f\x23\x50\x60\x77\x6f\x12\x11\x26\x4c\x25\x83\x87\x49\ +\x01\x86\x24\x8d\xae\x13\xee\x59\x8a\x00\xe1\x18\x07\x1b\x6d\x59\ +\x17\x2b\x40\xe5\xee\xd3\xed\x07\x9e\xfb\xde\xee\xba\x8f\x7b\x8d\ +\xf2\x63\x1a\x07\x5d\x8c\x55\x35\x2e\xe5\xca\x2d\x8c\xa9\xcd\xdc\ +\x43\x28\x7f\x76\xb5\xfe\x01\x97\x6b\xeb\xef\xd0\xcf\x0f\x5f\x00\ +\xf5\x2e\xbc\x0f\x74\x32\x2a\x47\xfd\x00\xbf\x01\xb9\xef\xbe\x56\ +\x47\x6e\xf5\x8e\xcc\x3e\x23\xdc\x3d\x60\xd8\x75\x38\xc8\xb8\xc7\ +\xb8\x1c\xd9\x3e\x1f\xba\x63\xc1\x01\x1b\x5e\xab\xe7\xb1\xbd\x9e\ +\xf7\x9d\x3e\x5f\x21\x7d\x46\x9a\xf4\xa7\xbe\x1b\x4f\xd8\x4a\x30\ +\xe9\x68\x60\x91\xda\xb8\x94\xe3\x2b\xa6\xde\xe3\x2b\xe5\x80\x22\ +\xf3\xf2\xd5\x73\x40\x3c\x1d\x43\x0d\x92\x6a\x20\x9c\x12\x78\x30\ +\x44\x02\xc3\x03\x88\xd2\x02\xad\xa1\xc0\xa2\x19\x90\x57\x26\x81\ +\xe5\x72\x89\xef\xc6\xa3\x36\xd5\xae\x06\x02\x0a\x34\xd7\x28\xc6\ +\x81\x8b\x5b\xc0\x52\x35\x33\x40\x53\xe9\x10\x3a\x65\x40\x53\x81\ +\x6f\x03\x33\x76\x24\x90\x6b\x83\x32\xe8\x88\xb9\xf8\x3a\x3b\xce\ +\x95\x14\x86\x0e\x8d\x4d\xa5\xd0\x9a\xe3\x6b\xef\x38\xd5\xd2\x94\ +\xef\xe0\xe3\x50\x53\x00\x05\x7f\x0f\xa4\xde\x01\x96\x0b\xcd\x23\ +\x53\x56\x86\x2a\x26\xf0\xcd\x7a\x0a\xec\x90\x68\x25\xca\x80\xfb\ +\x43\xd3\x5c\x43\x41\x7c\xd5\x16\x14\x66\xae\x81\x62\x12\xcc\x81\ +\x0d\x01\x88\x5c\x0a\x2c\x9a\x72\xdc\x49\x30\xad\x24\xc5\x17\x7e\ +\x49\x6e\x5c\xd8\x3f\x34\xf0\x50\xde\xc0\x43\x5d\x66\xfd\x67\x2f\ +\xa7\xee\xdc\xda\x39\x25\xab\x2e\x4f\x11\x4d\xf0\x75\xa0\x0f\x6f\ +\xfe\x0b\x1d\xb4\x71\xa7\ +\x00\x00\x06\x94\ +\x00\ +\x00\x25\x7d\x78\x9c\xe5\x59\xdb\x6e\xdb\x38\x10\x7d\xcf\x57\x68\ +\x9d\x97\x16\x6b\x51\x22\x75\x57\xec\xf4\xa1\x45\x17\x05\x76\xb1\ +\xc0\x36\xc5\x3e\x16\xb4\x44\xdb\xda\xca\xa2\x41\x51\xb1\xdd\xaf\ +\xdf\xa1\xee\xb2\xe5\x36\x6d\xd2\x36\x41\x14\xc4\x91\x66\x86\x97\ +\x39\x3c\x73\x91\x33\x7b\xb5\xdf\xa4\xda\x2d\x13\x79\xc2\xb3\xf9\ +\x04\x23\x73\xa2\xb1\x2c\xe2\x71\x92\xad\xe6\x93\x0f\x37\x6f\x75\ +\x7f\xa2\xe5\x92\x66\x31\x4d\x79\xc6\xe6\x93\x8c\x4f\x5e\x5d\x5f\ +\xcc\x7e\xd3\x75\xed\xb5\x60\x54\xb2\x58\xdb\x25\x72\xad\xbd\xcb\ +\x3e\xe5\x11\xdd\x32\xed\xc5\x5a\xca\x6d\x68\x18\xbb\xdd\x0e\x25\ +\xb5\x10\x71\xb1\x32\x5e\x6a\xba\x7e\x7d\x71\x31\xcb\x6f\x57\x17\ +\x9a\xa6\xc1\xba\x59\x1e\xc6\xd1\x7c\x52\x0f\xd8\x16\x22\x2d\x0d\ +\xe3\xc8\x60\x29\xdb\xb0\x4c\xe6\x06\x46\xd8\x98\x74\xe6\x51\x67\ +\x1e\xa9\xd5\x93\x5b\x16\xf1\xcd\x86\x67\x79\x39\x32\xcb\x2f\x7b\ +\xc6\x22\x5e\xb6\xd6\x6a\x37\x3b\xab\x34\xc2\x41\x10\x18\x26\x31\ +\x08\xd1\xc1\x42\xcf\x0f\x99\xa4\x7b\x7d\x38\x14\xf6\x38\x36\x94\ +\x98\xa6\x69\x80\xae\xb3\xbc\x9b\x55\xb8\x4f\x01\x8a\xb3\x9b\x29\ +\xb5\xfd\xd5\x01\xfe\x2d\xfc\xb6\x03\x1a\x01\xca\x79\x21\x22\xb6\ +\x84\x91\x0c\x65\x4c\x1a\x6f\x6e\xde\xb4\x4a\xdd\x44\xb1\x8c\x7b\ +\xd3\x34\xe8\x0f\xd6\x1d\x1c\x49\x46\x37\x2c\xdf\xd2\x88\xe5\x46\ +\x23\x2f\xc7\xef\x92\x58\xae\xe7\x13\xcb\x46\xd8\x82\xcb\x29\x85\ +\x6b\x96\xac\xd6\xf2\x58\x9a\xc4\xf3\x09\xf8\x4a\x02\xbf\x7a\xee\ +\x51\x09\x57\x06\xf5\xc4\x61\xab\x31\x51\x40\x10\xd6\x04\x76\x2c\ +\xaf\xb2\x69\x5c\x08\x63\x1e\xa9\x3d\xc1\x94\x6c\x93\xd0\x42\xf2\ +\x0d\x9c\x71\x14\xa5\x34\xcf\x93\x65\x12\xc1\x03\xcf\xb6\x69\xb1\ +\x4a\xb2\x8f\x82\x27\x1f\x37\x45\x2a\x93\x6d\xca\x50\x83\x76\xbb\ +\x18\xdb\x6f\xb9\x90\xfa\x3e\xde\x02\x8a\xae\x37\xaa\x3c\x34\xca\ +\x6b\xd0\xce\x62\xb6\xcc\x95\x55\xe5\x92\x7a\x02\x9f\x2a\x1d\x68\ +\xe1\x84\x18\x15\x7f\x08\x1a\x27\xc0\xcb\xca\xae\xb2\x1c\x6a\x1c\ +\xcf\x6b\xc6\xc0\xa8\x5c\xf2\x6d\x63\x0b\x5e\xca\x43\xaa\x5c\x03\ +\xa1\x1e\xf1\x94\x8b\xf0\xd2\x34\xf1\xc2\x71\xaf\x4a\x11\x87\x83\ +\x48\xe4\x21\xc4\x57\x93\x6e\x0c\x5f\x2e\x73\x06\xa0\x9b\x3d\x59\ +\x09\x39\x8c\x80\xb5\x82\x89\x66\x9c\x59\xad\xb3\xf2\xbd\xb1\x09\ +\x91\x6b\x7b\xa6\xe3\xfb\xf6\xe4\x8b\x3b\xb4\x5d\x0f\x7b\xcb\xe1\ +\x0e\x4d\x64\x07\xbe\x69\x05\x84\x5c\x9d\x5f\x7f\x64\x2e\x1c\x7b\ +\x96\x7f\x3c\xd7\x98\xb7\x78\xd4\x5b\x1f\xb7\xab\xcd\x8c\x21\xec\ +\x5f\x3e\xa5\xe6\xdc\x61\x1b\x29\x8b\x60\x7e\x9a\xee\xe8\x21\x6f\ +\x17\x29\xe3\x2f\x5c\x0b\x06\xf9\xe2\x72\xe4\x3c\xbf\x74\xdc\x35\ +\xed\xcb\x69\x70\xff\x9c\x0e\xf0\x64\x91\x4e\x49\x54\xe4\x74\x5a\ +\xd2\xb7\x5d\xd5\xd3\x7d\xc8\x12\x09\x29\xa5\xc8\x99\x78\xaf\xc2\ +\xf2\xef\xec\x43\xce\x4e\xac\x6e\x04\xcd\x72\xc8\x01\x1b\x00\x26\ +\xa2\x29\x7b\x01\x59\xdb\x55\x97\xf7\xb2\x03\xe8\x17\x40\x11\x1c\ +\x41\x81\x88\x33\x40\x03\xbb\x43\x34\x30\xf2\x9c\x01\x20\x3d\x83\ +\x87\x46\x64\x66\xa8\x88\x2e\xef\xda\x64\xa3\x32\x4d\x7c\x9b\xb0\ +\x5d\x17\xf6\x0b\xda\xce\xbe\xa5\x2b\x56\xf2\x16\x80\x58\x96\x57\ +\xad\x58\x70\x11\x33\xd1\xa8\xca\x65\xdc\x81\xaa\xa6\x76\x55\x4d\ +\x2f\x86\xb8\xab\x59\x5b\xbd\x39\xae\xcf\xd7\x34\xe6\xbb\xf9\x84\ +\x1c\x2b\x3f\x73\x0e\x1e\x62\xc8\xac\x81\xe7\x9b\x27\xea\x68\x3f\ +\x9f\xe8\xd8\x45\x41\x80\xcd\x96\x6a\x9d\x16\x16\x24\x04\x79\x6a\ +\xa8\x7f\xa2\x2c\x84\x00\x1c\xf5\x94\x1e\x18\x78\x55\xfe\x69\x82\ +\x30\x5f\xf3\xdd\x4a\x28\x74\xa4\x28\xd8\xf1\x48\xa5\xd1\x17\x0b\ +\xbe\x1f\x57\x43\x42\x2f\x54\x25\xd7\x8b\xea\x20\xb7\xfb\xfe\xac\ +\x45\x12\xb3\x7c\x7c\x60\x9e\xd1\xad\xbe\x4a\xf9\x82\xa6\xe3\x06\ +\xbb\x24\x03\x94\xf4\xba\x54\x61\xab\x3d\x84\x63\x8b\xa6\x6e\x79\ +\xa7\x6e\xd7\x16\xfb\x2e\x16\x8f\x55\x87\xf3\xaa\x0d\xdd\x27\x9b\ +\xe4\x33\x8b\x55\xbe\xaa\xa3\x6e\x00\x4b\xc3\x52\x79\x50\x35\x78\ +\x7f\x50\xb2\x41\x00\x29\x01\x09\x82\x2e\xaa\xb8\x48\xa0\xb4\xed\ +\xfb\xa9\xa1\x12\x1d\xfa\x22\x55\xb1\xa1\x3d\xdb\x97\x04\xab\x68\ +\x7e\xac\x3b\xf4\x75\x4d\x04\x9c\x12\xbf\x94\x6f\x98\xa4\x31\x95\ +\xb4\x8b\x82\x46\x02\x7b\x33\x1b\xcf\xa0\x55\x0a\xff\x79\xf3\xb6\ +\x4d\xf6\x51\x14\xfe\xcb\xc5\xa7\x2e\x4f\x2b\x03\xba\xe0\x05\x20\ +\xdd\x16\x40\x55\x56\xa3\x50\x05\x26\x95\xd7\xc9\x06\xb8\xad\xfa\ +\xa2\xdf\xa1\x3d\x81\x78\x6c\x15\x03\x63\x05\x56\x37\x69\x35\xad\ +\x60\x55\xdf\x33\xda\x2a\xc6\xd1\x26\x51\x83\x8c\xf7\x32\x49\xd3\ +\x77\x6a\x91\x5e\x51\xaa\x27\x4d\x64\xca\x7a\x95\xca\xa8\x77\xdf\ +\x14\x93\x9e\x73\x33\xa3\xf1\xbe\x7c\x5a\x75\xa8\x0c\x82\xa2\x3d\ +\xe8\x94\x2e\x18\x30\xf4\x4f\xa5\xd4\x4e\xb4\x2b\xc1\x8b\xed\x86\ +\xc7\xac\x1e\xde\xa2\x09\xb9\xb7\x3d\xb2\xaa\x50\x2e\x61\xf7\x21\ +\xf8\xf5\xe2\x24\xed\xfa\xce\xcb\x2b\xa5\xed\x75\x08\xe5\xa3\x28\ +\x52\xe8\x65\x6e\x59\xc6\xe3\x18\x8a\xaa\xe0\x9f\xd8\xf8\x04\x01\ +\x4c\x50\xe9\xab\x70\x09\x31\x72\xcd\xf2\x22\x8d\x1c\x30\x64\x22\ +\x05\x3e\xcb\xd0\x6e\x64\x31\x85\x4c\x24\x04\x3d\x84\x19\xb4\xfe\ +\x8d\xb4\xdd\xc4\x80\xca\xca\x21\xa0\x4b\xd0\x0a\x9b\x16\xb2\xab\ +\x80\x6d\xff\xd8\x2b\x8a\x63\x14\x3e\x8c\x09\x05\x98\x3a\xc8\xb2\ +\x4c\xcb\xed\xd6\x10\x60\x6a\x21\xdf\xb4\x7d\x55\x86\xdb\xd2\xb7\ +\xa5\x72\x3d\x06\xee\x65\x50\x5e\x0d\x54\x97\x15\x04\x43\x64\x08\ +\x22\xbe\xe9\x92\x00\xbb\x8d\x5c\x81\x09\x67\x19\x2e\x0a\x29\xfb\ +\xb2\xff\x78\x92\x85\x25\x6c\xdf\x8f\x21\x74\xc2\x81\x6b\x7a\xbe\ +\x6d\xb5\x3e\xa9\xf0\xd3\x88\x87\x3c\xd5\x62\x5b\x53\xe5\x73\x79\ +\x69\x91\x66\x4e\x7d\xe4\x94\x0f\xde\xb9\xfb\xc1\x99\x28\x1c\x2c\ +\xcf\x0d\x74\x57\xef\x20\xef\x75\x00\x19\x38\x26\xb9\xd0\x21\xf9\ +\xdf\x52\x59\x08\xa6\x92\xcc\xd7\x51\x84\xf2\x01\x3f\x5f\x41\xd1\ +\xc6\x7e\xe0\x11\x3b\xf8\xa5\x28\x12\x14\x54\x28\x06\xc8\x05\xfc\ +\xe0\x73\x6a\xf6\x3f\x4f\xd1\xf2\x6d\x4f\x77\xac\x07\x04\xeb\xc9\ +\x50\xae\xa1\x90\x35\x25\x18\x9d\x52\xce\x1e\xbf\x3d\xc7\x37\x4f\ +\xf7\x9e\x23\xe3\xac\x3a\x6c\x01\x44\xa7\xa6\x9c\x53\x12\xc0\x2b\ +\x29\x37\x7a\x3f\x4e\x42\xff\x41\x43\xf6\xc9\xb0\x50\x85\x25\xa9\ +\xbe\x5e\xb0\xc8\x20\xe5\xf9\xe7\xee\xcf\x51\xd0\xd6\x9d\xe7\x48\ +\x41\x1b\xf9\x53\x17\x59\xd5\x89\xdf\x3d\xe9\xe1\x07\x45\x6b\xb9\ +\xf4\x96\x84\x3e\x32\xbe\x55\xdf\x58\x1c\x95\x08\x17\x55\x8d\xc6\ +\x14\x7b\x55\xcf\xe1\x0d\x58\x37\x7e\x7b\x8e\x72\x81\xee\xff\x6c\ +\x10\x7f\x36\xe5\x46\x41\xc4\xc8\xaf\x40\xec\x97\x8e\x3b\x12\xcf\ +\x7c\x50\xe2\x3d\x99\x44\x87\x1d\x64\xd7\xc4\x33\x6b\x0a\xde\x83\ +\x78\x5e\xf0\x3c\xeb\x6d\x8b\xdd\x14\xdb\x75\xaf\xf7\x0d\x7d\xde\ +\x83\x62\x76\xc4\xbc\xe5\x92\x2e\x89\xf5\x18\x99\xd7\xa5\x3c\x17\ +\xd9\xdf\xcf\xb9\x1f\x47\xb7\x71\xe8\x1e\x03\xdd\xba\x44\xd7\x0f\ +\xda\xbb\xd1\xed\x39\x52\xcd\xab\x72\x9c\x2a\x0c\xe4\x3e\x5c\xfb\ +\x91\xc9\xed\x11\xb3\xad\xa2\x98\x42\xcf\x1d\xb0\xad\x4c\xc7\x56\ +\xc5\xb6\xb1\xfb\x33\x6f\x14\xcf\x91\x81\xdd\x5b\xad\x85\x70\xdb\ +\x13\x77\x84\xc3\xe7\xee\xcf\xbe\x55\x3c\x47\x26\x76\xaf\xb5\x4d\ +\x44\xdf\xeb\xdd\x16\xff\xb8\x26\xf9\xd7\x33\x11\x1f\x05\xb1\x03\ +\x15\x01\xfb\xf5\x2b\xed\x3d\xbe\x51\x09\x7e\x36\x68\x8f\x81\x78\ +\xc4\x84\xb7\xd9\xba\x76\xdc\xf5\x7d\xe2\x39\xa6\x39\xe8\x7e\xed\ +\x29\xc6\x75\x98\xde\xe7\x7b\xbb\x87\xa4\xd9\x13\xc9\x6f\x7f\xb5\ +\xb5\x13\x30\x74\xb5\xd7\x1a\x0e\x10\x51\x77\x47\x7f\xcf\xbc\x45\ +\x7c\x23\x60\x33\x63\x75\x7d\x31\x53\xff\x06\xbb\xbe\xf8\x1f\xbe\ +\x4f\x01\xc4\ +\x00\x00\x09\x99\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x70\x65\x6e\x5f\ +\x64\x69\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x2d\x36\x38\x2e\x36\x31\x31\x38\x34\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x2d\ +\x32\x2e\x36\x31\x31\x30\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ +\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ +\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ +\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ +\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ +\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ +\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ +\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ +\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ +\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ +\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ +\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ +\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ +\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x23\x38\x30\x38\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x31\x2e\x31\x39\x32\x35\x36\x39\x36\x31\x70\ +\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\ +\x33\x33\x33\x33\x33\x20\x48\x20\x32\x36\x2e\x36\x36\x36\x36\x36\ +\x37\x20\x56\x20\x32\x38\x2e\x38\x20\x48\x20\x30\x20\x5a\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ +\x30\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ +\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\ +\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x30\x2e\x38\x37\x30\x39\x32\x39\x37\x32\x70\x78\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ +\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ +\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\ +\x33\x20\x31\x36\x2c\x39\x2e\x32\x34\x34\x34\x34\x34\x35\x20\x56\ +\x20\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x4c\x20\x30\x2c\x32\ +\x37\x2e\x30\x32\x32\x32\x32\x32\x20\x76\x20\x2d\x32\x34\x2e\x38\ +\x38\x38\x38\x38\x38\x37\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\x2b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x72\x65\x6d\x6f\x76\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ +\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x38\x2e\x34\x32\x36\x32\x38\x37\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x33\x35\x2e\x32\x34\x33\x38\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\ +\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ +\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ +\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\ +\x30\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\ +\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\ +\x74\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\ +\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x36\x2e\x30\x39\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x63\x65\ +\x63\x65\x63\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x37\x65\x37\ +\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x35\x2e\x31\x39\x31\x32\x39\x38\x39\x36\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ +\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ +\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x38\x36\ +\x36\x36\x36\x36\x37\x2c\x31\x36\x2e\x38\x36\x31\x32\x31\x31\x20\ +\x48\x20\x32\x38\x2e\x32\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x38\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ +\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ +\x70\x65\x73\x3d\x22\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x12\x20\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x34\x20\x28\x35\x64\x61\ +\x36\x38\x39\x63\x33\x31\x33\x2c\x20\x32\x30\x31\x39\x2d\x30\x31\ +\x2d\x31\x34\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\ +\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\ +\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x75\x6e\x64\ +\x6f\x5f\x73\x61\x76\x65\x5f\x72\x6f\x69\x2e\x73\x76\x67\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ +\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x34\x2e\x35\x34\x38\x38\x30\ +\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x79\x3d\x22\x31\x36\x2e\x31\x30\x34\x39\x38\x39\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\ +\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\ +\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ +\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x37\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x32\x34\ +\x37\x35\x31\x33\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x33\x33\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x33\x32\x35\x36\x36\x65\x2d\ +\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x35\ +\x2e\x32\x31\x30\x36\x34\x36\x38\x65\x2d\x31\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\x34\ +\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ +\x2e\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\ +\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\ +\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\ +\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ +\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\ +\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ +\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\ +\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\ +\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\ +\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\ +\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\ +\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\ +\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\ +\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\ +\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\ +\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\ +\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\ +\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\ +\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\ +\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\ +\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\ +\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\ +\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\ +\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\ +\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\ +\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\x32\ +\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\ +\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\ +\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x64\x3d\x22\x4d\x20\x33\x30\x2e\x34\x30\x36\x39\x35\x34\ +\x2c\x31\x31\x2e\x36\x39\x35\x31\x30\x38\x20\x43\x20\x32\x36\x2e\ +\x30\x30\x34\x31\x39\x38\x2c\x33\x2e\x33\x31\x30\x30\x37\x35\x38\ +\x20\x31\x39\x2e\x33\x36\x39\x31\x35\x38\x2c\x34\x2e\x35\x32\x38\ +\x36\x37\x30\x31\x20\x31\x30\x2e\x36\x36\x36\x36\x36\x37\x2c\x37\ +\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x4c\x20\x38\x2e\x36\x36\x36\ +\x30\x31\x30\x37\x2c\x31\x2e\x39\x34\x31\x30\x36\x32\x34\x20\x32\ +\x2e\x32\x30\x39\x35\x30\x37\x36\x2c\x31\x35\x2e\x39\x30\x32\x37\ +\x20\x33\x2e\x36\x32\x39\x36\x31\x36\x31\x2c\x31\x36\x2e\x34\x39\ +\x37\x36\x33\x35\x20\x31\x36\x2e\x39\x32\x37\x34\x35\x32\x2c\x31\ +\x37\x2e\x30\x36\x38\x36\x35\x31\x20\x31\x33\x2e\x36\x31\x35\x35\ +\x36\x39\x2c\x31\x31\x2e\x35\x31\x34\x35\x34\x38\x20\x63\x20\x35\ +\x2e\x38\x30\x33\x39\x39\x39\x2c\x2d\x31\x2e\x32\x38\x36\x31\x30\ +\x35\x20\x31\x31\x2e\x36\x30\x39\x39\x34\x38\x2c\x2d\x32\x2e\x35\ +\x39\x31\x38\x30\x38\x38\x20\x31\x34\x2e\x33\x38\x34\x32\x36\x34\ +\x2c\x32\x2e\x36\x39\x31\x38\x36\x36\x20\x32\x2e\x35\x32\x34\x36\ +\x31\x33\x2c\x32\x2e\x32\x38\x32\x34\x32\x38\x20\x33\x2e\x39\x39\ +\x32\x33\x38\x34\x2c\x31\x2e\x37\x33\x34\x33\x39\x32\x20\x32\x2e\ +\x34\x30\x37\x31\x32\x36\x2c\x2d\x32\x2e\x35\x31\x31\x33\x20\x7a\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x32\x39\x38\x38\x2d\x37\x2d\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ +\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\ +\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\ +\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\ +\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ +\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ +\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\ +\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\ +\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\ +\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\ +\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\ +\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\ +\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\ +\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\ +\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\ +\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\ +\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\ +\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\ +\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\ +\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\ +\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\ +\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\ +\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\ +\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\ +\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\ +\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\ +\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\ +\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\x32\x3b\ +\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\ +\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\ +\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x4d\x20\x33\x30\x2e\x30\x39\x32\x30\x33\x36\x2c\ +\x39\x2e\x33\x38\x30\x39\x31\x34\x31\x20\x43\x20\x32\x35\x2e\x36\ +\x38\x39\x32\x38\x32\x2c\x30\x2e\x39\x39\x35\x38\x38\x31\x30\x37\ +\x20\x31\x39\x2e\x30\x35\x34\x32\x34\x31\x2c\x32\x2e\x32\x31\x34\ +\x34\x37\x35\x36\x20\x31\x30\x2e\x33\x35\x31\x37\x34\x39\x2c\x35\ +\x2e\x31\x35\x32\x34\x37\x32\x32\x20\x4c\x20\x38\x2e\x33\x35\x31\ +\x30\x39\x33\x33\x2c\x2d\x30\x2e\x33\x37\x33\x31\x33\x32\x36\x39\ +\x20\x31\x2e\x38\x39\x34\x35\x39\x30\x32\x2c\x31\x33\x2e\x35\x38\ +\x38\x35\x30\x35\x20\x33\x2e\x33\x31\x34\x37\x30\x31\x31\x2c\x31\ +\x34\x2e\x31\x38\x33\x34\x34\x32\x20\x31\x36\x2e\x36\x31\x32\x35\ +\x33\x34\x2c\x31\x34\x2e\x37\x35\x34\x34\x35\x38\x20\x31\x33\x2e\ +\x33\x30\x30\x36\x35\x32\x2c\x39\x2e\x32\x30\x30\x33\x35\x34\x31\ +\x20\x63\x20\x35\x2e\x38\x30\x33\x39\x39\x39\x2c\x2d\x31\x2e\x32\ +\x38\x36\x31\x30\x34\x35\x20\x31\x31\x2e\x36\x30\x39\x39\x34\x37\ +\x2c\x2d\x32\x2e\x35\x39\x31\x38\x30\x39\x36\x20\x31\x34\x2e\x33\ +\x38\x34\x32\x36\x33\x2c\x32\x2e\x36\x39\x31\x38\x36\x33\x39\x20\ +\x32\x2e\x35\x32\x34\x36\x31\x32\x2c\x32\x2e\x32\x38\x32\x34\x32\ +\x38\x20\x33\x2e\x39\x39\x32\x33\x38\x33\x2c\x31\x2e\x37\x33\x34\ +\x33\x39\x32\x20\x32\x2e\x34\x30\x37\x31\x32\x37\x2c\x2d\x32\x2e\ +\x35\x31\x31\x32\x39\x39\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x2d\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ +\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ +\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x31\x2e\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ +\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ +\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\ +\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x38\x2e\x31\x33\x33\x33\x33\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x39\x2e\ +\x32\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x32\x2e\x38\x34\x34\x34\x34\x34\x35\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\x5a\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6e\x65\x77\x5f\x66\ +\x69\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x2d\x34\x36\x2e\x36\x38\x35\x31\x38\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x36\x2e\x31\x38\x33\x33\x38\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ +\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ +\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ +\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ +\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ +\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ +\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ +\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ +\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ +\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ +\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ +\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ +\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ +\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x23\x66\x32\x66\x32\x66\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x31\x2e\x33\x30\x36\x33\x39\x34\x35\x38\x70\ +\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x33\x33\x33\x33\ +\x33\x33\x33\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\x48\x20\ +\x33\x32\x20\x56\x20\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x48\ +\x20\x35\x2e\x33\x33\x33\x33\x33\x33\x33\x20\x5a\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\ +\x38\x2d\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ +\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\ +\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\ +\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\ +\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\ +\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\ +\x3a\x23\x66\x66\x66\x66\x31\x35\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ +\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x63\x36\x62\x36\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x30\x39\x30\x39\x31\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ +\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ +\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ +\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\ +\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\ +\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\ +\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x32\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x36\x2e\x36\x36\ +\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\ +\x22\x31\x31\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x39\x38\x31\x38\x31\x38\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x34\ +\x30\x30\x30\x30\x30\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ +\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\x6b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\x64\x5f\x6c\x6f\x67\x69\x6e\x2e\ +\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ +\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ +\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\ +\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\ +\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\ +\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\ +\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\ +\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\ +\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\ +\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x38\x2e\x34\x30\x33\x33\x38\x34\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x33\x35\x2e\x33\x37\x37\x36\x36\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\ +\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x37\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\ +\x75\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\ +\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\ +\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ +\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ +\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\ +\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\ +\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\ +\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\ +\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\ +\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\ +\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\ +\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\ +\x32\x33\x33\x32\x35\x31\x31\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ +\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ +\x20\x2d\x30\x2e\x35\x34\x39\x36\x33\x37\x33\x35\x2c\x33\x37\x2e\ +\x37\x38\x33\x32\x37\x20\x63\x20\x30\x2c\x30\x20\x38\x2e\x34\x39\ +\x33\x38\x31\x39\x33\x35\x2c\x2d\x32\x33\x2e\x34\x34\x37\x35\x37\ +\x20\x31\x36\x2e\x31\x30\x35\x31\x36\x30\x33\x35\x2c\x2d\x32\x33\ +\x2e\x33\x33\x36\x34\x38\x32\x20\x37\x2e\x35\x30\x31\x38\x37\x38\ +\x2c\x30\x2e\x31\x30\x39\x34\x38\x38\x20\x31\x35\x2e\x37\x31\x35\ +\x39\x31\x39\x2c\x32\x33\x2e\x34\x36\x31\x39\x31\x33\x20\x31\x35\ +\x2e\x37\x31\x35\x39\x31\x39\x2c\x32\x33\x2e\x34\x36\x31\x39\x31\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x38\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x61\x63\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ +\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x31\x2e\x32\x35\x32\x38\x36\x32\x31\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x72\ +\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x6a\x6f\x69\x6e\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x38\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x63\x78\x3d\x22\x31\x35\x2e\x34\x35\x38\x36\x37\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x37\x2e\x32\x31\x35\ +\x36\x35\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\ +\x22\x36\x2e\x32\x38\x32\x38\x31\x39\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x79\x3d\x22\x35\x2e\x36\x39\x30\x38\x31\x37\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x30\x2e\x33\x38\ +\x39\x31\x37\x31\x35\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x16\x64\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x73\ +\x65\x74\x5f\x63\x75\x6d\x75\x6c\x61\x74\x69\x76\x65\x5f\x73\x74\ +\x72\x65\x74\x63\x68\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ +\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x31\x2e\x31\x32\x37\ +\x38\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x31\x37\x2e\x39\x39\x37\x31\x35\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ +\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ +\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\ +\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ +\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ +\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ +\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ +\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ +\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ +\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x66\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\ +\x38\x33\x37\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ +\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\ +\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\x2e\x34\x35\ +\x31\x31\x34\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\ +\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\ +\x30\x2e\x38\x34\x33\x36\x37\x38\x34\x38\x2c\x30\x2e\x35\x33\x36\ +\x38\x34\x38\x37\x39\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ +\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ +\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x38\x39\x33\x37\ +\x32\x39\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\x39\x38\x2c\x30\ +\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ +\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x37\x2e\x37\x39\ +\x39\x37\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x33\x35\x2e\x39\x38\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\ +\x33\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x38\x66\x66\x66\x38\x66\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\ +\x30\x34\x39\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ +\x6c\x3a\x23\x66\x66\x61\x33\x61\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ +\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\ +\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\ +\x31\x33\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x32\x33\x2e\x33\x32\x30\x36\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ +\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ +\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\ +\x35\x30\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\ +\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\ +\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\ +\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\x30\ +\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x32\x31\x31\x37\x36\x34\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ +\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x2d\x34\x2e\x30\x34\x30\x31\x33\x38\x34\x65\x2d\x31\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x33\x2e\ +\x38\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\x36\x39\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x30\x37\x36\x32\x34\ +\x39\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\ +\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\ +\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ +\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\ +\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\ +\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\ +\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ +\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\ +\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\ +\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\ +\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\ +\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\ +\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\ +\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\ +\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\ +\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\ +\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\ +\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\ +\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\ +\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\ +\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\ +\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ +\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ +\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\ +\x36\x32\x37\x65\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ +\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x70\x78\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\ +\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\ +\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\ +\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ +\x3d\x22\x6d\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x20\x63\x20\x2d\x34\x2e\x30\x37\x34\x32\x30\x34\x2c\x30\x2e\x30\ +\x30\x31\x34\x20\x2d\x38\x2e\x33\x37\x31\x35\x35\x35\x35\x2c\x33\ +\x2e\x39\x39\x32\x38\x32\x33\x36\x20\x2d\x39\x2e\x36\x2c\x36\x2e\ +\x34\x20\x43\x20\x35\x2e\x31\x37\x31\x35\x35\x35\x35\x2c\x39\x2e\ +\x38\x37\x33\x38\x34\x33\x20\x33\x2e\x30\x38\x34\x32\x38\x33\x2c\ +\x31\x38\x2e\x39\x31\x31\x35\x36\x34\x20\x31\x2e\x30\x36\x36\x36\ +\x36\x36\x37\x2c\x32\x35\x2e\x36\x20\x30\x2e\x30\x35\x37\x38\x35\ +\x38\x36\x37\x2c\x32\x38\x2e\x39\x34\x34\x32\x31\x38\x20\x2d\x31\ +\x2e\x38\x30\x38\x38\x30\x38\x2c\x33\x30\x2e\x32\x37\x37\x35\x35\ +\x31\x20\x2d\x32\x2e\x33\x35\x36\x36\x30\x36\x2c\x33\x30\x2e\x37\ +\x37\x34\x38\x33\x20\x2d\x32\x2e\x39\x30\x34\x34\x30\x34\x31\x2c\ +\x33\x31\x2e\x32\x37\x32\x31\x30\x39\x20\x2d\x33\x2e\x32\x2c\x33\ +\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x32\x2c\x33\x30\ +\x2e\x39\x33\x33\x33\x33\x33\x20\x63\x20\x30\x2e\x37\x30\x36\x38\ +\x37\x35\x37\x2c\x30\x2e\x31\x35\x38\x36\x32\x39\x20\x30\x2e\x34\ +\x34\x30\x34\x38\x31\x33\x2c\x31\x2e\x30\x31\x35\x33\x37\x32\x20\ +\x30\x2e\x31\x33\x30\x35\x36\x35\x31\x2c\x31\x2e\x38\x30\x34\x30\ +\x38\x37\x20\x2d\x30\x2e\x33\x30\x39\x39\x31\x36\x32\x2c\x30\x2e\ +\x37\x38\x38\x37\x31\x33\x20\x2d\x30\x2e\x36\x36\x33\x33\x35\x34\ +\x31\x2c\x31\x2e\x35\x30\x39\x33\x39\x39\x20\x2d\x30\x2e\x31\x33\ +\x30\x35\x36\x35\x31\x2c\x31\x2e\x33\x39\x35\x39\x31\x33\x20\x30\ +\x2c\x30\x20\x30\x2e\x32\x36\x30\x34\x35\x35\x36\x2c\x31\x2e\x35\ +\x33\x32\x30\x34\x31\x20\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x2c\ +\x30\x20\x31\x2e\x38\x37\x32\x38\x37\x37\x37\x36\x2c\x2d\x31\x2e\ +\x35\x33\x32\x30\x34\x20\x35\x2e\x33\x35\x38\x31\x37\x37\x36\x2c\ +\x2d\x33\x2e\x39\x39\x34\x38\x32\x37\x20\x36\x2e\x34\x2c\x2d\x38\ +\x2e\x35\x33\x33\x33\x33\x33\x20\x43\x20\x37\x2e\x34\x31\x36\x39\ +\x37\x38\x31\x2c\x31\x36\x2e\x35\x32\x32\x39\x38\x38\x20\x39\x2e\ +\x35\x37\x36\x37\x38\x34\x2c\x35\x2e\x32\x38\x32\x39\x30\x35\x31\ +\x20\x31\x36\x2e\x31\x37\x35\x35\x34\x39\x2c\x35\x2e\x33\x32\x34\ +\x32\x38\x35\x20\x32\x32\x2e\x34\x2c\x36\x2e\x34\x20\x32\x31\x2e\ +\x33\x33\x33\x33\x33\x33\x2c\x39\x2e\x36\x20\x32\x36\x2e\x36\x36\ +\x36\x36\x36\x37\x2c\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\x63\ +\x20\x32\x2e\x34\x31\x37\x33\x38\x34\x2c\x36\x2e\x32\x38\x35\x32\ +\x20\x36\x2e\x34\x2c\x39\x2e\x36\x20\x31\x30\x2e\x36\x36\x36\x36\ +\x36\x36\x2c\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x20\x36\x2e\x34\ +\x2c\x31\x2e\x30\x36\x36\x36\x36\x37\x20\x35\x2e\x33\x33\x33\x33\ +\x33\x34\x2c\x30\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\x30\x20\ +\x43\x20\x34\x34\x2e\x38\x2c\x33\x32\x20\x34\x33\x2e\x37\x33\x33\ +\x33\x33\x33\x2c\x33\x35\x2e\x32\x20\x34\x32\x2e\x36\x36\x36\x36\ +\x36\x37\x2c\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x34\x31\x2e\ +\x39\x32\x34\x35\x30\x33\x2c\x33\x31\x2e\x31\x38\x30\x37\x32\x31\ +\x20\x33\x35\x2e\x30\x35\x38\x33\x34\x37\x2c\x33\x32\x2e\x33\x32\ +\x36\x32\x35\x32\x20\x33\x32\x2c\x32\x35\x2e\x36\x20\x32\x38\x2e\ +\x39\x34\x31\x36\x35\x33\x2c\x31\x38\x2e\x38\x37\x33\x37\x34\x38\ +\x20\x32\x37\x2e\x34\x38\x30\x35\x39\x35\x2c\x31\x31\x2e\x33\x30\ +\x39\x36\x35\x33\x20\x32\x35\x2e\x36\x2c\x37\x2e\x34\x36\x36\x36\ +\x36\x36\x37\x20\x32\x33\x2e\x37\x31\x39\x34\x30\x35\x2c\x33\x2e\ +\x36\x32\x33\x36\x38\x20\x32\x31\x2e\x37\x35\x39\x31\x38\x37\x2c\ +\x31\x2e\x31\x31\x34\x34\x33\x35\x35\x20\x31\x36\x2c\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ +\x3d\x22\x63\x7a\x73\x73\x63\x73\x63\x73\x73\x63\x73\x63\x63\x63\ +\x73\x7a\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\ +\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\ +\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\ +\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\ +\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\x30\x30\ +\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\ +\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\ +\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\ +\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\ +\x42\x6f\x6c\x64\x27\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ +\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\ +\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\ +\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x38\x39\ +\x38\x39\x38\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x34\x2e\x32\x36\x36\x36\x36\ +\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\ +\x74\x33\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\ +\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x34\x2e\x32\x36\x36\x36\x36\x36\x39\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x79\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\ +\x73\x69\x7a\x65\x3a\x32\x35\x2e\x36\x30\x30\x30\x30\x30\x33\x38\ +\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\ +\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ +\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x32\x22\x3e\x25\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\ +\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ +\x67\x3e\x0a\ +\x00\x00\x06\x59\ +\x00\ +\x00\x4e\xd5\x78\x9c\xe5\x9c\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ +\x54\xed\x25\x41\x4b\xbd\x6d\x3d\x62\x3b\x87\x06\x01\x02\xf4\xd4\ +\xa6\xe8\x31\x90\x25\xda\x26\x56\x12\x0d\x8a\x5e\xdb\xf9\xf5\x21\ +\xf5\xb2\x65\x6b\x81\xa6\xa4\x0a\xed\x52\x45\x90\x6a\x66\x48\x91\ +\x9f\x66\xc8\x21\x45\x67\xf1\xf1\x94\x67\xda\x33\x24\x25\xc2\xc5\ +\x52\xb7\x0d\x4b\xd7\x60\x91\xe0\x14\x15\xdb\xa5\xfe\xf7\xd7\xcf\ +\x20\xd0\xb5\x92\xc6\x45\x1a\x67\xb8\x80\x4b\xbd\xc0\xfa\xc7\xd5\ +\xc3\xe2\x17\x00\xb4\xdf\x09\x8c\x29\x4c\xb5\x23\xa2\x3b\xed\x4b\ +\xf1\x54\x26\xf1\x1e\x6a\xef\x76\x94\xee\x23\xd3\x3c\x1e\x8f\x06\ +\x6a\x84\x06\x26\x5b\xf3\xbd\x06\xc0\xea\xe1\x61\x51\x3e\x6f\x1f\ +\x34\x4d\x63\xcf\x2d\xca\x28\x4d\x96\x7a\x53\x60\x7f\x20\x59\x65\ +\x98\x26\x26\xcc\x60\x0e\x0b\x5a\x9a\xb6\x61\x9b\xfa\xc5\x3c\xb9\ +\x98\x27\xfc\xe9\xe8\x19\x26\x38\xcf\x71\x51\x56\x25\x8b\xf2\xf1\ +\xca\x98\xa4\x9b\xce\x9a\xb7\xe6\xe8\x56\x46\x76\x18\x86\xa6\xe5\ +\x98\x8e\x03\x98\x05\x28\xcf\x05\x8d\x4f\xa0\x5f\x94\xb5\x71\xa8\ +\xa8\x63\x59\x96\xc9\x74\x17\xcb\x7f\x67\x15\x95\x0c\xe8\x9e\xfd\ +\xe9\xcc\x5b\x81\x51\xe2\x03\x49\xe0\x86\x95\x83\x46\x01\xa9\xf9\ +\xe9\xeb\xa7\x4e\x09\x2c\x23\xa5\xe9\x55\x35\x2d\xcf\xde\x53\x7b\ +\x90\x8b\x38\x87\xe5\x3e\x4e\x60\x69\xb6\xf2\xaa\xfc\x11\xa5\x74\ +\xb7\xd4\x5d\xcf\xb0\x5d\x76\xcd\x2a\xe1\x0e\xa2\xed\x8e\xde\x4a\ +\x51\xba\xd4\x59\xeb\x9d\x30\xa8\xef\xaf\x9c\xc3\xae\x0d\x9a\x8a\ +\xa3\x4e\x63\x19\xa1\x63\xd8\x1a\xb1\x67\xae\x5f\xdb\xb4\x5d\x88\ +\x52\x9c\xf0\x36\xb1\x2a\x61\x8e\xe2\x03\xc5\x39\x7b\x6b\x49\x92\ +\xc5\x65\x89\x36\x28\x61\x37\xb8\xd8\x67\x87\x2d\x2a\xbe\xf5\x85\ +\xdf\x52\x94\x55\xff\x63\xb4\x28\xbb\xe7\xc2\xd3\x1e\x13\x0a\x4e\ +\xe9\x9e\x01\x9d\xfb\x83\xca\x73\xab\x5c\x31\xed\x22\x85\x9b\x92\ +\x5b\xd5\xbd\xe3\x77\xac\x7b\xbe\xae\x99\x95\xb6\x6b\x2c\x6f\x69\ +\xfa\x8c\xe0\xf1\x62\xbb\x8e\xcb\x9a\xa0\xa6\xed\xe3\x2d\xf3\xb6\ +\x0c\x93\xa5\xfe\xb8\xa9\xae\x46\xb1\xc6\x24\x85\xa4\x55\xcd\xab\ +\xab\xa7\xc2\xec\x8d\x20\x7a\xae\xe3\xab\xa9\xbb\x6d\x2f\xaf\xb5\ +\xd3\x5b\xc3\xfa\x72\x17\xa7\xf8\xb8\xd4\x9d\x5b\xe5\x77\x8c\x73\ +\x56\x2b\x7b\x33\xa1\x1f\x58\x77\xea\xe4\xb4\xd4\x81\x1d\x18\xee\ +\xcc\x9b\xdb\x77\x4a\xde\x1e\xdf\xb0\x9c\xd0\x0a\xef\x74\x07\x42\ +\x58\xfc\x81\x2c\x3e\x43\xd6\xa7\xea\xaf\xb6\x82\x72\x87\x8f\x5b\ +\xc2\xd9\x50\x72\x80\xb7\x25\xb9\x06\xac\xd7\xf8\x34\xac\x66\xee\ +\x70\xe0\x91\x0d\x0e\x05\xa2\x2c\x7a\xf6\xa7\xeb\x5a\x0f\x28\x85\ +\xe5\x70\xc1\xb2\x88\xf7\x60\x9b\xe1\x75\x9c\x0d\x1b\x1c\x51\xc1\ +\x18\x81\xc6\xd1\x6d\xb7\x7b\x05\xb7\x16\xad\xd7\xfb\x56\xf0\x82\ +\x05\x6b\xfb\xdd\x6b\x68\x54\xe7\x97\x55\x79\x7c\x42\x39\xfa\x0e\ +\x19\x18\xbb\xf2\x3a\xe6\x59\x3d\x2c\x75\x31\x4d\xa3\x67\x1e\xc1\ +\xa7\x33\x97\xe9\xad\x90\xf3\xe4\x02\x27\x0c\xfd\x4e\x88\x09\x62\ +\x81\x71\xd5\x9c\x56\x74\xbe\x16\xf1\x78\x67\xc3\xf5\xa9\x72\xaf\ +\xca\xf9\xfc\x5b\xdd\xf9\x5a\xd7\x78\xbd\x79\xef\xf6\x95\x3c\x87\ +\x34\x4e\x63\x1a\x5f\x62\xa0\x95\xb0\xb6\x59\x6d\xcf\xd8\xd0\x19\ +\xfd\xf9\xe9\xf3\xaa\x79\xd0\x22\x49\xa2\x7f\x30\x79\x6a\x9f\xab\ +\x69\xdc\x20\x5e\xe3\x03\x23\xad\xaf\x3a\xf1\x22\x4d\x22\x36\xd8\ +\xb1\x41\x60\x85\x72\xe6\xd9\x7c\x9c\xfc\x95\x0d\x6e\x0b\xf3\xa2\ +\xe8\x19\x73\x58\x97\x4a\xeb\x6a\x09\xac\x47\xcd\xc1\xa9\x23\x4d\ +\x72\xc4\x0b\x99\x7f\x51\x94\x65\x5f\xf8\x43\x9a\x1e\x5f\x55\x8a\ +\x68\x06\x2f\xc2\x85\xd9\xb4\xbe\xe9\x9b\x79\xd5\xb9\x85\xd9\xf6\ +\xbe\xba\xdb\x5e\xa8\xf4\x82\xa2\x7b\xd1\x59\xbc\x86\xcc\x43\xff\ +\xe0\x4a\xed\x4e\xbb\x25\xf8\xb0\xcf\x71\x0a\x9b\xe2\x1d\x4d\x98\ +\xd0\xee\x95\xd1\x73\xc6\xf4\x1b\xd6\xfa\xe8\x71\xed\xf2\xff\x3e\ +\xf0\x1b\xd0\x8c\x12\x91\x5d\xdf\x92\x43\xc6\x46\xbb\x67\x58\xe0\ +\x34\xfd\x50\x52\x82\x9f\x60\xf4\x68\x55\x57\x73\x5b\x07\x43\x64\ +\x19\x9e\x1b\x7a\xfc\xdd\xb7\x72\x46\x08\x92\x8c\x79\x2b\x8d\xbc\ +\x56\x96\xc6\x6c\x94\x21\x24\x3e\x47\x05\x9b\xe8\x5b\x69\xf7\xcc\ +\x9e\xa3\xf2\xe6\xce\x02\x37\x04\x36\x08\xc0\x45\xd5\xc4\xde\xcc\ +\x70\xdd\xcb\x74\xc2\xaf\x36\xe4\x3c\x23\xac\x34\x5e\xa7\xe1\x4e\ +\x6b\x19\x37\x4e\x7b\xe6\xa3\xd6\x9d\x2b\x93\x5e\x1c\x90\xca\xa5\ +\xe7\x1e\xbf\xe6\xdd\x0b\x7e\x19\xa4\x65\xcd\x66\x0c\xcc\x94\x41\ +\x86\x63\x80\xb4\x5d\xc3\xef\x5b\xbe\x79\x8e\x36\x98\x8d\x41\x32\ +\x30\x82\xaa\x2f\x8e\x3a\x24\xfd\x31\x38\x3a\xae\x31\x57\x07\x21\ +\x73\xc6\x51\xbc\x91\x65\x75\xbd\x44\x53\x14\xe5\x2b\x98\x68\xc2\ +\x71\xfc\xd1\x75\x0d\x4f\xe6\x4c\x33\x6d\x92\x82\x04\xad\x1e\x39\ +\x23\x50\xcb\x07\x3d\x41\x7a\xf7\xe6\x63\xa4\x3a\x13\xc7\x18\xc8\ +\x74\x41\xd9\xe9\xcd\xc4\xd9\x59\xc2\x2e\xd8\xa3\x27\x3b\xa5\x99\ +\x3a\x3d\x57\x26\x3c\x89\x79\xcc\xd4\xb9\x09\x4f\xbc\xfd\x98\x55\ +\x2e\x75\x11\x5f\x24\x0f\xce\x1c\x6a\x65\x2e\x7c\xf0\x13\xe6\xd8\ +\x8f\xe0\xc0\x98\x55\x26\x0a\xf1\x93\x3b\x81\xa8\xe8\x81\xc0\x91\ +\x49\x50\xb5\xec\x8f\x2f\xe4\x3c\x51\x1f\x74\xe6\xb7\x33\x48\xb5\ +\x1a\xf1\x5d\x85\xa2\xb9\xde\x5c\x10\x9d\x98\x07\x49\x32\x9f\x54\ +\x24\x23\x6c\x76\x68\x84\x37\x0c\x07\x31\x06\xb7\x9b\x0d\x6f\x1e\ +\x65\x08\x7c\xe1\xd1\x71\x38\xb6\xdd\xba\x12\x65\xdc\xd2\x03\x8e\ +\xe8\x3a\xd9\xb1\x8d\x1b\xa1\xdc\xd0\x9e\xf8\xe6\x6b\x00\x44\x57\ +\x7b\x76\xcf\x05\x6d\x65\xb6\xad\xab\x2c\xc7\x13\x75\x3f\x7b\xcc\ +\xb1\x70\xea\x04\x5d\xf1\xad\xea\x1e\x3e\x47\x72\x9e\x3d\x71\x7e\ +\x36\x98\x8b\x4f\xc9\x43\xc3\x9f\x62\x1c\x2d\x36\x1f\xcb\x8d\x63\ +\x5b\xf2\x92\x79\xe2\x00\xf9\x44\x3c\x07\xae\xe8\xae\xc3\xa0\x2f\ +\xca\x46\x39\xf9\x9c\x86\x6f\x83\x81\xd0\x1a\x83\xa5\x62\xf9\x61\ +\xb3\x93\x23\x7e\xce\x41\xe5\x24\xbb\xd9\xcc\x01\xe1\x5c\x2a\x45\ +\xb5\x16\xcf\x9e\x27\xbc\xe0\xbb\xf2\x37\x65\x77\x71\x80\xa8\x0f\ +\xf6\x21\xaa\xe5\x83\x3c\x94\x45\xb3\x9c\x3e\x3f\x89\x6b\xbd\x57\ +\xc0\xaf\xda\x00\x13\xfe\xb2\xd2\x27\xa8\xde\xde\x97\xcf\xa6\x12\ +\xd1\x45\x5f\x9f\xa1\xec\xc5\xca\x2b\x80\xc8\x4f\xcb\x01\x6b\x2e\ +\x79\x4e\x91\x97\x69\xf7\xb1\xbd\x0a\xa4\xd5\x9e\xac\xf0\x5e\x18\ +\x70\xfd\xdb\xe4\xf0\xa7\x33\xc6\x56\x4a\x49\x5c\x94\xfc\xac\xff\ +\x52\x2f\x93\x38\x83\xef\x80\xfd\x9b\xfd\xfe\xcd\x38\x70\x95\x58\ +\x8a\x7e\xe1\xba\x19\x09\x02\x43\xde\xf9\xed\xcd\xe6\x67\x16\xdc\ +\xf5\x0f\x9d\xfe\x4f\x86\xa2\xd9\xf8\xe0\x19\x4f\xc9\x27\x15\xa7\ +\x4f\xb1\xf6\xc4\x31\x58\xca\x3e\x35\x31\x75\x96\x82\x0c\x87\x4f\ +\xee\x28\xe7\x8f\xa2\x61\x3d\x88\x51\xfe\x8f\x5b\x26\x8e\x51\x7c\ +\xb5\x3d\xc8\x51\xfe\x4f\x5b\x26\xce\x51\x74\xb9\x3d\x48\x51\xea\ +\x0f\x5b\x26\x0e\xd0\x1b\x07\xa1\xec\xa3\xa1\xaf\x80\xa3\xf8\xaa\ +\x71\xd8\x19\x15\x9b\xa5\xeb\x7d\x20\x41\x92\x83\x67\x4f\xa4\x7e\ +\xf8\x9f\x3c\xc4\x66\x05\x3e\x0a\x48\xf5\x5c\xb2\x59\x0e\x8e\x41\ +\x53\x9d\x35\xa1\xdc\xa3\x14\xb2\x3f\x30\x4c\x1c\x9e\xf8\x71\xe5\ +\xe1\x0f\xae\xaa\x51\x0c\xc4\xcf\x93\x0d\x9f\x02\x50\x68\x76\xe1\ +\xc9\xce\x28\xa7\x1a\xa5\x9f\x2e\x9b\x34\xc8\xfa\xc3\x75\x20\xf7\ +\x78\xa3\x3a\xd3\x49\x93\x74\x0b\x6f\xec\x0c\x1f\x30\x53\x08\x63\ +\x30\xd6\x69\xef\xff\xf2\xe1\x6b\x61\x6e\x57\x0f\x0b\xfe\xcf\x09\ +\xad\x1e\x7e\x00\x7b\xad\x87\x0c\ +\x00\x00\x06\xb8\ +\x00\ +\x00\x1f\xf5\x78\x9c\xdd\x59\x49\x93\x9b\x48\x16\xbe\xfb\x57\x10\ +\xaa\x8b\x1d\x23\x92\xdc\x17\x5a\xaa\xbe\x38\x3a\x7a\x22\x7a\x2e\ +\xbd\x1e\x1d\x08\x52\x2a\xc6\x08\x34\x80\x4a\x92\x7f\xfd\xbc\x04\ +\xb1\x68\x29\xaf\x72\xb7\x5d\x28\x2a\x4a\x7c\xef\xe5\xf6\xbd\x15\ +\x34\xfb\x71\xbf\xce\xbc\x47\x5b\x56\x69\x91\xcf\x27\x04\xe1\x89\ +\x67\xf3\xb8\x48\xd2\x7c\x35\x9f\xfc\xf1\xfb\x4f\xbe\x9e\x78\x55\ +\x1d\xe5\x49\x94\x15\xb9\x9d\x4f\xf2\x62\xf2\xe3\xfd\x8b\x59\xf5\ +\xb8\x7a\xe1\x79\x1e\x0c\xce\xab\x30\x89\xe7\x93\x87\xba\xde\x84\ +\x41\xb0\xd9\x96\x19\x2a\xca\x55\x90\xc4\x81\xcd\xec\xda\xe6\x75\ +\x15\x10\x44\x82\xc9\xa0\x1e\x0f\xea\x71\x69\xa3\x3a\x7d\xb4\x71\ +\xb1\x5e\x17\x79\xd5\x8c\xcc\xab\xbb\x91\x72\x99\x2c\x7b\xed\xdd\ +\x6e\x87\x76\xac\x51\x22\xc6\x98\x00\xd3\x80\x52\x1f\x34\xfc\xea\ +\x90\xd7\xd1\xde\x3f\x1d\x0a\x7b\xbc\x36\x94\x62\x8c\x03\x90\x0d\ +\x9a\x1f\xa7\x15\x56\xc0\xca\x06\xfe\x7a\xf5\x0e\x40\x55\xb1\x2d\ +\x63\xbb\x84\x71\x16\xe5\xb6\x0e\x5e\xff\xfe\xba\x17\xfa\x18\x25\ +\x75\x32\x9a\x26\xcd\xdf\x56\x71\xb4\xb1\x27\xab\x76\x60\xcb\x40\ +\xb4\xb6\xd5\x26\x8a\x6d\x15\x74\x78\x33\x7e\x97\x26\xf5\xc3\x7c\ +\xc2\x38\x22\x0c\x2e\xd1\x80\x0f\x36\x5d\x3d\xd4\xe7\x68\x9a\xcc\ +\x27\xb0\x7b\x6a\x74\x7b\x3f\xb2\x30\x69\x15\x8e\x13\x87\x63\xdb\ +\x23\xea\xbd\xb4\x5a\xc6\x5a\x61\xad\xcc\xd4\xa3\x98\x12\x1f\x13\ +\x9f\x88\x57\xcd\xa0\xee\x4c\x61\x52\xc4\x6e\x93\xb0\x86\x5d\xa7\ +\xd1\xb6\x2e\xd6\x60\xc6\x38\xce\xa2\xaa\x4a\x97\x69\x0c\x37\x45\ +\xbe\xc9\xb6\xab\x34\x7f\x93\xae\x37\x45\x59\xbf\xa9\x36\x36\xae\ +\xcb\x28\x7b\x93\xa5\x8b\x32\x2a\x0f\xa8\xe3\xb6\xdf\x88\xdd\x3b\ +\x45\x7f\x9f\x6c\x80\x61\xa9\xae\x0a\x0f\x9d\xf0\x1e\xa4\xb3\xc4\ +\x2e\x2b\xa7\xd5\x1e\xd7\xdd\xc1\x79\xd5\xc4\x0b\x1a\x69\xbf\x59\ +\xb7\xd3\xe4\x31\xb5\xbb\x41\x77\x11\x55\x2d\xa5\x9e\xb7\x89\x56\ +\xe0\x7e\x59\x51\xce\x27\x77\xcb\xe6\x3a\x0a\x16\x45\x99\xd8\xb2\ +\x13\xc9\xe6\x3a\x11\x15\x60\xa2\xb4\x3e\xb4\x51\x73\x9c\xbb\xdb\ +\xaf\x9b\xb5\x97\xe3\xeb\xf2\xea\x21\x4a\x8a\xdd\x7c\x42\xcf\x85\ +\xef\x8a\x62\x3d\x9f\x28\x64\x88\xc6\x9c\xa8\x73\x71\xbc\x07\x6b\ +\x23\xa1\x85\x21\xd2\x5c\x08\xdd\x7e\x28\x32\x52\x5e\x4c\x1b\x6f\ +\xcb\x12\xe2\xd1\xcf\xa2\x83\x85\x23\x35\xff\xc8\x51\xa9\x7a\x28\ +\x76\xab\xd2\x51\x53\x97\x5b\x7b\x3e\xd2\x49\xfc\xc5\xa2\xd8\x5f\ +\x17\x83\x37\x6c\x5d\xa4\xfb\xdb\x3c\xad\x21\x9a\x36\xfb\xf1\xac\ +\xdb\x34\xb1\xd5\xf5\x81\xbb\x34\x07\x06\xfc\xa3\x5f\x13\xd6\x13\ +\x7c\xae\xd1\x39\xb9\xc2\x4f\x69\xc0\xd6\x2e\x48\x3e\x8a\x0e\x4f\ +\x8b\xd6\xd1\x3e\x5d\xa7\xef\x2c\x9c\x9b\x9c\xab\x54\x79\xb4\xf1\ +\x57\x59\xb1\x88\xb2\x0f\x1c\xbb\x2c\xea\xc6\xe3\xdd\x3a\xf7\x8d\ +\xd2\xec\x84\xba\x76\x9c\xe7\xd5\x07\x17\xf5\xfb\x83\xc3\x26\x1d\ +\xe8\x38\x77\x00\x53\x52\xf4\x60\x51\xa6\x10\x3b\xa3\x33\x75\xd0\ +\x61\x0c\xb9\x1c\x01\x79\x7a\xdf\x78\x60\xe3\x9f\xea\x5c\x76\x18\ +\xcb\x8e\x81\x11\x5c\x46\x46\x83\xaf\x6d\x1d\x25\x51\x1d\x0d\x61\ +\xd2\x21\xd4\x98\xfe\x64\x90\x6e\xc3\x5f\x5f\xff\x74\x7f\x5c\x68\ +\x16\xc7\xe1\x5f\x45\xf9\xb6\x5b\xd7\xf3\x9c\x42\xb4\x28\xb6\x60\ +\xae\xc9\x7d\x0f\xcf\x92\x38\x84\x04\x09\x79\xe2\x3e\x5d\x83\xf3\ +\xbb\xdc\xfa\x2f\x48\x88\xb3\x60\x10\x9c\x28\x3b\xb2\x86\x49\xdb\ +\x69\x4b\xdb\x66\xda\xab\xe5\x26\x89\xd7\xa9\x1b\x14\xfc\x56\xa7\ +\x59\xf6\x6f\xb7\xc8\xf1\xc4\xa3\x49\xd3\x3a\xb3\x03\x38\x0b\x8e\ +\xbb\x3f\x9e\x2d\x18\x1d\x6e\x16\x74\xa7\x6f\xee\x56\x03\x2b\x27\ +\x81\xd3\x1b\x3a\x8b\x16\x16\x1c\xe5\x17\x27\xf4\x2e\xa4\xab\xb2\ +\xd8\x6e\xd6\x45\x62\x8f\xc3\x7b\x36\x21\x2b\xf6\x26\xab\x0f\x19\ +\xc8\x97\xb0\xfb\xf0\x4e\x69\xb3\x88\xe8\x0f\xee\xc6\x3f\x26\x92\ +\x90\xb4\xb7\xe5\x36\x83\x84\xf8\x68\xf3\x22\x49\x7e\xa8\xea\xb2\ +\x78\x6b\xc3\x3b\x2b\xdd\xe7\x78\xdb\x46\x54\x48\x11\xef\x80\x2c\ +\xcd\x2d\x6c\x24\xac\xfe\xb7\x8d\x4a\x3b\x46\xff\x5b\xa4\x79\x08\ +\xcc\xd9\xb2\x43\x9b\x9b\x0c\xe2\xa2\x0e\xfb\xf1\x49\x04\xd9\xaa\ +\x2c\xa3\x43\x98\x43\x1b\x30\x46\x8b\xe5\xb2\xb2\x75\x88\x3b\xac\ +\xdf\xec\x89\x87\xbb\x73\x32\x4c\x06\xdf\xed\x6a\x19\xed\x91\xbe\ +\x90\x0d\x90\x0b\x00\x04\x25\x4c\x72\x26\x86\xf9\x1a\x9f\x16\x94\ +\x73\x8e\x07\xb0\x04\x54\x22\x6c\x04\x65\x9a\xf6\x76\x9f\x6d\xa2\ +\xfa\xe1\x1a\xbf\xa3\x53\x84\x77\x50\xea\x85\xb6\xa7\xdc\x11\x64\ +\xa8\x50\xf2\x9c\xbf\xc5\xb6\xae\x6f\xc5\xde\x25\x53\x2e\xe4\x3c\ +\x38\xb1\x54\x70\x0c\x31\xa5\x12\x49\x4a\x25\x23\x1e\x45\x98\x6a\ +\xc6\xd9\x14\xba\x09\x80\x28\x65\x1e\x47\x58\x48\xa9\xd5\xd4\xe7\ +\xc8\x28\xb8\xa4\xc7\x10\xd3\x58\x28\x2c\x7a\x35\xda\x61\x74\x2a\ +\x90\x80\x9e\xc9\xe8\x01\x21\xc8\x71\xc8\x39\x4c\xa5\x18\xd5\x53\ +\x70\x17\xad\xb5\xf1\x04\xe2\x58\x43\x6d\x01\x05\x3d\xae\x7a\xad\ +\x25\x1d\xa3\x1c\x33\xe5\xb3\x11\xde\x97\x98\x22\x07\x9e\xea\xa2\ +\xf4\xa1\xd8\x3c\x46\xf5\xb6\xb4\x2e\x61\x7d\xaa\x39\xa4\x5a\xd2\ +\x6f\xc5\x1c\x50\x4b\x8d\x00\x1e\xc0\x1c\x50\x91\x39\xd7\x82\x5e\ +\x9a\x83\x7e\x9c\x39\x58\x87\x91\x0b\x73\xb0\xce\x1c\xe2\x09\x73\ +\x88\x0f\x99\xc3\x57\x5f\xcd\x1e\x49\xf2\xed\xd8\x83\x03\x5f\x4c\ +\x02\x65\x53\x86\x11\x13\xc2\x48\xfe\x9e\xf0\x10\xe2\xd2\x20\xe4\ +\x3d\xf6\x30\x17\xf6\xf8\xec\xf0\xf0\x3f\x23\x3e\x56\x27\x5d\x01\ +\xc1\x6a\x48\x98\xd0\x3c\xe7\x95\x2b\x94\x40\x42\x54\x97\xe9\xfe\ +\x25\x46\xd0\x02\x32\x25\x30\x9b\x62\xf7\x41\x92\x50\x86\xb9\x84\ +\xad\x32\x04\xc9\x51\x2b\x3d\xf5\x0d\x52\x46\x11\xc9\xd8\xab\xbe\ +\x18\x9f\x58\xfd\xfd\x69\x11\xae\xf3\x92\xd2\x3c\x64\xfc\xbd\x76\ +\x6f\x2c\xff\x1f\xcf\xa7\x1c\x09\xb7\x3a\x9f\x32\x81\xdc\x03\x1a\ +\xa6\xde\x9f\x9e\x34\x88\x0d\x0f\x3e\xa7\x96\x80\xc6\x45\xfa\x27\ +\x82\x0f\x58\x62\x44\x4b\xdf\x24\x41\xd5\x76\x7d\x05\xf4\xb0\x71\ +\x3c\xea\x28\xbe\x57\x1a\xcd\xd1\xd3\xa7\x3d\x71\xde\xcf\x23\x6e\ +\xaf\xb3\xa8\x7d\xf6\xed\xb1\x08\x49\xc8\x48\xcc\x36\xfb\x4f\xe7\ +\xf1\x09\x76\xd6\x40\x04\xc4\x4e\xd3\x2e\x4f\x25\xe4\x90\xd6\xc9\ +\x62\xef\x68\x30\x88\xb4\xeb\x5f\xaf\xb0\xc6\x94\xa2\x3e\xfe\x24\ +\xef\xbb\x99\x73\x11\x25\xf8\x6d\x69\x21\xa6\x8d\x38\x32\x55\x18\ +\x12\xe0\x91\x16\xec\xb2\x2b\x6d\xe8\x7a\xea\xfb\x35\x66\x34\xc7\ +\xbe\xa4\xcf\x84\x18\xd6\x96\x01\x75\x2b\x62\xb4\x6f\x9e\x07\x33\ +\xec\xc6\x1e\x63\x7c\xf2\x2c\x88\xe9\xb3\xc6\x8d\x78\xc1\xfe\xf3\ +\x08\x25\xd5\x26\x5e\x79\x2b\x5e\xc6\x1d\xf1\xf7\xcc\x8b\xaf\xbb\ +\xb6\xe7\x56\xa9\xd7\xc7\x7f\x3b\x31\x5f\xb9\x56\x0b\x8d\x1a\xdf\ +\x31\x5f\x54\xab\xe9\x3f\x90\x7a\xbf\x36\x31\xac\x6b\xf2\xbe\x84\ +\x18\xf2\x49\xed\xdf\x77\x41\x0c\xd7\xb7\xe8\xee\xc6\x4f\x79\xcf\ +\x85\x18\x7a\x8b\x50\xe2\xcf\x2f\xc7\x30\x75\x8b\x50\x32\x9f\xe5\ +\x31\xb3\x60\xf5\x81\x57\x36\x77\x2c\xa1\x8a\xcb\x2f\x7d\x63\x8c\ +\x39\x37\xfd\xbb\x9e\x2f\x7e\x59\x43\x34\xd4\x43\xc9\x81\x3c\xb0\ +\x8d\xe2\x44\x12\xe0\xce\x27\x08\x53\xc2\x85\x00\xc6\xe0\xbb\x66\ +\x5a\x28\x33\xc5\x48\xb9\xaa\x65\xc8\x08\x23\x48\x32\x81\xb9\x60\ +\xf0\x98\x4f\x04\xe2\x46\x19\x06\x0f\xab\xf0\x28\x62\xdc\x1b\x52\ +\xd6\x4e\x66\x0c\x67\x06\xda\x4c\xec\x11\xf7\xee\xd4\x10\xce\x60\ +\x3d\xc8\x7b\x98\x62\x45\xae\x83\x99\x7b\xcd\x6a\x14\x31\xb0\x09\ +\xa4\xb5\xd4\x58\x0e\x88\xdf\x43\xae\xcc\xc2\xb4\xee\xf7\x34\x26\ +\x18\x48\xae\x4c\x3b\x06\x7f\xf6\xa8\x44\x94\x1b\xcd\x24\x6c\x99\ +\x21\x89\x0d\xc5\x92\xb5\xe5\x1a\x06\x60\xcd\x94\xa4\x9e\x5b\x80\ +\x28\x42\x39\x8c\xed\x8f\xd8\x1d\x5b\x8f\xc1\x77\x17\x6f\xd1\x05\ +\xe3\x1a\x2a\xf8\xd0\xf2\x7d\x9c\x0b\x35\x0e\x34\x73\xbf\xba\xdc\ +\xbf\xf8\x3f\xa8\x9a\x0b\xf8\ +\x00\x00\x04\xe3\ +\x00\ +\x00\x1a\x61\x78\x9c\xed\x58\x59\x6f\xe3\x36\x10\x7e\xf7\xaf\x50\ +\x95\x97\x16\x0d\x75\x5a\xd6\x11\xd9\xfb\xd0\x60\x81\x05\xfa\xd4\ +\x6e\xd1\x67\x5a\xa2\x65\x36\x12\x29\x50\x54\x6c\xef\xaf\xdf\xa1\ +\x6e\x1f\x59\x64\x93\x06\x5d\xd4\x51\x10\x38\x9c\x6f\x86\x9c\xf9\ +\xe6\x10\x9d\xf8\xc3\xbe\xc8\xb5\x47\x22\x2a\xca\xd9\x52\xb7\x0d\ +\x4b\xd7\x08\x4b\x78\x4a\x59\xb6\xd4\xff\xfa\xfc\x11\x05\xba\x56\ +\x49\xcc\x52\x9c\x73\x46\x96\x3a\xe3\xfa\x87\xd5\x2c\xfe\x09\x21\ +\xed\x37\x41\xb0\x24\xa9\xb6\xa3\x72\xab\x7d\x62\x0f\x55\x82\x4b\ +\xa2\xfd\xbc\x95\xb2\x8c\x4c\x73\xb7\xdb\x19\xb4\x13\x1a\x5c\x64\ +\xe6\x2f\x1a\x42\xab\xd9\x2c\xae\x1e\xb3\x99\xa6\x69\x70\x2e\xab\ +\xa2\x34\x59\xea\x9d\x41\x59\x8b\xbc\x51\x4c\x13\x93\xe4\xa4\x20\ +\x4c\x56\xa6\x6d\xd8\xa6\x3e\xaa\x27\xa3\x7a\xa2\x4e\xa7\x8f\x24\ +\xe1\x45\xc1\x59\xd5\x58\xb2\xea\x66\xa2\x2c\xd2\xcd\xa0\xad\xbc\ +\xd9\xb9\x8d\x92\x1d\x86\xa1\x69\x39\xa6\xe3\x20\xd0\x40\xd5\x81\ +\x49\xbc\x47\xc7\xa6\xe0\xe3\x25\x53\xc7\xb2\x2c\x13\xb0\x51\xf3\ +\x79\x5a\x51\x05\x84\x96\xf0\x3b\xa8\xf7\x02\xa3\xe2\xb5\x48\xc8\ +\x06\xec\x88\xc1\x88\x34\xef\x3f\xdf\x0f\x20\xb2\x8c\x54\xa6\x93\ +\x6d\x7a\x3e\x8f\x4e\x3d\x22\x99\xe1\x82\x54\x25\x4e\x48\x65\xf6\ +\xf2\xc6\x7e\x47\x53\xb9\x5d\xea\xee\xdc\xb0\x5d\x78\xbc\x46\xb8\ +\x25\x34\xdb\xca\x53\x29\x4d\x97\x3a\x78\xef\x84\x41\xbb\x9e\x14\ +\x87\xdd\x2a\x74\x1b\x47\x03\x62\x19\xa1\x63\xd8\x9a\xb0\x3d\xd7\ +\x6f\x75\xfa\x10\xa2\x94\x27\xca\xa7\xa5\x9e\xd5\x34\x25\x46\x4f\ +\xcb\xb0\x07\xd9\x97\x5c\x48\xb4\x4f\x4b\x20\x67\xe1\x5f\x04\x0f\ +\x3d\xb8\x02\x34\x4e\xc9\xa6\x52\x5a\xad\xa7\x6a\x05\xae\xfa\xba\ +\x66\x36\xe8\x70\xb0\x3a\x35\x7d\xa4\x64\x37\xea\xae\x71\xd5\xb2\ +\xa1\x69\x25\xce\xa0\x72\x72\x2e\x96\xfa\xcd\xa6\x79\x3a\x60\xcd\ +\x45\x4a\x44\x0f\x2d\x9a\xe7\x08\xe2\xc0\x2e\x95\x87\xb6\x57\xba\ +\xbd\x7b\x7f\xd5\xae\x03\x6e\x5d\xc6\xab\x2d\x4e\xf9\x6e\xa9\x3b\ +\xa7\xe0\x17\xce\x8b\xa5\xee\x19\x5e\x18\x84\x96\x7d\x8a\x26\xfb\ +\xa5\x8e\x7c\xcf\x00\x77\x02\xcb\x3b\x43\xe1\x3c\xe4\x18\x0b\xdb\ +\xb6\x5c\xcf\x3f\x43\x6b\x21\xa0\x9b\x50\x8e\x0f\x04\xa2\x6a\x3e\ +\xfa\x03\xaa\x2d\xdf\x65\x42\xb1\x23\x45\x4d\x4e\x2d\x15\x82\xd6\ +\x6b\xbe\xbf\x0c\x43\x72\x6b\xd5\xa7\xa8\x66\x54\x42\x2f\x94\xfb\ +\xe9\xae\x2a\xe1\xd5\x65\xc3\x1d\x65\x40\x02\xea\xaa\xd2\x76\x07\ +\x8e\x4f\x35\xfa\x12\xf5\xad\xe0\x09\x0d\x70\xed\x8c\xe7\x0e\x3a\ +\x3c\x0d\x15\x78\x4f\x0b\xfa\x85\x40\xdc\x67\x54\x57\x0c\x97\x28\ +\xcb\xf9\x1a\xe7\x9d\xf7\xab\x46\x23\x3e\xa2\xa5\x35\xd2\x34\x79\ +\x50\xfd\xb8\x3f\x28\x99\xde\x0b\x15\x9f\x4a\xe0\xfa\x0b\x6f\x10\ +\x72\x41\x33\xca\x26\xfe\xf6\xa2\xc3\x54\xa4\xba\x17\x86\xef\xbe\ +\x29\xb0\xa6\xfc\xfc\x53\xec\x30\xc5\xba\xba\x37\xcf\x0b\xbf\x91\ +\x17\x44\xe2\x14\x4b\x3c\x76\x41\x2f\x71\xc2\xd0\xea\x23\x83\x41\ +\x18\xfd\x71\xff\x71\xd5\x1d\x14\x27\x49\xf4\x37\x17\x0f\xfd\xb9\ +\x9a\xa6\x14\xf0\x9a\xd7\x90\x0a\x7d\x35\x88\xe3\x34\x89\x60\x74\ +\x15\x58\xae\x68\x01\xb5\xad\xa6\xde\xaf\x30\xaa\x62\x73\x04\x8e\ +\x94\x15\x59\xe3\xa6\xed\xb6\x82\xb4\x33\xf0\xe2\x8b\x20\x4d\x0a\ +\xaa\x8c\xcc\x3f\x25\xcd\xf3\x4f\xea\x90\x2e\xe2\xc9\xa6\x54\xe6\ +\x64\x14\xc6\x66\xe7\x7d\x17\x9b\x39\x09\x2e\x36\xfb\xe8\x9b\x55\ +\x36\xb2\x72\xd4\x14\x43\xa2\x73\xbc\x26\x50\x04\xbf\x2b\x50\x3b\ +\x43\x33\xc1\xeb\xb2\xe0\x29\xe9\xcc\x07\x36\x49\x22\x87\x94\xc9\ +\x43\x0e\x78\x33\x50\xa2\x1b\xab\x79\xee\x52\x5a\x95\x60\x01\xf3\ +\x3c\xa7\x8c\xdc\x71\x18\xa4\x9b\x9c\xef\xa2\x47\x5a\xd1\x75\x4e\ +\xee\x9a\x4f\x9a\x43\xe4\x83\x68\x03\xe1\x37\xf6\x1b\xc7\x69\x16\ +\xa8\x1b\x34\x91\xdd\x2e\x45\x9d\x93\x88\x71\xf6\x05\x46\xd4\x5d\ +\x25\x05\x7f\x20\x83\x7e\xbb\x6c\xdb\x2d\xb2\xfa\xa5\x3a\x1b\xe2\ +\x88\xd6\xb5\x94\x53\xd9\x3f\x9c\xb2\x08\x68\x27\xa2\x97\x36\x8b\ +\x1c\x1a\x46\x46\xf3\x5e\x96\x62\x98\x64\x42\x40\x14\x70\x28\x99\ +\x4a\xf9\x66\x53\x11\x19\x39\x46\xe0\x3a\x81\x65\x7b\x41\x0f\x8e\ +\x1e\x17\x58\x3c\x10\xd1\x5a\x12\x86\x21\x40\xb4\xc6\xc9\x83\x22\ +\x94\xa5\x11\x4e\x60\xac\xd4\x39\x5c\x2e\x8e\x1a\x4a\xd1\xea\x42\ +\x44\x28\x18\xc4\xfd\x6b\xcd\x19\x24\xfd\xc0\x98\x8f\x4a\xaa\x95\ +\x16\xc3\xea\xa8\xd9\x84\xc2\xe6\x86\x1b\xb8\x73\x77\x6c\x33\x01\ +\x3a\xbe\x61\x2f\x82\xc0\xb5\xc2\xa1\xdc\xde\xd3\xfa\xc6\x69\xb5\ +\xd1\xe2\xbb\x13\x8b\x7e\xf0\xcc\x92\x40\xfd\x3c\x3f\xb3\x8b\xd0\ +\xc6\x36\xfe\x9f\x65\xf6\xfb\xdb\xd5\x6f\x5f\x6f\xc1\x34\xb7\x4e\ +\x7b\x49\x75\xe7\xef\x39\xfe\x01\x73\x8c\xec\x17\xf4\xee\xdc\x08\ +\x9b\x94\xfe\x8b\x69\x2e\xb1\xdc\x9e\xa4\xf9\x5b\x33\xf6\x5b\x13\ +\xd5\x35\xdc\xf6\x92\x65\xbf\x65\x72\x06\x5f\x86\xc8\xd4\x1d\x4d\ +\xeb\x5b\xc0\xbf\xf5\x8d\x79\x7b\xd5\xd3\x12\xcd\xba\x75\x7d\xc3\ +\x6d\x9f\xa7\x17\x47\x09\x52\x84\xb8\x96\x33\x36\xe1\xf8\xb5\x80\ +\x33\x08\x47\x72\x81\xe0\x0b\xc2\x23\x96\xb5\x20\x6a\x82\xbe\x05\ +\x95\xb6\x31\x6f\x33\x3d\xff\x0f\xa8\x74\x1c\x63\x7e\x6b\x43\xe5\ +\x03\x81\xb6\x65\xb4\x64\xde\x5a\x4f\xfd\x7d\xce\x9e\x1f\x5e\x3d\ +\x7b\x41\xd7\x95\xaf\xa0\x10\x79\x57\x4e\xa2\xe3\xb6\x9d\xec\xbf\ +\x86\xc4\xc5\xb5\x93\x18\xbc\xaa\x8f\x91\x87\xdc\xeb\x65\x70\xf8\ +\xaf\xc1\xe9\x38\x5c\xb8\x13\xee\xce\x16\x97\x99\xf4\xdf\x79\xf4\ +\x2f\x0e\xc6\x97\x90\xe9\xa1\x2b\x7e\xc5\x8c\x74\x5e\x1a\x91\x2f\ +\xa1\x73\x71\xcd\x2f\x9b\x09\x9d\xc1\xab\xbb\x1c\xe6\xe5\xe4\x6a\ +\xff\x3c\x2e\x63\x33\x5b\xcd\x62\xf5\xcf\xc0\xd5\xec\x2b\xe2\xa2\ +\xf8\x66\ +\x00\x00\x06\xcc\ +\x00\ +\x00\x21\x2b\x78\x9c\xdd\x59\x59\x8f\xa4\x36\x10\x7e\xdf\x5f\x81\ +\x7a\x5f\x12\xa5\x01\x63\x6e\x66\x7a\xf6\x61\x57\xab\x44\x4a\x94\ +\x28\xbb\x9b\x48\x79\x59\xb9\xc1\xdd\x43\x06\x30\x31\xa6\x8f\xfd\ +\xf5\x29\x03\xe6\xe8\x63\xe7\xd4\x1e\xc3\x68\xd4\x50\x55\x36\xae\ +\xcf\x75\x9a\xcb\x57\xbb\x3c\xd3\x36\x94\x57\x29\x2b\x16\x33\xcb\ +\x40\x33\x8d\x16\x31\x4b\xd2\x62\xbd\x98\x7d\x78\xff\x56\x0f\x66\ +\x5a\x25\x48\x91\x90\x8c\x15\x74\x31\x2b\xd8\xec\xd5\xd5\x8b\xcb\ +\x6a\xb3\x7e\xa1\x69\x1a\x0c\x2e\xaa\x28\x89\x17\xb3\x6b\x21\xca\ +\xc8\x34\xcb\x9a\x67\x06\xe3\x6b\x33\x89\x4d\x9a\xd1\x9c\x16\xa2\ +\x32\x2d\xc3\x32\x67\x83\x78\x3c\x88\xc7\x9c\x12\x91\x6e\x68\xcc\ +\xf2\x9c\x15\x55\x33\xb2\xa8\x5e\x8e\x84\x79\xb2\xea\xa5\xb7\xdb\ +\xad\xb1\xb5\x1b\x21\x2b\x0c\x43\x13\x61\x13\x63\x1d\x24\xf4\x6a\ +\x5f\x08\xb2\xd3\xa7\x43\x61\x8d\xa7\x86\x62\x84\x90\x09\xbc\x41\ +\xf2\x6e\x52\x51\x05\xa8\x94\xf0\xdf\x8b\x2b\x82\x51\xb1\x9a\xc7\ +\x74\x05\xe3\xa8\x51\x50\x61\xbe\x79\xff\xa6\x67\xea\xc8\x48\x44\ +\x32\x9a\x26\x2d\x6e\xaa\x98\x94\x74\xf2\x56\x45\x6c\x11\x20\x39\ +\xad\x4a\x12\xd3\xca\x54\xf4\x66\xfc\x36\x4d\xc4\xf5\x62\x66\x3b\ +\x86\x65\xc3\xe5\x36\xc4\x6b\x9a\xae\xaf\xc5\x21\x35\x4d\x16\x33\ +\x58\x3d\x0e\x83\xf6\x79\xb4\xc3\x56\x2b\xd0\x4d\x1c\x8d\xf7\xde\ +\xc0\xda\x0f\x34\xf0\xe2\xc0\x47\x81\x1f\xce\x35\x8c\xb0\xa5\x23\ +\x4b\xb7\xdc\x1f\x9b\x41\x4a\xa7\x28\x61\xb1\x5c\x24\xbc\x83\xe6\ +\x29\xa9\x05\xcb\x61\x1b\xe3\x38\x23\x55\x95\xae\xd2\x18\x1e\x58\ +\x51\x66\xf5\x3a\x2d\x3e\x92\x24\xf9\x58\xa5\xeb\xe2\xa3\x60\x2c\ +\x33\x14\xa2\xfd\xeb\xe9\xae\x64\x5c\xe8\xbb\xa4\x04\x5c\x3d\xff\ +\x24\x73\xaf\x98\x57\xc0\xbd\x4c\xe8\xaa\x92\x52\xad\x92\xf2\x09\ +\xb4\x6c\x79\xc0\x8d\xb3\xb4\xfc\x83\x88\xeb\x56\x42\xd3\xd4\xf3\ +\x87\x22\x15\xb0\xd1\x75\x45\xf9\x3b\x09\xed\xef\xc5\x87\xaa\x45\ +\x55\xcd\xa4\x24\x03\xcf\xee\x26\x83\xe9\xd6\x4a\x62\xb4\xaa\x8c\ +\x2c\x69\xb6\x98\xbd\x06\xf9\xd9\x88\x9d\x34\xb3\x07\x9e\xdb\x8f\ +\x86\xf1\xe5\x68\x29\xf2\xaa\xc4\x3e\x03\xd8\x56\x69\x96\x45\x05\ +\x38\xd4\x45\x25\x38\xbb\xa1\xd1\x4b\xd4\x5c\xdd\xa3\xde\xec\x74\ +\x84\x0d\xcb\xf2\x5d\xa7\xdc\x29\x72\x96\x16\x14\x96\x10\x2d\x6b\ +\x21\xc6\xb4\x7f\x59\x5a\x44\x79\x2a\x28\x57\x54\x06\x3a\xa6\x62\ +\x1f\x59\xb3\xf1\xdb\x61\x89\xb9\x66\x21\xc3\x93\x97\x3f\xb7\x5d\ +\xd8\xf0\x58\x43\x73\xdd\x31\x70\x43\x3a\x77\x3f\x99\x45\x6a\x2a\ +\xf5\x0a\x82\x70\x4a\x57\x00\xc5\xac\x80\x75\x0a\xc6\xf5\xb8\xe6\ +\x1b\x22\x6a\x0e\x2a\x43\x60\x31\xbf\x6d\x60\xb0\x65\xd8\xcd\xf5\ +\x68\x60\x42\xeb\x79\x01\xe3\x3d\x95\xc5\x84\xf6\xb3\x02\xc6\xc6\ +\x8f\x47\xc4\x7d\x56\x88\x58\xde\xe3\x11\xf1\x1f\x8e\x08\x07\x81\ +\x13\x88\xf4\x0b\xbe\x68\xb0\x01\x3c\x5c\x37\x71\x9a\x07\x7d\xca\ +\xd3\x79\x9d\x41\xde\xd9\xd0\x82\x25\x49\x8f\xdf\xaa\xb9\xa6\xf8\ +\x59\x86\x77\x88\x5c\xf5\x5f\x4d\x38\xfd\x3c\x76\xcd\x43\x96\xc2\ +\x4f\xe4\x28\x5a\x42\xaa\x6b\xc2\x39\xd9\x8f\x77\xad\xa1\xb2\xd5\ +\xaa\xa2\x22\x42\x9f\x47\x5e\x42\x27\x35\x0f\xc2\x69\x40\xee\xea\ +\x05\x15\xd7\x9c\x09\x53\xd5\x0d\xa7\xb9\x3b\xa8\x07\x54\x9e\x98\ +\x30\xf6\xc0\xc0\x46\x30\xa1\x71\x20\x3a\x06\xf2\x6c\x27\xc4\xf6\ +\x03\x4d\xf4\x14\xc4\x8e\xe1\x5a\x9e\x7f\x04\xf3\xed\x06\x7a\x77\ +\x90\xcf\x9a\xf2\x6f\x9a\x65\x1b\x41\x1b\xf5\xb0\x6d\x38\xad\xf1\ +\xfe\xac\xe1\xe0\x40\x79\x65\xb7\x21\xba\x5f\xd0\x9f\xa0\xa2\xea\ +\x2a\xb0\x3a\x2a\xf6\x25\x85\x4a\x25\x8e\xef\x8e\xe4\x14\xbd\xd3\ +\x60\xba\xed\x36\x7f\x25\x30\x87\xdc\x6a\x79\xda\x5f\x9a\x8d\x8c\ +\xb0\x79\x3c\x03\xe5\xfd\xd2\xc4\xbd\xa0\xbc\x34\xd7\x5d\xa9\x68\ +\xaa\x8a\xaf\x29\x2b\x4d\x59\x49\x36\x77\xc3\x14\x50\xe2\x26\x9b\ +\x94\x6e\x87\x72\x73\x49\xfa\xaa\xb1\x24\x6b\xe8\x5b\x32\xc6\x17\ +\xb3\x0e\xf0\x8e\xb1\x64\x3c\xa1\x5c\xb1\x1a\x1f\xf2\x26\xac\x0e\ +\xa7\xb6\xdd\x7a\x31\x55\x51\xce\xda\xf3\xd1\x69\x3e\x60\x9f\xb0\ +\x2d\xb8\xee\x21\xf3\x13\x63\x39\x74\x02\x46\xe8\x86\x08\xa3\xf0\ +\x90\x1d\x83\x57\x63\xc3\x47\x7e\x18\x62\xff\x88\x09\xef\x0b\x0c\ +\x07\x61\x48\x49\x47\x13\x03\xdc\x1c\x5a\x39\x3d\x23\x7b\x0a\x4a\ +\x35\x3f\x6a\x97\x21\x4a\x6d\xd7\x5c\x82\x23\x78\x4d\x0f\x47\x4a\ +\x8e\xbe\x5c\xb2\xdd\x69\x36\x34\x12\xb5\x6c\x12\xf5\xba\xad\xcf\ +\xcb\xdd\x78\xd6\x3a\x4d\xe4\xfe\x9d\x1a\xb8\x4d\x0b\xc0\x40\xef\ +\x42\x9c\x65\xf7\x10\x1f\x4a\xa8\x38\xe7\xa3\x73\x12\xbb\xc1\x86\ +\x0e\x59\xfb\xf3\xac\x9c\xec\xc0\x27\x3e\x51\xd0\xdb\x3a\x14\xa9\ +\x0a\x52\xea\xeb\x8c\x2d\x49\x76\x8b\xda\x9c\x89\xa6\x59\x92\xef\ +\xe9\xcc\x72\x02\x9d\x32\x6d\x69\xc9\x8b\xd9\x6e\x2f\x69\x93\xae\ +\x45\x12\x6c\xdf\x1b\xaa\x08\xc6\x53\x68\xbb\x76\x63\xbf\x68\x49\ +\xfb\x31\x49\xb6\x97\xd0\xe2\xef\x1a\x1b\x3c\x08\xf3\x1d\x6f\x3f\ +\xe6\xb5\xfe\x73\x69\x1e\xfb\x46\x43\xcf\xa9\x20\x09\x11\x64\x70\ +\x14\x45\xc1\x61\xd8\x6b\x06\x9d\x7a\xf4\xe7\x9b\xb7\xbd\x27\xc6\ +\x71\xf4\x37\xe3\x37\x83\xfb\x4a\x01\xb2\x64\x35\x6c\xd7\xb8\x89\ +\x4a\xe2\x08\x7a\x6b\x68\x31\xaf\xd2\x1c\xcc\x5f\xb6\xe5\x3f\x41\ +\x2f\x0d\x2e\xdb\x33\x26\xc2\x12\xac\x49\x7e\x82\x69\x39\x6d\x9b\ +\xf4\x93\x27\x15\x49\x0c\xd1\x0d\x06\x99\xef\x04\x84\xd3\x5f\xe4\ +\x4b\xa6\xc1\x57\x4e\x9a\x8a\x8c\x8e\xc3\x48\xb7\x7a\x15\x4c\x46\ +\xca\x5d\x9a\x4a\xfb\xe6\x69\x3d\xa0\x32\x71\x9c\xc3\x86\xf2\x57\ +\xc9\xd4\x8e\xb8\x6b\xce\xea\x32\x87\x68\xd6\x0d\xef\xd1\x1c\xd5\ +\x3a\xa7\x92\xc1\x9d\xab\x1b\x84\x9c\xe0\xb0\x3a\x44\x5f\xaf\xb6\ +\x41\x5d\xa6\x18\x25\x07\x55\xe0\xd8\xe1\xa8\xb3\x3a\x79\x1a\x22\ +\xaf\xd3\x27\x22\xf2\x9a\x78\x05\xd8\x77\x68\x38\xbe\x0d\xd9\xc6\ +\xa3\xba\xe5\xf5\x0c\x3e\x11\x93\xc5\x8d\x6d\xd8\x96\x6b\x7b\x61\ +\xd0\x5b\xc5\x24\x1d\xdf\xb7\xee\x6e\xeb\x2d\xe7\xcb\xa6\xe2\x26\ +\x0d\xa3\x39\x92\xd9\xb7\x03\x66\x0a\xb0\xd4\x08\xbc\x75\xc0\xe1\ +\xae\x69\xf7\x96\x94\xfb\x9d\x42\xd5\x83\x34\xef\xef\xa0\xfc\x43\ +\xa7\x20\x0b\xbe\x1d\xc8\x2c\x03\x76\x10\x61\x37\x78\x9a\xbe\xae\ +\x2d\x84\x55\x16\x98\xcb\xe2\x57\x7b\xad\xd9\x06\x6e\x6f\x8f\x6e\ +\x8e\xd0\xb1\x7d\x1f\xeb\xe8\xce\xf8\x3c\x89\xcd\xc8\xb6\xd6\x72\ +\xdd\x27\x43\x20\xd7\x5c\x15\x92\x1e\xd2\xdc\xf6\x50\x04\xce\x97\ +\x04\xe2\xe9\x2d\x21\x1f\x5b\x42\xdf\x12\xc5\x9a\x72\x53\x1b\x82\ +\xcb\x99\xfb\x33\x76\xa1\xe3\x67\x03\x88\x15\xa8\x20\xf1\x28\x40\ +\xac\xef\x1a\x90\x71\xac\x90\xa7\x04\x5d\xac\x68\x6e\x8f\x6e\xce\ +\x41\x60\x7f\xd7\x10\x8c\x6d\xc2\x6f\x7d\xe4\xb1\x4e\xe2\x3c\x1b\ +\x40\x7a\x65\x1f\x07\x48\xf8\x74\x80\xbc\x5c\x61\xf9\xd7\x63\x82\ +\xa9\xfc\x9b\x62\x02\xd5\x1f\xc2\xd8\xfd\x0a\x35\xc8\xf0\xa9\xc6\ +\x32\xe4\x17\x4f\xb8\xa0\x06\xb1\x71\x4b\x0d\x65\x29\x07\xde\x24\ +\x77\xd1\x02\x7a\x2f\xad\xfd\x73\x8c\x1c\xf4\xf5\x0f\x89\xb6\x27\ +\x9a\x8c\xe6\x60\xa3\xb7\x9e\x24\xad\x4a\x68\x4b\xa2\xb4\x90\x18\ +\x5c\xb0\x0d\xe5\xab\x8c\x6d\xa3\x4d\x5a\xa5\xcb\x8c\x5e\x34\xbf\ +\x69\x26\x95\x53\xa4\x16\xf8\xd8\xa7\x21\xf9\x4c\x97\x02\xf0\x7c\ +\xa2\x9c\xf5\x3b\x63\xb9\xab\xd5\xad\x5d\xca\x53\xee\xc9\xa8\x47\ +\x81\x68\x65\xe3\xe0\x68\xb3\x2e\x72\xc2\x6f\x28\x6f\x47\xd1\x82\ +\x80\x72\xfa\x92\xc4\x37\xb2\x63\x2b\x92\x88\xc4\xd0\xe4\xd7\x19\ +\x11\xd3\xef\x8c\x4d\x23\x13\xb8\x47\x8d\xcc\xa8\x03\xe9\xcf\x66\ +\x07\xd7\x97\x9d\x7a\xf7\x19\x66\x88\x9c\xd0\x9a\x78\x46\xb3\x0f\ +\xc3\x6c\xc7\xdd\x0b\xd8\x85\xef\xda\xd8\xf1\xee\x1d\x1f\x7c\x08\ +\x05\x87\xe5\x95\xef\xd8\xce\x17\x3e\x45\x54\x27\x88\xbe\x0c\x0b\ +\xde\x1c\x7b\x86\xd3\xda\x3c\xf6\xdb\xd0\x12\xca\xf4\xeb\x68\x99\ +\xa6\xab\x4a\x6d\xae\x1f\xe7\x17\xa8\xd4\xef\x1b\x39\x9a\xc3\xc2\ +\x4b\x79\xe0\x70\xf5\xe2\x7f\xff\x30\xb7\x9c\ +\x00\x00\x14\x49\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x3c\x00\x00\x00\x3c\x08\x06\x00\x00\x00\x3a\xfc\xd9\x72\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\ +\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xdd\x08\x11\x15\x26\x08\x6d\x49\xb4\xe7\x00\x00\x00\x19\x74\x45\ +\x58\x74\x43\x6f\x6d\x6d\x65\x6e\x74\x00\x43\x72\x65\x61\x74\x65\ +\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x57\x81\x0e\x17\x00\ +\x00\x13\xb1\x49\x44\x41\x54\x68\xde\xed\x9b\x69\xac\x5d\xd5\x75\ +\xc7\x7f\x6b\x9f\xe1\x0e\xef\x79\x7c\x1e\x62\x0c\xc6\x53\x08\x83\ +\x6d\x0c\x24\x81\xb4\x0c\xcd\xd0\xd0\x14\xda\x8c\x2d\x49\x54\x94\ +\x34\x52\xa4\x56\x8d\x54\x94\xa0\x14\x45\x95\x9a\x2f\x19\xd4\x08\ +\x21\x94\x34\x49\x45\x5b\x29\x80\x4a\x49\x49\x43\xa2\x26\xa4\x19\ +\x4a\x08\x04\xcc\x10\x1c\x08\x60\x0c\xd8\xc6\xf6\xf3\xf3\xb3\xdf\ +\x3c\xdc\x7b\xcf\xb0\xf7\x5e\xfd\x70\xce\xbd\xef\xde\xf7\x3c\x12\ +\x42\x3f\x24\x47\xba\xda\xf7\xbc\x7b\xd6\xde\x67\xed\x35\xfe\xd7\ +\x5e\x0f\x7e\xcb\x2e\xb9\xe4\x9e\x45\xd5\xd7\x64\x25\x9d\xfb\x28\ +\x80\x2f\x46\xe9\xba\x6f\x3f\xa7\x5a\xfe\xde\xa6\xa1\x9b\x56\x41\ +\xa5\xeb\x79\xed\x79\xae\x4d\xdb\x5e\xa7\xb6\x31\x48\x9f\xb8\x76\ +\xaa\x3d\x0b\x21\x70\xcb\xff\xfb\xb6\x6b\xd7\x57\xed\xbd\x7f\x45\ +\x9b\x3a\x77\xd5\xa7\x7f\x61\xff\x11\x78\xb6\x9b\xe1\xbf\x7a\xad\ +\x18\xd2\xf9\x0c\x6a\xef\xfb\xa9\x6f\xff\x28\xc7\xa0\x57\x14\x29\ +\x99\xd2\x79\xf4\x82\xaa\x22\xf3\x18\x16\x81\x7c\xd4\xaf\x5f\xfb\ +\xa1\xca\x7b\x0f\xdd\x95\x8e\xb7\x19\x7e\x6d\x98\xd5\x5e\xb5\xee\ +\x5c\x7e\xde\xbd\xca\x31\x9e\x53\x54\xa5\x98\xa4\x33\x76\x99\x46\ +\xb9\x01\x3a\x6f\x3d\x11\x50\xcf\x5a\x0c\x51\xb7\x84\x5f\x53\xfb\ +\x5d\xb0\x01\x2c\xdc\x10\x9d\x67\xef\xe2\xa5\x6b\x1e\x9d\x23\xf3\ +\x0b\x6d\x7c\xc1\xe6\x82\xeb\x5e\xe9\xb4\x18\x5e\xa9\x55\xd6\x50\ +\x27\x44\x30\x08\x1e\xed\x8c\x85\x62\x49\xa9\x78\xe5\xa8\x82\xd7\ +\xb9\x7b\x04\x0c\x82\xd3\x92\x4e\x8a\xbf\x89\x2f\xe6\xe8\xd0\x99\ +\x39\x69\xab\x2a\x6a\xc0\x28\x9d\xf5\x9c\x2f\xd6\x33\x08\xea\x0b\ +\x13\xf0\xe5\x7a\x28\xe4\xea\xd9\x93\xcd\x30\xab\xf9\x02\x1e\x4e\ +\x8b\xe1\x4b\x59\xcd\xd5\x66\x29\x15\x00\xad\x83\xb4\x40\xab\xc5\ +\x88\x01\x8d\x41\x72\xd0\x10\x24\x29\x7e\xc3\x82\x46\x20\x59\xa9\ +\x7f\x35\x20\x01\x6a\x40\x13\x6d\xd3\x91\x97\xaf\x93\x00\x95\xf2\ +\xd9\xa0\xa0\xc7\x95\xcf\xcf\xd1\x15\x76\x5e\x05\xd2\x92\xbe\x05\ +\xc4\x18\x84\x69\x6f\xf9\x97\xc9\x7d\xec\xcc\x27\x5e\x01\xc3\x5d\ +\x3e\xa4\x26\x86\xf3\x09\xa8\x1a\x43\xd3\x47\xd4\x4d\x4e\xd3\xc7\ +\xd4\x8d\x45\x55\x48\x09\x89\x44\x71\x12\x12\x4b\x4c\xa6\x21\x01\ +\x90\x6b\x48\x45\x3c\x22\xda\x79\xbe\xa0\x8f\x50\x85\x44\x23\x2a\ +\xe2\xc9\x29\x47\x0d\x11\x3c\x8e\x80\x08\x30\xd2\x5e\x6f\x8e\x0e\ +\xa0\xe5\x23\xaa\x62\x49\x35\xa2\x6a\x1c\x56\x43\x14\x98\x71\x42\ +\x9f\x84\xc7\xf4\xf6\x27\x67\x58\xe0\xe3\x9c\xc3\x66\xea\x2c\xa7\ +\x1f\xab\x4a\xe2\x21\xd3\x0a\xc6\xfb\x72\x74\x78\x02\x72\x8d\x70\ +\x84\x38\x02\x14\x21\xd5\x0a\x01\xc5\x8b\x78\x02\x8c\xba\x05\x74\ +\x8a\x21\xd3\x0a\x8a\xc1\x6a\x04\x06\x32\x8d\x31\x28\x0e\x83\xc3\ +\x12\x74\xe8\xb4\x43\xdf\x9e\x1f\x8a\xe7\x45\x95\x5c\x23\x40\x48\ +\xb0\x18\x91\x63\x85\xa9\x53\x53\xe9\xcd\xd4\xb9\xd4\x54\xc9\x34\ +\xa0\x22\x09\x06\x8f\x25\x26\x92\x0c\x4b\x48\x2c\x19\x8e\xa0\x98\ +\x50\x72\x8c\x86\x44\x9a\xd1\x72\x01\x5e\x1d\x56\x05\x63\x2c\x91\ +\xc9\x09\x25\x22\x92\x8c\x96\x8b\x09\x4c\x86\x18\x83\xc7\x60\x34\ +\x23\x77\x06\xe3\x1c\x16\x47\x64\x1c\xa1\x31\x44\x62\x09\xb0\xe4\ +\x44\xe5\x7a\xc5\x08\x52\x68\x80\x64\x78\x0c\x11\x19\x94\x0e\xdc\ +\xe0\xf0\xea\x4f\x4f\xc2\x2b\xb5\xca\xa5\xac\xa6\x26\x86\xe5\xf4\ +\x93\x69\x40\xae\x31\x82\x22\x14\xbb\x19\x50\x21\xd7\x98\x14\x87\ +\xc7\x90\x6b\x84\xc7\x90\xba\x80\xe7\x26\xfa\xf8\xde\xbe\x35\x0c\ +\xcd\xc6\x28\xc2\x9a\xbe\x84\x2b\xd6\x8e\xb3\x65\x75\x4a\x10\x3a\ +\xee\xdc\x75\x26\x97\xac\x1c\x63\xdb\xaa\x19\x12\x1f\xf3\xb3\x03\ +\x2b\xf8\xd9\xe0\x00\x2d\x2b\xf4\xc5\x9e\x6d\x2b\x66\x79\xd7\xc6\ +\x11\xfa\xa2\x80\x80\x90\x5c\x63\x0c\xbe\xb3\xae\x22\x0b\xfe\x96\ +\x13\xa1\x08\x5e\x2d\x81\x9a\x63\xf2\x75\x5c\x86\xd7\x50\xe7\x6a\ +\xb3\x94\xf3\x09\xb0\xaa\x54\x24\x41\x50\x2a\x92\x62\x4a\xfb\xaa\ +\x48\x82\x23\xa0\x2a\x2d\x1c\x01\x82\x12\x92\xf1\xe8\xf0\x4a\xbe\ +\xf0\xd8\x66\xde\x73\xd9\x19\x7c\xe0\x8d\x1b\x31\x62\xd8\xb9\xeb\ +\x65\x9e\x1c\x7c\x99\x95\xfd\x7b\x59\xb9\x74\x9c\xff\x3d\xb4\x96\ +\x15\x4b\xfb\xb8\xd4\xec\xe4\xbe\x7d\xab\xf8\xa7\x9d\xeb\xf9\xcc\ +\x75\x17\xb0\x69\xed\x52\xf6\x0f\x4f\xf0\xfc\x4b\xfb\x68\xda\x49\ +\x96\xc7\xb3\x84\x58\x3c\x86\xaa\xb4\xf0\x18\x2a\x92\x94\xdb\x2e\ +\x54\x24\x05\x28\xdf\xcf\x03\x42\x0b\x8b\xa3\x4b\xc2\x72\x0a\x0c\ +\x5b\x3c\x11\x50\x35\x86\xc4\x83\xc1\x23\x68\x31\x8a\x62\xd4\x63\ +\xca\x51\x84\xe2\x1e\x8f\xf5\xf0\xe5\xa7\xce\xe1\xe3\xef\xbf\x82\ +\xeb\xce\x3d\x82\x3f\xfc\x1d\xac\x1a\xce\xbb\xe8\x0d\x98\xcb\xb7\ +\x33\xbb\x77\x1c\xd3\x38\x4c\x5c\xeb\x27\xec\x8b\x30\x38\x1e\x38\ +\xba\x89\x6b\xaf\xdc\xc2\xdb\x56\x3f\x47\x34\xb5\x87\x0d\x2b\xce\ +\xe6\xed\x1b\x37\x90\xee\xaf\x60\x5a\xc5\xfc\xa2\xda\x59\xcf\x88\ +\x16\x99\x55\xfb\x7d\x98\x7b\x87\x82\x3b\xc5\xfb\xb9\x84\xec\x84\ +\x12\xbe\x52\x57\xf1\x69\xb9\x10\xc4\x22\x6a\x68\xfa\x9c\x4c\x2b\ +\x58\xe2\xd2\x29\x05\x18\xf5\xb4\xb4\x86\x7a\x21\xd5\x2a\x78\x4a\ +\xa7\x15\x32\xd4\xa8\xb0\x7f\x42\xb8\x66\xed\x0b\x4c\x3e\xfb\x43\ +\x04\x47\xc3\xc6\xc8\xd1\x41\x22\xb1\xa8\xa9\xe0\x83\x3e\x50\xf0\ +\x5e\x68\x68\x1f\xdb\xce\xdb\xc4\x7d\x8f\xed\x66\x53\xe3\x45\xd6\ +\xd4\x9b\x2c\xab\x3f\xc3\x9a\xfe\x5f\xe0\x35\x20\x90\x3e\x02\x75\ +\x24\xe5\x7a\x89\x56\xd1\x32\x11\x49\xb5\x5a\x9a\x52\x8c\xfa\xc2\ +\xe9\x29\x14\x3e\x40\x82\x53\xb3\xe1\x1c\x47\x4d\x9a\x04\x52\x78\ +\xd0\x58\x32\x8c\xf7\x44\x92\x11\x50\x29\x9c\x96\x28\xea\x85\x3e\ +\xd3\x00\x0f\x75\xd3\xc4\xa9\x21\x20\x66\xc6\xaf\xa2\x12\x87\xf4\ +\x0f\x7f\x87\xd4\x40\x2b\x83\x1d\x87\x06\xd8\x3b\x59\xa3\x6a\x2c\ +\x57\xad\x9b\x64\xeb\xf2\x46\x91\x38\x88\x23\xd6\x26\x7f\xbe\x35\ +\x61\xb2\xb5\x9e\x7b\x77\xa5\xd4\xc3\x94\x8a\x64\x5c\xbe\xe6\x30\ +\x7f\xb4\x61\x8c\xaa\xc9\x09\xc5\x81\x87\x9a\x34\x01\xe8\x33\x8d\ +\x22\x75\x44\xa9\x4a\x8b\x14\x47\xcd\xb4\xc8\x4b\x86\x13\xef\xc8\ +\xd5\x9d\x9a\x97\x8e\x08\x68\x69\x9d\x00\x47\x23\x0b\x18\x9a\x59\ +\xc2\xa6\xe5\x16\x5b\x3a\x8e\xb6\x84\xdb\x92\x4d\xb5\x8a\x78\xed\ +\x38\xad\xbe\xc5\x03\xe4\xd6\x31\x9d\x06\x78\x89\xc9\xc2\x2a\xcb\ +\xcf\xbc\x80\x3d\x52\xe3\xa7\x2f\x4c\xb3\x7e\xcd\x38\x1b\x7d\xf1\ +\xe2\x5e\x03\x9a\xf4\xc3\xd0\xfd\xdc\x78\xf5\x9f\x71\xf0\xaa\xab\ +\x39\x70\x78\x9c\x27\x5f\x1c\xe1\x8e\x27\x17\xd3\x57\xd9\xcb\xe5\ +\x67\x8e\xcd\x49\x18\xe9\xac\xd7\x0e\x4b\x73\x12\x16\x2c\x45\x5c\ +\xb7\x58\xa2\x32\x6a\x9c\x82\x84\x2d\x75\xd3\x24\xc0\x72\xe7\xee\ +\xb3\x79\xc7\xba\x23\x38\xeb\xcb\x50\xa0\x40\x82\x31\x8a\x7a\x83\ +\xd3\x14\xa7\x82\x37\x29\xd5\xd0\x13\x4a\x85\x8d\xf5\xa3\xac\x5a\ +\x76\x1e\x0f\x1c\x58\xc2\x3b\x37\x8c\xb1\x28\xc8\xb8\x7c\xf5\x38\ +\xaf\x5f\x77\x01\x43\xb3\x55\xe2\x9a\x2d\x34\x03\xc5\x88\xa3\x2e\ +\x4d\x9c\xcd\xe1\xe9\x5b\x58\xd3\xb7\x81\x0d\x8b\x56\xf1\x96\x3f\ +\xd8\xc6\x81\xf1\x33\xd9\xdd\xb2\xbc\x53\x0e\x10\x88\xef\x68\x92\ +\x78\xa5\x6e\x8a\x0d\x13\xef\xa9\x49\x8b\x94\x2a\x55\x93\x90\x6b\ +\x08\x02\x69\xb7\x84\x4f\xc6\xb0\x20\x38\x35\x20\x01\xc3\x8d\x2a\ +\xcd\x2c\xe4\xae\xdd\x67\xb0\x7d\xe5\x24\x0d\x5b\x01\x6f\xa9\x04\ +\x0e\x27\x31\xcf\x1c\xad\x71\xf6\xd2\x8c\x46\x0a\x1f\x3e\x7f\x88\ +\x7a\x6c\x08\xd3\x61\x3e\xf1\xbe\xeb\xf9\xea\x37\x67\x98\xce\xf6\ +\x71\xc9\xea\x09\xcc\xc4\xf3\x3c\x72\x74\x96\xc1\x23\xeb\x30\x1b\ +\xc0\xa9\x21\xb3\x1e\xe7\xc1\x18\xc3\x5d\xbb\x5e\xc7\x40\xa5\xc5\ +\xfa\xa5\x53\xf4\x99\x61\x76\x1c\x39\xcc\xde\x43\x17\x70\xcd\x3b\ +\xd6\xe1\x09\x10\x2d\x34\xc8\xa9\xc1\x13\xe0\xd5\x14\xe1\x87\x00\ +\x57\x7e\x54\x85\xa6\x87\x59\xe7\x19\x77\x96\xcc\xfb\x36\xa8\xea\ +\x01\x9b\x0b\x18\x0e\x28\xe2\xad\xc7\xb1\xb2\xcf\x72\xee\xca\x84\ +\x47\x8e\x5a\x2e\x3f\x73\x86\xef\xef\xab\xb3\x61\x69\x8b\xbd\x93\ +\x55\x36\x2f\xcf\x69\x64\xc2\x95\x67\x37\x78\xf8\x60\x9d\x5c\x63\ +\x72\x35\xa8\xcb\xb9\x62\xe9\x93\xd4\xae\x7f\x07\x0f\x3c\xf4\x10\ +\x4f\x3c\x3b\x89\x02\x03\xcb\x97\xf3\xb1\x6b\x2e\x62\x6b\x65\x07\ +\xd9\x64\xcc\x55\xdb\xd7\x71\xd6\xc0\x41\x32\x1f\xb2\xe8\x8c\x0b\ +\x79\xfc\xe5\x19\x7e\x72\xb8\x89\xa8\xa3\x6f\xf1\x32\x3e\x76\xed\ +\xc5\xbc\x69\xd1\x0e\xb2\x91\x98\x80\x00\xab\x11\x19\x15\x72\x0d\ +\xc9\x28\x62\x7b\xf1\x37\x8f\xd5\x88\x94\x98\x3d\x99\xe5\xbf\xa7\ +\x26\x78\x31\x19\x67\x5f\x3a\xd3\x9b\x2e\x1e\x8f\x61\x8f\x27\x92\ +\x9c\x00\xc7\xb6\x15\x53\x84\xe4\x6c\x59\x31\x43\x2d\x4c\x79\xfd\ +\xb2\x59\x32\xeb\xd8\xbe\x62\x92\x5a\x25\x24\x1c\x68\x51\x0b\x95\ +\xf3\x97\x4f\xd1\x17\xa6\x04\x12\x12\x4a\x8e\x0c\xff\x94\xb7\xad\ +\x99\x62\xdb\xbb\x2f\xa6\xe5\x62\x54\x85\x7a\xd0\x60\x49\x6b\x07\ +\xe9\xc8\x33\x44\x92\xf3\x91\x37\x7b\xaa\x13\x87\x09\x27\x32\xfe\ +\xf0\x1c\xc7\xe5\xdb\xb7\x92\xfa\x1a\xa6\xcc\xb2\x96\xa4\x3b\x71\ +\x87\x1e\x23\x94\x7c\x5e\xa6\x55\xac\x51\x64\x5a\x21\x91\x64\xe4\ +\x0a\x42\xca\x84\x6d\xf2\x78\xe3\x30\x07\xf3\x19\x50\x10\xd1\x53\ +\x53\x69\x4b\x88\x22\x5c\xb2\xa6\x81\x97\x90\x0b\x57\x37\x11\x42\ +\xce\x5b\x91\x50\x91\x14\x11\x4f\xcb\xd7\x59\xb7\xa8\x45\xcb\xd7\ +\xd8\xb2\xaa\x89\xd7\x80\xbc\x54\x3f\xa7\x9e\x6c\xe8\x61\xaa\xf1\ +\x1e\xfa\xc3\x0a\x8e\x80\xc0\xcd\xe0\xb3\x09\xac\xab\xe0\x4c\x88\ +\xd9\xff\x1d\x8c\x4e\xe1\x34\xc4\x1f\xd9\xc1\xe2\x78\x27\x36\xa8\ +\x53\x91\x8c\xcc\x7a\x6c\x3a\x89\x57\x2d\x5e\x51\x0a\x07\xe7\x08\ +\x71\x1a\xe0\x24\x44\x15\x9c\x06\xa4\x04\xbc\x94\xe6\x3c\x38\x3b\ +\xc2\xa8\xcb\x99\x76\x49\x17\x96\x96\x93\x33\xec\x70\x54\x25\x21\ +\x28\xd3\xc5\x48\x72\x14\x21\x26\x2b\x33\xad\x04\x11\x70\x12\x52\ +\x91\x14\x27\x86\x8a\x64\x05\x9a\x55\x4f\x2c\x79\x27\xbf\x26\x3b\ +\x42\x98\x59\x32\x8d\xa8\x48\x86\x88\xe2\x84\x82\xce\x4e\x50\x31\ +\x4d\x54\x0a\x24\x58\x49\x47\x11\x62\x22\x49\x41\xa3\x22\x89\x91\ +\x80\x88\x1c\x23\x8a\x93\x80\x8a\x49\x71\x3e\x28\xb2\x2b\x01\xf5\ +\x86\xaa\xa4\xec\xcd\x66\xf9\xc6\xc4\xcb\xf3\x8a\x07\x65\xc9\xa3\ +\xd0\x67\x39\xa1\x0d\x27\x5a\x25\xc0\x75\xd2\xb7\xb6\xfb\xcf\x34\ +\x2e\xb5\xc0\x93\x69\xdc\x41\x31\x81\xba\x52\xc2\x51\x29\x89\xa0\ +\x4c\x0c\x2a\x58\xc2\x42\x63\xd4\x60\x68\x3f\xdf\xa6\xb7\xa8\x1a\ +\x52\x2d\x73\x63\x22\x04\x2d\xd0\x0f\xa5\xa3\x22\x24\xc4\x76\xa1\ +\xac\x62\xdd\x5c\x95\x9d\xad\x9c\x23\xf9\x0c\xbb\x92\x66\x2f\xb3\ +\x85\x3e\xa3\x99\x82\x47\x4e\x98\x5a\x2a\x4a\x88\xed\x48\xb8\xfd\ +\x3d\x10\x4b\x40\x40\x20\x16\x83\x12\x88\x23\xc0\x12\x88\x23\xc4\ +\xe2\x44\xf1\x6a\x08\xc4\x82\x42\x48\x11\xbb\x03\x29\xb0\x72\x41\ +\xef\xe6\xd1\x39\xbc\x78\x82\xf2\x39\xaf\xc5\x7a\x8e\xa0\x93\xaf\ +\x87\x25\x5a\x32\xe2\xe6\xe6\xc0\xe2\x54\x79\x60\x76\x82\xfb\x67\ +\x0e\x90\xf6\x24\x19\x85\xdd\xfa\x5c\xc9\xc7\x3c\x6a\xf5\x16\x84\ +\xc9\xe3\x32\x6c\xda\xa8\x47\x4c\x47\x4d\xad\x86\x08\x8a\xd5\x10\ +\x43\x81\x50\xac\x86\xe4\x44\xe5\x18\xe3\xdb\x78\x16\x70\x04\x64\ +\x1a\x95\x92\x2d\xbc\x69\x21\xb1\x60\x1e\x5d\x54\xd2\x85\x9d\x39\ +\x33\x0a\x3a\x41\xf1\x1a\x94\xe1\xc7\xe0\xca\x75\x12\x1f\x30\xe1\ +\x95\x54\x95\xc1\x7c\x9a\x71\x97\xcc\xcb\x99\xa5\xcd\xac\xda\x59\ +\xfd\xa4\x4b\xf4\xdf\x86\xee\x4a\x53\x80\x4b\xee\x59\x24\xc7\xb4\ +\xe1\x48\xb2\x22\xb5\xd4\xc2\x3e\x7d\x89\x3b\x15\x21\x2e\xd1\x92\ +\x25\x2a\x71\x70\x48\x2c\xe9\x02\x3c\x5c\x91\x0c\x2d\x25\x2e\x68\ +\x99\x9a\xba\x2e\xfc\x1c\x11\x4b\x8a\xa7\xd8\xd8\x22\xb1\x81\x8a\ +\x64\xa0\x82\x88\xc7\x77\x49\xd8\x96\xeb\x8c\x58\xcb\x67\x0e\xff\ +\x0a\x03\x1c\xce\xd2\x52\x8d\xcb\x6a\x26\x8a\xcf\x69\x33\x7b\xa3\ +\x6b\xe9\xd7\x86\xfe\xa3\x60\xf6\x84\x2a\x1d\x48\x11\xd2\xbd\x68\ +\x89\x8c\x8a\xf0\x6e\xca\x50\x5f\x20\x13\x47\x20\xbe\x83\x5e\x50\ +\x87\x2b\x7f\x57\x91\x82\xae\x4c\x0b\x3c\x41\x41\x5f\xa2\x9d\x82\ +\xae\xb8\x17\x9d\x9b\xd7\xe1\x3a\x74\x06\x0f\x22\x18\x5c\x29\xe3\ +\x82\x0e\x84\xfd\x79\x73\x5e\x25\xb4\x30\x52\xb5\x90\x8f\x7b\x6f\ +\x67\xf4\x26\xd7\xd2\x2f\x0f\xdd\x9d\xf6\x54\xf1\x7e\xf1\x81\x19\ +\x3d\x46\x2e\x1d\xd2\xf4\xf5\x52\xc2\x82\x95\x36\x5a\x8a\x7a\x72\ +\xe9\x64\x01\x5a\x2a\x4c\x21\x27\x2a\x43\x47\x50\x38\x28\x29\x4a\ +\x3c\x96\xf0\x04\x74\xc5\xbc\x56\x23\xbc\x2f\x4a\x45\xd2\xf1\x09\ +\x31\x01\x8e\x07\x1b\x39\xcf\x24\x93\x8c\xe6\x49\x6f\x39\xb7\x9d\ +\x3f\x58\xc8\xc7\xbc\xcd\xa7\xf5\xb3\x76\x5a\x6f\x1e\xfe\xaf\xd4\ +\xb7\xd5\xb8\xcd\xec\xc9\xd1\x92\xcc\x47\x4b\xae\x07\x2d\x55\x69\ +\x60\x15\x62\x69\xe1\x55\x30\xc4\xc4\x92\x77\x42\x56\xa0\x1e\xbc\ +\x45\x7d\x4c\x28\x19\xa1\xf1\x78\x7a\x51\x96\x57\x21\xc5\x11\x4b\ +\x4a\x4e\x4c\xd5\x24\xa5\x97\x9e\x73\x5a\xa1\x38\x9e\x4f\x27\xf9\ +\xe6\xc4\x1e\xb2\xb2\x74\x53\x14\xdf\x8b\xba\x95\x5a\xb0\x13\x2e\ +\xcb\x27\xf5\x8b\x83\xb7\x27\x9f\x3b\x51\xb9\xea\x38\x68\xa9\x8f\ +\x80\x22\x64\x58\x09\xbb\x24\x3c\x87\x87\x9b\xbe\xca\x37\x5f\x78\ +\x1d\xc3\xcd\x1a\xd5\x20\xa7\x1a\x28\xe7\xae\x68\xb2\x7d\xd5\x14\ +\x22\x85\x84\x87\x1a\x75\xee\xdb\x3b\xc0\xaf\x46\xfa\x11\x94\xb5\ +\x8b\x12\xde\xb9\x71\x9a\xad\x03\x90\xf4\xa0\xac\x18\x47\x58\x14\ +\xfb\x7c\x71\x2f\xe2\xc9\xbc\x30\x6c\x9b\x38\xf5\x8c\xe6\x29\x16\ +\xed\x39\x5e\x41\x41\x9d\x92\x4f\xf8\x24\x1b\xd7\x5b\x07\x6f\x4f\ +\xfe\x61\x3e\x3f\x6d\xc9\x1e\x9b\x61\x85\x5c\x2d\xf5\xa0\x51\xda\ +\x70\x5b\xc2\x8e\x58\xb2\x02\x95\x48\x82\x88\x62\xbd\xf0\xe3\xa1\ +\xf5\x2c\x5f\x5c\xe3\x2d\x1b\x2b\xec\x1f\x69\xf1\xa5\xc7\x66\x79\ +\xdf\xa6\x03\x5c\xbf\x65\x08\x75\x96\x2f\x3d\x7e\x01\xd5\xfe\x15\ +\x7c\xf4\xbd\x5b\xa8\xc5\xc2\xa3\xcf\xec\xe7\x85\xd9\xbd\x5c\xb6\ +\x72\xb0\x83\x7a\x54\x85\xa4\xd4\x9c\x8c\x98\xaa\x49\xc9\xd4\x62\ +\xf0\xcc\xaa\xe7\x0b\x47\x9e\xe3\xb9\x74\xa6\xf7\x7c\xaa\xad\xd2\ +\x0e\xf2\x09\x6d\x66\x63\xfa\xf5\xc1\x3b\x92\x9b\xda\x6c\xcc\x57\ +\xe3\x13\x32\x2c\x08\x5e\x0d\x22\x1e\x55\x29\xe7\x36\x1d\x6f\x5a\ +\x54\x18\x3d\x2a\x01\x95\xbe\x65\x5c\xb9\x7d\x15\xd7\x9d\x7b\x04\ +\xfa\xcf\xe1\xae\xa7\xea\xfc\xf0\xc1\x27\xf8\xa0\x1b\xe6\x85\xf1\ +\x65\xb4\xa2\xb5\xdc\xf0\xa7\xe7\xb0\xc9\x3e\x4c\xa8\x0d\xde\xf8\ +\xd6\x0b\x49\xd3\x4d\xf8\xbd\x4f\x14\xf3\xa9\xf4\xcc\xab\x18\x54\ +\x21\xf5\x4a\xae\x9e\x69\xef\xba\xb2\x86\xc2\x13\x4b\x69\xbb\xa5\ +\x64\x9b\xd9\xa8\xde\x36\x78\x47\xf2\xa9\xf9\x52\x6d\x33\x7d\x7c\ +\x86\xcb\xbd\x08\x35\x28\xeb\xc9\x45\x3e\xad\x2a\x64\x5d\x40\xbb\ +\x3c\xab\x23\xf7\x31\xaa\xca\xec\xd8\x41\x1a\x2f\xfd\x98\x96\x0d\ +\x98\x1e\x79\x2b\x95\xbe\xa5\xa4\xd4\xe8\x5f\xb9\x01\xdd\x6d\xd8\ +\xf1\xc8\x03\xc8\xf2\x7d\xf4\x47\x29\x8b\x87\x77\xe3\x4c\x95\xaa\ +\x54\xc9\x35\x26\x29\xb3\xb9\xac\xcc\xb4\xda\xf1\xfa\xd9\x34\xe7\ +\x47\xb3\x13\xec\x4b\x27\xd9\xd7\xf1\xc8\xe5\x71\x0d\x52\x4a\xb6\ +\xc3\xec\x0d\xc7\x92\xec\xb1\xa4\x3b\xc7\x70\x57\x5a\x66\x29\xd4\ +\xb7\xc8\x90\x0c\x95\x32\x56\xb6\xe3\x64\x3b\x0e\x67\x12\xe3\xbd\ +\xb2\x7b\xd8\xf2\x93\xd6\x62\x5e\x9a\x5a\xc2\xc3\x23\x09\x1f\x7c\ +\xdb\xd9\xd4\x83\x9c\x81\x45\x23\x5c\x73\xd9\x15\xdc\x7e\xdf\x24\ +\xdf\x0f\x36\xb3\x6e\x71\x8b\x37\xad\x1a\xe5\xf7\xcf\x9a\x61\x71\ +\x2d\xc5\x11\x52\x91\xa4\x23\xe1\x58\x52\x9c\x3a\x22\x12\x46\x6d\ +\x83\x87\x66\x0f\x71\xd4\x36\x7a\x0f\xd1\x55\x50\xab\xe4\xe3\x3e\ +\x29\xd5\xf8\x94\x25\x3b\xc7\xf0\xbc\x53\xbd\x80\x76\x31\xcc\x60\ +\xb5\x88\xa7\xed\x0c\xca\x96\x49\xbd\x94\x59\x91\x57\x18\x9c\x0e\ +\x79\x4c\xb6\xf0\xf2\x54\xc4\x92\xa5\x4b\xb8\x68\xd9\x20\xf9\x94\ +\xc1\xcc\x0c\xf3\xfe\x73\x86\xb9\xfa\xf7\x3e\xcc\xe3\xcf\xee\xe7\ +\xe9\xe7\xf7\xf1\xb5\x47\x0f\xf1\xcc\xc4\x34\x7f\xff\xe6\x67\xcb\ +\xac\x2a\xee\x9c\x38\x38\x75\xbc\x98\x39\x9e\x4a\x26\x39\x98\x25\ +\xb4\x7c\xd6\x75\x5a\x58\x24\x15\x45\x9c\xd5\x2c\x1b\xd7\x5b\xdb\ +\x36\xbb\xfd\x8e\x7e\xf9\xe5\xf5\xb3\x7a\x3c\x27\xb5\x30\x93\xec\ +\x76\x04\xbe\x90\x70\xd5\xb4\xa8\x48\x8b\x47\x07\xeb\x04\x9a\x61\ +\x5d\x86\xda\x14\xe3\x53\xaa\xd2\xa2\x6a\x52\x62\x49\x89\x42\xe1\ +\xfd\x57\xbd\x81\xcf\xff\xe5\xc5\xfc\xeb\xa7\xaf\x66\xa0\x3f\xe4\ +\x9f\xff\xe7\x20\x91\x16\x30\x52\xf7\x7e\x8b\x25\x4f\xdd\xc4\xdb\ +\x97\xec\xe0\xef\xfe\x78\x31\x9f\xfb\x9b\x6b\xf9\xc1\x9e\x45\x54\ +\x4d\x42\x2c\x29\x55\x53\xcc\x57\x91\x84\x3e\x49\x78\x2a\x19\xe1\ +\x2b\xa3\x2f\x72\xef\xd4\x41\x66\x7c\xde\x03\xde\x35\x17\xb2\x31\ +\x6f\xb3\x71\xff\xc5\xc1\xdb\xe7\x1c\xd4\x2f\xaf\x9f\xd5\x4b\xee\ +\x59\x24\x27\x93\x6c\x47\xc2\x3a\xef\x40\xda\x74\x6c\xd8\x71\xff\ +\xc1\x95\x0c\xd4\x72\x1e\x3c\xb4\x82\xb3\xfa\x9b\x2c\xad\x2b\x97\ +\xaf\x19\xed\x20\x1a\xeb\x3c\xd3\x87\x77\xd1\xd4\x1f\xe2\x4d\x9d\ +\x77\xbf\xf9\x23\xdc\x72\xef\xeb\xf8\xe9\xe0\x11\xde\xb2\x66\x94\ +\x97\x67\x16\xb1\x38\xca\xa8\x4e\x3f\x8e\xd9\xf3\x08\x7b\x46\x2f\ +\x66\xf5\xc0\x32\x32\x8d\xc9\x35\x26\x53\x4b\xea\x0b\x9b\x1d\xb3\ +\x0d\x0e\x66\x49\x6f\x97\x40\xa9\xca\x9a\x2b\xd9\xa8\xf7\xf9\x94\ +\x7e\xf6\x78\x71\xf6\x64\x92\xed\x55\xe9\x2e\x3b\xd6\xc2\x57\x62\ +\xf0\x6c\x5e\xda\x64\x75\x3d\xa1\x16\x7a\x36\x2f\x6b\xb0\x6f\x7a\ +\x11\x22\xa5\x3f\x35\x9e\xb5\x2b\xfa\x59\xda\x3f\x83\xc1\xa3\xbe\ +\xc5\xeb\x79\x92\xcb\xb6\x6e\x61\xdf\x6c\x93\x33\x66\x73\xbe\x7f\ +\x70\x3d\x81\x4f\x59\x14\x67\xe4\x1e\x7e\x39\x51\xe1\xaf\xdf\x73\ +\x11\xd2\xfa\x5e\x39\x8f\x27\x57\xcf\x8f\x66\x27\x78\xa8\x71\xa8\ +\x4b\x8d\x3b\x4e\x19\xcd\x20\x1b\xf5\x6a\xa7\xf5\x26\x3b\xad\x37\ +\x9f\x8e\x83\x3a\x25\xa7\x65\xca\x43\x2a\x50\xb6\xad\x6a\x30\xd2\ +\xaa\x72\xce\x40\x8b\xe9\x2c\xe2\xbc\x81\x26\x4e\x43\x54\x8a\xb3\ +\xdb\xbf\xb8\x62\x05\xfd\xc9\x24\x6e\x3a\xc4\xab\xa1\xd2\xdc\xc3\ +\x87\x2e\xde\xc2\xf0\xf8\x5a\xce\x70\xa3\x5c\xb3\x7e\x3b\xbb\x0f\ +\xcd\x32\x31\xdd\xa4\x3f\x0e\xf9\xd4\xd5\xe7\xb3\xd9\x3c\x85\x3b\ +\x18\x90\x79\x61\xb6\x0c\x3d\x2f\x67\x93\x1c\xb5\xb3\xbd\xed\x0e\ +\xd2\x91\xac\xda\x19\xbd\x11\xe1\x2b\xc3\xdf\x4e\xfd\xe9\x38\xa8\ +\x53\x72\x5a\x1e\x25\x24\x27\x10\xc7\x96\x15\xd3\x54\x24\x21\xd1\ +\x84\x48\x72\x52\xad\x14\x68\x08\x4f\x68\x32\xce\xcb\x7e\x40\x2b\ +\x4b\x08\xc9\xf1\x12\xe0\xed\x34\x2b\xc6\xbe\xcb\xf2\xea\x6a\xa2\ +\xd9\xfd\x2c\x96\x80\x6d\x5b\x37\xe0\xa3\x65\x04\xbe\x81\x8e\xdd\ +\xc3\xec\xf8\x01\x6a\x62\x19\xb6\x4d\xbe\x70\xf4\x39\x8c\x08\x7b\ +\xb3\xe6\x1c\xb3\xa5\xd9\xfa\x1c\xb2\x11\xaf\x76\x46\x3f\xe9\x9a\ +\xfa\xb5\xa1\xbb\xd3\xac\x2d\xd9\xb6\x44\x4f\x47\xb2\x3d\x12\xee\ +\xb6\x1b\x2f\xbe\x03\xb4\x8d\x18\x8c\x28\x81\x96\xa0\xbd\xac\x3e\ +\x88\x40\xa0\x0e\x33\xb5\x0b\xf1\x75\x02\xe3\x11\x55\x02\x02\x4c\ +\x6b\x18\x6d\x8d\x62\x24\x43\x26\x9f\xc3\x4f\x3e\x5d\xa6\x8a\x69\ +\x59\x58\xed\x23\x14\x87\x53\xcf\xae\x6c\xa6\xab\x7b\xa7\xcb\x74\ +\xe7\x98\xbd\x51\x9d\x7e\x7d\xe8\xee\x5e\x88\xd7\xcd\xf4\x69\x33\ +\x3c\xbf\xbb\x26\x22\xa4\xe5\xfb\x08\xc4\xe1\x55\x8a\x94\x52\x8b\ +\xa3\xc8\xa2\x7c\x6b\x10\x55\x12\xad\x81\xa7\x33\xb6\x0b\x00\x9d\ +\x32\x4f\x89\x96\x8c\x38\x5c\x1b\x2d\xe1\x79\xb0\x99\xf3\x7c\x3a\ +\xc9\x98\x4b\x7b\xdb\x96\x7c\x8f\x1a\x7b\x3b\xad\x37\x29\xfa\x95\ +\xc1\xdb\x0b\xc9\x9e\xae\x73\x3a\x65\x95\xce\xd5\x51\x95\x56\x51\ +\x72\x29\x0b\x74\xe2\x0b\x00\x6f\xf0\x54\xa5\xd5\x41\x4b\x35\x69\ +\xa2\x48\xe7\x6c\x29\xa3\x42\x54\x16\x05\x2a\x26\xc5\xf8\x42\x5b\ +\x72\x62\x62\x49\x09\xc4\xf3\x4c\x32\xc9\x7f\x4e\xee\xc1\x96\x79\ +\x53\x8f\xcd\x5a\x25\x1b\xf5\x36\x9f\xd4\xcf\xda\x29\x7f\xf3\xf0\ +\xbd\x99\x3f\x59\x6e\xfc\x8a\x54\xba\xbb\x75\x28\xf5\xca\x7e\x27\ +\x40\xc8\x32\x13\xd3\x3f\x0f\x2d\xb5\x73\xe9\x44\xab\x9d\x13\xbc\ +\x02\xf5\x14\xa7\x87\xb6\x5d\x4a\xf5\x41\x51\x70\xc3\x91\xf8\x80\ +\x11\x67\x01\x61\xd4\x25\x64\xf8\x85\x6d\x4b\x16\xb2\x51\xcd\xf2\ +\x89\x93\x43\xbc\x5f\xab\xd7\xf2\xa2\x3b\x17\x69\x6f\xc5\xaf\x18\ +\x2f\x94\xe5\x7c\xa2\x76\x16\x5b\xa3\x88\xc4\x57\x89\x24\x23\xd3\ +\xb9\xd3\xc3\x86\xef\xa3\xcf\x34\x68\xfa\x7a\x89\x6b\x8b\xaa\x66\ +\x28\x79\x99\x36\xa6\x65\x3c\xb7\x0c\xe5\xca\xdf\x1e\xf9\x15\xfb\ +\xb3\xf9\xd5\xc5\xd2\x6f\x58\x25\x1f\xd3\x24\x1b\xf5\xb7\x76\xa3\ +\x9e\xdf\xc4\x65\xe6\x57\x0e\xba\xef\x33\x2d\x50\x8b\xed\x40\x86\ +\xf2\xd3\xd5\x00\xd6\x2e\x76\xb7\x7f\xa3\xeb\xf7\x5c\x95\x4c\x95\ +\x14\xc5\x1c\xab\x0b\xaf\x0d\xde\xc7\x7c\x33\x1b\xf5\x5f\x9d\x0f\ +\xf1\x5e\x49\xd8\x39\x75\x95\x6e\xe7\xad\x65\x78\x78\xd1\x4d\x73\ +\x5b\x73\x98\x88\x80\x8f\xd6\x37\xf2\x86\xb0\x56\x1c\x4b\x96\xed\ +\x63\xa9\x56\xcb\xb1\x82\x78\x5f\x56\x24\xa3\xce\xe9\x80\x7a\xc3\ +\xce\x24\xe7\x67\x8d\x09\x06\xf3\x69\x0e\xe7\xe9\xdc\xc6\xea\x1c\ +\xb3\xd9\xb8\x6f\x66\x23\x7a\xdb\xe0\x9d\xa7\x0f\x04\x7e\x6d\x2f\ +\xdd\xe9\x67\x44\x68\x78\xcb\x93\x7a\x04\x80\xf7\xf8\x01\xaa\xd2\ +\x87\xaa\xa3\x5a\x3a\xaf\xee\x9e\x8b\x5a\xd9\xe3\x91\x51\x94\x82\ +\x52\x02\xaa\x92\x72\x24\x9f\xe1\xfe\xc6\x01\xc6\xdb\xc7\x1f\xc7\ +\x62\xf6\xa8\xbb\x6d\xf0\xce\xf4\x86\x5f\x37\x83\x3a\x2d\x95\x9e\ +\x83\x5f\xda\x01\x11\xdd\xb1\xf9\xe9\xac\xc1\x77\x5b\x33\x3c\x6f\ +\x3d\x0d\x1f\x91\x68\xd9\xbd\xa3\xd5\xce\xd8\xfe\xde\xf4\x31\xbb\ +\x33\xcf\xb7\xa6\x67\xd9\x95\x35\x49\xbd\x2b\xa6\xed\xee\x85\x74\ +\x90\x8d\xfb\x24\x1b\x71\x5f\x1f\xbc\x33\xbd\xe1\x4f\x74\x40\x5e\ +\xad\xb0\x73\x8a\xb9\xb4\x42\xa7\x81\x53\x7a\xc3\x85\xc2\xbf\xb7\ +\xf6\x02\xf0\xe1\xda\x46\xb6\x45\xcb\xa8\x18\x83\x7a\x43\xcd\xb4\ +\x8a\x62\x9e\x49\xf0\x2a\x64\x54\x10\x12\x1e\x6a\x8e\xf0\x8d\xc9\ +\x97\x3b\xf4\xed\x2a\x45\x11\x67\x21\x1b\x75\x59\x36\xaa\xb7\x0e\ +\xde\x91\xde\x74\x9d\xae\x94\xdd\xb7\xb7\x78\x35\x63\xed\x49\x6c\ +\x58\x3b\x4d\x22\x1d\x4e\x17\x38\x98\x42\xd5\xc7\x5c\xca\xcf\xd3\ +\x84\x8a\x40\xa0\xe0\x68\x61\x00\xa7\x4d\x84\x00\x83\x23\xd1\x94\ +\x51\x9b\x2f\x2c\xa5\xb6\x99\x1d\x71\x36\x1b\xd7\x2f\x0e\xde\x51\ +\x14\xdc\xee\x96\x11\x7d\xb5\x63\xed\x89\x19\x16\x29\xba\x57\x3b\ +\x1e\x77\xde\x99\x79\x79\x2b\x0a\x3f\x4f\x8f\xf0\x62\x3e\x8b\x60\ +\xf0\xea\x31\x5a\x8c\x82\xe9\xb4\xe2\x7b\x55\x46\x5d\xb3\x33\x45\ +\x7b\x26\x9f\x2a\xe9\x88\xfa\x7c\xb2\x80\x78\x6f\x3f\xb0\x4c\x7e\ +\xb2\x6e\x42\x5f\x2b\xc9\x76\x44\x77\xfe\xcd\x7d\x7a\xdc\x3e\xe6\ +\x6e\x09\x9d\xa8\x2f\xb9\xeb\x59\xa1\x97\xa6\xfd\xdd\x4e\x79\xec\ +\xb4\x7e\x3a\x9f\xf2\x37\x0f\x7f\xfb\xd5\xcf\xa0\x4e\x59\xc2\xc9\ +\x21\xff\xf9\xe3\xfd\xff\x01\xf3\x7a\x24\xda\xff\x94\xd1\xd3\xd4\ +\x2d\xf3\x36\x03\x16\x74\xa7\xa3\x84\xae\xa9\xcf\xf9\x54\xef\x6a\ +\x33\xfb\x9b\x0c\x3d\x27\x94\xf0\xaa\x77\xc5\xf5\x9e\x83\x72\xe9\ +\xd5\x68\x99\xff\x45\x7a\xff\xa7\xe0\x18\x6d\x14\x0b\x9e\x17\x83\ +\x1c\xbe\x27\x6b\xf0\xdb\x7a\xfd\xa6\xb2\xa8\xdf\x5d\xbf\xbb\x7e\ +\x0b\xaf\xff\x03\x05\xf2\x7b\x06\xf0\x22\xce\x4f\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x0e\x9e\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x65\x6c\x65\x63\ +\x74\x5f\x61\x6c\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ +\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x78\x3d\x22\x32\x2e\x36\x34\x36\x39\x32\x38\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x31\x36\x2e\x37\x30\x39\x34\x39\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\ +\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\ +\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\ +\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\ +\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ +\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ +\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ +\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ +\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ +\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ +\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ +\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\ +\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\ +\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x23\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ +\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x34\x35\x34\x35\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\ +\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\ +\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\ +\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ +\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ +\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ +\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x64\x34\x30\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x33\x38\ +\x35\x31\x33\x39\x32\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\ +\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\ +\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\ +\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x32\x39\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x35\x2e\x33\ +\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x32\x2e\x32\x38\x32\x39\x32\x37\x33\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\ +\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ +\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ +\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\ +\x30\x30\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\ +\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ +\x66\x64\x34\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x32\x2e\x33\x38\x35\x31\x33\x39\x32\x33\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ +\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\ +\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\ +\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ +\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x35\x2d\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x33\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x31\x34\x2e\x39\x33\x33\x33\x33\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x32\x38\x32\x39\x32\ +\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\ +\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\ +\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\ +\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\ +\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\ +\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x66\x66\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ +\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x64\x34\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x33\x38\x35\x31\ +\x33\x39\x32\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\ +\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\ +\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\ +\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x32\x39\x39\x35\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x2e\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x34\x2e\ +\x35\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x32\x2e\x32\x38\x32\x39\x32\x37\x33\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\x72\ +\x00\ +\x00\x1c\x3a\x78\x9c\xed\x58\x49\x6f\xe3\xc8\x15\xbe\xf7\xaf\x20\ +\xe4\x4b\x37\x42\x52\xb5\x2f\xf2\x32\x08\xd2\x98\x41\x80\x99\x4b\ +\x32\x41\x8e\x03\x8a\x2c\xd9\x8c\x29\x52\x20\x29\x5b\xf2\xaf\xcf\ +\x57\x94\x48\x4a\x96\x64\xf4\x24\xf6\x74\x0e\x91\x60\xc8\x7c\xef\ +\x55\xd5\x5b\xbe\xb7\x14\x6f\x7e\xd8\x2c\x8b\xe0\xc9\xd5\x4d\x5e\ +\x95\xb7\x13\x1a\x93\x49\xe0\xca\xb4\xca\xf2\xf2\xfe\x76\xf2\x8f\ +\x5f\x7f\x8c\xcc\x24\x68\xda\xa4\xcc\x92\xa2\x2a\xdd\xed\xa4\xac\ +\x26\x3f\xdc\x7d\xba\x69\x9e\xee\x3f\x05\x41\x80\xc5\x65\x33\xab\ +\x9a\xf9\xed\xe4\xa1\x6d\x57\xb3\xe9\xf4\xf9\xf9\x39\xae\x56\xae\ +\x6c\x9e\x93\x36\x7d\x98\x57\xd5\x63\x5c\xd5\xf7\xd3\x75\x9d\x4f\ +\x19\x21\x76\x0a\xd9\xc9\xb8\x32\x4b\x87\x85\xab\x75\x5d\x74\xa2\ +\x59\x3a\x75\x85\x5b\xba\xb2\x6d\xa6\x34\xa6\xd3\x03\xf1\x74\x14\ +\x4f\x6b\x97\xb4\xf9\x93\x4b\xab\xe5\xb2\x2a\x9b\x6e\x65\xd9\x5c\ +\x1d\x08\xd7\xd9\xe2\x48\xab\x67\xde\x09\x51\x6b\xed\x94\xb0\x29\ +\x63\x11\x24\xa2\x66\x5b\xb6\xc9\x26\x3a\x5e\x0a\xeb\xce\x2d\x85\ +\x01\x64\x0a\xde\x28\xf9\x6d\x52\xb3\x06\xfe\x5c\xe1\x6f\x10\xef\ +\x09\x71\x53\xad\xeb\xd4\x2d\xb0\xce\xc5\xa5\x6b\xa7\x5f\x7f\xfd\ +\x3a\x30\x23\x12\x67\x6d\x76\xb0\x4d\x5e\x3e\x36\x69\xb2\x72\x47\ +\xa7\xf6\xc4\x9d\x07\x92\xa5\x6b\x56\x49\xea\x9a\x69\x4f\xef\xd6\ +\x3f\xe7\x59\xfb\x70\x3b\xe1\x22\xa6\x1c\x1f\xd9\x11\x1f\x5c\x7e\ +\xff\xd0\xbe\xa6\xe6\xd9\xed\x04\xda\x33\x6b\x75\xf7\x7c\x80\x0d\ +\xba\x13\xd8\x6f\x3c\x3b\x44\x4d\xcc\x82\xcf\xce\xa8\xd4\x68\x62\ +\xb4\x0d\x03\x46\x18\x8d\x08\x8d\xa8\xfc\xd2\x2d\xea\x6d\x9a\x65\ +\x55\xea\x95\xc4\x19\x6e\x99\x27\xeb\xb6\x5a\x22\x8c\x69\x5a\x24\ +\x4d\x93\x2f\xf2\x14\x0f\x55\xb9\x2a\xd6\xf7\x79\xf9\x5b\xe3\xda\ +\x16\x30\x6c\x7e\x6b\xab\xaa\x88\x7b\x8f\x0e\xc7\xbb\xcd\xaa\xaa\ +\xdb\x68\x93\xad\xe0\x57\xa5\xcf\x32\xb7\x3d\xf3\x0e\xdc\x9b\x41\ +\x09\xaf\x41\xf6\x94\xbb\x67\xbf\x66\x67\xf2\x3c\x69\x76\xae\x0a\ +\x82\x55\x72\x0f\x58\x15\x55\x7d\x3b\xb9\x5a\x74\x9f\x3d\x63\x5e\ +\xd5\x99\xab\x7b\x96\xea\x3e\x47\xac\x0a\xae\xcf\xdb\xed\x2e\x8f\ +\xf6\x7b\xf7\x1a\xf9\x5d\x07\x3e\x39\xcf\x6f\x1e\x92\xac\x7a\xbe\ +\x9d\xb0\xd7\xcc\x97\xaa\x5a\x62\x57\x84\xc0\x6a\x43\x4e\xd8\xe9\ +\x06\x4c\x12\x1b\x4b\xa9\x36\x27\x4c\xaf\x8f\x8e\x39\xd3\xea\xcc\ +\xca\x75\x5d\x23\xd3\xa2\x22\xd9\x3a\x18\xd5\xfd\xd0\xbd\x50\xf3\ +\x50\x3d\xdf\xd7\xde\x39\x6d\xbd\x76\xaf\x57\x7a\x4e\x34\x9f\x57\ +\x9b\xf3\x6c\xc4\x79\xed\x73\x38\x5a\x97\x79\x8b\x3c\x59\x6d\x0e\ +\x77\x5d\xe7\x99\x6b\xce\x2f\x6c\xca\x64\x15\xdd\x17\xd5\x3c\x29\ +\xce\x0b\x3c\xe7\x25\x9c\x14\xed\x21\x4d\xf9\x10\x83\xd7\x12\x3d\ +\xbe\x35\xb9\x24\x01\xdd\x4f\xe2\xb0\x67\x6d\x2f\xb3\x96\xc9\x26\ +\x5f\xe6\x2f\x0e\x8e\xa1\x17\xcd\xae\xab\xb6\xc3\xb2\xdf\xe6\xae\ +\x13\xba\x39\x72\xdd\x6e\xdd\x0e\x7b\xfe\x99\x13\x22\x27\x3d\xb1\ +\xdd\xfa\x24\xdf\x6c\x3d\x63\x20\x56\x75\x8e\xac\x38\x50\xb9\x27\ +\x6d\x0f\x49\x3e\xfb\x91\x34\x9b\x0e\x83\x1d\x42\xf5\x6b\xde\xf6\ +\x90\x17\x4c\xbb\xd4\x98\x9e\xe6\x46\x47\xcf\xdc\xa2\x19\x93\xc4\ +\x3f\xa1\x30\xd8\xde\xa2\x22\x2f\x5d\x52\xff\x54\x27\x59\x0e\x9b\ +\x0f\x4d\x3a\xe6\x48\xc3\xe8\xa8\x74\x33\x07\xd8\xf3\x12\x91\x69\ +\xaa\x02\x06\xde\xed\x39\x37\x4d\x5b\xad\x7a\x29\x68\xdb\x6e\x0b\ +\x5f\x27\x40\x8c\xba\x9c\x9b\x5d\x2d\x14\x6a\x2b\xb9\xee\x48\xfb\ +\x5c\x9a\x91\x58\x1b\xc3\xb8\xe4\xf4\x7a\x32\x2e\xae\x16\x0b\x94\ +\x8f\x43\xc7\xec\x2b\x1b\x96\x42\x1b\xbe\xb7\xdb\x5b\x7e\xac\xea\ +\xef\xb6\x8c\xca\x77\xb1\x6c\x31\xd7\x73\x7d\x6c\xd9\xef\x30\x88\ +\xea\x37\x0d\xba\x99\xfa\xc8\x75\xff\x2d\x5d\x9b\x64\x49\x9b\x8c\ +\x41\xed\x29\x40\x20\xeb\x03\x8b\xce\x38\xfb\xdb\xd7\x1f\x07\xfd\ +\xd3\x74\xf6\xcf\xaa\x7e\x1c\x8f\xf6\x02\xc9\xbc\x5a\x43\xa3\xc1\ +\x4a\x0f\x97\x74\x86\x5e\x86\x92\x7e\x97\x2f\x51\xcf\x7c\x1b\xfc\ +\x13\x7a\x17\xce\x1f\x18\x47\xc2\x1e\xe8\xe3\xa6\xbb\x6d\x6b\xb7\ +\x6b\x8a\x67\x27\x83\x2c\x5d\xe6\x7e\xd1\xf4\xef\x6d\x5e\x14\x7f\ +\xf5\x87\x0c\x96\x0f\x9b\xe6\x6d\xe1\x46\xe2\xcd\x74\xaf\x7d\xef\ +\x9f\x03\xe3\x6e\xa6\xbd\xf5\xdd\xd3\xfd\x49\x8d\xab\xd6\xab\x65\ +\x95\xb9\x7d\x65\x7c\x9d\xed\x45\x32\x77\xa8\x52\x3f\x7b\x5e\x30\ +\xd4\x82\x6c\xa8\xa3\xfb\x13\x57\x49\xfb\x30\xe4\xe0\x2e\xf6\x0b\ +\x68\x3f\xbb\x12\x86\x6b\xee\xa3\x5e\x57\x8f\x6e\x76\x35\x9f\xa7\ +\x69\x46\xf6\x8f\xbb\x02\x37\x13\xb1\x30\x1e\xf4\x84\xf5\x74\x1f\ +\x5e\x9c\x3e\x9b\xaf\xdb\xf6\x90\xf6\xaf\x2a\x2f\x67\xf0\x8e\xab\ +\x7b\x6a\xf7\x50\xa0\x56\xb5\x33\xd1\xd3\xb2\x04\x4d\xa6\xae\x93\ +\xed\xac\xc4\x3c\xd7\x53\x07\xc8\x0d\xe8\xf2\xc0\x08\xa8\x88\x2d\ +\xb1\xc4\xd8\x90\x9a\x58\x10\xab\xad\x08\xa8\x0a\xd1\xd5\x63\xbb\ +\xfb\x4c\x0e\x53\xc3\xdb\xc9\x89\x19\x21\x3a\xb6\x99\xaa\x84\xd2\ +\x6d\x55\x47\x68\x38\x4f\x49\xbb\xae\x9d\x87\xf2\x80\xd9\x8b\x1e\ +\xe2\x42\x18\x91\x5d\xfb\x87\x83\xbc\xe8\x1e\xeb\x75\x81\x3e\xff\ +\xe4\xca\x2a\xcb\x06\x17\x32\xe1\xbf\xc7\x2e\x44\xb3\xd5\x92\x09\ +\xc1\xd4\x5b\x8e\x39\xeb\x82\x5f\x02\x98\x2a\xd0\x63\x58\xc8\x64\ +\xac\x18\x27\xd6\x04\x2a\xa6\x52\x18\x43\x64\xc8\x79\x6c\x91\x7c\ +\x9c\x06\x7f\x09\x64\xcc\x85\x16\x42\xf3\x10\xf3\x94\x32\x12\xf5\ +\x3c\xe0\x58\xcb\x98\xd1\x34\xe4\x34\x96\x8a\x4b\x25\x02\x16\x2b\ +\x2b\x09\xb5\x58\x8d\xd2\xa5\x98\x92\x2a\x28\x82\x88\xc6\x28\xc7\ +\x4c\x71\x38\x37\x36\x8a\x48\x8d\x2d\x49\xcc\x29\x15\x96\x1a\x19\ +\x32\x13\x53\x82\xee\xae\x41\x24\x9c\x11\x23\x94\x0e\x19\x34\xa1\ +\x12\x07\x80\x68\xb8\x95\x54\x21\x52\xd0\x93\x1b\xc3\x65\xf0\x73\ +\x80\x91\x00\xfa\x32\xa9\x42\xf4\x7f\x22\x39\xa7\x3a\x48\x03\xd4\ +\x7e\xa8\x24\x69\x88\xf9\xd2\x32\x45\xa9\x82\x4e\x46\x1a\x22\xac\ +\x3f\x9c\x10\x4d\x35\x83\xea\x46\x73\x43\x99\x97\xa2\x9a\x2a\x19\ +\x90\x90\x60\xad\xe5\xca\x12\xe5\xa9\x04\x6b\xbc\x1c\xb1\x42\x5a\ +\x1b\x72\x1c\x2b\x21\x40\xa5\x56\x56\xe0\x51\x60\x14\x64\x22\x80\ +\xa4\x66\x7e\xcb\x50\xc4\xd0\xd5\x42\x5b\x6f\xac\xe4\x44\xe8\x10\ +\xba\xc2\x27\xf0\xdf\xcb\x11\x90\x6a\x60\x05\x61\x94\xdf\x0c\xa4\ +\x01\x3b\x43\x17\x43\xd2\xfa\x3a\x81\x21\xa3\xe9\x3e\xe9\x4b\x33\ +\xc2\xcd\x15\x45\xbe\x6a\xdc\x59\xc4\x31\x8d\x5e\x62\xbf\x1d\x71\ +\xbb\x09\xf1\x35\xe2\x94\xb5\xc8\x5b\x25\xdf\x23\x15\x87\xd4\xb2\ +\x8c\x47\x7c\x1c\x12\xea\xa4\x6c\x7c\x51\x45\xa6\x26\x6d\x9d\x6f\ +\x3e\xfb\xa0\x48\xae\xb5\xa5\xba\x0b\xae\x35\x52\x32\x80\xc7\xff\ +\xaf\x91\x47\xfb\xc0\x31\x20\x46\x29\xca\x43\x44\xf4\xcb\xb0\x9d\ +\x9f\x21\x23\xc0\xcc\x50\xcc\x98\x63\x5e\xfb\xe9\x31\x62\x08\xa6\ +\x12\x5a\x8e\xa3\x44\x0d\x69\x81\xc0\x1a\x69\xa9\x18\xa9\x5b\x4f\ +\x05\x3e\x8d\x15\xf4\xcd\xec\xde\xb7\xbd\xae\xb2\x91\xeb\x2c\x6f\ +\x56\x28\x99\xb8\xe0\xf8\x42\x76\x5d\xe1\x66\xb1\x28\xaa\xe7\xd9\ +\x53\xde\xe4\xf3\xc2\x5d\x77\xbf\x79\xe1\xdd\xd2\x93\xba\x60\x1d\ +\xf8\x0d\xd5\xd3\xf9\xef\x71\x20\x00\x67\xa4\x05\xd5\xc4\x7e\x64\ +\xf5\xf4\xd4\x5d\x7f\x9e\x91\x93\x30\x5e\x2f\x93\xfa\xd1\xd5\xbb\ +\x05\xae\x4c\xa0\x7c\x34\x4f\xd2\x47\xdf\x5b\xca\x6c\x96\xa4\x18\ +\x18\xd7\x45\xd2\xba\x57\xa5\x17\xe5\x06\x20\xc2\x5d\x8a\xb1\xd8\ +\x3b\xd9\x20\x6f\x54\x8c\xd8\x22\x5f\x14\x12\x47\xfb\xd4\x3e\xc1\ +\x88\x34\x56\x45\x3c\xa2\xef\x58\x82\x51\x22\x8c\x54\xaf\x13\xa2\ +\xf7\x7a\xaa\xfd\xf7\x7b\x78\xfd\x52\xc1\xe6\x31\x65\xa8\x9b\xdc\ +\xf7\x2c\x49\x51\x66\x04\x2a\x36\x6a\x9f\x50\x96\x86\x4c\xec\xe0\ +\x2f\x2f\x7a\x2e\xb2\xef\xe7\xbb\x23\x7c\xd2\x84\x71\x26\x4f\x3c\ +\x65\x98\x1f\xc4\xc5\x77\xf0\x14\xfa\xcf\xbe\xbb\x03\x6b\x5d\x73\ +\xa7\xb8\xb7\xc7\x5d\x0b\x65\x21\x55\x31\x6e\x8c\x42\x9d\xd6\xa1\ +\xbd\xa7\xde\xd1\x4f\x57\xc2\xe2\xa4\xf9\x25\x8c\xed\xb9\xff\x2b\ +\x73\xd1\x2f\x01\x1a\xaf\x66\xd2\x72\xee\xf1\x44\x31\x5c\x48\x1b\ +\x58\xd4\x7c\x21\xa4\x16\xa1\x85\xe3\xb4\x3d\xbc\x18\x1c\x0e\x47\ +\x91\xfe\x43\xf1\x05\x92\xe2\xdf\x23\x0d\x31\x53\x60\x82\xe0\x0c\ +\xee\x20\x4a\x48\x45\xad\x77\xdb\xee\xd6\x19\x32\x28\xe6\x3f\xe2\ +\x22\xb8\x22\xf5\x41\x6e\x3a\xd7\xaf\x29\x86\x5b\xa6\xf4\x1f\xee\ +\xa6\xa5\x77\x13\x45\xb9\xc2\x34\x86\xba\x25\xf1\x2b\x6c\x40\xe1\ +\x1c\x89\xa1\x48\xc1\x75\x96\x53\x49\xcd\x65\x2f\xd9\x88\xfd\x97\ +\x7e\xea\x27\xa6\xdd\x3b\x87\xa4\x4e\x27\x1f\xd2\xaa\x2f\xa4\xf8\ +\x38\x57\xc1\x59\x2f\xae\xae\xc6\x49\x1e\xe3\xa4\x51\xc7\x71\x22\ +\x1f\x19\xa1\x77\xee\xe2\xe3\xd4\x76\x70\x4b\x1a\xbc\xdd\x4d\x5b\ +\x7e\xd8\x62\x56\x1f\xbc\x1b\x19\xf9\x98\xa4\x4c\xac\xb5\x56\xa8\ +\x19\xa7\x6c\x3f\x7e\xc9\x5d\x0a\x71\x79\x86\xbd\x3d\xc7\xee\xf2\ +\x32\xf2\x83\xb9\x55\xdc\xa8\x70\xd8\x3f\xf8\x73\x30\x48\x87\xc3\ +\x7f\x01\xc1\x97\x06\xd0\x12\x13\x31\xe5\x4c\x84\xb8\x0e\x52\x4a\ +\xb8\x55\x6f\x89\x7b\x21\x21\x08\x6a\xa3\x01\x7a\x39\xc3\x85\xe1\ +\x2d\x71\x54\x07\xa1\xd0\x71\x8c\xbf\x31\x08\x8b\x4b\x26\xc3\x75\ +\x08\x5d\x08\xc5\x41\xb2\xee\x86\xc0\x0c\x63\xb8\xa4\xbc\x9c\xda\ +\xd9\xb4\x49\xdd\x9e\x9d\xff\x5d\x99\xf9\x51\x54\x29\xdc\xa5\x98\ +\x3a\x37\x33\x77\x2f\xe8\xdc\xe7\xc8\xe2\xa6\xc3\x04\xcc\xfa\xf2\ +\xff\x04\xf9\x6e\x09\x12\x5d\x48\x11\xe6\x5f\x34\x68\x42\xc4\xf9\ +\x0c\xe9\xee\x2b\x1a\x17\x96\x33\x19\xf4\x9f\xa6\xc8\x32\xe0\xbe\ +\x39\x01\xc0\xb8\x44\x0d\xfb\x07\xc9\x5b\x20\x96\x31\x93\x12\xe0\ +\xed\x38\x98\x9a\xe4\xdb\xc2\x02\x33\x17\xc1\xfd\x5b\x62\x76\xd0\ +\x94\xb0\x37\xa4\x25\x46\x69\x8d\xe1\xcc\x0b\x0b\x83\x8b\xbd\x1c\ +\xb3\x83\xf7\xc9\xc1\x3e\x28\x37\x2c\xc1\xfe\xfe\x0d\xc1\x97\xe1\ +\x35\xf1\xfd\xdd\xa7\x1b\xff\x56\xef\xee\xd3\xbf\x01\x7f\xce\x3c\ +\x87\ +\x00\x00\x06\x59\ +\x00\ +\x00\x4e\xd5\x78\x9c\xe5\x9c\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ +\x54\xed\x25\x41\x4b\xbd\x6d\x3d\x62\x3b\x87\x06\x01\x02\xf4\xd4\ +\xa6\xe8\x31\x90\x25\xda\x16\x56\x12\x0d\x8a\x5e\xdb\xf9\xf5\x21\ +\xa9\x87\x2d\x5b\x0b\xa4\x25\x55\x68\x97\x0a\x82\x40\x33\x43\x8a\ +\xfc\x34\x43\x0e\x29\x3a\x8b\x8f\xa7\x22\xd7\x9e\x21\xae\x32\x54\ +\x2e\x75\xdb\xb0\x74\x0d\x96\x09\x4a\xb3\x72\xbb\xd4\xff\xfe\xfa\ +\x19\x04\xba\x56\x91\xb8\x4c\xe3\x1c\x95\x70\xa9\x97\x48\xff\xb8\ +\x7a\x58\xfc\x02\x80\xf6\x3b\x86\x31\x81\xa9\x76\xcc\xc8\x4e\xfb\ +\x52\x3e\x55\x49\xbc\x87\xda\xbb\x1d\x21\xfb\xc8\x34\x8f\xc7\xa3\ +\x91\x35\x42\x03\xe1\xad\xf9\x5e\x03\x60\xf5\xf0\xb0\xa8\x9e\xb7\ +\x0f\x9a\xa6\xd1\xe7\x96\x55\x94\x26\x4b\xbd\x29\xb0\x3f\xe0\x9c\ +\x1b\xa6\x89\x09\x73\x58\xc0\x92\x54\xa6\x6d\xd8\xa6\x7e\x31\x4f\ +\x2e\xe6\x09\x7b\x7a\xf6\x0c\x13\x54\x14\xa8\xac\x78\xc9\xb2\x7a\ +\xbc\x32\xc6\xe9\xa6\xb3\x66\xad\x39\xba\xdc\xc8\x0e\xc3\xd0\xb4\ +\x1c\xd3\x71\x00\xb5\x00\xd5\xb9\x24\xf1\x09\xf4\x8b\xd2\x36\x0e\ +\x15\x75\x2c\xcb\x32\xa9\xee\x62\xf9\x73\x56\x51\x45\x81\xee\xe9\ +\xdf\xce\xbc\x15\x18\x15\x3a\xe0\x04\x6e\x68\x39\x68\x94\x90\x98\ +\x9f\xbe\x7e\xea\x94\xc0\x32\x52\x92\x5e\x55\xd3\xf2\xec\x3d\xb5\ +\x07\xb9\x8c\x0b\x58\xed\xe3\x04\x56\x66\x2b\xe7\xe5\x8f\x59\x4a\ +\x76\x4b\xdd\xf5\x0c\xdb\xa5\xd7\x8c\x0b\x77\x30\xdb\xee\xc8\xad\ +\x34\x4b\x97\x3a\x6d\xbd\x13\x06\xf5\xfd\x95\x73\xd8\xb5\x41\x53\ +\x71\xd4\x69\x2c\x23\x74\x0c\x5b\xc3\xf6\xcc\xf5\x6b\x9b\xb6\x0b\ +\x51\x8a\x12\xd6\x26\x5a\x25\x2c\xb2\xf8\x40\x50\x41\xdf\x5a\x92\ +\xe4\x71\x55\x65\x9b\x2c\xa1\x37\xa8\xdc\xe7\x87\x6d\x56\x7e\xeb\ +\x0b\xbf\x41\x8c\x58\xed\x46\x4b\xb2\x7b\x2c\x3c\xed\x11\x26\xe0\ +\x94\xee\x29\xcf\xb9\x3f\xa8\x3c\xb7\xca\x15\xd5\x2e\x52\xb8\xa9\ +\x98\x55\xdd\x39\x76\x47\x7b\xe7\xeb\x9a\xc9\xb5\x5d\x5b\x59\x43\ +\xd3\xe7\x0c\x1e\x2f\xb6\xeb\xb8\xaa\x01\x6a\xda\x3e\xde\x52\x67\ +\xcb\x11\x5e\xea\x8f\x1b\x7e\x35\x8a\x35\xc2\x29\xc4\xad\x6a\xce\ +\xaf\x9e\x0a\xd1\x17\x92\x91\x73\x1d\x5e\x4d\xdd\x6d\x7b\x59\xad\ +\x9d\xde\x1a\xd6\x57\xbb\x38\x45\xc7\xa5\xee\xdc\x2a\xbf\x23\x54\ +\x2c\xf5\x99\x31\x0b\x83\xd0\xb2\x6f\xb5\xc9\x69\xa9\x03\xdf\x35\ +\x7c\xdf\x0d\x6c\xf7\x4e\x4b\x9f\xe7\xd0\x06\xb9\xbe\x17\xdc\x2b\ +\x0f\x18\xd3\xf8\x03\x79\x7c\x86\xb4\x53\xfc\x9f\xb6\xfe\x6a\x87\ +\x8e\x5b\xcc\xe0\x10\x7c\x80\xb7\x25\x99\x06\xac\xd7\xe8\x34\xac\ +\xa6\xee\x70\x60\x91\x0d\x0e\x65\x46\x68\xf4\xec\x4f\xd7\xb5\x1e\ +\xb2\x14\x56\xc3\x05\xab\x32\xde\x83\x6d\x8e\xd6\x71\x3e\x6c\x70\ +\xcc\x4a\x0a\x09\x34\x8e\x6e\xbb\xdd\x3b\xb8\xb5\x68\xbd\xde\xb7\ +\x82\x17\x2c\x68\xdb\xef\xde\x43\xa3\x3a\xbf\xac\x2a\xe2\x53\x56\ +\x64\xdf\x21\x05\x63\x73\xb7\xa3\xae\xd5\xc3\x52\x17\xd3\x34\x72\ +\x66\x11\x7c\x3a\x33\x99\xde\x0a\x19\x4f\x26\x70\xc2\xd0\xef\x84\ +\x08\x67\x34\x30\xae\x9a\xd3\x8a\xce\xd7\x22\x16\xef\x74\xb8\x3e\ +\x71\xff\xe2\xde\xe7\xdf\xea\xce\xd7\xba\xc6\xed\xcd\x7b\xbf\xe7\ +\xf2\x02\x92\x38\x8d\x49\x7c\x09\x82\x56\x42\xdb\x66\xb5\x3d\xa3\ +\x43\x67\xf4\xe7\xa7\xcf\xab\xe6\x41\x8b\x24\x89\xfe\x41\xf8\xa9\ +\x7d\xae\xa6\x31\x83\x78\x8d\x0e\x94\xb4\xbe\xea\xc4\x8b\x34\x89\ +\xe8\x60\x47\x07\x81\x55\x56\x50\xd7\x66\xe3\xe4\xaf\x74\x70\x5b\ +\x98\x17\x45\xcf\x98\xc1\xba\x54\x5a\x57\x8b\x61\x3d\x6a\x0e\x4e\ +\x1d\x69\x52\x64\xac\x90\xf9\x17\xc9\xf2\xfc\x0b\x7b\x48\xd3\xe3\ +\xab\x4a\x33\x92\xc3\x8b\x70\x61\x36\xad\x6f\xfa\x66\x5e\x75\x6e\ +\x61\xb6\xbd\xe7\x77\xdb\x0b\x95\x5e\x50\x74\x2f\x3a\x8f\xd7\x90\ +\x7a\xe8\x1f\x4c\xa9\xdd\x69\xb7\x18\x1d\xf6\x05\x4a\x61\x53\xbc\ +\xa3\x09\x13\xd2\xbd\x32\x72\xce\xa9\x7e\x43\x5b\x1f\x3d\xae\x5d\ +\xf6\xe7\x03\xbb\x01\xcd\x30\x11\xd9\xf5\x2d\x3e\xe4\x74\xb8\x7b\ +\x86\x25\x4a\xd3\x0f\x15\xc1\xe8\x09\x46\x8f\x16\xbf\x9a\xdb\x3a\ +\x18\x22\xcb\xf0\xdc\xd0\x63\xef\xbe\x95\x53\x42\x10\xe7\xd4\x5b\ +\x49\xe4\xb5\xb2\x34\xa6\xc3\x0c\xc6\xf1\x39\x2a\xe9\x44\xdf\x4a\ +\xbb\x67\xf6\x1c\x95\x35\x77\x16\xb8\x21\xb0\x41\x00\x2e\xaa\x26\ +\xf6\x66\x86\xeb\x5e\xa6\x13\x76\xb5\x21\xe7\x19\x21\xd7\x78\x9d\ +\x86\x39\xad\x65\xdc\x38\x2d\xf5\x56\x70\xef\xca\xb8\x17\x07\x98\ +\xbb\xf4\xdc\x63\xd7\xbc\x7b\xc1\x2f\x83\xb4\xac\xcd\x86\x82\x99\ +\x32\xc8\x70\x0c\x90\x36\x1d\xff\xfb\x96\x6f\x9e\xa3\x0d\x66\x63\ +\x90\x0c\x8c\x80\xf7\xc5\x51\x87\xa4\x3f\x06\x47\xc7\x35\xe6\xea\ +\x20\xa4\xce\x38\x8a\x37\xda\x81\xd1\xcb\x34\x45\x51\xbe\x82\x89\ +\x26\x1c\xc7\x1f\x5d\xd7\xf0\x64\xce\x34\xd3\x26\x29\x48\xd0\xea\ +\x91\x33\x02\xb5\x7c\xd0\x13\xa4\x77\x6f\x3e\x46\xaa\x33\x71\x8c\ +\x81\x4c\x17\x94\x9d\xde\x4c\x9c\x9d\x25\xec\x82\x3d\x7a\xb2\x53\ +\x9a\xa9\xd3\x73\x65\xc2\x93\x98\xc7\x4c\x9d\x9b\xf0\xc4\xdb\x8f\ +\x59\xe5\x52\x17\xf1\x45\xf2\xe0\xcc\xa1\x56\xe6\xc2\x06\x3f\x61\ +\x8e\xfd\x08\x0e\x8c\x19\x37\x51\x88\x9f\xdc\x09\x44\x45\x0f\x04\ +\x8e\x4c\x82\xaa\x65\x7f\x6c\x21\xe7\x89\xfa\xa0\x33\xbf\x9d\x41\ +\xf8\x6a\xc4\x77\x15\x8a\xe6\x7a\x73\x41\x74\x62\x1e\x24\x49\x7d\ +\x52\x91\x8c\xb0\xd9\xa1\x11\xde\x30\x1c\xc4\x18\xdc\x6e\x36\xbc\ +\x79\x94\x21\xf0\x85\x47\xc7\xe1\xd8\x76\xeb\x4a\x94\x71\x4b\x0f\ +\x38\xa2\xeb\x64\xc7\x36\x6e\x84\x72\x43\x7b\xe2\x9b\xaf\x01\x10\ +\x5d\xed\xd9\x3d\x17\xb4\x95\xd9\xb6\xe6\x59\x8e\x27\xea\x7e\xf6\ +\x98\x63\xe1\xd4\x09\xba\xe2\x5b\xd5\x3d\x7c\x8e\xe4\x3c\x7b\xe2\ +\xfc\x6c\x30\x17\x9f\x92\x87\x86\x3f\xc5\x38\x5a\x74\x3e\x96\x1b\ +\xc7\xb6\xe4\x25\xf3\xc4\x01\xb2\x89\x78\x0e\x5c\xd1\x5d\x87\x41\ +\x5f\x94\x8d\x72\xf2\x39\x0d\xdb\x06\x03\xa1\x35\x06\x4b\xc5\xf2\ +\xc3\x66\x27\x47\xfc\x9c\x83\xca\x49\x76\xb3\x99\x03\xc2\xb9\x54\ +\x8a\x6a\x2d\x9e\x3d\x4f\x78\xc1\x77\xe5\x6f\xca\xee\xe2\x00\x51\ +\x1f\xec\x43\x54\xcb\x07\x59\x28\x8b\x66\x39\x7d\x7e\x12\xd7\x7a\ +\xaf\x80\x1f\xdf\x00\x13\xfe\xb2\xd2\x27\xa8\xde\xde\x97\x4f\xa7\ +\x12\xd1\x45\x5f\x9f\xa1\xec\xc5\xca\x2b\x80\xc8\x4e\xcb\x01\x6b\ +\x2e\x79\x4e\x91\x97\x69\xf7\xb1\xbd\x0a\xa4\x7c\x4f\x56\x78\x2f\ +\x0c\xb8\xfe\x6d\x72\xf8\xaf\x33\xc6\x56\x4a\x70\x5c\x56\xec\xac\ +\xff\x52\xaf\x92\x38\x87\xef\x80\xfd\x9b\xfd\xfe\xcd\x38\x30\x4f\ +\x2c\x45\xbf\x70\xdd\x8c\x04\x81\x21\xef\xfc\x36\x67\xf2\xd3\x0c\ +\xeb\x5f\x3a\xfd\x9f\x0c\x45\xb3\xf1\xc1\x33\x9e\x92\x4f\x2a\x4e\ +\x9f\x62\xed\x89\x63\xb0\x94\x7d\x6a\x62\xea\x2c\x05\x19\x0e\x9f\ +\xdc\x51\xce\x1f\x45\xc3\x7a\x10\xa3\xfc\x1f\xb7\x4c\x1c\xa3\xf8\ +\x6a\x7b\x90\xa3\xfc\x9f\xb6\x4c\x9c\xa3\xe8\x72\x7b\x90\xa2\xd4\ +\x1f\xb6\x4c\x1c\xa0\x37\x0e\x42\xd9\x47\x43\x5f\x01\x47\xf1\x55\ +\xe3\xb0\x33\x2a\x36\x4b\xd7\xfb\x40\x82\x24\x07\xcf\x9e\x48\xfd\ +\xf0\x3f\x79\x88\xcd\x0a\x7c\x14\x90\xea\xb9\x64\xb3\x1c\x1c\x83\ +\xa6\x3a\x6b\x42\xb9\x47\x29\x64\x7f\x60\x98\x38\x3c\xf1\xe3\xca\ +\xc3\x1f\x5c\x55\xa3\x18\x88\x9f\x27\x1b\x3e\x05\xa0\xd0\xec\xc2\ +\x92\x9d\x51\x4e\x35\x4a\x3f\x5d\x36\x69\x90\xf5\x87\xeb\x40\xee\ +\xf1\x46\x75\xa6\x93\x26\xe9\x16\xde\xd8\x19\x3e\x60\xa6\x10\xc6\ +\x60\xac\xd3\xde\xff\xe5\xc3\xd7\xc2\xdc\xae\x1e\x16\xec\xbf\x13\ +\x5a\x3d\xfc\x00\x35\xeb\x83\x36\ +\x00\x00\x05\xfe\ +\x00\ +\x00\x1c\x9e\x78\x9c\xdd\x58\x49\x8f\xdb\x36\x14\xbe\xcf\xaf\x60\ +\x95\x4b\x8b\x9a\x5a\x28\x5b\xdb\xd8\xce\x21\x41\xd1\x00\xc9\xa5\ +\x4d\xdb\x63\x20\x4b\xb4\xcd\x8e\x24\x0a\x14\x35\xb6\xf3\xeb\xfb\ +\x28\x89\xb2\xe4\x05\x98\x20\x9e\x41\xa6\x02\x12\x4b\x6f\x21\xdf\ +\xfb\xde\x46\xce\xfc\xed\x3e\xcf\xd0\x23\x15\x15\xe3\xc5\xc2\x70\ +\x4c\xdb\x40\xb4\x48\x78\xca\x8a\xcd\xc2\xf8\xeb\xf3\x6f\x38\x30\ +\x50\x25\xe3\x22\x8d\x33\x5e\xd0\x85\x51\x70\xe3\xed\xf2\x6e\xfe\ +\x13\xc6\xe8\x9d\xa0\xb1\xa4\x29\xda\x31\xb9\x45\x1f\x8a\x87\x2a\ +\x89\x4b\x8a\x7e\xde\x4a\x59\x46\x96\xb5\xdb\xed\x4c\xd6\x11\x4d\ +\x2e\x36\xd6\x2f\x08\xe3\xe5\xdd\xdd\xbc\x7a\xdc\xdc\x21\x84\x60\ +\xdf\xa2\x8a\xd2\x64\x61\x74\x0a\x65\x2d\xb2\x46\x30\x4d\x2c\x9a\ +\xd1\x9c\x16\xb2\xb2\x1c\xd3\xb1\x8c\xa3\x78\x72\x14\x4f\xd4\xee\ +\xec\x91\x26\x3c\xcf\x79\x51\x35\x9a\x45\xf5\x66\x20\x2c\xd2\x75\ +\x2f\xad\xac\xd9\xb9\x8d\x90\x13\x86\xa1\x65\x13\x8b\x10\x0c\x12\ +\xb8\x3a\x14\x32\xde\xe3\xb1\x2a\xd8\x78\x49\x95\xd8\xb6\x6d\x01\ +\xef\x28\xf9\x34\xa9\xa8\x02\x40\x4b\xf8\xd7\x8b\x6b\x82\x59\xf1\ +\x5a\x24\x74\x0d\x7a\xd4\x2c\xa8\xb4\xde\x7f\x7e\xdf\x33\xb1\x6d\ +\xa6\x32\x1d\x2c\xa3\xf1\x1c\xed\x3a\x02\xb9\x88\x73\x5a\x95\x71\ +\x42\x2b\x4b\xd3\x1b\xfd\x1d\x4b\xe5\x76\x61\xb8\x53\xd3\x71\xe1\ +\x99\x35\xc4\x2d\x65\x9b\xad\x3c\xa5\xb2\x74\x61\x80\xf5\x24\x0c\ +\xda\xef\x41\x72\x38\xad\x40\xb7\x70\xd4\x73\x6c\x33\x24\xa6\x83\ +\x84\x33\x73\xfd\x56\x46\xbb\x10\xa5\x3c\x51\x36\xc1\x92\x34\x67\ +\x71\x2d\x79\x0e\x51\x4b\x92\x2c\xae\x2a\xb6\x66\x09\x7c\xf0\xa2\ +\xcc\xea\x0d\x2b\xbe\xc8\xad\xa0\xd5\x96\x67\xe9\x17\xc9\x79\x66\ +\x6a\x04\xfb\xed\xe8\xbe\xe4\x42\xe2\x7d\x5a\x02\x8e\x9e\x7f\x91\ +\x79\xd0\xcc\x25\x70\xe7\x29\x5d\x57\x4a\xaa\x75\x4a\x7d\x81\x57\ +\xbe\x81\xac\x86\xdb\xdb\xa8\x0c\x4c\x1f\x19\xdd\x1d\x65\x57\x71\ +\xd5\x02\x87\x50\x19\x6f\x20\xc9\x32\x2e\x16\xc6\x9b\x75\xf3\x74\ +\x8c\x15\x17\x29\x15\x9a\xe5\x35\xcf\x88\xc5\x21\x10\x4c\x1e\xda\ +\xb2\xea\xd6\xd6\xf6\xaa\x55\x7b\xbe\x7d\x99\x5f\x6d\xe3\x94\xef\ +\x16\x06\x39\x65\x7e\xe5\x3c\x87\x55\x67\x66\xe0\x7a\x76\xe0\x9e\ +\xb2\x93\xfd\xc2\xc0\x33\xd7\xf4\x66\xd3\x20\x38\x63\x36\xf6\x38\ +\x8e\xef\x10\x7f\x76\xc6\xac\x85\x80\xba\xc3\x59\x7c\xa0\xe0\x54\ +\xf3\xe3\x74\x42\x10\x9a\xdd\x46\x28\x70\xa4\xa8\xe9\xa9\xa6\xe2\ +\xe0\xd5\x8a\xef\x2f\xb3\x21\x0d\x6a\x55\xd1\xb8\x2e\x98\x84\xaa\ +\x29\xf7\xc3\x55\x6b\x96\xd2\xea\xb2\x62\x55\xc4\x25\xde\x64\x7c\ +\x15\x67\x97\x05\x76\xac\x00\x90\x70\x97\xe0\x8e\xdb\xc7\xe0\x54\ +\x42\x67\xbb\x6f\x9f\x61\xd2\x49\x80\xed\x67\x71\xe8\x58\x87\xeb\ +\xac\x3c\xde\xb3\x9c\x7d\xa5\x00\x8c\x73\x86\x8a\xf2\x6c\x08\xcb\ +\xb2\x11\x98\x8f\x60\x6b\x75\x10\x92\x07\x55\xd9\xfb\x83\xa2\x19\ +\x9a\xa8\xf0\x56\x04\x12\x86\x7e\x4f\xe4\x82\x41\xc1\x0c\xcc\xd5\ +\xa4\xc3\x90\xa4\xfa\x00\xb4\xf1\x7d\x93\x7f\x4d\x76\xfa\xa7\xbc\ +\xc3\x90\xd7\x95\x85\x75\x5e\x17\x0d\x3d\xa7\x32\x4e\x63\x19\x1f\ +\x8b\x44\x53\xc0\x36\x5b\x7b\x06\x2d\x35\xfa\xe3\xfd\x6f\xcb\x6e\ +\xa3\x79\x92\x44\xff\x70\xf1\xa0\xf7\x45\x48\x09\xc4\x2b\x5e\x43\ +\x24\x8c\x65\x4f\x9e\xa7\x49\x04\x4d\x10\x9a\xc3\x92\xe5\x90\xfa\ +\xaa\x7f\xfe\x0a\x4d\x6f\x6e\x1d\x19\x23\x61\x05\xd6\x71\xd1\x76\ +\x59\x68\x1f\x4d\x37\xbd\x38\x52\xd2\x24\x67\x4a\xc9\xfa\x53\xb2\ +\x2c\xfb\xa0\x36\xe9\x3c\x1e\x2c\xca\x64\x46\x8f\xc4\xb9\xd5\x59\ +\xdf\xf9\x66\x0d\x9c\x9b\x5b\xda\xfb\xe6\x6b\x73\x44\x65\x54\x34\ +\x7d\xa0\xb3\x78\x45\x21\x83\x3f\x2a\x26\x3a\xcf\x13\xc1\xeb\x32\ +\xe7\x29\xed\xd4\x35\x9a\x34\xcb\x58\x59\xf5\x8e\x56\xf2\x90\x81\ +\x48\xd3\x72\xa2\x37\x76\xf3\xdc\xa7\xac\x2a\x41\x09\x86\x43\xc6\ +\x0a\x7a\xcf\xa1\x2b\xaf\x33\xbe\x8b\x1e\x59\xc5\x56\x19\xbd\x6f\ +\x7e\x59\x06\xce\xf7\xa4\x35\x20\x10\x15\x30\xcf\xef\x2b\x29\xf8\ +\x03\x8d\xba\xc6\xd6\x7d\xb6\xc5\x14\x11\xe8\xe9\xbe\x4d\xa6\x61\ +\x38\xd5\x0c\xb5\x03\x18\x1c\xad\x6a\x29\x87\xb4\x7f\x39\x2b\x22\ +\xc0\x97\x0a\x4d\x6d\x3e\x32\x28\x0c\x19\xf5\xda\x69\x0c\x1d\x4d\ +\x08\xb0\x75\xb0\x77\x43\xe5\xeb\x75\x45\x65\x64\x6b\x5a\xd7\x19\ +\x23\xe7\x3e\x8f\xc5\x03\x15\xad\x02\x2d\x62\xb0\x1e\xaf\xe2\xe4\ +\x41\x01\x56\xa4\x51\x9c\x40\x5b\xa9\x33\x38\x86\x8c\x0a\xa6\x8c\ +\xe5\xd6\xb5\x9d\x00\x07\xf8\x98\xf2\xc9\xa8\x5e\x54\x1b\x74\x61\ +\x6e\xa9\xb9\x47\x7a\xaa\x00\x19\x12\x98\x7e\xa8\x9e\x23\x55\x95\ +\x89\xdf\xd6\x49\xd0\x27\xcd\x3c\x61\x22\xc9\x9e\x31\x36\xea\x6d\ +\x80\x44\xf3\x29\xea\x8c\x2a\xee\x57\x98\x2e\x7d\xf0\xba\xcd\x46\ +\xc1\x73\x4c\x37\x68\x47\xd2\x6b\x8d\x9d\x8f\xbd\x51\xec\x3c\xd3\ +\x0e\x3d\xd7\x0d\xc9\x38\x86\xa3\xb3\x4b\x13\x2d\x20\x92\x57\x13\ +\x25\xd2\xe6\x9a\xff\x5a\xa3\x14\x8c\x62\x34\x33\x5d\x77\x1c\x8d\ +\xab\x31\x72\x6c\x73\x34\x77\x20\x54\x6a\xd1\x93\x40\x9d\x77\xaa\ +\x4b\x30\x92\x76\x7d\x77\xfa\xac\x8d\xaa\x87\xac\x77\x03\x80\xf8\ +\x84\xb4\x77\xee\xc4\x75\xdb\x1e\xe1\xa3\xdf\x91\x7d\x06\x17\x4c\ +\xc9\x23\x58\xc7\x13\x17\x2f\xc0\x52\xc9\x05\x86\xb3\xd7\x63\x2c\ +\x6b\x41\x47\x33\xbc\x9f\xc5\x30\x1c\xd4\xf8\x82\x63\x52\x92\xdc\ +\x00\x32\xc7\x0c\x43\xcf\x26\xb3\xa0\xdc\x7f\x3b\x66\x17\x91\xc8\ +\x51\x7f\x94\x98\x10\xdf\xf4\x1b\x4c\x50\x82\x74\x70\xdc\x89\x7d\ +\xed\xfd\x3c\xb5\x7c\x9f\x60\xfb\xc9\x68\xdd\x24\x83\x1c\x7f\x36\ +\x75\x66\xb3\x1b\xe2\xa1\xab\x01\x32\x43\xe7\x08\xe0\x61\x4f\xf0\ +\xd4\x24\x0d\x50\xd7\xde\xcf\xf1\x08\xa6\xcf\x87\x46\x40\xcf\x93\ +\xa3\x0b\x24\xb9\x21\x1a\x78\x90\x1e\x76\xeb\xa8\x8f\x5c\x93\x4c\ +\x34\xc3\x47\x9e\x39\x9d\xe0\xc0\x9c\xb5\x50\x7d\x44\x8e\x6b\x06\ +\xad\x46\x68\x7a\xc8\x09\x41\x58\xfd\x87\xc8\xb4\x93\x99\x10\xa7\ +\xc3\x18\xb9\x64\x42\x66\x20\x95\x21\xbd\xc0\x04\x16\x3f\x43\x72\ +\x6a\xbb\xfe\x0b\x22\xa9\x53\x60\x1a\xbe\x44\x67\xb2\x75\xc2\xb9\ +\xd7\xa1\x3f\x02\x36\x80\xde\x1b\x41\x3f\xed\x33\xd7\x1f\x48\x68\ +\x5a\x13\x8b\x8f\xc3\x18\x10\x73\xda\xc0\xef\x75\x1d\xfd\x29\x31\ +\xc0\xee\x37\xf7\xc2\x5e\x4e\x8a\xb8\xa8\xd4\xa5\x00\x27\x70\xa5\ +\xa4\x02\x37\x57\x1c\xef\x09\x82\x30\x8c\xf0\xe9\x85\xe7\xc7\xea\ +\xa2\x9f\x86\x5d\x54\x01\xfb\xae\x09\x54\x8b\xf1\xe9\xcb\x95\xbe\ +\x89\xc9\x0b\x76\xce\xe7\x1d\x24\xfa\xd8\xed\x7f\xd7\x20\xc1\xce\ +\xff\x07\x10\xe7\x16\x93\xf5\x1b\xaa\xef\x47\x04\x64\x58\x24\x5e\ +\x5f\x23\x5e\x57\x19\x83\xdf\x6b\xee\x4f\x5f\xb5\xfb\xa3\x7c\xd0\ +\x6f\xdf\x97\x0f\xe1\x6b\x3f\x6b\x39\xc4\x0c\x6e\x72\xcc\xc2\x17\ +\xe6\xc8\xeb\x82\x82\x04\xb7\x82\xe2\x25\xe7\xc8\xf3\x40\xa1\x4f\ +\x3b\xb7\xc1\xe3\xf9\x4e\x8e\x3f\xd8\x9d\xd6\x3e\x9e\xfb\x7c\xf4\ +\x37\xea\x2f\xb6\x97\x2e\xb5\x4f\xaf\x97\x27\x5d\x6a\xe7\xd6\x66\ +\x79\x37\x57\x7f\xff\x5d\xde\xfd\x07\x5c\xd5\x81\xeb\ +\x00\x00\x05\xfe\ +\x00\ +\x00\x1c\x9e\x78\x9c\xdd\x58\x49\x8f\xdb\x36\x14\xbe\xcf\xaf\x60\ +\x95\x4b\x8b\x9a\x5a\x28\x5b\xdb\xd8\xce\x21\x41\xd1\x00\xc9\xa5\ +\x4d\xdb\x63\x20\x4b\xb4\xcd\x8e\x24\x0a\x14\x35\xb6\xf3\xeb\xfb\ +\x28\x89\xb2\xe4\x05\x98\x20\x9e\x41\xa6\x02\x12\x4b\x6f\x21\xdf\ +\xfb\xde\x46\xce\xfc\xed\x3e\xcf\xd0\x23\x15\x15\xe3\xc5\xc2\x70\ +\x4c\xdb\x40\xb4\x48\x78\xca\x8a\xcd\xc2\xf8\xeb\xf3\x6f\x38\x30\ +\x50\x25\xe3\x22\x8d\x33\x5e\xd0\x85\x51\x70\xe3\xed\xf2\x6e\xfe\ +\x13\xc6\xe8\x9d\xa0\xb1\xa4\x29\xda\x31\xb9\x45\x1f\x8a\x87\x2a\ +\x89\x4b\x8a\x7e\xde\x4a\x59\x46\x96\xb5\xdb\xed\x4c\xd6\x11\x4d\ +\x2e\x36\xd6\x2f\x08\xe3\xe5\xdd\xdd\xbc\x7a\xdc\xdc\x21\x84\x60\ +\xdf\xa2\x8a\xd2\x64\x61\x74\x0a\x65\x2d\xb2\x46\x30\x4d\x2c\x9a\ +\xd1\x9c\x16\xb2\xb2\x1c\xd3\xb1\x8c\xa3\x78\x72\x14\x4f\xd4\xee\ +\xec\x91\x26\x3c\xcf\x79\x51\x35\x9a\x45\xf5\x66\x20\x2c\xd2\x75\ +\x2f\xad\xac\xd9\xb9\x8d\x90\x13\x86\xa1\x65\x13\x8b\x10\x0c\x12\ +\xb8\x3a\x14\x32\xde\xe3\xb1\x2a\xd8\x78\x49\x95\xd8\xb6\x6d\x01\ +\xef\x28\xf9\x34\xa9\xa8\x02\x40\x4b\xf8\xd7\x8b\x6b\x82\x59\xf1\ +\x5a\x24\x74\x0d\x7a\xd4\x2c\xa8\xb4\xde\x7f\x7e\xdf\x33\xb1\x6d\ +\xa6\x32\x1d\x2c\xa3\xf1\x1c\xed\x3a\x02\xb9\x88\x73\x5a\x95\x71\ +\x42\x2b\x4b\xd3\x1b\xfd\x1d\x4b\xe5\x76\x61\xb8\x53\xd3\x71\xe1\ +\x99\x35\xc4\x2d\x65\x9b\xad\x3c\xa5\xb2\x74\x61\x80\xf5\x24\x0c\ +\xda\xef\x41\x72\x38\xad\x40\xb7\x70\xd4\x73\x6c\x33\x24\xa6\x83\ +\x84\x33\x73\xfd\x56\x46\xbb\x10\xa5\x3c\x51\x36\xc1\x92\x34\x67\ +\x71\x2d\x79\x0e\x51\x4b\x92\x2c\xae\x2a\xb6\x66\x09\x7c\xf0\xa2\ +\xcc\xea\x0d\x2b\xbe\xc8\xad\xa0\xd5\x96\x67\xe9\x17\xc9\x79\x66\ +\x6a\x04\xfb\xed\xe8\xbe\xe4\x42\xe2\x7d\x5a\x02\x8e\x9e\x7f\x91\ +\x79\xd0\xcc\x25\x70\xe7\x29\x5d\x57\x4a\xaa\x75\x4a\x7d\x81\x57\ +\xbe\x81\xac\x86\xdb\xdb\xa8\x0c\x4c\x1f\x19\xdd\x1d\x65\x57\x71\ +\xd5\x02\x87\x50\x19\x6f\x20\xc9\x32\x2e\x16\xc6\x9b\x75\xf3\x74\ +\x8c\x15\x17\x29\x15\x9a\xe5\x35\xcf\x88\xc5\x21\x10\x4c\x1e\xda\ +\xb2\xea\xd6\xd6\xf6\xaa\x55\x7b\xbe\x7d\x99\x5f\x6d\xe3\x94\xef\ +\x16\x06\x39\x65\x7e\xe5\x3c\x87\x55\x67\x66\xe0\x7a\x76\xe0\x9e\ +\xb2\x93\xfd\xc2\xc0\x33\xd7\xf4\x66\xd3\x20\x38\x63\x36\xf6\x38\ +\x8e\xef\x10\x7f\x76\xc6\xac\x85\x80\xba\xc3\x59\x7c\xa0\xe0\x54\ +\xf3\xe3\x74\x42\x10\x9a\xdd\x46\x28\x70\xa4\xa8\xe9\xa9\xa6\xe2\ +\xe0\xd5\x8a\xef\x2f\xb3\x21\x0d\x6a\x55\xd1\xb8\x2e\x98\x84\xaa\ +\x29\xf7\xc3\x55\x6b\x96\xd2\xea\xb2\x62\x55\xc4\x25\xde\x64\x7c\ +\x15\x67\x97\x05\x76\xac\x00\x90\x70\x97\xe0\x8e\xdb\xc7\xe0\x54\ +\x42\x67\xbb\x6f\x9f\x61\xd2\x49\x80\xed\x67\x71\xe8\x58\x87\xeb\ +\xac\x3c\xde\xb3\x9c\x7d\xa5\x00\x8c\x73\x86\x8a\xf2\x6c\x08\xcb\ +\xb2\x11\x98\x8f\x60\x6b\x75\x10\x92\x07\x55\xd9\xfb\x83\xa2\x19\ +\x9a\xa8\xf0\x56\x04\x12\x86\x7e\x4f\xe4\x82\x41\xc1\x0c\xcc\xd5\ +\xa4\xc3\x90\xa4\xfa\x00\xb4\xf1\x7d\x93\x7f\x4d\x76\xfa\xa7\xbc\ +\xc3\x90\xd7\x95\x85\x75\x5e\x17\x0d\x3d\xa7\x32\x4e\x63\x19\x1f\ +\x8b\x44\x53\xc0\x36\x5b\x7b\x06\x2d\x35\xfa\xe3\xfd\x6f\xcb\x6e\ +\xa3\x79\x92\x44\xff\x70\xf1\xa0\xf7\x45\x48\x09\xc4\x2b\x5e\x43\ +\x24\x8c\x65\x4f\x9e\xa7\x49\x04\x4d\x10\x9a\xc3\x92\xe5\x90\xfa\ +\xaa\x7f\xfe\x0a\x4d\x6f\x6e\x1d\x19\x23\x61\x05\xd6\x71\xd1\x76\ +\x59\x68\x1f\x4d\x37\xbd\x38\x52\xd2\x24\x67\x4a\xc9\xfa\x53\xb2\ +\x2c\xfb\xa0\x36\xe9\x3c\x1e\x2c\xca\x64\x46\x8f\xc4\xb9\xd5\x59\ +\xdf\xf9\x66\x0d\x9c\x9b\x5b\xda\xfb\xe6\x6b\x73\x44\x65\x54\x34\ +\x7d\xa0\xb3\x78\x45\x21\x83\x3f\x2a\x26\x3a\xcf\x13\xc1\xeb\x32\ +\xe7\x29\xed\xd4\x35\x9a\x34\xcb\x58\x59\xf5\x8e\x56\xf2\x90\x81\ +\x48\xd3\x72\xa2\x37\x76\xf3\xdc\xa7\xac\x2a\x41\x09\x86\x43\xc6\ +\x0a\x7a\xcf\xa1\x2b\xaf\x33\xbe\x8b\x1e\x59\xc5\x56\x19\xbd\x6f\ +\x7e\x59\x06\xce\xf7\xa4\x35\x20\x10\x15\x30\xcf\xef\x2b\x29\xf8\ +\x03\x8d\xba\xc6\xd6\x7d\xb6\xc5\x14\x11\xe8\xe9\xbe\x4d\xa6\x61\ +\x38\xd5\x0c\xb5\x03\x18\x1c\xad\x6a\x29\x87\xb4\x7f\x39\x2b\x22\ +\xc0\x97\x0a\x4d\x6d\x3e\x32\x28\x0c\x19\xf5\xda\x69\x0c\x1d\x4d\ +\x08\xb0\x75\xb0\x77\x43\xe5\xeb\x75\x45\x65\x64\x6b\x5a\xd7\x19\ +\x23\xe7\x3e\x8f\xc5\x03\x15\xad\x02\x2d\x62\xb0\x1e\xaf\xe2\xe4\ +\x41\x01\x56\xa4\x51\x9c\x40\x5b\xa9\x33\x38\x86\x8c\x0a\xa6\x8c\ +\xe5\xd6\xb5\x9d\x00\x07\xf8\x98\xf2\xc9\xa8\x5e\x54\x1b\x74\x61\ +\x6e\xa9\xb9\x47\x7a\xaa\x00\x19\x12\x98\x7e\xa8\x9e\x23\x55\x95\ +\x89\xdf\xd6\x49\xd0\x27\xcd\x3c\x61\x22\xc9\x9e\x31\x36\xea\x6d\ +\x80\x44\xf3\x29\xea\x8c\x2a\xee\x57\x98\x2e\x7d\xf0\xba\xcd\x46\ +\xc1\x73\x4c\x37\x68\x47\xd2\x6b\x8d\x9d\x8f\xbd\x51\xec\x3c\xd3\ +\x0e\x3d\xd7\x0d\xc9\x38\x86\xa3\xb3\x4b\x13\x2d\x20\x92\x57\x13\ +\x25\xd2\xe6\x9a\xff\x5a\xa3\x14\x8c\x62\x34\x33\x5d\x77\x1c\x8d\ +\xab\x31\x72\x6c\x73\x34\x77\x20\x54\x6a\xd1\x93\x40\x9d\x77\xaa\ +\x4b\x30\x92\x76\x7d\x77\xfa\xac\x8d\xaa\x87\xac\x77\x03\x80\xf8\ +\x84\xb4\x77\xee\xc4\x75\xdb\x1e\xe1\xa3\xdf\x91\x7d\x06\x17\x4c\ +\xc9\x23\x58\xc7\x13\x17\x2f\xc0\x52\xc9\x05\x86\xb3\xd7\x63\x2c\ +\x6b\x41\x47\x33\xbc\x9f\xc5\x30\x1c\xd4\xf8\x82\x63\x52\x92\xdc\ +\x00\x32\xc7\x0c\x43\xcf\x26\xb3\xa0\xdc\x7f\x3b\x66\x17\x91\xc8\ +\x51\x7f\x94\x98\x10\xdf\xf4\x1b\x4c\x50\x82\x74\x70\xdc\x89\x7d\ +\xed\xfd\x3c\xb5\x7c\x9f\x60\xfb\xc9\x68\xdd\x24\x83\x1c\x7f\x36\ +\x75\x66\xb3\x1b\xe2\xa1\xab\x01\x32\x43\xe7\x08\xe0\x61\x4f\xf0\ +\xd4\x24\x0d\x50\xd7\xde\xcf\xf1\x08\xa6\xcf\x87\x46\x40\xcf\x93\ +\xa3\x0b\x24\xb9\x21\x1a\x78\x90\x1e\x76\xeb\xa8\x8f\x5c\x93\x4c\ +\x34\xc3\x47\x9e\x39\x9d\xe0\xc0\x9c\xb5\x50\x7d\x44\x8e\x6b\x06\ +\xad\x46\x68\x7a\xc8\x09\x41\x58\xfd\x87\xc8\xb4\x93\x99\x10\xa7\ +\xc3\x18\xb9\x64\x42\x66\x20\x95\x21\xbd\xc0\x04\x16\x3f\x43\x72\ +\x6a\xbb\xfe\x0b\x22\xa9\x53\x60\x1a\xbe\x44\x67\xb2\x75\xc2\xb9\ +\xd7\xa1\x3f\x02\x36\x80\xde\x1b\x41\x3f\xed\x33\xd7\x1f\x48\x68\ +\x5a\x13\x8b\x8f\xc3\x18\x10\x73\xda\xc0\xef\x75\x1d\xfd\x29\x31\ +\xc0\xee\x37\xf7\xc2\x5e\x4e\x8a\xb8\xa8\xd4\xa5\x00\x27\x70\xa5\ +\xa4\x02\x37\x57\x1c\xef\x09\x82\x30\x8c\xf0\xe9\x85\xe7\xc7\xea\ +\xa2\x9f\x86\x5d\x54\x01\xfb\xae\x09\x54\x8b\xf1\xe9\xcb\x95\xbe\ +\x89\xc9\x0b\x76\xce\xe7\x1d\x24\xfa\xd8\xed\x7f\xd7\x20\xc1\xce\ +\xff\x07\x10\xe7\x16\x93\xf5\x1b\xaa\xef\x47\x04\x64\x58\x24\x5e\ +\x5f\x23\x5e\x57\x19\x83\xdf\x6b\xee\x4f\x5f\xb5\xfb\xa3\x7c\xd0\ +\x6f\xdf\x97\x0f\xe1\x6b\x3f\x6b\x39\xc4\x0c\x6e\x72\xcc\xc2\x17\ +\xe6\xc8\xeb\x82\x82\x04\xb7\x82\xe2\x25\xe7\xc8\xf3\x40\xa1\x4f\ +\x3b\xb7\xc1\xe3\xf9\x4e\x8e\x3f\xd8\x9d\xd6\x3e\x9e\xfb\x7c\xf4\ +\x37\xea\x2f\xb6\x97\x2e\xb5\x4f\xaf\x97\x27\x5d\x6a\xe7\xd6\x66\ +\x79\x37\x57\x7f\xff\x5d\xde\xfd\x07\x5c\xd5\x81\xeb\ +\x00\x00\x14\xeb\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x7a\x6f\x6f\x6d\x5f\x74\x6f\ +\x5f\x49\x6d\x61\x67\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ +\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ +\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ +\x33\x37\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ +\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\ +\x30\x66\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ +\x6f\x70\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\ +\x30\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ +\x23\x62\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ +\x6f\x70\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ +\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\ +\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\ +\x30\x33\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ +\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\ +\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\ +\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\ +\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\ +\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\ +\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x66\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\ +\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\ +\x31\x34\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\ +\x32\x34\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\ +\x38\x2c\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\ +\x35\x38\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ +\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ +\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\ +\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x2e\ +\x37\x39\x39\x34\x35\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x35\x34\x2e\x37\ +\x33\x33\x32\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x30\x2e\x36\x36\x31\x37\ +\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ +\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ +\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\ +\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ +\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ +\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\ +\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ +\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ +\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\ +\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\ +\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\ +\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\ +\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\ +\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ +\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ +\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\ +\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x2d\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ +\x72\x69\x78\x28\x30\x2e\x36\x33\x36\x33\x36\x33\x34\x2c\x30\x2c\ +\x30\x2c\x30\x2e\x35\x34\x32\x34\x35\x31\x33\x35\x2c\x38\x2e\x37\ +\x31\x34\x36\x36\x38\x37\x2c\x34\x2e\x39\x35\x35\x32\x35\x37\x32\ +\x29\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ +\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x34\x33\x36\x37\x38\x34\x38\ +\x2c\x30\x2e\x35\x33\x36\x38\x34\x38\x37\x39\x2c\x30\x2c\x30\x29\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\ +\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\ +\x2e\x34\x35\x31\x31\x34\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\ +\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x38\x33\x37\x30\x35\ +\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\ +\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x33\x37\x36\x37\x2d\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x35\x2e\x39\x38\ +\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\ +\x3d\x22\x32\x37\x2e\x37\x39\x39\x37\x36\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\ +\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\ +\x38\x39\x33\x37\x32\x39\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\ +\x39\x38\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\x35\x30\ +\x38\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\x30\x2c\ +\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\ +\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x78\x3d\x22\x32\x33\x2e\x33\x32\x30\x36\x32\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ +\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ +\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\ +\x39\x37\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ +\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\x63\ +\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ +\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x31\x2e\x39\x30\x37\x36\x32\x34\x39\x36\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ +\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\ +\x36\x39\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ +\x22\x31\x33\x2e\x38\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x34\x2e\x30\x34\x30\x31\x33\ +\x38\x34\x65\x2d\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x32\ +\x31\x31\x37\x36\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x31\x30\x37\x31\x31\ +\x35\x32\x2c\x30\x2e\x37\x30\x33\x34\x38\x33\x35\x38\x2c\x30\x2c\ +\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\ +\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ +\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\x38\x34\x30\x39\x33\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x31\x39\x2e\ +\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\ +\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x34\x38\x34\x34\ +\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\ +\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x35\x35\x32\x32\x30\ +\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ +\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\ +\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x30\x35\x31\x33\ +\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\x39\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\x2e\x32\x35\x37\x38\ +\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x31\ +\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\x35\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x32\x30\x33\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\ +\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\x39\x2e\ +\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x12\x0e\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x62\x61\x6e\x64\x5f\x70\x72\x6f\x63\x65\x73\x73\x69\x6e\x67\ +\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\ +\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ +\x31\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x36\x2e\x35\x38\x31\x34\x37\x39\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x2d\x32\x2e\x33\x31\x37\x38\x30\x30\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\ +\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\ +\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ +\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\ +\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ +\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\ +\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x37\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\ +\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x6f\ +\x63\x6b\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ +\x63\x75\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\ +\x22\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ +\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ +\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ +\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ +\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\ +\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\ +\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ +\x2e\x39\x33\x37\x34\x39\x39\x39\x35\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ +\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\ +\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ +\x4d\x20\x2d\x31\x36\x2e\x38\x37\x35\x2c\x32\x31\x2e\x36\x39\x32\ +\x31\x34\x35\x20\x38\x2e\x39\x34\x33\x30\x34\x32\x31\x2c\x32\x32\ +\x2e\x30\x33\x34\x35\x30\x33\x20\x39\x2e\x34\x30\x33\x39\x34\x30\ +\x31\x2c\x33\x31\x2e\x37\x37\x37\x39\x34\x32\x20\x33\x31\x2e\x32\ +\x35\x37\x32\x39\x33\x2c\x31\x36\x2e\x34\x38\x37\x39\x38\x39\x20\ +\x37\x2e\x39\x32\x39\x30\x36\x38\x34\x2c\x30\x2e\x35\x39\x38\x39\ +\x30\x39\x36\x32\x20\x38\x2e\x33\x38\x39\x39\x36\x36\x31\x2c\x31\ +\x30\x2e\x33\x34\x32\x33\x35\x33\x20\x2d\x31\x37\x2e\x34\x32\x38\ +\x30\x37\x36\x2c\x31\x30\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x38\x31\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ +\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x37\x37\ +\x31\x63\x38\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ +\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\ +\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x31\x2e\x31\x32\x30\x32\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x38\x2e\x30\x32\x39\x32\x31\x39\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x2e\x33\x35\x36\x38\ +\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x35\x30\ +\x2e\x38\x38\x32\x32\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x34\x30\x2e\x34\x39\x35\x32\x33\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\ +\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\ +\x2e\x34\x33\x37\x34\x34\x35\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x39\x33\x39\x32\x33\ +\x38\x35\x2c\x30\x2e\x34\x34\x38\x32\x31\x38\x38\x37\x2c\x30\x2c\ +\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\ +\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\x2d\x32\x2e\x34\x32\x34\ +\x32\x31\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\ +\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\x22\x32\x32\x2e\x37\x31\x39\ +\x32\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\ +\x2e\x38\x35\x32\x36\x32\x39\x31\x34\x2c\x30\x2e\x35\x32\x32\x35\ +\x31\x36\x35\x35\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x72\x79\x3d\x22\x32\x2e\x35\x38\x33\x30\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\ +\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\ +\x30\x2e\x35\x37\x31\x34\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x78\x3d\x22\x34\x30\x2e\x38\x31\x32\x36\x31\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x2e\ +\x36\x36\x34\x37\x35\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x38\x2e\x30\x32\x39\x32\x31\x39\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\ +\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x32\x31\x34\x34\x37\ +\x38\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x35\x66\ +\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ +\x2e\x30\x33\x37\x35\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ +\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\x2d\ +\x32\x2e\x34\x38\x38\x31\x36\x35\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\x22\x32\ +\x30\x2e\x38\x35\x39\x31\x36\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x31\x31\x32\ +\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ +\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ +\x2e\x39\x37\x39\x32\x36\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x38\ +\x2e\x30\x32\x39\x32\x31\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x2e\x30\x31\x36\x33\x39\ +\x32\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x33\ +\x2e\x33\x30\x35\x34\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x32\x32\x2e\x39\x31\x35\x32\x30\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\ +\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\ +\x2e\x37\x35\x33\x34\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x30\x39\x38\x39\x37\ +\x37\x32\x2c\x30\x2e\x35\x38\x36\x35\x37\x31\x31\x32\x2c\x30\x2c\ +\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\ +\x6e\x74\x65\x72\x2d\x78\x3d\x22\x2d\x32\x2e\x34\x38\x38\x31\x36\ +\x39\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\ +\x6e\x74\x65\x72\x2d\x79\x3d\x22\x31\x38\x2e\x36\x34\x33\x30\x36\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\ +\x38\x38\x35\x31\x35\x36\x34\x2c\x30\x2e\x36\x31\x35\x30\x31\x34\ +\x37\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x32\x2e\x38\x34\x36\x39\x30\x34\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\ +\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x37\ +\x2e\x37\x33\x37\x33\x32\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x78\x3d\x22\x32\x38\x2e\x36\x36\x38\x37\x31\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x2e\x32\ +\x30\x36\x36\x35\x35\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x38\x2e\x30\x32\x39\x32\x31\x39\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\x63\x63\x63\ +\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ +\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ +\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ +\x39\x35\x36\x33\x35\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ +\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ +\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\ +\x22\x2d\x32\x2e\x34\x32\x34\x32\x31\x37\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\ +\x22\x31\x36\x2e\x32\x36\x38\x36\x36\x39\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x11\x80\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x7a\x6f\x6f\x6d\x5f\x74\x6f\ +\x5f\x52\x4f\x49\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ +\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\ +\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x30\x66\ +\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ +\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\ +\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\x30\x36\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x62\ +\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\ +\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\ +\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\x74\x6f\ +\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x30\x33\ +\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ +\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\ +\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\ +\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ +\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\ +\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\ +\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\x47\x72\ +\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\x2e\x36\ +\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x66\ +\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\ +\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\x31\x34\ +\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ +\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\ +\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\x32\x34\ +\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\x38\x2c\ +\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\x35\x38\ +\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\ +\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\ +\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\ +\x39\x30\x32\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x33\x38\x2e\x33\x32\x38\ +\x32\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x31\x39\x2e\x31\x31\x38\x33\x31\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\ +\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\ +\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\ +\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\ +\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ +\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ +\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ +\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ +\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ +\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ +\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ +\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\ +\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ +\x78\x28\x30\x2e\x35\x37\x30\x37\x35\x32\x33\x2c\x30\x2c\x30\x2c\ +\x30\x2e\x35\x37\x30\x37\x35\x32\x33\x2c\x39\x2e\x36\x38\x35\x37\ +\x32\x32\x36\x2c\x34\x2e\x37\x33\x30\x33\x34\x31\x35\x29\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\ +\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\ +\x3d\x22\x35\x2e\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x72\x65\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ +\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ +\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ +\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ +\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\x38\x33\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x33\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x37\x2e\x30\x36\ +\x36\x36\x36\x37\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x63\ +\x20\x30\x2c\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\ +\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\ +\x32\x30\x30\x30\x30\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\ +\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ +\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x33\x2e\x32\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ +\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ +\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\x36\x36\x36\x36\ +\x36\x37\x2c\x31\x36\x2e\x36\x30\x32\x32\x38\x39\x20\x63\x20\x31\ +\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\ +\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\x30\x30\ +\x30\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x38\x30\x38\ +\x30\x38\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ +\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x33\x2e\x35\x38\x39\x30\x39\x35\x31\x32\x70\x78\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\ +\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\ +\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\ +\x38\x34\x30\x39\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\ +\x3d\x22\x31\x39\x2e\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x63\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\ +\x2e\x34\x38\x34\x34\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x31\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ +\x35\x35\x32\x32\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ +\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ +\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ +\x64\x74\x68\x3a\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\ +\x2e\x30\x35\x31\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\ +\x2e\x32\x35\x37\x38\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x32\x31\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\ +\x35\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ +\x2e\x37\x32\x30\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\ +\x28\x2d\x33\x39\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0b\xb0\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x63\x6b\x73\ +\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ +\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ +\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ +\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ +\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ +\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x32\ +\x31\x2e\x37\x33\x36\x36\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\x34\x2e\x32\ +\x35\x36\x35\x31\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ +\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ +\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ +\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\ +\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ +\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ +\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\ +\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ +\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ +\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\ +\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ +\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ +\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ +\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ +\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ +\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ +\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\ +\x23\x62\x66\x61\x64\x61\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ +\x62\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x30\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x31\x33\x33\ +\x33\x33\x34\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\ +\x23\x36\x36\x36\x36\x36\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ +\x62\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x30\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x34\x35\x31\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x33\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x32\x2e\x38\x30\x30\ +\x30\x30\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\ +\x62\x66\x61\x64\x61\x64\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x62\ +\x66\x62\x66\x62\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x30\x32\x2d\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x39\ +\x2e\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x32\x2e\x31\x33\x33\x33\x33\x36\x35\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x36\x36\x36\x36\x36\x36\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x66\x62\x66\x62\x66\x62\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x35\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x34\x35\x31\x39\x2d\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x35\x2e\x33\x33\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x2e\x33\x33\x33\x33\ +\x33\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\ +\x2e\x33\x33\x33\x33\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x16\xb0\ +\x00\ +\x01\xff\x66\x78\x9c\xed\x5d\x59\x73\xe3\xc8\x91\x7e\x9f\x5f\x41\ +\x73\x5e\x3c\x61\xa1\x84\x2a\xa0\x80\x02\x5b\x6a\x3f\x78\xc2\xb1\ +\x13\x61\xc7\x46\xd8\x5e\xef\xe3\x04\x45\x42\x12\xb7\x49\x42\x01\ +\x42\x57\xff\xfa\xad\xc2\x41\xf0\x48\xb5\xc5\x49\x30\xd1\x1a\x24\ +\x67\x3a\x28\xe2\x46\x7e\x95\x59\x79\x55\xe6\xd5\x9f\x5f\x56\xcb\ +\xd1\x53\x9a\x6f\x16\xd9\xfa\x7a\x2c\x85\x3f\x1e\xa5\xeb\x59\x36\ +\x5f\xac\xef\xae\xc7\xff\xf3\xaf\xbf\x7a\x66\x3c\xda\x14\xd3\xf5\ +\x7c\xba\xcc\xd6\xe9\xf5\x78\x9d\x8d\xff\xfc\xf9\x87\xab\x3f\x78\ +\xde\xe8\x2f\x79\x3a\x2d\xd2\xf9\xe8\x79\x51\xdc\x8f\x7e\x59\x7f\ +\xd9\xcc\xa6\x0f\xe9\xe8\x8f\xf7\x45\xf1\x30\xb9\xbc\x7c\x7e\x7e\ +\x16\x8b\x7a\xa3\xc8\xf2\xbb\xcb\x9f\x46\x9e\xf7\xf9\x87\x1f\xae\ +\x36\x4f\x77\x3f\x8c\x46\x23\x7b\xdf\xf5\x66\x32\x9f\x5d\x8f\xeb\ +\x13\x1e\x1e\xf3\x65\x79\xe0\x7c\x76\x99\x2e\xd3\x55\xba\x2e\x36\ +\x97\x52\xc8\xcb\x71\x7b\xf8\xac\x3d\x7c\xe6\xee\xbe\x78\x4a\x67\ +\xd9\x6a\x95\xad\x37\xe5\x99\xeb\xcd\x8f\x3b\x07\xe7\xf3\xdb\xed\ +\xd1\xee\x69\x9e\x83\xf2\x20\x99\x24\xc9\xa5\xaf\x2e\x95\xf2\xec\ +\x11\xde\xe6\x75\x5d\x4c\x5f\xbc\xfd\x53\xed\x33\x42\xa7\x2a\xdf\ +\xf7\x2f\xed\xbe\xf6\xc8\xf7\x1d\x35\xd9\x58\x82\x3e\xd8\x7f\xdb\ +\xc3\x9b\x0d\x62\x93\x3d\xe6\xb3\xf4\xd6\x9e\x97\x8a\x75\x5a\x5c\ +\xfe\xfc\xaf\x9f\xb7\x3b\x3d\x5f\xcc\x8b\xf9\xce\x65\x1a\x7a\xee\ +\xdd\x75\x8f\xc8\xeb\xe9\x2a\xdd\x3c\x4c\x67\xe9\xe6\xb2\xd9\x5e\ +\x9e\xff\xbc\x98\x17\xf7\xd7\xe3\x20\x14\x32\xb0\x1f\x5d\x6e\xbc\ +\x4f\x17\x77\xf7\xc5\xe1\xd6\xc5\xfc\x7a\x6c\x9f\x5e\x07\xca\x2f\ +\x7f\xef\x0c\x0e\x59\x1d\x50\x5f\x78\xb2\xdd\xe3\x8b\x44\x09\x39\ +\xca\xa5\x0e\xe2\xea\x98\xe6\x15\x26\xf3\x6c\xe6\x9e\xc9\x5e\x32\ +\x5d\x2d\xa6\x8f\x45\xb6\xb2\xa8\xcd\x66\xcb\xe9\x66\xb3\xb8\x5d\ +\xcc\xec\x8f\x6c\xfd\xb0\x7c\xbc\x5b\xac\x7f\xb5\x17\x2d\x8a\x34\ +\xff\x35\x9f\x6e\xdc\x57\x91\xae\x1e\x7e\xfd\xc7\x7f\xff\x22\x1a\ +\x52\x6e\xef\x9b\xbe\x3c\x64\x79\xe1\xbd\xcc\x1f\x2c\x41\xa3\x58\ +\x68\x70\xf7\x6b\xbb\xfb\xb3\xdd\x7f\x35\x4f\x6f\x37\xee\xb8\xea\ +\x0d\xdd\x2f\xfb\x8a\x6a\x3c\xba\x2c\xf7\x6e\x1f\xd8\x3d\xed\xfc\ +\x69\x91\x3e\xb7\xc7\xde\x4c\x37\x15\x15\x47\xa3\x87\xe9\x9d\x1d\ +\x71\xcb\x2c\xbf\x1e\xff\x78\x5b\x7e\xea\x1d\x37\x59\x3e\x4f\xf3\ +\x66\x57\x54\x7e\xf6\x76\x65\x16\x95\x45\xf1\x5a\xf1\x58\x7d\xed\ +\xe6\x89\xdd\x55\xb7\xfb\x7d\x78\xff\xe6\x7e\x3a\xcf\x9e\xaf\xc7\ +\xea\x70\xe7\xd7\x2c\x5b\x5d\x8f\x63\x91\x48\xe3\x87\x32\x3e\xdc\ +\x3d\x7b\xb9\x1e\x7b\x81\x14\x71\x12\x18\x63\x8e\xf6\xba\x07\x4a\ +\x84\x09\x74\x54\x23\xb7\xbb\xf3\x31\xcf\x2d\x17\x7a\xcb\xe9\x6b\ +\x6a\xdf\xaa\xfc\x0a\xea\x83\x36\xf7\xd9\xf3\x5d\xee\xa8\x53\xe4\ +\x8f\xe9\xe1\x99\x6e\x8f\x77\x73\x93\xbd\xc0\xbb\xed\xa0\x78\x74\ +\xfc\xed\x3d\xae\x17\x85\xe5\xa1\x87\x97\xdd\xab\x3e\x2e\xe6\xe9\ +\xe6\x8d\xeb\xba\x7d\xdf\xb8\xf0\xf3\x62\x6d\x89\xe4\xd5\xa3\x5d\ +\x06\x5b\x0c\x0e\x8f\x68\x86\x7e\xec\x1f\x91\xa4\x3e\xc2\xde\xe1\ +\x08\x87\x7a\xd7\xeb\xdb\xbb\x56\xd3\x97\xc5\x6a\xf1\x35\xb5\x74\ +\x91\xe5\xb0\xb3\x43\x6b\x8f\x2a\xd5\x69\xa3\x51\xf1\xea\xd8\xf8\ +\xe5\xd5\x6d\x1b\x37\x1b\x1d\x39\xdd\x06\x1d\x84\xd1\x76\x63\x96\ +\x2f\x2c\x77\xec\x3c\x4e\xb3\xe9\x75\x77\x93\x63\x7a\x2b\xb3\x5f\ +\xca\xf1\x55\x8e\xbe\xf8\x70\xdf\xeb\xee\xbe\x7a\xd8\x5f\x1e\x8f\ +\xfb\x72\xfb\x2a\x2d\xa6\xf3\x69\x31\x6d\x99\xa0\xd9\x62\x99\x46\ +\x37\x6f\x66\xe5\xe7\xe4\x1f\x3f\xff\xf5\x73\x7d\xa3\xab\xd9\x6c\ +\xf2\xbf\x59\xfe\xa5\xb9\xef\x68\xe4\x0e\x98\xde\x64\x8f\x96\xd2\ +\xe3\xcf\xdb\xcd\x57\xf3\xd9\xc4\x4a\x3c\x2b\x09\x3e\x2f\x56\x76\ +\x68\x3b\x61\xf9\x27\x2b\xe1\xae\x2e\xdb\x1d\x7b\x07\x3b\x62\xb5\ +\x17\xad\x2e\x9b\xa7\x95\xe8\x04\xe7\x8f\xf9\x6c\xb5\x70\x27\x5d\ +\xfe\xb3\x58\x2c\x97\xbf\xb8\x9b\xd4\x6f\xbc\x73\xd1\x45\xb1\x4c\ +\xdb\x8d\x57\x97\xf5\xd3\xd7\xef\x76\xb9\xf3\x72\x57\x97\xcd\xdb\ +\x97\xbf\xee\x5a\xaa\x94\x3c\x71\xc4\x38\xcb\xe9\x4d\xba\xbc\x1e\ +\xff\xcd\xed\x1c\x1d\xed\xbd\xcb\xb3\xc7\x87\x55\x36\x4f\xeb\xd3\ +\x1b\x2c\xee\xfe\xd3\x71\x07\xb7\x0d\xde\xba\xad\x9d\x15\x97\xcb\ +\x6c\x0b\x52\x3a\x2b\xb6\x23\xa1\x78\x5d\xda\xcb\x95\x62\x6a\xf2\ +\xa3\x5f\x7e\x3e\xcd\x17\x9b\x07\x7b\x41\x3b\xbb\x2c\x17\xeb\xf4\ +\x53\x66\xc5\xfa\xed\x32\x7b\x9e\x3c\x2d\x36\x8b\x9b\x65\xfa\xa9\ +\xfc\x5e\x2c\x2d\x41\xb7\x9b\x6a\x61\x35\xb1\x82\xdf\x24\xe5\xe7\ +\xd3\xad\x25\xf4\xa4\x96\x89\xe5\x0f\xaf\x39\x48\x56\x3f\xf3\xc7\ +\x65\x3a\x59\x67\xeb\xaf\x56\x16\x7e\xda\x14\x79\xf6\x25\x75\xc7\ +\x1b\x6d\x1f\xa1\xfa\x59\xf1\xed\x44\x0b\x99\xc8\x30\x8a\x8c\x6c\ +\xb6\xbb\xe7\xb2\x6f\x38\xb9\x79\x2c\x8a\xdd\x6d\xff\x97\x2d\xd6\ +\x13\x8b\x74\x9a\x37\x5b\xcb\x1f\x4b\xcb\x82\xc5\x24\x6c\xb6\xcd\ +\xa7\x56\x76\xe6\xb9\x7d\x43\x7b\xf7\x74\x77\x6b\x76\x7b\xbb\x49\ +\x8b\x89\xb2\xf2\x4f\x19\x5f\x6a\xd3\xec\x6c\x1f\x7d\x35\xcd\xbf\ +\xa4\x79\x75\x66\xba\x9e\xda\x97\xf7\x6e\xa6\xb3\x2f\x0e\x9b\xf5\ +\x7c\x32\x9d\x59\x41\xf6\xb8\xb4\x6a\xd0\x1e\x0f\x3b\x92\x07\x41\ +\xdc\x72\x67\x2d\x90\xa2\x44\xb8\x79\x36\x68\x99\xbb\x91\x43\xda\ +\x88\x92\x31\xcd\x76\x8f\x13\xdb\x2a\x12\x7b\x33\xc9\x68\x64\x79\ +\xd8\x93\x81\x30\xbb\x4c\x6c\x31\x7e\x98\x16\xf7\x07\x18\x97\x78\ +\xec\xbc\xf0\x16\xee\x3d\x5a\xab\x6a\xe6\x0f\xc2\xf0\x9c\xb4\xde\ +\x92\x73\xfb\x1e\x96\x48\x7f\x1f\x6d\xa5\xd1\x85\xb7\xfd\x73\xf4\ +\xef\x51\x10\x54\x3f\xe2\x3d\x9a\xba\x57\x54\x49\xd2\x92\xa2\x9d\ +\xa6\xb2\xb5\x7d\xe4\x22\xcb\x3d\x3b\x61\x3d\x4d\x8b\xc7\x3c\xdd\ +\x93\x8c\x5b\x09\x67\x59\xc9\x09\x05\x3b\xb7\xcc\x66\x1f\x9d\x76\ +\x81\x16\xea\x62\x4b\xa9\xd1\x7f\x8d\x8e\xc5\xfe\x0e\xd5\xcc\xf7\ +\x43\x35\x29\x2c\x88\xbe\xd2\xe6\xe1\xe5\x74\xb2\x81\xc4\x58\x8d\ +\x1a\x24\x82\x0b\x15\x8b\xb8\xfc\x6b\x34\xdb\x6e\x0d\x2f\xfc\xb7\ +\xfe\x3e\xa2\x55\x10\xc7\xca\xf3\xdf\x4d\xad\x4e\x06\x91\x8c\x75\ +\x28\xb5\xee\x90\x1e\x91\x08\x2f\x1a\xa5\xde\x51\xc2\xbf\xf0\x42\ +\xa1\xca\xe1\xf1\xd6\xdf\xc7\x94\x30\xe1\x87\xa7\x83\x94\xf5\x68\ +\xe8\x84\x1a\xde\xfb\xb9\xe8\x3b\xa5\x87\x52\x1d\x0d\x0c\x2f\xf9\ +\xf0\xa4\x88\x3b\x1d\x1a\x1f\x9e\x55\xb6\x53\x49\x37\xf4\x08\x3e\ +\x3a\x3d\x64\xdc\x29\x3d\xde\xaf\xb6\xfc\x47\x7a\x94\x3a\xf6\x96\ +\x06\xbd\x4c\xb2\x56\x8c\xa0\xe6\x57\x4f\xfd\x9e\xc8\xb1\x1d\x2a\ +\x38\x9a\x48\x42\x96\x39\x33\x41\x64\x17\x4a\x18\xa9\x0c\x39\x2f\ +\x41\x22\x2c\xbf\x84\xbf\x1b\x52\xb4\x86\x1e\x8a\x20\xbf\x41\xff\ +\x38\x87\x1f\xa4\x91\x40\xe5\xf9\xef\x76\x7a\x40\x54\xf7\x4f\xa7\ +\xf5\x6f\xf2\x75\xf8\x47\x48\x21\x5c\x1c\xc6\x6f\x05\x79\xe3\x73\ +\x15\xed\xa6\xc6\xb9\xe1\x8b\x44\x86\xca\xe8\xb8\xdd\xe5\xfc\x94\ +\x81\x08\x8f\x9c\x1b\x8d\xe8\xd0\x8c\xdb\x79\x71\xdb\x11\x29\xa7\ +\x23\xa7\x1b\x07\x14\x23\xd7\x03\x72\x09\x02\xb9\x50\x44\xc7\xc8\ +\x69\x11\x24\x7e\x18\x47\x8c\xdc\xb9\x79\x6e\xc7\x85\x70\x3a\x76\ +\xb5\x9a\x69\x18\xbb\x3e\xb0\xc3\xcc\x74\x10\xd7\x25\xa2\xc4\x2d\ +\x50\x8c\xdc\xd9\xb9\x2e\xea\x98\xeb\x18\x3b\xb2\xb9\x6e\xc7\x0a\ +\xec\x48\x4f\x09\x84\x8e\x64\xe2\xb3\x9e\x42\x30\xdb\xa1\x74\x15\ +\x73\xe8\x51\x63\xf4\x28\xe7\xbb\xae\x19\xcf\x08\x3f\xb6\xd0\xc9\ +\x84\xa1\x3b\x3b\xe3\x75\xcd\x76\x8c\x1d\xdd\x84\x87\x50\x34\x95\ +\x0f\xe4\x8b\xb0\x61\x4e\x3a\xe1\xc9\xae\x67\x3c\x86\x8f\x08\x3e\ +\x8c\x95\x00\xfa\x32\x59\x57\x21\x63\x3c\x84\xb2\x02\x0b\x4d\xc6\ +\x8e\x6c\xc2\xc3\x48\xcc\xa4\xe2\x3b\xf6\xac\xf4\x36\xe1\x21\xa4\ +\xa6\x92\x80\x99\x40\x8a\x9e\x3b\xdb\x0c\x15\xbd\x04\x10\x9a\x87\ +\x39\xa4\x0d\x80\xc7\x7b\x2a\xfc\xaa\x38\xed\x9e\xe4\xf4\x1b\x67\ +\x27\xe3\x77\xf6\x59\x0f\x8d\x60\x00\xc8\x4f\x46\x90\x6e\xee\x03\ +\xa4\xe7\x69\x00\x2a\xb1\xcf\x7d\xa1\x48\x4a\x9e\x64\xec\x08\xe6\ +\x3e\x8d\x45\x2f\x14\xba\x42\x8b\x21\xec\xc3\xc5\x09\x99\x0d\x28\ +\xf6\x33\x35\x9e\x86\xb1\x3b\x7f\x50\x0f\x32\x1c\xf0\xec\xc7\x10\ +\x12\xc6\xf6\xf0\x12\x14\x54\x60\x94\x60\xf4\x48\x9c\x9d\x50\xa0\ +\xe1\x34\xfc\xb4\x88\x18\x3a\xf2\xd0\x1e\x1e\x37\x88\xef\x22\x11\ +\x96\x64\x92\x8c\xe0\xf9\x23\x7c\x78\xd3\xe1\x80\xf5\x18\x3d\xc2\ +\x18\x1f\x1e\xbd\x7a\xfd\x1a\xfb\x5e\x7a\x0c\xf5\xe1\x35\xd0\xc3\ +\xe9\x8f\x01\xa4\x0a\xf6\xe1\x6d\x3f\xd0\xfb\xc9\xfa\x0b\x89\xe3\ +\xd3\x8b\xcf\x22\x3f\x19\x3d\x92\x80\x1f\x5e\xfd\x84\x0a\xa3\xb0\ +\xe5\x4e\x1a\xf7\xc3\xdb\xee\x46\xc4\x65\xed\x20\x06\xb1\x0f\x10\ +\xb1\xf3\x5f\xab\xab\xec\x4a\xd0\x44\x28\x36\x22\x88\x26\x41\x60\ +\x09\xdf\x69\x08\xba\xe9\x8e\xc1\xeb\x65\x0e\xc4\xea\x2f\x4d\x5a\ +\xe0\x9e\xfe\xd2\x7a\x65\x18\x40\x82\x19\x10\x3b\x01\xb6\x85\xdc\ +\x18\xc3\x5e\xc2\x7f\x40\xaa\x35\x9e\x09\xdb\x15\x63\x0c\xe0\xf9\ +\x63\x80\x68\x39\x0a\xf1\x20\x43\x48\x19\x03\xc4\xba\x42\x0f\xd5\ +\x98\xd6\x31\xc3\xe8\x51\xc4\x00\x8f\xca\x9c\x9e\x8a\xdf\x36\xe1\ +\x85\x41\xec\x27\x1a\x88\x46\xf0\xd0\x90\xe0\x14\x26\xc2\x40\xe0\ +\x59\xf8\x8f\x21\xa4\x8c\x06\xa2\xb5\x18\xb0\x36\x08\x9b\xf3\xb4\ +\xd1\x40\xb4\x39\x01\x32\x22\xa3\x48\x17\x12\x44\x8b\x52\xc8\x27\ +\xca\xaa\x0c\x65\x60\x10\xed\x94\x81\x44\x29\x43\x48\x1a\x1d\x44\ +\x63\xb8\x9f\x54\xc1\xd6\x3c\x69\x5c\x10\x2d\x44\x4d\x5d\xff\x93\ +\x41\xec\x69\x51\x12\x3a\xaf\x09\x86\x90\xa4\x48\xdd\xa0\xb1\x2b\ +\x17\x25\xa1\xf5\x50\xe5\x43\x75\x28\x18\x3d\x0a\x67\xa8\x46\xe7\ +\xc6\xb4\x06\xc3\x2e\x7a\xc7\x3d\x83\x18\xc4\x73\xae\x8b\xc0\x33\ +\x21\x98\x5e\xc8\x30\xd2\x19\x83\x78\x4e\x04\xbd\x32\x0c\x21\x65\ +\x9a\x28\x3e\x51\x14\x5c\x61\xc6\x20\x12\x6a\xa3\xe8\x4c\x35\x5e\ +\x62\xd6\x93\x22\x8a\x36\xe4\x41\x3b\x82\x01\xa4\x53\x63\xce\xa3\ +\x8d\xf2\x32\x17\x42\x35\x06\xeb\x8f\x01\xf3\xb4\x75\xa5\x9d\xd2\ +\x94\x25\x1c\x34\x84\xb5\x1a\x83\xce\xb6\xff\x0e\x8a\x35\x9d\xd6\ +\x1b\xf8\x77\x85\x62\x12\x40\xbd\x1f\x42\xed\xfe\xd3\x00\x82\x81\ +\x1f\xc4\xf6\xff\x03\xb7\x4c\xe2\x0e\xdf\xd7\x66\xb4\x88\x23\x95\ +\x44\x44\x91\x89\x01\x23\xe8\xca\x6d\x41\xb9\x6a\xa7\x61\x68\x0d\ +\x07\x77\x3c\x63\xd8\x9b\x35\x01\xac\x9a\x38\x0d\xc2\x83\x9a\x3f\ +\x8e\x2d\x63\xfb\x21\xa9\x8d\x3d\x68\xf4\x2a\xa3\x02\xd0\x48\x4f\ +\xc3\xcf\xaa\x2e\x7e\xe2\x27\x8a\x41\xec\xa9\xe8\x16\x14\xa3\x47\ +\xb1\xa0\x0c\x84\xd4\xf6\xc3\x6a\xcc\xf9\x59\x30\xf2\xc0\xb2\x07\ +\x78\x16\x64\x10\x89\xe3\x4c\x80\x5b\xad\x03\x5d\xc6\x08\x77\x60\ +\xc4\x82\x94\xca\x43\x83\x66\xc6\xc8\x6a\x9f\x41\x14\x18\x86\xb1\ +\xaf\x62\x5c\x90\x87\xbb\x03\x56\xf4\x85\x0e\x8d\x0c\x89\x9c\xa5\ +\x03\xc6\xb0\x2c\xc7\x85\xb7\xef\x41\x46\x64\x10\x89\x4b\x3a\x9d\ +\x49\xa0\xb2\x8d\x4f\xe8\xf2\x46\x1b\x18\xa0\xab\x8d\xe7\x44\xca\ +\x55\x4d\xe8\x49\x51\x2a\xa1\xa4\xb1\xff\xed\x81\x98\x88\x28\x0e\ +\xfd\x98\xa8\xbd\xc4\x80\x41\x2c\xf3\x48\xa1\xe0\xd3\x69\x20\x46\ +\x42\x5b\x0c\xd9\x59\xd3\x67\x18\x1f\x4a\xa2\x39\x0d\xc5\x44\x84\ +\xd6\xde\x97\x8c\x62\x8f\xf6\x3e\x5e\xa0\x1a\x61\xa7\xbf\x20\xe2\ +\x59\xb1\x57\x83\x1f\x2c\x1e\xdb\x81\x7a\xc3\x33\x23\x65\x6e\x29\ +\xda\xcc\xb0\x16\x85\x54\xb1\x8a\x25\x73\x63\x8f\x69\x19\xf8\x70\ +\x14\xe8\xba\x61\x5e\xa4\xcc\x2f\x45\x83\x28\x03\x8b\x97\x65\xc6\ +\x3e\xd7\x1d\x0e\x18\xc4\x26\xdb\xf4\x2c\xd6\x06\xc3\x48\xab\xa7\ +\x2a\x74\x86\x06\x3c\x33\x86\xf6\x22\x89\x8a\x88\xea\x28\x0c\x18\ +\xc6\x6d\xea\x30\xda\x23\x0e\x1b\x1c\x0c\x24\x71\xe6\x29\x3e\x65\ +\xea\x3b\xc8\x5c\x1c\x70\x06\xb1\xcb\x3d\x45\xf7\x1b\xe1\x86\x3f\ +\xbd\x27\x9f\xa2\x97\x94\x72\xc7\x9f\x9e\xe0\x2b\x93\xde\x80\xd9\ +\x10\xdf\xae\x30\xac\x97\xea\x13\x19\xfc\x03\xc6\xb0\x4a\x7d\x43\ +\x2f\xc3\x80\x3a\x57\x30\x88\xb4\x26\x06\x9a\x13\x0f\x04\x29\x37\ +\xad\xa0\xb6\x2d\xd0\x08\x42\xed\x7f\x18\x46\xd2\xa4\xb7\xae\x9b\ +\xa7\xa9\x7a\xad\x30\x1b\x14\xe7\xe7\x42\xe7\x36\x3d\x4b\x0b\x43\ +\x06\x91\x6e\x2a\xec\xa4\x0b\x5e\x02\xd4\xcf\x67\xc3\x82\x3c\x69\ +\x11\xbd\xc8\x1b\x62\x46\xc6\x91\x32\x24\x7c\x96\x4a\x35\xac\xd3\ +\xd0\x7a\x4b\xd1\x93\x22\x24\x4f\x19\x44\xba\x49\x51\x76\xd0\x9c\ +\x0b\xac\x98\xc1\x46\x3e\xe5\xa4\x18\x75\x50\x07\x33\xf0\xab\x7a\ +\xec\x8a\x61\xec\x37\x8e\x88\x6d\x74\x08\xd6\x3e\x61\xe5\x86\xb4\ +\x08\x11\x7a\x66\x04\xb9\xb1\x3d\x92\x41\x24\x0a\x06\xa3\x3d\xe0\ +\x1c\x49\xec\x39\x18\x8c\x46\xf0\xc0\xf1\xc6\xe5\xdc\x48\xc3\xc0\ +\xe8\xe6\xe9\x90\xa9\xcf\x18\x92\xc6\x82\xd1\x18\x42\x61\x44\x36\ +\x13\x69\x63\xc1\x68\x10\x21\x33\x91\x41\xa4\x8d\x05\xa3\x6d\x0b\ +\x50\x9a\x72\x89\x5a\x3a\xfb\x10\xad\xce\x40\x2e\x37\x46\x90\x62\ +\x2a\x2c\xc3\xc0\x67\xe1\x40\x36\x28\x88\x8b\x9f\x9c\xc5\xf1\xcd\ +\x28\xd2\x46\x83\xd1\x3e\x9a\x7d\xe7\x0c\xdb\x14\xd4\x61\x60\x74\ +\x5e\x14\x38\x17\x32\x8e\x84\x9e\xd2\xae\xb3\xbc\x59\x93\x21\xf3\ +\x8e\x62\x93\x30\x0e\xc4\x27\x03\x47\x31\xef\xb9\x80\xef\x59\x62\ +\x13\x6c\xc9\x93\x07\x7c\xd1\x38\x06\xf5\x56\xc6\xb1\xdf\x88\xef\ +\x59\x96\xab\xb1\x1e\x43\x1b\xf1\xc5\x26\x78\x83\xdc\xc8\x8d\x67\ +\xc8\x23\xbe\x68\x3f\x37\xc7\x0b\xfb\xd2\x6e\xf0\xd1\xc2\x44\x44\ +\x25\x45\xf6\xfd\xdb\xdb\xae\x5e\x04\x08\xde\xde\x96\xe7\x0f\x13\ +\xc1\x32\xe2\x8b\x6e\xa3\x27\xa1\x18\x05\x25\x86\x83\xe6\x42\x17\ +\xf1\x45\xf7\xb0\xdc\xca\xcc\x5d\x08\x69\x4b\xd3\x0c\x18\xc2\x2a\ +\xe0\x8b\xf5\xae\x95\x16\x3d\xe3\xd7\xdf\xba\x5f\x34\x17\x42\x82\ +\xb4\xcd\x2e\x65\x14\x69\xec\x43\xac\x9f\xad\x6d\xdf\xcc\x30\xf6\ +\x15\xf6\xc5\x46\x7d\x61\x9d\x26\xac\xfc\x70\x01\x63\x48\x12\xf5\ +\x45\x2b\xa6\x10\x23\x32\x88\xb4\x41\x5f\x6c\xc0\x49\x1e\x96\x2e\ +\x65\xb3\x82\xb8\x61\x09\x5a\x96\x82\x6c\xc8\x40\x12\x7a\x4b\xb1\ +\xa6\x05\xe8\xa6\x61\x95\x86\xd6\x57\xda\xad\x24\x65\xf4\x68\x83\ +\xc0\xd8\x70\x45\xab\xb7\xb0\x89\xdf\x63\x10\x18\xeb\xf0\x6e\x11\ +\x63\x18\x7b\x8d\x01\x63\x81\x6c\xe3\xf6\xbb\x42\xd5\xaf\xd7\x6f\ +\x33\x90\x24\x31\xe0\xf3\x70\xe3\x56\x5f\x65\x10\x89\x62\xc0\xd8\ +\x92\x18\xdf\x83\xe7\x74\xc0\xa5\xbc\x5d\x09\x68\x74\xdb\xa0\xfe\ +\xcb\xb1\x73\x28\xb8\x83\x36\xb3\x60\x31\x76\x2e\xaa\x4f\xd8\x70\ +\x26\x84\x2c\x45\x74\x43\x3d\x6e\x1a\x44\xa9\xa3\x6a\x58\x43\x3d\ +\x8d\x15\x95\x38\x4c\xc9\x60\x04\xe9\x16\xe1\xe3\xdb\x05\x41\x5c\ +\x28\x85\xd1\xd2\x68\xa2\xe8\xc5\x80\x31\xac\x72\x32\xc0\x65\xf8\ +\x38\x2e\x64\x04\x49\xb3\x32\x12\x70\xcd\x53\x07\x3a\x0d\x37\xee\ +\x22\xf6\xd9\x74\xc0\x8b\x60\x37\x44\x06\x92\x32\x33\x23\x38\x4f\ +\x7f\xd9\x44\xa8\xd0\x7e\x34\xa3\x78\x7e\x76\x2c\x57\xe4\xe3\x61\ +\x84\x98\x91\x61\xa4\x8f\xef\xa3\x7b\x05\xc3\x62\x95\x6d\x7e\x42\ +\x57\x38\xbe\x8b\x1e\xec\x7e\xa3\x9c\x1b\x07\xed\x7e\x4b\x4a\x73\ +\xc3\x87\x3c\xe1\x1d\xf4\x0a\x66\xcb\x9f\xd4\x77\xa3\xbc\x18\xdf\ +\x9d\x14\x6a\x16\xcc\x38\xd2\xda\x8e\x5d\x34\xef\x06\xdb\x05\xb3\ +\xcd\x41\x6c\x3c\x2a\x38\x9f\xb8\x83\x29\xd2\x08\x77\x20\x55\xc5\ +\xf6\x01\x43\xe9\xf4\x1c\xe7\x05\x40\x07\x1a\x95\x50\xd2\x8a\x56\ +\xe6\xc8\x3e\x83\xfe\x8e\x27\xcf\xe2\x97\x63\x7e\xa4\xd5\x75\xb4\ +\xd5\x5a\xd1\xca\x0e\xa8\xb5\xd2\xb6\xf0\x1e\x30\x92\x95\xb6\x53\ +\xb2\xe6\x59\x64\x6b\x20\xa4\xb6\x1f\xa2\x84\xaa\x01\x03\xd9\xa6\ +\x37\x9a\x33\x29\xae\x0c\x25\x75\x6e\x5c\x88\x0f\x24\x73\x66\x55\ +\xaf\x48\x02\x42\x55\x1d\x21\x67\x75\x19\x19\x2a\xa3\x63\xb5\x07\ +\x5d\x08\x15\x66\x50\x22\x0a\xe3\x48\x92\xa8\x38\xc3\x86\xce\x33\ +\x80\x43\xee\xdd\xe0\x81\xd9\xc5\x0c\x1e\x59\x16\x0e\x60\x29\xbe\ +\x1b\x3b\x0d\x97\xaa\x35\x32\xf1\x49\x8a\x83\x0d\x1a\x3a\x97\x7c\ +\x03\xe8\x2f\xef\x06\xcf\x34\xcb\x30\x18\xbc\x7e\xd6\x7d\x03\x06\ +\xe1\x7b\xc1\x53\x12\x6e\x98\xc0\x52\x93\x32\x2e\x8c\x99\xf6\x12\ +\xa8\x3a\x26\x03\x48\xb8\xdc\x14\x31\xf1\x29\x1f\xe8\xfd\xc4\xb2\ +\x93\x74\x99\x29\x10\xcb\x7f\x37\x7c\x01\xa4\x73\x32\x7c\x44\x2a\ +\x27\x46\x6c\x82\xa6\x5e\x2c\x12\xe3\x27\x21\x8b\x4d\x02\xce\xc3\ +\x98\x0b\x6f\x2c\xeb\x66\xf0\x88\xe6\xbc\x18\xc3\x79\x90\xad\x67\ +\xd5\xd0\x28\x70\xe8\x31\x78\x04\x73\x1e\x10\x0a\x44\x19\x7b\x8c\ +\x1e\x9d\x97\x05\x61\xeb\xc1\x5e\x96\x48\x48\xad\x68\x1a\x22\x0c\ +\x1a\xba\x10\xa7\x6a\xc2\x5e\x16\x06\x8f\x2e\x66\x1b\x61\x7c\x64\ +\xa0\xc6\x92\x08\x2b\x34\xb5\xe2\xa0\x10\x89\x9b\xa5\x7b\x2f\x0b\ +\xe3\x47\xb7\x96\x09\xa3\xb3\x80\xcc\x17\x8a\xc0\x4a\x4e\xc6\xee\ +\xfc\xbc\x07\x2e\xae\xc7\x71\x1e\x83\x47\x17\x5d\x00\x16\x2c\xe1\ +\xa2\x0b\x6c\xa8\xd3\x46\x17\x30\x9e\x16\x90\xfb\x18\x40\xb2\x24\ +\xec\xce\x5d\x9c\xac\xb3\x10\xa6\x94\x75\x1e\x98\x65\xf4\x08\xe3\ +\x7a\x08\x95\x13\x8e\xeb\xb1\xb5\x4e\x19\xd7\xf3\x11\x99\x80\x70\ +\x60\x8f\xf1\xa3\xca\xe1\x44\xcd\x7b\xa0\x9b\xd3\x08\x63\x05\x67\ +\xc0\x3a\x0b\x01\xf3\xc5\xd0\xe2\x3f\x9c\xa3\x93\xe1\xa3\xcb\xe3\ +\x44\x99\xeb\xdf\xaa\xb8\xcd\xf1\x21\x8a\x20\x03\xd8\x71\x19\x6b\ +\xf0\x31\x7e\x74\xd9\x9c\x98\xc9\x0f\x56\x5c\x58\x7a\x12\xe7\x73\ +\x76\x6f\x3b\x30\x84\x94\x19\x9d\xd0\xd2\x4c\xac\xd3\x93\x45\x28\ +\x65\x52\x27\x4a\x88\x86\x90\x0a\x4a\x89\xa0\x3b\x7b\xc0\x8d\x0a\ +\xaa\x75\xb5\x80\x1a\x83\x6b\xd1\xcb\xcd\x08\x49\xab\x16\x6a\x74\ +\x6f\xd7\x03\x00\xdb\x2e\x30\x0c\xe0\xf9\xf5\x50\x30\x5d\xa9\x83\ +\x2e\x5a\x0e\x54\xc6\x8f\xa8\xde\x24\xba\x4b\xf6\xa1\x0c\x65\xf4\ +\x68\x42\x47\x60\x4d\xbb\x0e\xb8\x8f\xe7\x40\xda\x46\x84\x68\x06\ +\x04\xfb\xb9\xfa\x4d\x68\x97\x51\xa4\xe9\x44\x88\x56\x65\x0e\x57\ +\xf8\x31\x7e\x84\x9d\xeb\xba\x6d\xe6\x1a\x57\x2e\x52\x2a\xf4\x06\ +\x5d\x96\xa7\x6e\x0b\x82\x2e\xd4\xab\x84\xf6\x13\x3f\xd9\x63\x42\ +\x2d\x94\x31\x86\x4b\xd7\xd1\x58\x83\x06\x5d\xf9\xdc\x4e\x85\x49\ +\x14\x44\x81\x3e\x50\x48\x23\x23\x43\x43\x54\xa5\x77\xc0\xa2\xb4\ +\xec\x59\xa7\xf0\x5d\x40\xd9\xa8\xef\x55\x9a\x6a\x7c\x73\x6c\x48\ +\x25\x8d\x44\x58\xd2\x8a\xa8\x03\xc1\x80\x61\xac\xea\x47\x82\xab\ +\x38\x71\xa6\x3d\x2b\xa5\xc4\x0e\x6e\x83\x37\x2b\x40\x1b\x9f\x81\ +\xa4\xec\xb1\x04\x76\xca\x3a\x09\xc5\xb6\x91\xf9\x0e\x8a\xba\xea\ +\xa7\x1c\x90\xd4\x11\x19\x34\x8a\x95\x7e\x1a\xe1\x99\x31\x11\xaa\ +\x9a\x02\x19\xc6\xde\x62\x16\x60\xd2\x3d\xbe\x4d\x3d\x6b\xa9\xe4\ +\xa1\x0b\x1f\xaf\xa8\x42\xb3\x23\x23\x49\x1b\xc6\x88\xf0\x8a\x2a\ +\x98\x53\xca\x4a\x0e\x69\x20\x23\xc6\x87\x12\xf7\xd4\x1b\xb6\x17\ +\xa9\x43\x18\x0a\xaf\xe0\x18\x21\x8f\xe4\x29\x03\x49\x1b\xcb\x00\ +\xd3\xf3\x4f\x33\x37\x0e\x9a\x64\x07\x82\x9d\xa7\x67\x17\xa2\x65\ +\xcf\x0f\x4e\xc6\xf8\x78\xc8\x95\x6e\xef\x0e\x92\x11\x39\x17\xaa\ +\x2f\x27\x8d\xf3\x97\x26\x78\xb3\x90\x13\x31\xfa\x0f\x5e\x74\xc0\ +\x87\x9c\x88\xd1\x63\xd4\x22\x3c\x8f\x4d\xcf\x59\x6d\xd4\xa1\x0b\ +\x8d\x67\xc4\x37\xaa\x72\x31\x90\x84\xa1\x0b\xb0\x07\x1d\xfb\xd8\ +\x3e\x0e\x8c\x75\x6e\x4d\x74\x1e\x76\x24\xc5\x71\xd0\xab\xd6\xaa\ +\xe0\x45\x84\xd7\x52\xa1\x18\x14\x9b\x19\x94\x71\x0b\x70\xfd\x76\ +\x07\x53\x23\x83\x48\xe3\x62\x53\xdd\xfb\x69\x28\xb5\x9a\x41\x8b\ +\xd1\x2a\xe4\xe4\xe3\x67\x43\x50\x8c\xb2\x72\x4a\x1a\x72\xea\x20\ +\x23\x03\x0a\x58\xb0\xcd\x4f\x1e\x79\x02\xeb\x58\xe2\x53\xa4\x18\ +\x49\xda\xd0\x93\x44\xab\xa7\x20\x8c\xc4\xeb\x69\x06\x0c\xe3\xb6\ +\xcd\x75\xc2\xb1\xa8\x8f\x88\x5f\x80\x76\x9f\xb6\x16\xfd\x0e\x76\ +\x2a\x68\x8a\x7e\x31\x80\x67\x67\x40\xb0\xc3\xfc\x69\xac\xe7\x03\ +\x85\x9d\x19\x43\x3a\xe5\x14\x9f\x0b\x95\x88\xa8\x24\xc9\x5e\x1e\ +\x86\x8a\x45\xec\x78\x93\x2b\x0c\x91\x28\xa6\x1a\xaa\x52\x7a\x1a\ +\x23\xca\x06\x30\x46\xb1\xaf\xa6\x4c\x78\x8f\x29\x28\x4d\xb5\x88\ +\x18\x3f\x92\x58\xa2\x8f\x2f\x33\x74\xa0\x8a\x32\x78\x44\x01\x0b\ +\xb0\xcc\x25\x3e\x7a\xc8\xaa\x0c\x71\xcc\x42\x75\x5e\x6a\x8f\x21\ +\x24\xf4\xcc\xf8\xe8\x39\x10\xb6\x0a\x59\x8c\xd2\x78\x64\x3a\xa8\ +\x2e\x04\x8a\x51\x32\xfc\x06\x5c\xdb\x24\x29\x6b\xcd\x02\xe2\xf3\ +\xa4\xca\x26\xa0\x5b\xd4\xe2\xa7\x42\xfb\x61\x10\x29\xa6\x41\x0d\ +\xe7\x96\x9e\x06\x63\x20\x64\xac\x63\x7d\x28\x46\x19\x46\xb2\x5c\ +\x28\xdf\xd9\x84\x48\x18\xad\x45\xe8\x9b\xd0\x84\x87\xfe\xb5\x24\ +\xf4\x63\x9a\x02\xec\x83\x86\x31\x29\x33\xbd\xc1\x18\xfe\x69\x30\ +\x86\x22\xb4\x28\x9a\xc3\x49\x91\xb9\x91\x50\xa8\x3a\x23\x11\x5d\ +\xbc\x2d\x16\x81\x95\xaa\x31\xcf\x8e\x3d\xba\x69\xea\xea\x0a\x58\ +\x28\x8d\x30\x52\x49\xa5\x58\xb4\xf6\x18\xff\xf5\xc0\xd5\x50\xa7\ +\xa9\x3a\x52\xc4\xca\x21\xd9\x23\x90\x03\x36\x1b\x93\x00\xee\xaa\ +\x7d\x92\xd5\xd8\xe6\x5d\xb0\xe7\xa6\xaf\x85\xa5\xf8\x6a\x7c\x30\ +\x8a\x1c\x84\xa2\xad\xc6\x17\xa0\x7d\x38\x70\x48\x98\x7d\x70\x74\ +\x0a\x4e\x07\x69\xc3\x60\x40\x98\x31\xa4\x09\x47\x45\xf6\xdf\x59\ +\x6a\x9b\xf2\x9c\x48\xbe\x88\xa6\x8b\x95\x89\x20\x33\x32\x94\x84\ +\x29\xc3\x60\xcd\xef\x0e\xb4\x1b\x96\xa8\x54\xb6\xa2\xc2\x67\x67\ +\x80\x12\x95\x11\x24\xb3\xf6\xb5\x2b\xc2\xf7\xb1\x95\xd3\x01\xbb\ +\x6c\xaa\x00\xa3\x82\x72\x15\x3b\x70\xa2\xb2\xe7\x8d\x38\xc4\xd8\ +\x41\x90\x11\x8c\x15\x33\x90\xc4\xd1\xa9\x18\x32\xf8\x4f\xe3\x48\ +\x29\x74\x90\x04\x09\xfb\xc2\x7b\x8e\x4f\x81\x0b\xf6\x3b\x08\x35\ +\x52\x42\x39\xe8\x55\xdf\x89\x17\xa3\x3a\xae\x5b\x15\x15\x74\xdb\ +\x24\x7e\x18\x93\x68\x38\x83\x46\xcf\x31\xa2\xc2\x34\x5c\x97\x11\ +\xb0\xca\x9b\xe1\xa3\x5c\x85\x91\x60\xda\xad\xc3\xd9\x8b\xa1\xf0\ +\xe3\x48\xd2\xb4\x67\x1b\x34\x80\x95\xfb\x1b\xb4\x11\xdf\x8d\x60\ +\x5c\x75\xb9\x08\x19\xc1\x7e\x5c\x6d\xa0\x36\xfa\x6e\xf4\x54\x95\ +\xfe\xcd\xe8\xf5\xe6\xa6\x31\x90\x7d\xff\x6e\xfc\x12\x48\x7d\x39\ +\xc6\xef\x6e\xf7\xf6\x77\x41\xa0\xdb\x31\x53\xe4\xd3\xf5\xe6\x36\ +\xcb\x57\xd7\xe3\xd5\xb4\xc8\x17\x2f\x7f\xf4\x85\x36\xb1\xbe\xf0\ +\xdd\x7f\x22\x0e\xc3\x38\x91\x51\x7c\xa1\x13\x61\x94\x8c\x4d\x74\ +\x61\x84\x7d\x0a\xad\x13\xfd\xd3\xf8\x73\x7d\x95\xbd\x01\x02\x5f\ +\x33\xd6\x26\x49\x4c\xa4\xec\x35\x23\x2d\xfd\x44\xa9\xe0\xc2\xb3\ +\x9b\xe3\xd8\x6a\xd5\x52\xba\xcd\x2a\x91\x2a\x52\xc6\xdd\xf7\xa7\ +\x71\x7b\xb5\xfc\xb5\x74\x4d\xd9\x81\x1a\x05\xc9\xee\x76\x67\x12\ +\x5b\xed\x3b\x8a\x64\x2c\x77\xb6\xbb\xba\xe6\x46\x84\xbe\x4a\x76\ +\x0c\xac\x92\x5c\x9e\x53\x0d\xb4\x8c\x77\x9c\x59\x2d\x85\x8d\x30\ +\x3a\xf1\xb5\xd9\xdd\xd7\x00\x12\x8a\xc8\xd8\x57\xd7\x3b\xbb\x1a\ +\x20\xed\x5d\x5c\x3b\xaf\x60\x67\x57\xcd\x21\xd5\x00\x4f\x93\xe9\ +\x8d\x8c\xde\x1e\xe0\xe9\x53\xba\xce\xe6\xf3\xed\x00\x97\x66\x1e\ +\x59\xcb\x0c\x1e\xe0\xef\x1f\xb6\xdb\x5b\x6d\x07\xc1\xbb\x50\x4a\ +\x54\x28\x75\x94\xc4\x16\x8e\xc0\x28\x5f\xaa\x44\x97\x28\x39\xbc\ +\xa4\x31\x6e\x40\xf8\x61\x62\x74\x10\xc2\x28\xc5\x46\x6b\x65\xcc\ +\x01\x4a\xd2\x5e\xd7\xb7\xdb\x93\x7d\x94\x12\x11\xd9\xa1\x28\x75\ +\x78\x80\x52\xa8\xed\x5d\x7c\x3b\xda\x01\x94\xa4\x16\xbe\x1d\x8e\ +\x3a\x00\x50\xb2\x56\xb5\x7d\x5e\x23\xdf\x46\x29\xfe\x80\x30\x39\ +\xc2\x5a\x96\xb4\xe6\xa4\x1d\xe6\x87\xe3\xdf\x0e\x4c\x99\x44\x3a\ +\x50\xfb\x94\x3d\xae\x7e\x54\x51\x36\xd2\xb5\x8b\x17\xa0\x6c\x58\ +\x3b\x97\x92\x63\xca\xb6\x39\x25\x6f\x53\xd6\x33\xc3\x20\xad\x77\ +\xec\x10\x3f\x3b\x6d\x3f\x26\x65\x03\x61\xfc\xd0\x8a\x4d\x7d\x40\ +\xd8\x40\x68\x1d\xe8\x38\x89\xde\x4b\x58\x53\x52\x2f\x06\xe8\xba\ +\x07\x4e\x43\x50\x79\xa8\x91\x1e\x12\xf4\x23\x90\xf3\x61\x5a\xdc\ +\xef\x3c\x66\x36\x5f\x3c\xd8\x7f\xf6\xbc\x79\x5a\xbc\x3e\xa4\x1b\ +\xab\x80\xbd\xf1\xd9\x7d\xed\xf5\x97\x8d\xd5\x87\xd2\xc9\x2c\x5b\ +\x5b\xcd\xa8\xc8\x72\x6f\xf6\x98\x3f\x4d\x8b\xc7\xdc\xbe\xb4\xff\ +\x06\x81\x76\x36\xdb\xad\xab\x91\xb5\xf1\x44\x50\xc6\x85\x2e\x3c\ +\x69\x27\x80\xd1\xd3\x48\x0a\x39\x0a\x54\xf9\x75\xbf\xfb\xe3\xdf\ +\x23\xd7\x61\x64\xf4\xb7\x91\x17\x68\xa1\x2e\x1a\x87\x75\x3c\x72\ +\x32\xbd\x8a\x05\x5e\x34\x2b\x0e\x03\x7b\x1d\x2f\xda\x39\xda\xdb\ +\x46\x7c\xcb\x0d\xb2\xbe\xa5\x1d\x16\xee\xc8\xea\x5e\xe5\x97\x67\ +\xef\xf6\x75\xb4\x1a\x29\x77\x0b\xa1\xec\x66\x65\x95\x13\x77\x9d\ +\xd0\x5c\x6c\x83\x58\xf6\x61\xdc\xa9\xcb\x91\x5b\xe6\x5f\xde\xf0\ +\xc2\xe5\x05\xb8\x8b\x94\x87\x7f\x3d\x1e\x06\xfb\x3a\xed\x6d\xb6\ +\x2e\xbc\x72\x8f\x25\x7b\xbe\x9a\x2e\xab\x2d\x4f\xd3\x7c\x31\x5d\ +\x17\x7b\xdb\x9e\xcb\xf1\xb8\xb7\xc9\x82\x9b\x16\xb3\xfb\xfd\x6d\ +\x8b\xaf\xe9\x64\x95\xce\x17\x8f\xab\x4f\x4e\x2f\xf5\xee\x8f\xcf\ +\xbb\x9d\xae\x16\xcb\xd7\xc9\x3f\xed\xdc\xfc\xc9\x6b\x00\xf4\xaa\ +\xd3\x1f\xd2\xd9\xe2\x76\x31\x9b\x16\x8b\x6c\x5d\x1d\x51\xa4\x2f\ +\x85\x3d\x6a\x9e\xae\x9d\x7a\x5a\xfe\x9a\x2e\x17\x77\xeb\xc9\xa6\ +\x98\xe6\x45\xb5\x61\x9e\xce\xb2\xbc\x3a\xa7\x1c\x76\x07\x1b\x4b\ +\x0d\xb9\xda\xb3\x4c\x0b\x3b\x68\xed\x7d\xec\x80\x5c\xdf\x35\x8f\ +\xf5\x9c\xe5\xf3\xc3\x6d\xe5\x35\xb6\x0a\x44\x75\xf6\x73\xbe\x28\ +\xec\x21\xde\xca\x8e\xd1\xc9\x32\xf7\x8a\x1b\x6b\x16\xb8\x41\xe5\ +\xee\xbc\x2c\xf2\x4f\x37\xd3\x4d\x5a\xbe\xf6\xe6\x7e\x71\x5b\x4c\ +\x9a\x9f\xf5\x63\xaf\x67\xf7\x96\xf8\xd5\x73\xff\x66\x73\xa2\x66\ +\xc9\xf7\xb2\xf0\x2e\x1b\x56\xfc\xab\xdc\x3a\x2e\xab\xf7\x98\xe0\ +\xfd\xba\xfd\x9b\x6c\x7b\x1a\xff\xb9\x73\x83\x64\x4f\xfc\x55\xfc\ +\x17\x26\xd5\x98\x8e\x2f\x5a\x0e\x99\x8d\x2c\xeb\x5c\x34\x1d\x98\ +\x82\x6f\xfd\x7a\x4b\xdc\x19\x30\x42\xde\x08\xb7\x5b\xc0\xd0\x92\ +\xc2\x84\xb1\x56\xbe\x09\x1e\x5e\x4e\xb7\xb9\xde\x21\xe7\x7e\x13\ +\xc1\xa2\x63\x82\xa9\xba\xb0\xc7\x1e\xc1\xbc\x7d\x1a\x7d\xf3\xe7\ +\x5b\x34\xf3\xfd\x28\x90\x47\xe3\xeb\x5b\x34\x53\xb5\x26\x16\x86\ +\xdf\x13\xcd\x42\x4f\x7d\x63\x98\x79\x81\x95\xaa\xdb\x11\x76\xf8\ +\xfd\xbb\x1f\x4f\x9e\xfc\xc6\x88\xaa\x69\xd3\x0c\x97\xe3\x3f\x06\ +\x30\x74\x00\x02\x05\x49\x9d\x5d\x67\x75\x84\x3a\xfb\x2e\xd8\x0e\ +\xa1\x20\x71\x9f\xf8\x5b\xbf\x06\x30\xa8\x20\xaa\x05\x5b\x96\xdb\ +\xa5\x9a\xb7\x4f\xa8\x6f\xfe\x1c\xc2\x70\x8b\x8f\x08\x17\xcb\x76\ +\xb8\x29\xab\xcc\x0d\x59\x58\x79\x80\xc6\xae\xdb\x71\x55\x91\x67\ +\xd8\xf2\xea\x98\x42\xb1\x6f\xdf\xde\xd5\xfa\x1e\xf6\xd0\x39\x56\ +\x36\xa3\x2d\x59\x86\x3d\x64\x8e\xf5\xa3\x76\x8a\xdb\xba\xd7\x86\ +\x3d\x78\x8e\x15\xef\x76\x3e\xdb\x25\xd1\x47\x1c\x48\x57\x97\x77\ +\xee\x8f\xf2\xeb\xea\x72\xf3\x64\xbf\xfe\x1f\x0e\xa2\x7a\x19\ +\x00\x00\x08\x5d\ +\x00\ +\x00\x5c\xbe\x78\x9c\xe5\x5c\x59\x8f\xe3\xb8\x11\x7e\xef\x5f\xa1\ +\x68\x10\xec\x0e\xd2\xba\xa8\x5b\x6d\x7b\x81\x64\xb0\xc0\x22\x9b\ +\x97\xec\x06\x79\x5c\xb0\x25\xda\x2d\x8c\x0e\x83\xa2\xdb\xf6\xfc\ +\xfa\x14\x75\xdb\x6d\x6a\x73\x34\xa7\xd3\x1c\x0f\x66\x7a\x54\x55\ +\xbc\xbe\x2a\x92\x9f\x4b\x6c\xae\x7e\x38\x95\x85\xf6\x4c\x68\x93\ +\xd7\xd5\x5a\x77\x4c\x5b\xd7\x48\x95\xd6\x59\x5e\xed\xd6\xfa\x3f\ +\x7e\xfd\xd1\x88\x74\xad\x61\xb8\xca\x70\x51\x57\x64\xad\x57\xb5\ +\xfe\xc3\xe6\x6e\xf5\x07\xc3\xd0\xfe\x42\x09\x66\x24\xd3\x8e\x39\ +\x7b\xd2\x7e\xaa\x3e\x37\x29\xde\x13\xed\xfb\x27\xc6\xf6\x89\x65\ +\x1d\x8f\x47\x33\xef\x85\x66\x4d\x77\xd6\x47\xcd\x30\x36\x77\x77\ +\xab\xe6\x79\x77\xa7\x69\x1a\xb4\x5b\x35\x49\x96\xae\xf5\xbe\xc0\ +\xfe\x40\x8b\xd6\x30\x4b\x2d\x52\x90\x92\x54\xac\xb1\x1c\xd3\xb1\ +\xf4\xc9\x3c\x9d\xcc\x53\xde\x7a\xfe\x4c\xd2\xba\x2c\xeb\xaa\x69\ +\x4b\x56\xcd\x87\x99\x31\xcd\xb6\xa3\x35\xef\xcd\xd1\x6d\x8d\x9c\ +\x38\x8e\x2d\x1b\x59\x08\x19\x60\x61\x34\xe7\x8a\xe1\x93\x71\x59\ +\x14\xfa\x78\xab\x28\xb2\x6d\xdb\x02\xdd\x64\xf9\xef\x59\x25\x0d\ +\x00\xba\x87\xbf\xa3\xf9\x20\x30\x9b\xfa\x40\x53\xb2\x85\x72\xc4\ +\xac\x08\xb3\x3e\xfd\xfa\x69\x54\x1a\xb6\x99\xb1\x6c\x56\xcd\x80\ +\xe7\x45\xab\x17\x20\x57\xb8\x24\xcd\x1e\xa7\xa4\xb1\x06\x79\x5b\ +\xfe\x98\x67\xec\x69\xad\xbb\x9e\xe9\xb8\xf0\xf1\x5b\xe1\x13\xc9\ +\x77\x4f\xec\x5a\x9a\x67\x6b\x1d\x7a\x8f\xe2\xa8\x7b\x9e\x05\x87\ +\xd3\x19\xf4\x15\x27\xa3\xc6\x36\x63\x64\x3a\x1a\x75\x7c\x37\xec\ +\x6c\x86\x21\x24\x59\x9d\xf2\x3e\x41\x95\xa4\xcc\xf1\x81\xd5\x25\ +\x78\x2d\x4d\x0b\xdc\x34\xf9\x36\x4f\xe1\xa1\xae\xf6\xc5\x61\x97\ +\x57\xbf\x7d\x2e\x8b\xdf\x70\x96\x99\x03\x74\x63\x3b\xe4\xb4\xaf\ +\x29\x33\x4e\xd9\x1e\x00\x0c\xc2\x9b\xca\xf3\xa0\xdc\x80\x76\x95\ +\x91\x6d\xc3\xad\xba\xd1\xf0\x27\x18\x4e\xa8\x6b\x56\xab\x1d\x3b\ +\xc7\x7b\x96\x3d\xe7\xe4\x38\xd9\x3e\xe2\xa6\x43\x4c\xd3\xf6\x78\ +\x07\xd1\x55\xd4\x74\xad\x7f\xd8\xb6\x9f\x5e\xf1\x58\xd3\x8c\xd0\ +\x41\x15\xb4\x9f\x0b\x55\x0d\x1e\xc8\xd9\xb9\x9b\x4f\x7d\xdd\x43\ +\x7f\x79\xad\xa3\xde\xbe\xad\x6f\x9e\x70\x56\x1f\xd7\x3a\xba\x56\ +\x7e\xa9\xeb\x12\xfc\x65\xc6\x7e\x6c\x23\x3b\xbe\x56\xa7\xa7\xb5\ +\x6e\x38\x1e\xb4\xea\xc2\xbf\x2f\xb4\xd0\xa0\x17\x9a\x76\x80\xe2\ +\xde\xd5\x73\xe5\x81\x52\x98\x71\x46\x81\xcf\x04\x46\xd5\xfe\x18\ +\x6a\x68\x9e\xea\xe3\x8e\x72\x74\x18\x3d\x90\xeb\x92\x5c\x63\x3c\ +\x3e\xd6\xa7\xdb\x6a\x08\x80\x03\x9f\xcb\xc6\xa1\xca\x19\xcc\x97\ +\xfd\x69\x5e\xeb\x21\xcf\x08\x08\xb7\xb8\x68\x5e\x94\x3c\xe6\x15\ +\xa0\x60\xf4\xa1\xeb\xb8\x23\xc8\xd7\x16\x43\x1c\x87\x76\x24\xb0\ +\x80\xbe\xbd\x00\xba\x57\x9d\xc5\xaa\x12\x9f\xf2\x32\xff\x42\x60\ +\xe0\x4e\x1b\x57\x10\x3b\x17\xc3\xee\x8a\x69\x1a\x3b\xf3\x39\x79\ +\x3a\x73\x99\x3e\x08\x39\x5e\x5c\xe0\x86\x81\x3f\x0a\x6b\x9a\x43\ +\xa8\xcf\xba\x33\x88\xce\x73\x11\x9f\xc1\xb0\x00\x9f\xda\x00\x6a\ +\xc3\x2b\xbc\xd6\x9d\xe7\xba\x3e\xae\xad\x97\x81\xdd\xca\x4b\xc2\ +\x70\x86\x19\x9e\xa2\x7c\x90\xa0\x38\xb6\x87\x91\xc1\x62\x98\xfc\ +\xfd\xd3\x8f\x9b\xbe\xa1\x55\x9a\x26\xff\xac\xe9\xe7\xa1\x5d\x4d\ +\xe3\x06\xf8\xb1\x3e\x00\xd2\xfa\x66\x14\xaf\xb2\x34\x81\xe5\x0b\ +\xa6\xf5\x26\x2f\x21\x76\xf9\xca\xf7\x27\x58\xae\x56\xd6\xa4\xb8\ +\x30\xe6\x60\x4d\x95\x76\xd5\x52\xd2\xad\x83\x37\x37\x83\x2c\x2d\ +\x73\x5e\xc8\xfa\x85\xe5\x45\xf1\x13\x6f\xa4\x1f\xf1\xac\xd2\x9c\ +\x15\x64\x12\xae\xac\xbe\xf7\xfd\xd8\xac\xd9\xe0\x56\xd6\x30\xfa\ +\xf6\x69\x37\xa1\x72\x11\xf4\xa3\xa3\x0b\xfc\x48\x8a\xb5\xfe\x33\ +\x57\x6a\x2f\xb4\x3b\x5a\x1f\xf6\x65\x9d\x91\xbe\xf8\x80\xe6\xee\ +\x22\x0c\xbc\xd0\x46\xa3\x07\x19\xc5\x55\xc3\x91\x01\x3f\x60\x46\ +\xf3\xd3\xf7\x8e\x09\x7b\x46\x18\x7a\xd1\xbd\x6d\xa2\xc8\x0b\x42\ +\xe4\x85\xf7\xb0\xfa\xfb\x0e\x8a\x1d\x58\xb8\x40\x0c\x7e\xf6\x5c\ +\xcf\x8f\xef\x23\x64\xda\x20\x0c\xd1\xbd\x8b\x4c\xb0\x0b\x1d\xff\ +\xe3\xe8\x8e\x15\x25\x29\x9b\x79\xac\x8d\x12\x0f\xf1\x8f\xab\xcf\ +\xe4\x17\x01\xa8\x69\x67\xbe\x6c\xb4\x6d\x04\x41\x3c\x93\xf3\xe5\ +\x24\xb4\x4d\x0f\x36\xb4\x59\xff\xa7\x8d\xc3\x33\xd1\x8b\x32\xfd\ +\x74\xbd\xa5\xe2\x50\xf0\x0e\xfa\x91\x3b\x17\x37\xec\x5c\x00\x7c\ +\x5b\x70\x6e\xf2\xc1\xb6\xd3\x74\xbb\x7d\xe0\x0f\x46\xbf\x4c\x26\ +\x4e\xf7\x48\x0f\x05\x2c\xf7\xcf\xa4\xaa\xb3\xec\xa1\x61\xb4\xfe\ +\x4c\x92\x7e\x61\xee\x1f\xbb\xb5\x22\xb1\x87\x47\x88\x1b\x42\x0b\ +\x98\xc3\x2c\xf1\x06\x59\x86\x61\x75\xa5\x14\x9f\x93\x0a\x08\xcd\ +\x20\x1d\x9b\x9a\x45\x96\x04\x30\x83\xa0\xdb\x69\xe3\xd7\x05\xd3\ +\x70\xc4\x70\x62\x9c\x79\xca\xc2\xe9\x98\xd1\xb5\xfc\x55\xe0\x34\ +\x22\x31\xa0\x41\x10\xd9\xaa\x02\xea\x87\x66\x20\x61\xb2\x03\xa0\ +\xb6\x18\x50\xcf\xf3\x7d\x65\x01\x75\x4d\x3e\xdf\xdd\x57\x07\xd4\ +\x15\xe1\xb9\xdd\x22\x8c\xb0\xaa\x78\x7a\x71\x4f\x7a\x5e\x3d\x40\ +\xc3\x6f\x14\x50\xcf\x8c\xf8\x8c\x77\x5f\x7f\x09\x35\xfc\x6f\x14\ +\x52\x20\x6e\xed\xa4\x7f\xfd\x45\xd4\x50\x7d\xda\x7b\x66\x3c\x65\ +\x22\x26\x48\xa5\xf1\x26\xc3\x53\x9c\x39\x89\x00\x95\xc7\x9c\x96\ +\xc8\xa8\x12\xdc\x49\x00\xa9\x44\xee\x24\xde\x9c\x14\x61\x4f\x22\ +\x48\xa5\xb1\x27\x23\x10\x2f\xa4\x71\xac\x2e\xa2\x12\xf9\x93\x81\ +\xbe\x51\x48\x65\x32\x28\x43\x98\x28\x51\x03\x54\xd4\xed\xeb\x1e\ +\xba\x02\x55\x52\xd6\x69\xe9\x7b\xbd\x0a\x79\x27\x11\x9c\xf2\xf8\ +\x53\xb4\x80\xa8\x0a\x04\x4a\x88\xa8\x44\x02\xb5\x90\x1c\x55\x81\ +\x40\x89\x20\x95\x49\xa0\x84\xdb\xbd\x1a\x04\x4a\x08\xa9\x3c\x02\ +\x25\xdc\xed\xdb\xcd\x50\xd9\x20\x95\x49\xa0\x84\x5f\xee\x15\x87\ +\x54\x2a\x81\x12\xee\x4f\x8a\x83\x2a\x33\x09\x25\xfe\x3e\xaa\x06\ +\xa8\x41\x47\x3e\xed\xe0\x0a\x54\x59\xac\xd4\x5e\x4a\x43\xa9\xc0\ +\x4b\x45\x80\x4a\xcc\xeb\x89\x37\x28\x35\x88\xa9\x10\x52\x99\x99\ +\x3d\x71\x4a\x5f\x0d\x6a\x2a\x02\x55\x6a\x6e\x6f\x89\xef\xab\x40\ +\x4e\x85\xa0\x4a\xcc\xee\x89\x67\x7f\xe6\xa9\xbc\x43\x49\xcd\xef\ +\x89\xb7\x7d\xc5\x41\x95\x9b\xe1\x13\x9f\x8d\x50\x1c\x56\xa9\x14\ +\x15\x89\xdf\x43\x29\x01\xeb\x57\xe7\xa8\xc2\x6f\xa7\x7c\xe3\x57\ +\x16\x4e\x79\x0c\x55\x98\x92\x52\x1b\x4f\x89\xf4\x54\xb8\x3d\x29\ +\x8d\xa8\x4c\x6e\x2a\x4c\x9e\xa8\x8d\xa8\xc4\xac\xe9\xc2\x9b\x7c\ +\xd7\x7d\xf7\x5f\xa0\xde\x82\x96\x2e\x7c\x25\xf5\x3c\xfc\xde\x8f\ +\x44\xbd\x0d\x27\x15\xee\xf5\x08\x87\xdb\x77\x9f\x8e\x7a\x1b\x42\ +\x1a\x8a\xd3\xfb\x21\xc6\x19\x79\xe7\xa0\x7e\xed\x37\xf9\x0b\x87\ +\xa2\x78\xd2\xe4\xdd\x6f\x4e\x5f\xff\x55\xbe\x27\xa6\xa4\x6a\x23\ +\x2a\x37\x63\x2a\xdc\x9f\x94\x06\x55\x6e\xc6\x54\xf8\xba\x44\x6d\ +\x4c\x65\x26\x4c\x17\x68\x94\x02\xc4\xf4\x2d\x5e\xe7\xa3\xe5\x53\ +\x27\xef\x9e\x9a\xbe\xcd\xfb\xfc\x58\x71\x72\xfa\x36\x2f\xf4\x91\ +\x38\x09\xad\x04\x3b\x1d\x0e\xef\xba\x57\xa8\xca\x3c\x18\x29\x4e\ +\x40\x3f\xa6\x99\xeb\xbf\xf7\x40\x15\x42\x2a\xf3\x64\xa4\x98\xf4\ +\x2b\x8d\xa9\xd4\xa3\x91\xe2\x6d\x4a\x6d\x4c\x25\x66\xf9\x14\x67\ +\x53\x22\x48\xa5\x1e\x8e\x5c\x3a\x23\xa5\x00\x9b\x12\x62\x2a\xf7\ +\x74\xa4\x38\x52\x95\x60\x53\xc3\xef\xe8\x86\x57\xa8\x4a\x3c\xc9\ +\x27\xde\xf6\xa3\x08\xe3\x77\xff\xe5\x54\x84\xa8\xd4\xa3\x7c\x0b\ +\x07\x4e\x95\xc6\x54\x6e\x66\x6a\x81\xf3\xab\x8c\xaa\xe4\xc3\x7c\ +\x0b\xc7\xf8\x95\x46\x55\xea\x69\xbe\xa5\xfb\x63\x54\x20\x54\x02\ +\x50\x25\x1f\xe7\x5b\xfe\xbd\xf2\xf7\x4f\xa9\x44\xa8\xca\x3e\xcf\ +\x27\x8e\x56\xa5\x49\x95\xf4\x03\x7d\x0b\xd4\xea\xff\x25\x49\xb5\ +\xb2\x76\xc3\x7d\x8a\x33\x78\x6f\x5c\xf9\x77\x6f\xf3\x1b\xfe\x60\ +\x23\x8a\x62\xe4\xc1\x93\x19\xc6\xb1\x8b\xe2\x98\x2b\xec\x8f\xe3\ +\x38\xb9\x5b\x62\x33\x02\x55\xe0\x4f\x78\x73\xa7\x04\x66\xe0\x04\ +\x91\x1b\x4d\x04\xbe\xff\x2d\xf5\x20\x8c\xe2\x60\x5a\x86\xdb\x5b\ +\x24\x23\x2f\x70\x62\x7b\x32\x1d\xdc\x12\xf8\xa6\x1b\x45\x8e\x3d\ +\x55\xdd\x3b\xc5\xf7\x4d\x1f\xaa\xf7\xa6\x95\x67\x70\x89\x1b\x86\ +\x93\x1b\x2e\x9c\x40\x02\xfe\xe7\xd2\x09\x30\x44\xc7\xb3\x63\x37\ +\x0e\xfe\x43\x6f\xf8\x40\xd0\x5d\x3b\xb4\x3d\xff\x7f\x71\xcb\xd8\ +\xf9\xa5\xbb\x64\x6f\x19\x8c\xf7\xc9\x8e\x8e\x65\xe4\x34\xfa\xf3\ +\x54\x16\x49\x7b\xcd\xee\x5a\xdf\x53\xd2\x10\xfa\x4c\x5e\x40\x52\ +\x57\xcc\x68\xff\x0f\x5d\xa3\x25\x2e\x1e\x5a\xc9\xb1\x05\x3e\x79\ +\xac\x8b\xac\x13\x34\xf9\x17\x92\x38\xa8\x5b\x91\x6c\x27\xde\x9f\ +\x1e\x8a\xbc\x22\xfd\xa5\xa6\x89\xfd\xc7\xce\x6c\x8b\xcb\xbc\x38\ +\x27\x0d\xc4\x91\x01\xed\xe5\xdb\x07\x63\xe8\xb2\xd1\xd5\xb3\x27\ +\xe9\x78\xa3\x6e\xf2\xdd\x2f\x60\xa8\xfd\x19\x5a\xf9\xee\xa1\x20\ +\x0c\x80\x33\xfa\x8b\x43\x13\x1b\x5a\x38\xd6\x34\xbb\x10\x0c\xab\ +\xfe\xad\x83\xb1\x4b\x5e\x1a\xef\x20\x45\x62\xec\xbb\x6b\x4c\x63\ +\x3f\xf0\x23\x6f\x1e\xab\x08\x99\x21\xf2\x90\xeb\x5d\x84\x18\x87\ +\xd9\x0d\x63\x5f\xdf\xac\x18\xf4\xb0\x9a\x4d\xf8\xe1\x76\x53\x5a\ +\x73\x80\x39\x4a\x57\x2b\x46\x5b\x00\x0a\x5f\x2d\x4c\x2f\x5b\x17\ +\xb4\xff\x7b\xce\x7b\xc6\x34\xc7\x15\xfb\x1d\x87\x32\x4a\x58\xfa\ +\x74\x61\xd4\x39\xb9\x67\x48\xae\x8d\xae\x9c\xec\x98\xc8\xff\xef\ +\xdc\x3c\x19\xde\xf7\xde\x9e\x77\xd4\x28\xf2\x1d\x66\x07\x88\xd0\ +\x5b\xc3\x30\xa0\xd6\xdb\x8a\xea\x50\x42\x95\xe9\x85\x6e\x4b\xda\ +\x9a\xa0\x31\xc6\x20\x6a\xc6\x82\xdc\x5f\x06\x86\x86\xaa\xa4\x61\ +\x98\xb2\x87\x23\xcd\xb9\x81\xc1\x2f\x45\x4d\x0a\x6a\xb0\xc7\xde\ +\xa6\x4a\x9f\x6a\xda\x1b\xf5\x31\x35\x9f\xb4\xd7\x01\xa5\x6f\xfe\ +\xfa\xb7\x9f\x57\x56\xeb\xd3\x0d\xfc\x84\x3a\xba\xeb\x5b\x61\x81\ +\x5d\xf1\x5b\x66\x37\x77\xff\x02\x1c\x7f\x12\x5b\ +\x00\x00\x06\x71\ +\x00\ +\x00\x16\x14\x78\x9c\xed\x57\x6d\x8f\x9b\x46\x10\xfe\x7e\xbf\x82\ +\x72\x5f\x12\x15\x96\x7d\x7f\x71\x6c\x47\x6a\xa3\x48\x91\xda\x2f\ +\x6d\xaa\x7e\x8c\x30\xac\x7d\x34\x18\x2c\xc0\x67\x3b\xbf\xbe\xb3\ +\x18\x30\xbe\xf3\xe9\x1c\xe5\x22\x45\x55\xad\x44\xa7\x9d\x99\xdd\ +\x9d\x9d\x79\x66\xe6\x61\xfa\x76\xbf\xce\xbd\x7b\x5b\xd5\x59\x59\ +\xcc\x7c\x82\xb0\xef\xd9\x22\x29\xd3\xac\x58\xcd\xfc\xbf\x3e\xbe\ +\x0f\xb5\xef\xd5\x4d\x5c\xa4\x71\x5e\x16\x76\xe6\x17\xa5\xff\x76\ +\x7e\x33\xfd\x29\x0c\xbd\x5f\x2b\x1b\x37\x36\xf5\x76\x59\x73\xe7\ +\x7d\x28\x3e\xd7\x49\xbc\xb1\xde\xab\xbb\xa6\xd9\x4c\xa2\x68\xb7\ +\xdb\xa1\xac\x13\xa2\xb2\x5a\x45\xaf\xbd\x30\x9c\xdf\xdc\x4c\xeb\ +\xfb\xd5\x8d\xe7\x79\x70\x6f\x51\x4f\xd2\x64\xe6\x77\x1b\x36\xdb\ +\x2a\x6f\x0d\xd3\x24\xb2\xb9\x5d\xdb\xa2\xa9\x23\x82\x48\xe4\x9f\ +\xcc\x93\x93\x79\xe2\x6e\xcf\xee\x6d\x52\xae\xd7\x65\x51\xb7\x3b\ +\x8b\xfa\x76\x64\x5c\xa5\xcb\xc1\xda\x79\xb3\x63\xad\x11\x31\xc6\ +\x44\x98\x46\x94\x86\x60\x11\xd6\x87\xa2\x89\xf7\xe1\xf9\x56\xf0\ +\xf1\xd2\x56\x8a\x31\x8e\x40\x77\xb2\xbc\xce\x6a\x52\x43\x40\x37\ +\xf0\x7f\x30\xef\x05\xa8\x2e\xb7\x55\x62\x97\xb0\xcf\xa2\xc2\x36\ +\xd1\xbb\x8f\xef\x06\x65\x88\x51\xda\xa4\xa3\x63\xfa\x78\x9e\xdd\ +\x7a\x16\xe4\x22\x5e\xdb\x7a\x13\x27\xb6\x8e\x7a\x79\xbb\x7f\x97\ +\xa5\xcd\xdd\xcc\x67\x12\x71\xac\xb5\x69\x65\x77\x36\x5b\xdd\x35\ +\x0f\x84\x59\x3a\xf3\xc1\x77\x6a\xb4\x68\xd7\x23\x68\x90\xa3\x41\ +\x77\xec\x64\xd0\x60\x64\x28\x22\x5e\x45\x04\x53\x47\x9b\xfe\x01\ +\x93\xb4\x4c\x9c\x47\x70\xa4\x5d\x67\xf1\xb6\x29\xd7\x90\xb3\x24\ +\xc9\xe3\xba\xce\x96\x59\x02\x8b\xb2\xd8\xe4\xdb\x55\x56\x7c\xaa\ +\x37\x36\x69\xaa\x38\xff\x94\x66\x0e\x6f\x89\x45\x7d\x08\x87\x1b\ +\xed\x7e\x53\x56\x4d\xb8\x4f\x37\x10\x48\xa9\x2e\x2a\x0f\x63\xe5\ +\x7d\x66\x77\xbf\x94\x7b\x70\xd1\xc3\x1e\xa3\xf0\xcf\x9f\x83\x7c\ +\x9a\xda\x65\xed\xf4\xc7\xe7\xba\x15\xbc\x57\xf9\x5e\xd4\x6a\x07\ +\xef\x9d\xeb\xa9\x3b\xe3\x64\xbb\x88\xeb\x63\x40\x3d\x6f\x13\xaf\ +\x00\x7c\x79\x59\xcd\xfc\xdb\x65\xfb\xeb\x14\x8b\xb2\x4a\x6d\xd5\ +\xab\x64\xfb\x3b\x53\x95\x90\xa0\xac\x39\x1c\xcb\xad\x3b\xbb\x7f\ +\x86\x3b\x75\xd0\xe3\xcb\xfa\xfa\x2e\x4e\xcb\xdd\xcc\xa7\x0f\x95\ +\x5f\xca\x72\x3d\xf3\x05\x12\x46\x1b\x8c\xcd\x43\x75\x02\x91\x08\ +\x35\x43\x02\x4b\x4a\xf8\x23\x2d\x5c\x28\x11\xc6\x4a\x1b\x4a\x1e\ +\x29\xb7\x55\x05\x05\x19\xe6\xf1\xc1\xc2\xab\xda\x3f\xbd\x51\x7d\ +\x57\xee\x56\x95\x8b\x4e\x53\x6d\xed\xc3\x9d\x4e\x13\x2e\x16\x2e\ +\x0b\x97\xd4\x80\x90\xad\x2b\xf5\x70\x5b\x64\x0d\x94\xd3\x66\x3f\ +\x3e\x75\x9b\xa5\xb6\xbe\xbc\x71\x97\x15\x10\x84\xb0\x03\x36\x61\ +\x43\x8c\x1f\x5a\xf4\x30\x57\x58\x3f\x61\xe1\x00\xf2\x84\xea\xf0\ +\xb4\x6a\x1d\xef\xb3\x75\xf6\xc5\xc2\xbb\x1f\x85\xab\x2e\xe2\x4d\ +\xb8\xca\xcb\x45\x9c\x77\xde\xcf\x5b\x8b\xe9\x59\x58\x8e\x9b\x3c\ +\xaf\x39\xb8\x92\xde\x1f\x9c\xcc\xef\x85\x2e\x9e\x4e\xc0\x94\x14\ +\x83\xb0\xac\x32\xa8\x95\x91\xbf\xbd\xe8\x30\x16\xb9\x06\x00\xfd\ +\x7b\xdf\x02\xac\x85\x9f\x7a\xa8\x3b\x8c\x75\x1d\xee\xa3\xc7\xc0\ +\x6f\xe5\x6b\xdb\xc4\x69\xdc\xc4\xa7\x2a\xe8\x25\xd4\x18\xdc\xbf\ +\x0c\x7a\xe9\xe4\x8f\x77\xef\xe7\xdd\x45\xd3\x24\x99\xfc\x5d\x56\ +\x9f\xfb\x7b\x3d\xcf\x19\xc4\x8b\x72\x0b\xa9\xf0\xe7\x83\x78\x9a\ +\x26\x13\xe8\x7e\xd0\x17\xe6\xd9\x1a\xb0\xed\x1a\xe7\xcf\xd0\xed\ +\xa6\xd1\x49\x71\x66\xec\x82\x75\x3a\xf4\x78\x6c\x65\x8f\x6d\xf4\ +\xe2\x2c\x49\x93\x75\xe6\x36\x45\x7f\x36\x59\x9e\x7f\x70\x97\x74\ +\x2f\x1e\x1d\x9a\x35\xb9\x3d\x09\xa7\x51\xe7\x7d\xf7\xb6\x68\xf4\ +\xb8\x69\xd4\xbf\xbe\x5d\xad\x4e\x51\x39\x2b\x8a\x21\xd1\x79\xbc\ +\xb0\x00\x82\xdf\x9c\xd2\x7b\xa4\x5d\x55\xe5\x76\xb3\x2e\x53\xdb\ +\x6d\xef\xa3\xb9\x89\x9b\xbb\x21\x65\xcd\x21\x07\xfd\x12\xbc\x9f\ +\x14\x30\x84\xdf\xd4\x4d\x55\x7e\xb6\x93\x5b\x6a\x53\x18\x35\xdd\ +\xf2\x58\x09\x13\x8a\xb0\xd0\x52\x43\x89\xf7\xf2\x3c\x2b\x2c\xdc\ +\x35\x59\x6c\x9b\x66\x2c\xfb\xa7\xcc\x8a\x09\x84\xc6\x56\xbd\xb4\ +\x5d\xe4\x00\xea\x66\xc2\x7b\x59\x1a\x43\xb7\xa9\xaa\xf8\x30\xbe\ +\x3a\xec\x3a\xd4\x84\x0c\xb8\x72\xa8\xf0\x18\x47\x8a\x6a\xc2\x59\ +\x10\x32\xc4\x8c\xd2\x5c\x70\x2f\x24\x88\x61\x4c\xa8\x08\x18\xc2\ +\x94\x73\x89\x89\xf4\x18\xa2\x58\x08\x4a\x03\x83\x94\xd1\x58\x2b\ +\x05\x86\x14\x69\x42\x8c\x30\x01\x47\x92\x72\x62\xa8\x80\xcd\x14\ +\x71\xad\x29\x57\x01\x9c\x03\x52\x4e\x94\x17\x0a\xa4\x08\x87\xc3\ +\x03\x8a\x14\x37\x92\x50\x2f\x34\x88\x48\x62\x60\x00\xb9\x5b\x8c\ +\x81\x06\xe7\x85\x1a\x19\x81\x29\x55\x1a\x0e\x14\x94\x33\x71\x56\ +\x5c\x2e\xc4\x1c\xb3\x53\x69\x9c\x9a\x5d\x59\x40\xc8\x9a\xb2\x0a\ +\xa1\xed\xdd\xc7\xcd\xb6\xb2\xae\xbc\x7a\x7c\x4c\x2b\x50\x5e\x4a\ +\xce\x2d\x86\x37\xa5\xfc\x8d\x5b\x9c\x42\x74\x5c\x56\xdb\x1c\x66\ +\xd4\xbd\x2d\xca\x34\x1d\x12\x88\xdb\xdf\x79\x02\x31\x52\xca\x08\ +\x41\xa4\x7e\x89\xb4\xb8\x87\x3a\x77\xa1\x52\xd9\x20\xec\x7a\xa6\ +\x42\x52\x4b\xce\xb4\x1c\x14\x7d\xab\x94\x88\x01\x89\x91\xe4\x14\ +\x9b\xbd\xeb\x9f\x48\x68\x3e\x48\xa0\x83\x08\x86\x14\x66\x00\xb5\ +\x41\x58\xed\x5b\x3a\x00\xa9\x00\xff\x4f\x17\x56\xed\x2c\x33\x42\ +\x52\x6a\xa4\x19\xc4\x30\xee\x8b\xda\xd5\x38\x60\x27\x6e\xaa\x6c\ +\xff\x8a\x04\x38\x00\xd6\xa3\x25\x56\x5c\x60\x1d\xc0\x95\xd8\x60\ +\x26\xa9\x04\x05\x7e\xfd\x38\x55\x97\x28\xc1\x25\x83\x81\x16\x5c\ +\x4c\xe2\xd3\x8e\x10\xcc\x05\xd5\xc2\x39\xa2\x85\xc6\x4c\xab\x73\ +\x47\xaa\x63\x23\x25\x42\x48\xfd\x5c\x14\xc0\x94\x03\x9a\x15\xe6\ +\x67\x71\x15\x1a\x69\x8e\x05\xe6\x17\xd2\xa0\x08\xa5\xfc\x9a\xcc\ +\xf5\x79\x86\x69\x31\xea\xf5\xe7\xd8\x8c\x63\xc0\xda\xb7\x62\x93\ +\xc2\xc0\x30\xe6\x9b\xb0\xf9\x7c\x1d\x2d\x97\xed\xdd\xdf\xe8\xab\ +\x34\xd0\x75\xb0\x7a\xc9\x32\x82\xf0\x9a\xeb\xcb\x48\x21\x22\x38\ +\x74\x39\x71\x96\x6e\x8c\x88\x51\x1c\xab\x31\x2e\x18\x43\xe0\xac\ +\x32\xe4\x9a\x4a\x02\xbc\x41\x43\xd4\x5a\x3f\x5f\x48\x4a\x62\xc6\ +\x0d\x60\x16\x49\x6e\x04\x61\x86\x1d\xe1\x3b\xa4\xe0\xaa\x39\xb3\ +\x5c\x9a\x98\xa4\x3f\xcc\x9c\xf9\xdd\xcd\x19\xc6\xe0\x8b\x45\x07\ +\xa1\x42\x98\xc1\xbb\xa4\xf1\x20\x86\xae\x3e\x15\x0c\x1f\x0e\x34\ +\x56\x1a\x26\x60\xce\x48\x04\x33\x83\x05\x30\x31\x0c\x21\xc2\x19\ +\x71\x46\x19\xa7\x01\xc1\x88\xc3\x17\x0b\x67\x1e\x85\x38\x73\x8e\ +\x0d\x0f\x34\x58\x61\x43\xb5\x47\x04\x82\x56\x05\xa5\x17\x10\x82\ +\x04\x54\x27\xf7\x80\x1a\x4b\xc5\xe0\x8c\x80\xc0\x78\xe2\x50\xf2\ +\xa6\x9d\x58\x9a\x1a\xc8\x72\x40\xdc\x00\x72\x3d\xeb\xe2\x8c\x09\ +\xd9\xd7\x4f\x99\xab\x52\x83\x21\xbf\xda\xfe\x30\xa9\x01\x0a\x20\ +\x20\x0e\x86\x2a\x03\x98\xe3\xae\x65\x0a\x29\x07\x0a\xc0\x7a\x0a\ +\x40\x38\xef\x29\x80\xec\x29\x00\x31\x8f\x19\x00\xbf\x44\x00\x78\ +\x4f\x00\x04\xe9\x09\x00\x19\x08\x80\xd0\x3d\x01\xe0\x03\x01\x80\ +\xa6\x7d\x24\x00\xa3\xc6\x7b\x96\x1d\xf1\xa3\x72\x00\xf6\xd2\x1c\ +\x20\x7c\x6a\x96\x98\xeb\x48\x00\x75\x3d\x45\x1b\x71\xd6\xbd\xa0\ +\x20\xb8\x56\xec\xbb\xf1\x00\xf5\x9f\xe3\x01\x1a\xd8\x31\xe3\xd0\ +\x30\xc6\xb1\x25\xae\x74\xa8\x92\xe4\xab\x89\x80\xb9\xc8\x03\x42\ +\xf9\x3f\x13\xf8\xae\x4c\x20\x54\x57\x17\xd3\x45\x2a\x40\xda\x62\ +\x12\xa3\xef\x7b\x47\x05\x00\x04\x30\x67\xf4\xb3\x30\x7a\x51\x2a\ +\x30\x8d\x56\xf3\x9b\xa9\xfb\xf8\x9e\xdf\xfc\x0b\x55\x91\x2b\xcd\ +\ +\x00\x00\x0f\xa5\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x67\x62\x5f\x74\ +\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x2d\x31\x31\x2e\x35\x31\x30\x33\x33\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x37\ +\x2e\x30\x35\x35\x33\x31\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ +\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\ +\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\ +\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\ +\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\ +\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\ +\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x67\x75\x69\x64\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\x22\x33\x32\x2e\ +\x30\x30\x30\x30\x30\x31\x2c\x2d\x32\x2e\x31\x33\x33\x33\x33\x33\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x65\x6e\x74\ +\x61\x74\x69\x6f\x6e\x3d\x22\x30\x2c\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x67\x75\x69\x64\x65\x34\x34\x39\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x6c\x6f\x63\x6b\x65\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\ +\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\ +\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\ +\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\ +\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\ +\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\ +\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\ +\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\ +\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\ +\x64\x34\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ +\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x32\x2e\x31\x38\x33\x37\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\ +\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x31\x37\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x34\x2e\x35\x37\x31\x35\ +\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x31\ +\x2e\x32\x36\x39\x31\x34\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\ +\x37\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ +\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\ +\x2e\x30\x33\x34\x31\x36\x31\x36\x38\x2c\x2d\x30\x2e\x39\x39\x39\ +\x34\x31\x36\x33\x32\x2c\x30\x2e\x35\x36\x35\x33\x35\x36\x39\x31\ +\x2c\x30\x2e\x38\x32\x34\x38\x34\x36\x33\x39\x2c\x30\x2c\x30\x29\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\x30\x33\x34\ +\x31\x36\x31\x36\x38\x2c\x2d\x30\x2e\x39\x39\x39\x34\x31\x36\x33\ +\x32\x2c\x30\x2e\x36\x34\x30\x35\x32\x31\x39\x35\x2c\x30\x2e\x37\ +\x36\x37\x39\x33\x39\x38\x36\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x39\x31\x37\x31\ +\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ +\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x79\x3d\x22\x31\x38\x2e\x37\x32\x31\x38\x34\x34\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x35\x2e\x31\x37\x36\x33\ +\x35\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\ +\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\x31\x37\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x30\ +\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ +\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\x39\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\ +\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\x39\x2e\x38\x34\ +\x30\x35\x35\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x2d\x30\x2e\x34\x36\x31\x32\x31\x35\x34\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ +\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ +\x78\x28\x2d\x30\x2e\x30\x33\x34\x31\x36\x31\x36\x38\x2c\x2d\x30\ +\x2e\x39\x39\x39\x34\x31\x36\x33\x32\x2c\x30\x2e\x37\x30\x31\x34\ +\x36\x35\x32\x36\x2c\x30\x2e\x37\x31\x32\x37\x30\x33\x36\x35\x2c\ +\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\ +\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\ +\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\ +\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ +\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\ +\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\ +\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\ +\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\ +\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\ +\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\ +\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\ +\x73\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\ +\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\ +\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ +\x22\x30\x2e\x32\x31\x35\x35\x37\x30\x32\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x79\x3d\x22\x32\x31\x2e\x34\x35\x36\x35\x32\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\ +\x74\x33\x37\x36\x31\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\ +\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x30\x2e\x32\x31\x35\x35\x37\x30\x32\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x31\x2e\x34\x35\x36\x35\x32\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\ +\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\x33\ +\x2e\x38\x36\x36\x36\x36\x36\x37\x39\x70\x78\x3b\x6c\x69\x6e\x65\ +\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\x32\x35\x3b\x66\x6f\x6e\ +\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\ +\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\ +\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\ +\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\x64\x27\x3b\x66\x69\x6c\ +\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x32\x22\x3e\x52\x47\x42\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\ +\x74\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x0c\x39\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x61\x64\x64\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x78\x3d\x22\x38\x2e\x30\x33\x39\x32\x38\x33\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x31\x33\x2e\x31\x35\x35\x36\x37\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\ +\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\ +\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ +\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ +\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\ +\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ +\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\ +\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ +\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ +\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ +\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ +\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ +\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ +\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ +\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ +\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\x71\ +\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\ +\x2e\x32\x37\x39\x36\x32\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x79\x3d\x22\x31\x2e\x32\x32\x34\x34\x30\x31\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\x32\ +\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x67\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x33\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x65\x37\x65\x37\x66\x66\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x23\x65\x63\x65\x63\x65\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ +\x65\x37\x65\x37\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ +\x64\x74\x68\x3a\x35\x2e\x31\x39\x31\x33\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ +\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ +\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x36\ +\x2e\x30\x37\x39\x36\x32\x32\x36\x2c\x31\x37\x2e\x30\x31\x38\x39\ +\x34\x34\x20\x48\x20\x32\x38\x2e\x34\x37\x39\x36\x32\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x37\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ +\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x65\x63\x65\x63\x65\x63\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x65\x37\x65\x37\x66\x66\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\x31\x39\x31\x33\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ +\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ +\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\ +\x3d\x22\x4d\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x2c\x35\x2e\ +\x39\x38\x38\x35\x39\x36\x38\x20\x56\x20\x32\x38\x2e\x33\x38\x38\ +\x35\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x33\x37\x38\x32\x2d\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\ +\x70\x65\x73\x3d\x22\x63\x63\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x78\x3d\x22\x30\ +\x2e\x32\x35\x37\x36\x32\x31\x36\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x2d\x63\x65\x6e\x74\x65\x72\x2d\x79\x3d\ +\x22\x2d\x30\x2e\x35\x33\x31\x39\x30\x38\x36\x31\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0f\x81\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x35\x33\ +\x32\x30\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\x64\x5f\x61\x72\x72\x6f\x77\x2e\ +\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ +\x2e\x35\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x2e\ +\x35\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x35\x33\x32\x32\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x37\x2e\x36\x30\x39\x34\x30\x38\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\ +\x36\x2e\x30\x31\x33\x31\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\ +\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ +\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ +\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\ +\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x67\x72\x69\x64\x35\x33\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\ +\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ +\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x35\x33\x32\x35\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\ +\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\ +\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\ +\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\ +\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\ +\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\ +\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\ +\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x32\x39\x32\x39\ +\x39\x35\x33\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\ +\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\ +\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\ +\x6d\x75\x6c\x61\x74\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\ +\x35\x65\x35\x65\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x6d\x20\x31\x33\x2e\x37\x2c\x30\x2e\x31\x36\x36\x36\x36\x36\ +\x36\x37\x20\x63\x20\x2d\x31\x2e\x30\x39\x32\x36\x31\x35\x2c\x30\ +\x20\x2d\x31\x2e\x39\x36\x36\x36\x36\x37\x2c\x30\x2e\x38\x37\x34\ +\x30\x35\x31\x38\x33\x20\x2d\x31\x2e\x39\x36\x36\x36\x36\x37\x2c\ +\x31\x2e\x39\x36\x36\x36\x36\x36\x36\x33\x20\x56\x20\x31\x36\x2e\ +\x34\x33\x33\x33\x33\x33\x20\x48\x20\x34\x2e\x32\x36\x36\x36\x36\ +\x36\x37\x20\x63\x20\x2d\x32\x2e\x31\x33\x33\x33\x33\x33\x37\x2c\ +\x30\x20\x31\x31\x2e\x37\x33\x33\x33\x33\x33\x33\x2c\x31\x36\x20\ +\x31\x31\x2e\x37\x33\x33\x33\x33\x33\x33\x2c\x31\x36\x20\x4c\x20\ +\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x2c\x33\x33\x2e\x35\x20\x31\ +\x38\x2e\x31\x33\x33\x33\x33\x33\x2c\x33\x32\x2e\x34\x33\x33\x33\ +\x33\x33\x20\x63\x20\x30\x2c\x30\x20\x31\x33\x2e\x38\x36\x36\x36\ +\x36\x38\x2c\x2d\x31\x36\x20\x31\x31\x2e\x37\x33\x33\x33\x33\x34\ +\x2c\x2d\x31\x36\x20\x48\x20\x32\x32\x2e\x34\x20\x56\x20\x32\x2e\ +\x31\x33\x33\x33\x33\x33\x33\x20\x63\x20\x30\x2c\x2d\x31\x2e\x30\ +\x39\x32\x36\x31\x34\x38\x20\x2d\x30\x2e\x38\x37\x34\x30\x35\x31\ +\x2c\x2d\x31\x2e\x39\x36\x36\x36\x36\x36\x36\x33\x20\x2d\x31\x2e\ +\x39\x36\x36\x36\x36\x37\x2c\x2d\x31\x2e\x39\x36\x36\x36\x36\x36\ +\x36\x33\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x72\x65\x63\x74\x35\x33\x34\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\ +\x67\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x69\x76\x65\x6c\x6c\x6f\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\ +\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\ +\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\ +\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\ +\x6c\x6c\x3a\x23\x33\x33\x34\x35\x34\x61\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x65\x35\x65\x35\x65\x35\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x33\x33\x36\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\ +\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\ +\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ +\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\ +\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\ +\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\ +\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x35\x39\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\ +\x22\x32\x35\x2e\x35\x39\x39\x39\x39\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x63\x79\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x37\x2e\x34\ +\x36\x36\x36\x36\x35\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x36\x2e\x36\x36\x36\x36\x36\x36\x35\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\ +\x65\x35\x65\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x30\x2e\x32\x30\x32\x30\x31\x38\x37\x38\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x35\x2e\x32\x38\x38\x38\ +\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x32\ +\x37\x2e\x37\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x72\x78\x3d\x22\x32\x2e\x37\x39\x39\x39\x39\x39\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x33\x37\x36\ +\x38\x31\x31\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x65\x6c\ +\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\ +\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\x35\x65\ +\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ +\x2e\x33\x30\x31\x31\x35\x31\x38\x31\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\ +\x22\x32\x35\x2e\x35\x39\x39\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x63\x79\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x32\ +\x32\x32\x32\x32\x31\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x36\x2e\x33\x37\x36\x38\x31\x31\x35\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\ +\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x30\x30\x36\x33\x37\x35\x38\ +\x37\x2c\x30\x2e\x39\x39\x39\x39\x37\x39\x36\x37\x2c\x2d\x31\x2c\ +\x30\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x35\x65\ +\x35\x65\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x30\x2e\x32\x30\x38\x37\x39\x35\x32\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\ +\x3d\x22\x32\x37\x2e\x37\x33\x33\x38\x39\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x63\x79\x3d\x22\x2d\x32\x35\x2e\x35\x37\x38\x37\ +\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ +\x2e\x36\x30\x38\x37\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x37\x2e\x33\x31\x31\x30\x35\x36\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x06\x77\ +\x00\ +\x00\x24\x04\x78\x9c\xe5\x99\x4b\x8f\xdb\x36\x10\x80\xef\xfb\x2b\ +\x58\xe5\xd2\xa2\x2b\x4a\x24\xf5\x8e\xed\x1c\x12\x04\x09\x90\x5e\ +\xda\xb4\x3d\x06\xb2\x44\xdb\x6a\x24\xd1\x95\xa8\xb5\x9d\x5f\xdf\ +\xa1\xde\xb6\x6c\x64\x83\x7d\x65\x53\x01\x41\xa4\x99\xe1\xeb\xe3\ +\xcc\x70\xe8\x9d\xbd\xda\x67\x29\xba\xe1\x45\x99\x88\x7c\xae\x11\ +\x6c\x6a\x88\xe7\x91\x88\x93\x7c\x3d\xd7\xfe\xfc\xf8\x56\xf7\x34\ +\x54\xca\x30\x8f\xc3\x54\xe4\x7c\xae\xe5\x42\x7b\xb5\xb8\x9a\xfd\ +\xa4\xeb\xe8\x75\xc1\x43\xc9\x63\xb4\x4b\xe4\x06\xbd\xcf\x3f\x97\ +\x51\xb8\xe5\xe8\xe7\x8d\x94\xdb\xc0\x30\x76\xbb\x1d\x4e\x5a\x21\ +\x16\xc5\xda\xf8\x05\xe9\xfa\xe2\xea\x6a\x56\xde\xac\xaf\x10\x42\ +\x30\x6e\x5e\x06\x71\x34\xd7\xda\x06\xdb\xaa\x48\x6b\xc3\x38\x32\ +\x78\xca\x33\x9e\xcb\xd2\x20\x98\x18\xda\x60\x1e\x0d\xe6\x91\x1a\ +\x3d\xb9\xe1\x91\xc8\x32\x91\x97\x75\xcb\xbc\x7c\x31\x32\x2e\xe2\ +\x55\x6f\xad\x66\xb3\x63\xb5\x11\xf1\x7d\xdf\x30\xa9\x41\xa9\x0e\ +\x16\x7a\x79\xc8\x65\xb8\xd7\x8f\x9b\xc2\x1c\xcf\x35\xa5\xa6\x69\ +\x1a\xa0\x1b\x2c\x6f\x67\x15\x94\x00\x74\x0b\xff\x7a\xf3\x4e\x80\ +\x4b\x51\x15\x11\x5f\x41\x3b\x8e\x73\x2e\x8d\x37\x1f\xdf\xf4\x4a\ +\xdd\xc4\xb1\x8c\x47\xdd\x74\x3c\x8f\x46\x3d\x82\x9c\x87\x19\x2f\ +\xb7\x61\xc4\x4b\xa3\x93\xd7\xed\x77\x49\x2c\x37\x73\x8d\x59\x98\ +\x30\x78\xec\x5a\xb8\xe1\xc9\x7a\x23\x4f\xa5\x49\x3c\xd7\x60\xf6\ +\xd4\xf7\x9a\xef\x91\x73\x90\xc6\xa0\xed\x38\xe8\x35\x26\xf6\x29\ +\x26\xa8\x20\x36\x73\x1b\x9b\x6e\x09\x41\x2c\x22\x35\x27\xe8\x92\ +\x67\x49\x58\x49\x91\xc1\xae\x45\x51\x1a\x96\x65\xb2\x4a\x22\xf8\ +\x10\xf9\x36\xad\xd6\x49\xfe\x29\x0a\xd3\xa8\x4a\xc1\xa5\x3e\x95\ +\x5b\x1e\xc9\x22\x4c\x3f\xc5\x89\xf2\x3d\x58\x0d\xee\x78\xf6\x83\ +\xf3\xfd\x56\x14\x52\xdf\xc7\x5b\xa0\xea\xb8\x67\x95\x87\x4e\xb9\ +\x00\xed\x2c\xe6\xab\x52\x59\x35\x4b\x54\x5f\xb0\x46\x57\x43\x46\ +\xad\xed\x67\xac\xa6\x1b\xdf\x24\x7c\x37\xd8\x2e\xc3\xb2\xc1\x88\ +\xd0\x36\x5c\x83\xcb\xa5\xa2\x98\x6b\x2f\x56\xf5\xd3\x2a\x96\xa2\ +\x88\x79\xd1\xa9\x9c\xfa\x39\x52\x09\xd8\x96\x44\x1e\x9a\x20\x6b\ +\xfb\xee\xe6\xab\x7a\xed\xf5\xe6\x79\x7d\xb9\x09\x63\xb1\x9b\x6b\ +\xf4\x54\xf9\x45\x88\x6c\xae\xd9\xd8\xf6\x3d\xdf\x24\xa7\xda\x68\ +\x3f\xd7\x74\xd7\xc7\x0e\xf1\x5c\x6a\x4d\xb4\x30\x9e\x83\x89\x69\ +\x53\x66\xb9\x13\x65\x55\x14\x10\x85\x7a\x1a\x1e\x38\x2c\xaa\xfe\ +\xaf\xeb\xbf\xdc\x88\xdd\xba\x50\x70\x64\x51\xf1\xd3\x96\x4a\xa3\ +\x2f\x97\x62\x7f\x5e\x0d\x4e\x51\xa9\xf8\xd6\xab\x3c\x91\x10\x43\ +\xdb\xfd\xb8\xd7\x2a\x89\x79\x79\xbe\xe1\x2e\xc9\x81\x81\xde\x7a\ +\x33\x61\x3d\xe2\x53\x8b\xce\xb5\x5d\xd3\xbb\x60\x01\x53\x9b\x60\ +\x6e\x55\x87\xcb\xaa\x2c\xdc\x27\x59\xf2\x85\xc3\xba\x27\xa4\xcb\ +\x3c\xdc\xea\xeb\x54\x2c\xc3\xb4\x9d\xfd\xa2\xb6\x98\x1d\x61\x69\ +\x1a\x21\x24\x0f\x2a\x8e\xf7\x07\x25\xd3\x3a\xa1\xe2\xa9\x04\xcc\ +\x75\xec\x5e\x28\x8a\x04\xc2\x63\x34\xdf\x4e\x74\x18\x8b\x54\xd4\ +\x43\xd2\xde\xd7\xfe\x55\x7b\x9f\x7b\xaa\x3b\x8c\x75\xad\xdb\x1b\ +\x53\xbf\xaf\xe5\x19\x97\x61\x1c\xca\x70\x08\x82\x4e\x42\x7d\xdf\ +\xec\x56\x06\x09\x34\xf8\xfd\xcd\xdb\x45\x3b\xd0\x2c\x8a\x82\xbf\ +\x45\xf1\xb9\x1b\x17\x21\x65\x10\x2e\x45\x05\x5b\xa1\x2d\x7a\xf1\ +\x2c\x8e\x02\x48\x79\x90\x0a\x16\x49\x06\xae\xad\xb2\xe5\xaf\x90\ +\xe2\x66\xc6\xa0\x38\x32\x56\xb0\x86\x4e\x9b\x6e\x0b\xde\xe4\xce\ +\xb3\x07\x48\x1c\x65\x89\x6a\x64\xfc\x21\x93\x34\x7d\xaf\x06\x69\ +\x57\x3c\xea\x34\x91\x29\x1f\x84\x33\xa3\x9d\x7d\xbb\x36\x63\xb4\ +\xb8\x99\xd1\xad\xbe\xfe\x5a\x0f\x54\x8e\x82\xa2\xdf\xe8\x34\x5c\ +\x72\x70\x82\x0f\x4a\x89\x26\xda\x75\x21\xaa\x6d\x26\x62\xde\x36\ +\xef\x69\x42\xd6\xeb\xb7\x4c\x1e\x52\xd0\xaf\x60\xf6\x41\x9b\x68\ +\x5e\xaa\x0f\xbd\x4d\x13\x01\x69\x3e\x8b\x2a\x85\x74\x77\xc3\x73\ +\x11\xc7\x2f\x4b\x59\x88\xcf\x3c\x78\x61\x9a\x96\x67\x9a\xed\x67\ +\x13\x2d\x41\xff\x99\x26\x39\x87\x69\x04\xe5\xbf\x55\x58\xf0\xb1\ +\xf4\x1f\x91\xe4\x01\x70\xe3\x45\x27\xad\x3f\x52\xf0\x78\x19\x58\ +\x9d\x2c\x0e\x21\x13\x15\x45\x78\x08\x72\xa8\x08\xc6\x52\xb1\x5a\ +\x95\x5c\x0e\x23\x75\x53\x35\x31\x6b\x9f\x23\x47\x57\xcb\x65\xbe\ +\x4f\x7a\xe1\xd9\x43\x4a\x3d\xe7\x0f\x2a\xf5\x1c\x45\x05\xf8\xb7\ +\x8f\x2d\x97\xf9\x26\x73\xb8\x4e\x9c\x5e\x51\x1c\x99\x15\x60\xc7\ +\x30\x83\xc3\xca\xf1\xbd\xde\x2b\x66\xdb\x50\x6e\xce\xd1\x1f\xad\ +\x52\x91\x55\xcf\x31\x59\xda\x4c\x8a\x59\xd6\x29\xe2\x65\x25\xe5\ +\x7d\x01\xee\xf7\xbd\x5f\x07\x20\xfc\x0d\x99\xd7\x26\xfa\x0b\x75\ +\x60\x8e\x01\xab\x15\x41\xb4\x0e\x1c\x86\xcc\x2e\x72\x98\xa1\x14\ +\x85\x0e\x39\xfe\x26\x94\x55\xc1\x8f\x72\x49\x9f\x13\xc0\x49\x55\ +\x18\x41\x3a\x8e\xa2\xe7\x8e\xaa\x87\x74\xdd\xbf\xa1\x77\xc8\x3c\ +\x87\xcc\xfb\x7e\x90\x11\x0c\x3b\x68\x52\xdb\xdb\xee\xbf\x9d\xd9\ +\x05\x12\xfd\x29\x70\x4d\x3d\xec\xa1\xd7\x88\x61\xda\xbc\x4e\x5e\ +\x26\x74\x98\xeb\x52\xdd\xbc\x35\x9f\x7b\xf1\x19\xe2\xda\x16\xb1\ +\xed\x7b\x23\x90\x21\xbb\x4b\x49\xd7\xcc\xc6\x14\x45\x10\x47\xba\ +\x85\x69\x0d\xe5\xd2\xfb\x14\x85\x67\x3d\x7b\x10\xc4\xc4\xad\x2b\ +\xdc\x11\x84\x7e\xfb\x98\xf9\x4e\x51\x50\x82\xef\xc7\x27\x74\xff\ +\xd9\xa3\x70\xee\xcb\x2b\x9e\x7d\x80\x30\x7a\x67\x06\xec\xb9\x33\ +\x20\xce\x9d\x19\xdc\xbe\x08\xf9\x1e\x8f\xcc\x6c\x7c\x64\x32\x6c\ +\x35\x8b\x8e\x50\x57\xcf\x30\xa8\xc2\x2e\xbc\x5f\x38\x40\x75\xfa\ +\xc3\x00\x21\x5e\x57\x4d\xdd\x09\x08\x79\xd6\x40\xc6\x45\x15\xa1\ +\x7d\x51\x55\xbf\x4e\x5e\x2e\x21\x78\xcc\x44\xf1\xb0\x3e\xe1\x36\ +\x31\x72\xd7\x20\xb1\x7e\x18\x20\xfd\x62\xef\x06\xe4\xa1\x2a\x0b\ +\x6e\xae\x56\x13\x20\x0c\xdb\x8c\x7a\x8e\x63\x79\x4f\x72\xb1\x1d\ +\x6e\x69\x50\x8e\x78\x0d\x46\x1f\xdb\xc4\xf5\x2d\xef\xcc\x29\xe3\ +\xfa\x8f\x59\x76\x41\xd9\xec\x02\x19\xc6\xc8\x13\xb0\xd1\xad\xde\ +\x53\xa8\x8f\x29\x01\xaf\x75\x10\xa5\xd8\x6d\x64\x16\xb6\x15\x22\ +\x72\x26\xcf\x78\xe4\x71\x6b\x53\x13\x2e\xd3\xd4\xf7\x9e\xc2\x81\ +\x68\x7f\xb3\x71\xb1\x69\x3b\x16\x50\x42\xd4\xc2\xde\x35\x81\x48\ +\xbf\xe0\x43\x1e\x7d\xcc\x53\xe8\x49\xf1\x10\xab\x2d\x63\x06\x1e\ +\x08\x4e\x72\xe7\x9a\x38\xd8\x57\x0e\x65\x9d\xc5\xa3\xbb\xff\x0f\ +\x40\xf5\xcd\xb8\x8d\xb1\x9e\x08\x6a\xe3\xce\x82\x10\xf3\x29\x33\ +\xdd\xf3\x2e\xf4\xc8\xf7\xbf\x27\x64\x34\xca\x43\x04\x7b\x0a\x11\ +\xe9\x65\x5f\x83\xf4\x98\x67\xfb\x93\x42\xd2\xe9\x50\x05\x38\xd8\ +\xad\x33\xf3\xad\x29\xd9\xb7\xa6\x34\xb1\x93\x45\x98\x97\xea\xaf\ +\x29\x7a\xc4\x73\x58\x83\xfa\x93\x97\xee\x35\xb7\x34\xe7\x4c\x18\ +\x4f\xec\x0f\x73\x8d\x42\x92\x20\x36\xf3\x9c\xaf\x6f\x42\x0d\xde\ +\x33\x47\xfb\xe0\x44\x7e\x7c\xbc\x0f\x16\x64\x62\xdf\xb3\x7d\xd7\ +\x7e\x8a\x03\x81\x75\x07\x24\xc5\x3e\xac\xc9\x82\x80\x66\x97\x0a\ +\x72\xc5\xfe\xa1\xae\x68\xaa\xd4\x32\xc3\xd3\xea\xb3\xf5\x11\xfa\ +\x30\xe5\xa7\x8d\x9d\xfa\xfa\xa1\xb7\x32\x17\x7d\x18\xfd\xf6\x47\ +\x1c\x75\xc7\x87\x23\xc1\x6f\x0a\xae\xb4\xff\x81\x14\x2a\x2e\xa7\ +\xfb\xb0\xba\x2a\xd6\x42\x5d\x7d\x7f\xdd\xde\xfa\x1d\xe4\x41\xb1\ +\x58\xdb\xc0\x28\x13\x9c\x96\xc9\x5c\x9d\x3d\xdc\xd9\xea\xf1\x69\ +\x35\xff\xa0\x3c\x07\x54\x63\xa8\xce\x11\xd4\xfe\x37\x66\xc5\xb6\ +\xe3\xe4\x8e\x7e\x66\x84\x02\xdb\x6b\x65\xce\x68\x27\xd2\x09\x5d\ +\xf7\xeb\x74\xbf\x11\xed\xcc\x58\x2f\xae\x66\xea\xef\xae\x8b\xab\ +\xff\x00\x21\x49\x9d\x0d\ +\x00\x00\x06\xc2\ +\x00\ +\x00\x25\x13\x78\x9c\xdd\x59\xdd\x93\x9b\x36\x10\x7f\xcf\x5f\xc1\ +\x70\x2f\xed\xd4\x80\xc4\x37\x9c\x7d\x79\x68\xa6\x4d\x67\xda\x97\ +\x36\x6d\x1f\x33\x32\xc8\x3e\x1a\x40\x54\xe0\xb3\x9d\xbf\xbe\x2b\ +\x3e\x04\xd8\x38\xf5\x8d\xef\x2e\xbe\x90\xc9\x1c\xd2\xae\x84\xf6\ +\xb7\xbb\xbf\x95\xe4\xf9\xdb\x5d\x96\x2a\x0f\x94\x97\x09\xcb\x17\ +\x2a\xd6\x91\xaa\xd0\x3c\x62\x71\x92\xaf\x17\xea\x9f\x1f\x7e\xd2\ +\x7c\x55\x29\x2b\x92\xc7\x24\x65\x39\x5d\xa8\x39\x53\xdf\xde\xbd\ +\x99\x97\x0f\xeb\x37\x8a\xa2\xc0\xe0\xbc\x0c\xe3\x68\xa1\xde\x57\ +\x55\x11\x1a\x46\xb1\xe1\xa9\xce\xf8\xda\x88\x23\x83\xa6\x34\xa3\ +\x79\x55\x1a\x58\xc7\x86\xda\xab\x47\xbd\x7a\xc4\x29\xa9\x92\x07\ +\x1a\xb1\x2c\x63\x79\x59\x8f\xcc\xcb\x9b\x81\x32\x8f\x57\x52\x7b\ +\xbb\xdd\xea\x5b\xab\x56\xc2\x41\x10\x18\xc8\x34\x4c\x53\x03\x0d\ +\xad\xdc\xe7\x15\xd9\x69\xe3\xa1\xb0\xc6\xa9\xa1\x26\x42\xc8\x00\ +\x59\xaf\x79\x9e\x56\x58\x02\x2a\x05\xfc\x97\xea\x5d\x87\x5e\xb2\ +\x0d\x8f\xe8\x0a\xc6\x51\x3d\xa7\x95\xf1\xee\xc3\x3b\x29\xd4\x90\ +\x1e\x57\xf1\x60\x9a\x24\xff\x54\x46\xa4\xa0\xa3\xaf\x76\x9d\x0d\ +\x02\x24\xa3\x65\x41\x22\x5a\x1a\x5d\x7f\x3d\x7e\x9b\xc4\xd5\xfd\ +\x42\xb5\x6c\x1d\x5b\xf0\x38\x75\xe7\x3d\x4d\xd6\xf7\xd5\x61\x6f\ +\x12\x2f\x54\x58\xbd\x19\xf8\x4d\x7b\xe0\x61\xdc\x28\xb4\x13\x87\ +\x43\xdf\xeb\xa6\xf2\x1d\xf5\xdd\xc8\xf7\x90\xef\x05\x33\xc5\x44\ +\x26\xd6\x10\xd6\xb0\xf3\x7d\x3d\xa8\xb3\x29\x8c\x59\x24\x16\x09\ +\xdf\xa0\x59\x42\x36\x15\xcb\xc0\x8d\x51\x94\x92\xb2\x4c\x56\x49\ +\x04\x0d\x96\x17\xe9\x66\x9d\xe4\x1f\x33\x0a\xa8\x7c\x2c\x93\x75\ +\xfe\xb1\x62\x2c\xd5\x3b\x4c\xe5\x02\xe8\xae\x60\xbc\xd2\x76\x71\ +\x01\xc8\xba\xde\xa4\x70\xdf\x09\xef\x40\x3a\x8f\xe9\xaa\x14\x5a\ +\x8d\x99\xa2\x05\x76\x36\x32\x90\xa6\x49\x4e\x09\xff\x99\x93\x38\ +\x81\xe8\x6b\xf4\x1a\xcd\xb1\xc4\xf2\xb1\xd3\x8e\x81\x51\x65\xc5\ +\x8a\x4e\x17\x0c\xad\xf6\xa9\xb0\x0e\x3a\xb5\x88\xa5\x8c\x87\x37\ +\xae\xb7\x5a\xb9\xde\x6d\xdd\xc5\xc0\x39\x49\xb5\x0f\xf1\xad\xda\ +\x8f\x61\xab\x55\x49\xc1\x11\x68\xd0\x57\xbb\x01\x46\xc0\xb7\x3c\ +\x55\x31\x4e\x7c\xad\xd7\x32\xad\xa9\x09\x75\xcf\x47\xbe\x89\x03\ +\x53\xfd\xe2\x0a\x97\x11\xc4\x2c\x1a\xaf\x10\xe9\x76\xe0\x23\x2b\ +\x30\xcd\xdb\xd3\xdf\x9f\x98\x2b\x98\x9c\x0b\xe6\xc1\x8e\xeb\x7b\ +\x53\x66\xe3\x69\xb3\x03\xf9\xd9\xb9\x31\xc6\xbf\x76\xa5\x21\xbc\ +\x57\xbf\xc9\xd8\x12\x81\x15\x3f\x24\x74\xdb\xbb\x78\x49\x4a\xda\ +\x4e\x5f\x90\x35\xad\xd7\xb8\x50\x6f\x56\xf5\xd3\x0a\x96\x8c\xc7\ +\x94\x77\x22\xb7\x7e\x46\xa2\xd6\x8c\x86\xe4\xda\xb9\xbb\x30\x13\ +\xb3\x4a\x39\x9a\x96\x97\xf7\x24\x66\xdb\x85\x6a\x1e\x0a\x3f\x33\ +\x96\x2d\x54\x47\x77\x02\x3f\x40\xf8\x50\x1a\xed\x84\x0c\x07\xbe\ +\x8d\x90\x7d\x24\x84\xcf\x59\xba\x48\x36\xc7\xb7\x8e\x84\x1b\xce\ +\x01\x27\x2d\x25\x7b\x0a\x36\xd5\x7f\xba\xe9\xcb\x7b\xb6\x5d\x73\ +\x81\x4d\xc5\x37\xf4\x70\xa4\x90\x68\xcb\x25\xdb\x4d\x8b\x21\x7b\ +\x37\x82\x99\xb5\x4d\x9e\x54\xc0\x7e\xc5\x6e\x38\xeb\x26\x89\x69\ +\x39\x3d\x70\x9b\xe4\x00\x81\xd6\xf2\x10\xb6\x24\xc2\x87\x1a\x1d\ +\x29\x79\xe8\x94\xc6\xae\x4f\x94\x43\xd1\xfe\xb4\x28\x23\xbb\x24\ +\x4b\x3e\xd3\xb8\x8f\x37\xa9\x52\xe6\xa4\xd0\xd6\x29\x5b\x92\xf4\ +\x7f\xcc\xe6\xac\xaa\x19\x4a\x7c\xa7\x8d\xcd\x11\x74\x5d\x20\x57\ +\x7b\xc1\xd2\xbb\xbd\xe8\x93\xd1\x2d\x30\x17\x1d\x96\xe7\x3a\xb2\ +\x93\xf1\x04\xb8\x6e\x37\x4c\xfe\xa6\x6b\x3f\xec\x12\x9c\x0e\x75\ +\x75\x57\x87\x60\x1d\xa0\xde\xa1\x6c\x3f\x94\x35\x99\x33\x37\x8e\ +\x53\xa3\xee\xcf\x68\x45\x62\x52\x91\x3e\x4f\xba\x1e\x33\x08\xa4\ +\x65\x50\x1e\xc3\xdf\xdf\xfd\x24\x53\x3f\x8a\xc2\xbf\x19\xff\xd4\ +\x27\xab\x50\x20\x4b\xb6\x01\x77\x49\x3a\x14\x24\x1b\x85\x50\xd0\ +\x80\xd7\xef\x92\x0c\xa2\x5f\xd4\xc2\x1f\xa0\x80\x41\xc6\x4a\xc1\ +\x48\x59\x80\xd5\x4f\xda\x4c\xcb\x69\x53\x19\x27\xb7\x07\x71\x94\ +\x25\x62\x90\xf1\x47\x95\xa4\xe9\x2f\xe2\x23\x03\x8a\x6a\x27\x4d\ +\xaa\x94\x0e\x78\xcb\x68\x57\xdf\x31\xca\xc0\xb8\xb9\xd1\x59\x5f\ +\xb7\xd6\x3d\x2a\xa3\xc4\x91\x8e\x4e\xc9\x92\x42\xa0\xfc\x2a\x84\ +\xca\x91\x74\xcd\xd9\xa6\xc8\x58\x4c\xdb\xe1\x12\x4d\x1a\xc9\x92\ +\xd2\xd2\xe6\x0a\x56\x1f\xb6\x5c\x74\x2b\x1a\x83\xf2\x50\x37\xf9\ +\x26\x85\x42\xf6\x40\x73\x16\xc7\xc0\xa8\x9c\x7d\xa2\xe1\x0d\x90\ +\x81\x5f\x13\xac\x68\x36\x19\x15\xca\xa6\x20\x4a\x58\x46\x58\xfe\ +\xbb\x21\x9c\x0e\x7b\xff\x61\x49\x1e\x02\x6e\x94\x77\xbd\x75\x23\ +\x85\xac\xa8\x42\xbb\xeb\x8b\x09\x90\x15\xe7\x64\x1f\xe6\xb0\x69\ +\x1b\xf6\x36\x6c\xdd\x7f\x69\xc0\xed\xed\x33\x0a\x74\x61\xae\x15\ +\x04\x3d\xb7\x4f\x6e\x41\xc4\x33\xbd\x0d\x11\xcf\x28\x2b\x20\xbe\ +\x03\xdd\xf6\xac\x00\x59\x2e\xd5\xb0\x2b\x05\x7c\xa4\xc6\x6b\x5e\ +\xb4\xb0\x63\xb9\x81\xdf\x57\x90\x82\x54\xf7\x53\xe8\x0f\xac\x14\ +\xc8\xb6\xa5\x6b\x80\xac\xd9\x2c\xca\xb2\xed\x43\x88\x97\x9b\xaa\ +\x7a\x2a\x80\xa5\xdf\xa5\x1d\x00\xe1\x6f\x0a\x9a\x21\xe5\x2f\xa5\ +\x03\x66\x0c\xb0\xb0\x08\xb2\xb5\xc7\xa1\x67\x7f\x96\xc3\x0a\x2b\ +\xc6\x35\xa8\x03\x0f\xa4\xda\x70\x3a\xe2\x12\xc9\x09\x10\xa4\x22\ +\x8d\x80\xb2\xa3\xe8\xb5\x43\x25\x41\x9a\xc9\x37\xe5\xbd\x82\xa6\ +\x20\xf3\xaf\x07\x32\xac\x83\x07\x91\xe9\xf8\xc5\xee\xf1\x98\x9d\ +\x40\x42\x56\x81\x99\xe9\xeb\xbe\xf2\xa3\x62\xe9\x66\xf3\x7a\xf4\ +\x72\x84\x8e\xe5\x79\xa6\x86\xce\xc6\xe7\x49\x62\x06\x7b\x8e\x8d\ +\x1d\xe7\xc9\x10\xc8\x14\xa7\xa3\xa4\x99\xe5\xc0\xc1\x24\x82\x3c\ +\xd2\x6c\xdd\xac\x41\x39\xf5\x7e\x0c\x05\x6c\xbb\x9e\x0d\x08\x9f\ +\x1e\x47\x42\xeb\x35\xf3\x59\x42\x01\x5b\xba\xdf\xd8\xdc\x1a\x2c\ +\xfa\x4c\x08\x05\x8c\xf4\xb6\x29\x05\x0a\x76\x67\x10\x21\x4a\x2a\ +\x81\x9c\x05\xba\xdb\x35\xec\x59\x97\xe7\x8a\xa7\xdb\xf5\x88\x99\ +\x04\xd4\xd7\x9d\x46\x07\xc6\x1f\x21\x6a\x23\xcb\x7b\x41\x44\xc1\ +\xf5\xf5\xaa\x02\xeb\x25\xe8\x68\xa2\x0c\x5e\xa9\x0b\x34\xeb\xd1\ +\xfc\x27\xf5\x2a\x4e\xf2\x52\xec\xe1\xb4\x08\xb6\xc3\x94\x6b\xf5\ +\x8e\x74\xa2\x06\x1d\x29\x42\x59\xd6\x0e\xf7\xa7\x57\x47\x1c\xbd\ +\x27\x2e\x24\x0e\xed\xfc\x1a\x73\xa5\x50\x98\xb8\x0b\xbc\x4b\xa1\ +\x08\x5e\x3d\x14\xee\x53\x45\xc5\xab\xaf\xac\x96\x79\x31\x06\xe7\ +\xb3\xcf\x95\x62\x20\xa8\xf9\x42\x0c\xce\xdf\xb4\x5f\xe3\x16\x33\ +\x1b\x6e\x31\xad\xa6\x00\x79\x00\x47\x57\x94\x2c\x38\xb5\x9c\x78\ +\x3f\xb1\xe1\xd4\xcc\x6f\x06\x10\xec\x77\xa5\xf9\x22\x40\xf0\xab\ +\x06\x64\xb4\xed\x31\xe5\x21\xa4\x7e\x3d\x7a\x39\x05\xc1\x4b\x12\ +\xc5\xf3\xc6\x44\xb7\x49\xbb\x30\x49\xec\x6f\x06\x10\x69\xec\x65\ +\x80\x3c\xd7\xce\x62\xb5\x42\x16\x5e\x4e\x9d\x26\xbc\x97\x3c\x4a\ +\x4c\xa2\xe7\x0d\x39\x57\xa4\x90\xdc\x55\x2b\xae\x6e\xd7\x9e\xb4\ +\x66\x5a\x77\x08\xe8\x8f\x0f\xbd\xda\x73\x9c\x28\x1e\x51\xd1\xae\ +\xe4\x4c\x01\x3e\x46\x88\x4c\x9d\xc1\xbd\xa7\x0f\xf9\xeb\x74\xda\ +\x13\xd6\x98\x1b\x42\x06\x1c\x32\x4d\x29\xb6\xee\x60\xd7\x73\x82\ +\xaf\x71\x3b\xe8\xd8\x3a\x20\x11\x74\x2e\x78\xaf\xb8\xc1\x61\x92\ +\xf5\xdc\xe2\x9f\xbf\x1b\x39\xf7\x82\xf0\xe4\xe5\xbf\x1d\xb8\xb6\ +\xbb\x3c\xff\xf2\x9f\xba\xe2\xdf\x61\xd8\xba\x87\x90\xbe\xdc\xf5\ +\x3f\x1e\x01\x28\xec\x0c\x50\x5f\xd2\xdb\x4b\xff\xee\x30\xd9\x57\ +\xb0\xee\xd2\xff\x58\x22\xb2\xdf\x6c\x0e\x5c\xfd\x3c\xe2\xc7\xad\ +\xee\xfa\x64\x74\xd5\x6f\x43\x82\x58\x76\x60\x5a\x8f\x4c\xff\x29\ +\x1c\x9b\x00\x3d\xc2\xf2\x05\xc2\x13\x3b\xad\x6d\x33\xd3\x6e\xf2\ +\xd6\x81\x18\xb5\x90\xee\x8b\x34\xc2\x47\x31\x1a\xe0\xf3\x4f\x92\ +\x97\xde\x61\x77\xbf\x4f\x7d\x09\xb9\x96\x90\xbe\x02\x72\x40\xab\ +\x2d\x17\x62\xaf\xe1\xca\x40\xfc\x62\x62\xea\xe8\x14\x72\x4f\x9c\ +\xdc\x73\x63\x7d\xf7\x66\x2e\x7e\xe3\xbc\x7b\xf3\x1f\x59\x71\xc4\ +\xd1\ +\x00\x00\x0b\x7b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x63\x6c\x61\x73\x73\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\ +\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ +\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\ +\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\ +\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\ +\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x2d\x32\x38\x2e\x38\x38\x38\x33\x37\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\ +\x34\x2e\x36\x31\x36\x37\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ +\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\ +\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ +\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ +\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ +\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ +\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x38\x37\x34\x31\x33\ +\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ +\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x39\x2e\x39\x34\x31\x32\ +\x35\x35\x2c\x31\x33\x2e\x31\x32\x35\x20\x48\x20\x32\x30\x20\x56\ +\x20\x38\x2e\x33\x37\x38\x36\x30\x33\x31\x20\x4c\x20\x32\x38\x2e\ +\x38\x30\x31\x34\x30\x33\x2c\x31\x35\x2e\x39\x37\x32\x38\x34\x31\ +\x20\x32\x30\x2c\x32\x33\x2e\x35\x36\x37\x30\x37\x37\x20\x56\x20\ +\x31\x38\x2e\x38\x32\x30\x36\x37\x39\x20\x48\x20\x39\x2e\x39\x34\ +\x31\x32\x35\x35\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x33\x38\x31\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ +\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\ +\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\ +\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ +\x39\x33\x37\x34\x39\x39\x39\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ +\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\ +\x2d\x31\x38\x2e\x34\x30\x36\x32\x35\x2c\x2d\x31\x33\x20\x43\x20\ +\x2d\x31\x39\x2e\x32\x39\x37\x36\x30\x39\x2c\x2d\x31\x33\x20\x2d\ +\x32\x30\x2c\x2d\x31\x32\x2e\x34\x38\x30\x30\x31\x32\x20\x2d\x32\ +\x30\x2c\x2d\x31\x31\x2e\x38\x34\x33\x37\x35\x20\x76\x20\x34\x37\ +\x2e\x36\x38\x37\x35\x20\x43\x20\x2d\x32\x30\x2c\x33\x36\x2e\x34\ +\x38\x30\x30\x31\x32\x20\x2d\x31\x39\x2e\x32\x39\x37\x36\x30\x39\ +\x2c\x33\x37\x20\x2d\x31\x38\x2e\x34\x30\x36\x32\x35\x2c\x33\x37\ +\x20\x68\x20\x33\x36\x2e\x38\x31\x32\x35\x20\x43\x20\x31\x39\x2e\ +\x32\x39\x37\x36\x30\x39\x2c\x33\x37\x20\x32\x30\x2c\x33\x36\x2e\ +\x34\x38\x30\x30\x31\x32\x20\x32\x30\x2c\x33\x35\x2e\x38\x34\x33\ +\x37\x35\x20\x76\x20\x2d\x31\x2e\x39\x33\x37\x35\x20\x43\x20\x31\ +\x32\x2e\x36\x30\x30\x39\x31\x2c\x33\x30\x2e\x36\x33\x30\x36\x30\ +\x36\x20\x37\x2e\x35\x2c\x32\x33\x2e\x38\x34\x36\x35\x31\x37\x20\ +\x37\x2e\x35\x2c\x31\x36\x20\x37\x2e\x35\x2c\x38\x2e\x31\x35\x33\ +\x34\x38\x32\x38\x20\x31\x32\x2e\x36\x30\x30\x39\x31\x2c\x31\x2e\ +\x33\x36\x39\x33\x39\x34\x35\x20\x32\x30\x2c\x2d\x31\x2e\x39\x30\ +\x36\x32\x35\x20\x76\x20\x2d\x39\x2e\x39\x33\x37\x35\x20\x43\x20\ +\x32\x30\x2c\x2d\x31\x32\x2e\x34\x38\x30\x30\x31\x32\x20\x31\x39\ +\x2e\x32\x39\x37\x36\x30\x39\x2c\x2d\x31\x33\x20\x31\x38\x2e\x34\ +\x30\x36\x32\x35\x2c\x2d\x31\x33\x20\x5a\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x39\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ +\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0e\x79\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x73\x6d\x5f\x61\ +\x64\x64\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\ +\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\ +\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x2d\x37\x32\x2e\x39\x38\x31\x36\x37\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x34\ +\x37\x2e\x30\x36\x32\x39\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ +\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ +\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ +\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ +\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ +\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ +\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ +\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ +\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ +\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ +\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ +\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ +\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x36\x30\x30\ +\x38\x39\x32\x34\x31\x2c\x30\x2e\x37\x39\x39\x33\x32\x39\x39\x31\ +\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x39\x2e\x38\x39\x33\x32\x36\x35\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x36\x31\x36\x38\x33\x38\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\x31\x34\ +\x2e\x36\x37\x38\x39\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x78\x3d\x22\x31\x2e\x38\x34\x36\x31\x39\x30\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x35\x2e\ +\x33\x38\x38\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x35\x35\x2e\x35\x31\x36\x38\x34\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x36\x65\x36\x65\x36\ +\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ +\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ +\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\ +\x34\x30\x33\x30\x37\x30\x34\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ +\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x63\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x36\ +\x39\x35\x32\x36\x35\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x32\x37\x2e\x31\x37\x34\x30\x34\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x33\x35\x2e\x34\x31\x31\x33\x37\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x31\x33\x2e\x36\x37\x32\x34\x38\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x35\x34\x30\x36\ +\x39\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\ +\x33\x2e\x32\x33\x38\x37\x36\x39\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x72\x79\x3d\x22\x35\x2e\x33\x35\x37\x37\x36\x34\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\ +\x2e\x35\x34\x33\x31\x30\x33\x31\x33\x2c\x30\x2e\x38\x33\x39\x36\ +\x36\x36\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\ +\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ +\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x31\ +\x32\x2e\x38\x30\x30\x30\x30\x30\x31\x39\x70\x78\x3b\x6c\x69\x6e\ +\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x30\x25\x3b\x66\x6f\x6e\x74\ +\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\ +\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\ +\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\ +\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\x64\x27\x3b\x6c\x65\x74\x74\ +\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\ +\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\ +\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\ +\x31\x2e\x34\x33\x30\x32\x31\x38\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x32\x33\x2e\x34\x38\x31\x39\x39\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\ +\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\ +\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\x61\x6e\x33\x37\x39\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\ +\x2e\x34\x33\x30\x32\x31\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x79\x3d\x22\x32\x33\x2e\x34\x38\x31\x39\x39\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\ +\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\ +\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\ +\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\ +\x2d\x73\x69\x7a\x65\x3a\x31\x34\x2e\x36\x36\x36\x36\x36\x36\x39\ +\x38\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\ +\x31\x2e\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ +\x3a\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\ +\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x27\x73\x61\x6e\x73\x2d\x73\ +\x65\x72\x69\x66\x2c\x20\x42\x6f\x6c\x64\x27\x3b\x66\x6f\x6e\x74\ +\x2d\x76\x61\x72\x69\x61\x6e\x74\x2d\x6c\x69\x67\x61\x74\x75\x72\ +\x65\x73\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\ +\x61\x72\x69\x61\x6e\x74\x2d\x63\x61\x70\x73\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x2d\ +\x6e\x75\x6d\x65\x72\x69\x63\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\ +\x6f\x6e\x74\x2d\x66\x65\x61\x74\x75\x72\x65\x2d\x73\x65\x74\x74\ +\x69\x6e\x67\x73\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\ +\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x77\x72\x69\ +\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\ +\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ +\x74\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x32\x22\x3e\x4f\x53\x4d\x3c\x2f\x74\x73\x70\x61\ +\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\xf8\ +\x00\ +\x00\x56\xfd\x78\x9c\xe5\x5c\xcb\x8e\xeb\xb8\x11\xdd\xf7\x57\x28\ +\xbe\x9b\x04\x31\x65\x8a\x7a\x50\x52\xdb\x3d\x8b\xb9\x18\xcc\x00\ +\xc9\x26\x33\x49\x80\x6c\x06\xb4\x44\xdb\xc2\xd5\xc3\xa0\xe8\xb6\ +\x7d\xbf\x3e\x45\xbd\x6c\xd9\x9a\x20\x00\x65\x40\xb0\x05\x34\xba\ +\x55\x55\x24\x8b\x47\xc5\xe2\x11\xc5\xe6\xf2\x87\x53\x96\x1a\x9f\ +\x5c\x94\x49\x91\xaf\x66\x96\x89\x67\x06\xcf\xa3\x22\x4e\xf2\xed\ +\x6a\xf6\xcf\xdf\x7e\x42\xfe\xcc\x28\x25\xcb\x63\x96\x16\x39\x5f\ +\xcd\xf2\x62\xf6\xc3\xc7\xdb\xf2\x4f\x08\x19\x3f\x0a\xce\x24\x8f\ +\x8d\x63\x22\x77\xc6\x2f\xf9\xb7\x32\x62\x7b\x6e\xfc\x79\x27\xe5\ +\x3e\x5c\x2c\x8e\xc7\xa3\x99\x34\x42\xb3\x10\xdb\xc5\x5f\x0c\x84\ +\x3e\xde\xde\x96\xe5\xe7\xf6\xcd\x30\x0c\x68\x37\x2f\xc3\x38\x5a\ +\xcd\x9a\x02\xfb\x83\x48\x2b\xc3\x38\x5a\xf0\x94\x67\x3c\x97\xe5\ +\xc2\x32\xad\xc5\xec\x62\x1e\x5d\xcc\x23\xd5\x7a\xf2\xc9\xa3\x22\ +\xcb\x8a\xbc\xac\x4a\xe6\xe5\x97\x2b\x63\x11\x6f\x3a\x6b\xe5\xcd\ +\xd1\xae\x8c\xac\x20\x08\x16\x98\x2c\x08\x41\x60\x81\xca\x73\x2e\ +\xd9\x09\xf5\x8b\x82\x8f\x43\x45\x09\xc6\x78\x01\xba\x8b\xe5\xff\ +\x67\x15\x96\x00\xe8\x1e\x7e\x3a\xf3\x56\x60\x96\xc5\x41\x44\x7c\ +\x03\xe5\xb8\x99\x73\xb9\xf8\xfa\xdb\xd7\x4e\x89\xb0\x19\xcb\xf8\ +\xaa\x9a\x16\xcf\x5e\xab\x3d\x90\x73\x96\xf1\x72\xcf\x22\x5e\x2e\ +\x5a\x79\x55\xfe\x98\xc4\x72\xb7\x9a\xd9\x8e\x69\xd9\x70\xb9\x95\ +\x70\xc7\x93\xed\x4e\xde\x4a\x93\x78\x35\x03\xef\x49\xe0\xd7\xf7\ +\x57\xc1\x61\xd5\x06\x4d\xc5\x61\xa7\xc1\x66\x40\x4c\xcb\x10\x96\ +\x6b\xd3\xda\xa6\xed\x42\x18\x17\x91\xf2\x09\xaa\xe4\x59\xc2\x0e\ +\xb2\xc8\xe0\xa9\x45\x51\xca\xca\x32\xd9\x24\x11\xdc\x14\xf9\x3e\ +\x3d\x6c\x93\xfc\xf7\xbd\xe0\x9f\x09\x3f\xfe\x2e\x78\x5c\x98\x2d\ +\x7e\x5d\x63\xfc\xb4\x2f\x84\x44\xa7\x78\x0f\x28\x7a\x74\x50\x79\ +\x6e\x95\x1f\xa0\x5d\xc6\x7c\x53\x2a\xab\xba\x4b\xea\x0e\xfa\x44\ +\x67\xc6\xa2\xd2\x76\x1e\x2a\xf7\x62\xd5\xf0\xc5\x76\xcd\xca\x1a\ +\x36\xc3\xd8\xb3\x2d\x84\x58\x5a\x88\xd5\xec\xcb\xa6\xba\x1a\xc5\ +\xba\x10\x31\x17\xad\xca\xab\xae\x9e\xaa\x80\xc7\x90\xc8\x73\x3d\ +\xa8\x9a\xba\x5b\x7f\x55\xad\x9d\x1e\x0f\xeb\xcb\x1d\x8b\x8b\xe3\ +\x6a\x46\x6e\x95\xdf\x8b\x22\x5b\xcd\xa8\x19\x58\x3e\x76\x2c\x7a\ +\xab\x8e\x4e\xab\x19\xb2\x6d\x93\xd8\x98\xba\xf6\x9d\x56\x39\xe4\ +\x98\x36\xf5\x6d\x72\x57\x73\x74\x10\x02\x86\x1d\x4a\xd9\x99\x43\ +\xaf\xaa\x5f\x56\x63\x54\xee\x8a\xe3\x56\x28\x74\xa4\x38\xf0\xdb\ +\x92\x4a\x83\xd6\xeb\xe2\x34\xac\x86\x28\x38\xa8\x01\x8d\x0e\x79\ +\x22\x61\xd0\xec\x4f\xd7\xb5\x1e\x92\x98\x97\xc3\x05\xcb\x9c\xed\ +\xd1\x36\x2d\xd6\x2c\x1d\x36\x38\x26\x39\xa0\x84\x9a\xf8\xb6\xec\ +\xee\x21\xdc\x5a\xb4\xc1\x4e\xb1\xff\x07\x16\xe0\xfb\xdd\x83\x68\ +\x54\xe7\x3f\x56\x65\xec\x94\x64\xc9\x77\x0e\xc0\x58\x55\xdc\x41\ +\x6c\xf5\x60\xa9\x8b\x19\x86\x3c\xab\x81\x7b\x3a\x2b\xd9\xac\x15\ +\x2a\x3c\x95\x80\x04\x01\xed\x84\x85\x48\x60\x3c\x5c\xb9\xd3\x8a\ +\xce\xd7\x22\x35\xcc\x21\x4b\x9f\xaa\x00\xab\xc2\x8f\xde\xea\xce\ +\xd7\xba\x26\xee\x17\xf7\x81\x5f\xc9\x33\x2e\x59\xcc\x24\xbb\x8c\ +\x82\x56\x02\xbe\xe1\xb6\x67\x90\x31\xc3\x7f\x7c\xfd\xe9\xa3\x69\ +\x68\x19\x45\xe1\xbf\x0b\xf1\xad\x6d\xd7\x30\x94\x01\x5b\x17\x07\ +\x40\x7a\xf6\xd1\x89\x97\x71\x14\x42\x8e\x83\xb1\xff\x91\x64\x10\ +\xdb\x2a\x3d\xfe\x15\x72\xda\x72\x71\x51\xf4\x8c\x15\x58\x97\x4a\ +\xeb\x6a\x05\xaf\x93\xe5\xe0\x8c\x11\x47\x59\xa2\x0a\x2d\x7e\x95\ +\x49\x9a\xfe\xa2\x1a\x69\x7a\x7c\x55\x69\x22\x53\x7e\x11\x2e\x17\ +\x8d\xf7\x4d\xdf\x16\x57\x9d\x5b\x2e\xda\xde\x57\x77\xdb\x0b\x2a\ +\xbd\x41\xd1\x3d\xe8\x94\xad\x39\x44\xe8\xdf\x94\xd2\xb8\xd3\x6e\ +\x45\x71\xd8\x67\x45\xcc\x9b\xe2\x1d\x9a\x3c\x92\xdd\x23\x93\xe7\ +\x14\xf4\x1b\xf0\x3e\xfc\x82\x71\x14\x6d\x36\xef\xea\x06\x35\x79\ +\x22\xb4\xea\x5b\x71\x48\x21\xdf\x7d\xf2\xbc\x88\xe3\xf7\x52\x8a\ +\xe2\x1b\x0f\x9b\xcc\xd4\xdc\xd6\x83\x21\xc4\xed\x2d\x00\xc3\x45\ +\x0a\x41\x2a\x43\xa7\x95\xc5\x0c\xd2\x8b\x10\xec\x1c\xe6\x30\xad\ +\xb7\xd2\xae\xa9\x5e\x7c\x2a\x2f\x5d\xdf\x0e\x3a\x61\x33\xd8\x1c\ +\x93\x54\xa1\x75\x51\xb4\x63\xec\x5e\xd3\x0b\xe6\xf3\x90\x85\xe8\ +\x99\x88\x2a\x74\x1d\xa2\x2e\xbb\x7b\x90\xff\x0b\x30\xc6\x62\x67\ +\x62\x80\x21\x4b\x13\xb2\x7b\xe1\x43\xa0\xf3\x3c\x1f\x4f\x0e\x3a\ +\xe4\x6b\x82\xe7\x9b\xae\x22\x35\xb6\xff\x58\xf0\x1c\xc7\x75\xa7\ +\x07\x1e\xd6\x04\xcf\x22\xe6\x43\x71\xdb\x6c\x08\x23\x6c\x72\xb8\ +\xd9\xba\xb0\xd1\x7a\xba\x7d\x45\xec\x10\xd5\x04\x8f\x58\x66\x35\ +\x60\x9d\x57\x04\xcf\x47\xae\x2e\x7c\xae\xe9\xbd\x22\x72\x18\xe9\ +\x8e\x5a\x12\x98\x7e\x9f\x3f\xbf\x0e\x43\x41\x8e\x26\x78\x83\x1c\ +\x05\x8f\x06\xda\x44\xb9\x89\x36\xb5\x1b\x64\x27\xe3\xc1\x36\x51\ +\x56\xa2\x3d\x47\xdc\xf2\x92\xb1\x10\xdb\x6c\x82\x60\x82\x88\xd9\ +\xc8\xd3\x05\x6c\x88\x91\x3c\x39\x6a\x88\x22\xa2\x09\xdb\x20\x17\ +\x79\x76\xd8\x80\x83\x20\xdd\xb7\xfc\x5b\x16\x32\x5e\x4a\x9b\xe0\ +\x8a\x88\xf6\x3b\x6a\x6f\x4d\xa4\x97\xdb\x9e\x93\x6c\xf8\xba\x80\ +\x0d\xb2\x8d\x51\x81\x9b\x2a\xe1\xd0\x1d\x98\x83\x84\x63\x54\xe4\ +\xa6\xca\x39\xb4\xa7\xd0\x1b\xce\x31\x22\x68\x3e\x56\xd7\xe4\x40\ +\xb3\xb5\xe7\xcf\x41\xda\xf1\xfc\xc0\x01\xf3\xd0\x7e\x19\x1d\x62\ +\x1e\x2f\x80\x9c\x22\x1f\xba\xb3\xc3\x2d\xf9\x78\x01\xd8\x30\xb2\ +\xf5\x17\xde\x86\xd6\x3f\x46\x9d\x1a\xa6\xc8\xdd\xb0\xf6\xd2\x47\ +\x8f\xbd\xdd\xcf\xaf\xcf\x49\xe1\x1c\xed\xb9\x61\x90\xc3\x8d\x0f\ +\xdf\x54\x89\x9c\xa5\xbd\xd2\x3b\x48\xe5\xc6\x07\x70\xaa\x7c\x8e\ +\x6a\x73\xe1\x5b\x46\x37\x36\x76\xb1\x33\xc9\xc9\xc2\x46\xde\x63\ +\x88\xdd\x8b\xe0\xa7\xd6\x95\x1e\xf3\x95\xeb\x55\x00\xac\x56\x98\ +\xb4\x3f\x4e\xdf\xd2\xbc\x57\x41\x4f\x71\x3d\xa2\xfd\xe5\x61\x90\ +\xed\x8d\x0d\xa1\x9a\x7c\xa7\x07\x21\xd6\x7d\x39\xeb\x31\xbe\xfb\ +\x91\xfc\x8c\x98\x59\xda\xeb\x27\x83\x7c\xef\x55\xc0\xf3\xb5\x27\ +\x8c\x41\xb6\xf7\x2a\xf0\x61\xed\x35\x81\x5b\xae\x37\x36\x72\x18\ +\xc3\xa3\x99\x1e\x72\x30\x53\x68\x7f\x6b\x1d\xa2\x7a\xe3\xc3\xe7\ +\x38\x6c\x82\xbb\x4a\xa8\xfe\x7e\x9c\x21\xa2\x37\x36\x7c\x84\xd1\ +\xcd\xf4\x96\x56\x6a\xa2\xa7\xbd\x12\x7a\x43\xf3\xc6\xc6\xce\xa7\ +\x8c\xc5\x7c\x7a\xd8\x55\x4b\x7a\x0f\xd9\xd3\x34\x36\x82\x6a\x85\ +\x60\x7a\xb3\x86\xfe\x2e\x93\xfe\x67\xd9\xbb\x34\xf8\x8c\xa0\xa9\ +\x85\xbd\x87\x10\xbd\x57\x81\xaf\x5a\xd8\x7b\xc8\xca\xde\xab\x20\ +\xa8\x56\xf6\x74\x97\xe4\xef\xbe\xd5\x8e\x8c\xdd\x64\xd9\x9e\xa7\ +\xcd\x57\x86\x3f\xd9\x8e\x8e\xdf\x54\xe9\x1e\xd1\x4e\x7f\xc3\x5f\ +\x6e\x47\x06\x70\xca\x84\x2f\x18\x9d\xf2\x8d\x8d\xde\x94\x29\x1f\ +\xd1\x5f\x17\x1d\xfc\x8e\x3b\x32\x84\xeb\x28\xb6\xdd\x29\x06\xa0\ +\xfe\x9e\xec\xe1\x85\xaa\x3b\x50\x9f\x14\x3f\x18\xbe\x8f\x59\xaa\ +\x7a\x11\x00\x31\xcc\xc1\x63\x6f\x35\x1b\x1b\xbb\xc9\xd2\x17\xf2\ +\x18\xfa\x32\x3e\x7e\x53\xa5\x2f\xb6\x36\x75\x1e\x5e\xaf\x1a\x19\ +\xc0\x29\xd3\x97\xf1\xff\x05\x6f\x6c\xf4\x7c\x9f\xb1\xe9\xbd\xb9\ +\x61\xe4\x68\x4f\xbd\xfd\x0f\x6b\xd7\x30\x3e\x23\x62\xd5\x2e\x2a\ +\xed\xd9\x76\x98\xae\x3c\x3f\x76\xd5\x4a\x8b\x36\x59\x1e\xe6\x2a\ +\xcf\x8f\x5e\xb5\x7f\x4a\xfb\x45\xed\x8e\xa8\x8c\x07\xdc\x64\x39\ +\x8a\x37\xc2\x2b\xda\x30\x4b\x19\x13\xbc\xa9\x12\x14\xc8\x77\x8f\ +\xd9\x3b\x35\x22\x7a\x53\x66\x27\x6a\x9e\x1d\x7b\xe3\xd4\x98\xe9\ +\x6e\xd2\x2b\x2b\xd6\x63\x76\x4d\x8d\x87\xdf\x55\x9f\xd4\x20\xae\ +\xf6\x9f\xf5\xb0\x21\xa6\x45\x5d\x6c\x11\xdf\x1e\x13\x24\x12\x04\ +\x77\x7b\x69\x6d\x72\x87\xc8\x95\x68\xf0\xb8\xb1\xf3\x90\x50\xe1\ +\xe1\xc2\x78\xc5\xf6\xf5\x19\x0a\x60\x6a\x9b\x3e\x76\x7c\xea\xbb\ +\x17\x58\xf6\x4c\xee\x6e\x60\xa9\x4e\xd6\xeb\xb0\xd8\x14\xb9\x44\ +\x95\x06\x7a\x26\x32\x96\xd6\x92\x4f\x26\x12\x96\xcb\x9e\xec\x58\ +\x39\xdd\x13\x01\x0e\x5c\x46\xbb\xbe\x2c\xf9\xce\xc3\x8c\xc7\xc9\ +\x21\x7b\x4f\x93\x9c\x37\x07\xc4\xf5\x6c\x36\x2c\x4b\xd2\x73\xf8\ +\x2b\xcb\xcb\x77\xd4\x9e\xe6\x85\xea\xe2\x7b\x1e\x75\x07\x18\xd6\ +\x16\x92\x9f\x24\x58\xc5\x1c\x1c\xc2\xf5\x1d\x4b\x93\x6d\x1e\x96\ +\x92\x09\x59\x0b\x62\x1e\x15\xa2\x2e\x53\x3d\xa1\x1b\x21\x52\x9e\ +\xd4\x9a\x94\x4b\x78\xbe\xa8\x39\xc9\xad\x75\xeb\x58\x88\xf8\x56\ +\x56\xd5\x21\x05\xb8\xa0\x4e\x52\xab\x4b\x1f\x45\x22\xc1\x04\xa9\ +\x43\xc7\xc2\x54\x20\xb9\x7e\x8f\x13\xf5\xc4\x55\xcb\xa9\x14\xef\ +\xea\x88\xc3\xaa\xdb\xe5\x2e\xd9\xc8\xb0\xbd\x6d\xdc\xce\xa3\x1d\ +\x80\x5f\xfb\x1d\x27\xe5\x3e\x85\x88\x4a\xf2\xca\xa0\xf8\xe4\x62\ +\x93\x16\xc7\xf0\x33\x29\x93\x75\xca\xdf\xab\xdf\x49\xaa\x02\xac\ +\x15\xd5\x29\xa1\x19\xe2\x37\x29\xa1\x09\xf2\xeb\xf8\xac\x23\xdc\ +\x36\x9d\xea\x14\x4a\x87\xbc\x67\x4c\x7c\xe3\xa2\xb6\xe1\x39\x83\ +\x2a\xd1\x9a\x45\xdf\xd4\x31\x6a\x79\x1c\xb2\x28\x3a\x64\x87\x94\ +\x49\xde\x85\x15\x84\xf3\xdf\x0d\x7f\x1e\x98\x5e\x1d\x84\xc6\x8f\ +\x06\x44\x99\xe5\x60\x0b\xd3\xb9\xe5\x98\x3e\xf5\x68\xe0\x1a\x8e\ +\xe9\xd8\xc4\x0f\x40\x46\x88\xe9\x39\x0e\x0d\x1c\x23\x30\x9d\x39\ +\x69\x66\x65\x6a\xa8\xa3\x11\x3d\x6a\xe1\x60\x6e\xc3\xe8\xf5\x7d\ +\xd7\x31\x60\xd2\x09\x1c\x6a\x3b\xf6\xdc\xc6\x50\xa7\x1a\x83\x06\ +\xf1\xea\x13\x33\xc9\x5c\xa5\x00\x23\x82\x9a\x2d\xdf\x0d\x82\x39\ +\x72\x4d\x52\x9b\xd8\xa6\x0b\x15\x59\x73\x04\x54\x29\xa0\xbe\x45\ +\xa8\x81\xa0\x4a\xb8\xa7\xa6\x63\xa4\x86\x3d\x47\xa4\x4e\x29\xd0\ +\xec\xcf\x46\x4b\x0c\x3c\xe3\x5f\x86\x57\x1b\x98\x64\xde\x92\x54\ +\x83\x34\x3d\x9b\x23\xdb\xa4\xd0\x1e\x31\x6d\x1a\xd8\x98\xcc\xc1\ +\x8a\x52\x4a\x02\x30\xb7\xc0\x6f\xd7\x87\x32\x81\x8b\x21\x83\x19\ +\xb8\x2e\xec\xcc\xc1\x03\x52\xfd\x65\x40\x69\xec\x28\x4f\xa1\x1c\ +\xf5\x3d\x4c\x41\xe4\x9b\x84\x60\x6a\x79\x73\xc8\x7b\x56\x40\x09\ +\xb8\x69\x99\x34\x50\xd7\x1c\x46\x75\xdd\x3e\x14\x74\x69\x00\xd9\ +\xc7\x55\x1e\x58\xbe\x67\xfb\xd0\x1f\xa7\xae\xcd\x07\x21\xb4\x6a\ +\xd9\x01\x71\xa1\x74\xd5\x65\xf5\x08\xa0\x1e\xa2\x1a\xb7\xeb\xbf\ +\x3c\x33\x68\xba\x7b\xfd\xa4\xfe\xd3\x4b\x4a\x2a\x11\x90\xe0\xea\ +\xdf\x84\x2f\x67\x53\x16\x79\x0e\xf1\x5b\x08\x14\x1d\xc4\x27\x93\ +\x07\xc1\x7b\xa7\x21\x76\xa7\x1a\x42\xc4\xab\x83\x00\x4b\x48\x21\ +\x65\x19\x55\x97\xfa\xdd\x9d\x7f\xb8\xfd\x78\x5b\xaa\xf3\x07\x3f\ +\xde\xfe\x0b\xb7\x0d\x2e\x74\ +\x00\x00\x08\xae\ +\x00\ +\x00\x1e\xc0\x78\x9c\xed\x59\x5b\x8f\xe2\x56\x12\x7e\xef\x5f\xe1\ +\x65\x5e\x12\x2d\x36\xe7\x7e\xa1\xe9\x8e\xb4\x19\x45\x8a\x94\x7d\ +\xd9\x4d\x94\xc7\xc8\xd8\x07\xda\x3b\xc6\x46\xb6\x69\x60\x7e\x7d\ +\xbe\x63\x63\x03\x0d\xcc\xcc\x6a\x7a\xd4\x59\x69\x21\x33\x83\xab\ +\xea\x5c\xea\x3b\x5f\xd5\xa9\x72\x66\x3f\xec\x56\x79\xf0\xec\xaa\ +\x3a\x2b\x8b\x87\x11\x8d\xc8\x28\x70\x45\x52\xa6\x59\xb1\x7c\x18\ +\xfd\xf6\xeb\x4f\xa1\x19\x05\x75\x13\x17\x69\x9c\x97\x85\x7b\x18\ +\x15\xe5\xe8\x87\xc7\xbb\xd9\xdf\xc2\x30\xf8\xb1\x72\x71\xe3\xd2\ +\x60\x9b\x35\x4f\xc1\xcf\xc5\x87\x3a\x89\xd7\x2e\xf8\xee\xa9\x69\ +\xd6\xd3\xc9\x64\xbb\xdd\x46\xd9\x41\x18\x95\xd5\x72\xf2\x7d\x10\ +\x86\x8f\x77\x77\xb3\xfa\x79\x79\x17\x04\x01\xd6\x2d\xea\x69\x9a\ +\x3c\x8c\x0e\x03\xd6\x9b\x2a\x6f\x0d\xd3\x64\xe2\x72\xb7\x72\x45\ +\x53\x4f\x68\x44\x27\xa3\xa3\x79\x72\x34\x4f\xfc\xea\xd9\xb3\x4b\ +\xca\xd5\xaa\x2c\xea\x76\x64\x51\xbf\x3b\x31\xae\xd2\xc5\x60\xed\ +\x77\xb3\xe5\xad\x11\xb5\xd6\x4e\x08\x9b\x30\x16\xc2\x22\xac\xf7\ +\x45\x13\xef\xc2\xf3\xa1\xd8\xe3\xb5\xa1\x8c\x10\x32\x81\xee\x68\ +\xf9\x65\x56\xd3\x1a\x80\xae\xf1\x67\x30\xef\x05\x51\x5d\x6e\xaa\ +\xc4\x2d\x30\xce\x45\x85\x6b\x26\xef\x7f\x7d\x3f\x28\x43\x12\xa5\ +\x4d\x7a\x32\x4d\x8f\xe7\xd9\xaa\x67\x20\x17\xf1\xca\xd5\xeb\x38\ +\x71\xf5\xa4\x97\xb7\xe3\xb7\x59\xda\x3c\x3d\x8c\xb8\x88\x28\xc7\ +\x47\xb6\xc2\x27\x97\x2d\x9f\x9a\x97\xd2\x2c\x7d\x18\x61\xf7\xcc\ +\x9a\xee\xf9\x84\x1c\xb4\x33\x38\x4c\x3c\x1d\x34\x24\xb2\x2c\xa2\ +\x41\x45\x25\xd7\x9d\x4d\xef\xc2\x34\x2d\x13\xbf\x27\x4c\xe9\x56\ +\x59\xbc\x69\xca\x15\x4e\x2d\x49\xf2\xb8\xae\xb3\x45\x96\xe0\xa1\ +\x2c\xd6\xf9\x66\x99\x15\x7f\x54\x65\xf6\x47\xb9\xf6\x82\x3a\xea\ +\xe1\x1b\xd6\x72\xbb\x75\x59\x35\xe1\x2e\x5d\x03\x44\xa5\xaf\x2a\ +\xf7\xa7\xca\xe7\xcc\x6d\xff\x51\xee\xb0\xb9\x80\x04\x9c\xe1\xbf\ +\xd1\x23\xe4\xb3\xd4\x2d\x6a\xaf\xef\x1c\xf5\x4f\xf0\x54\x8f\x82\ +\x49\xab\x1d\xf6\xed\x37\x9d\xfa\x39\x8e\xb6\xf3\xb8\xee\xc0\x0c\ +\x82\x75\xbc\x04\xf1\xf2\xb2\x7a\x18\xbd\x5b\xb4\x9f\x83\x62\x5e\ +\x56\xa9\xab\x7a\x95\x6a\x3f\x67\xaa\x12\x87\x93\x35\xfb\x2e\xd4\ +\x0e\x73\xf7\x6e\xf8\x59\x07\x3d\xb9\xae\xaf\x9f\xe2\xb4\xdc\x3e\ +\x8c\xd8\x4b\xe5\xc7\xb2\x5c\x3d\x8c\x74\x64\xa9\x21\x82\xea\x97\ +\xea\x04\x48\x84\x3a\xa2\x4c\x2b\xaa\x2e\x06\x27\x58\x90\xe9\x48\ +\x50\x6e\xe5\x85\x6e\x53\x55\x88\xc5\x30\x8f\xf7\x0e\x4e\xb5\xff\ +\xd0\x83\x51\xfd\x54\x6e\x97\x95\x07\xa7\xa9\x36\xee\xe5\x48\xaf\ +\x09\xe7\x73\x7f\x08\xd7\xd4\xa0\xc6\xc6\x47\x79\xb8\x29\xb2\x06\ +\x91\xb4\xde\x9d\xce\xba\xc9\x52\x57\x5f\x1f\x58\x17\xf1\x3a\x5c\ +\xe6\xe5\x3c\xce\xaf\x1b\x6c\xb3\x02\x20\x85\x07\xd2\x53\x3e\x9c\ +\xc1\x4b\x8b\x3e\x02\x34\xb1\x37\x2c\x3c\x81\x6e\xa8\xf6\xb7\x55\ +\xab\x78\x97\xad\xb2\x8f\x0e\xc0\xd0\x96\x76\xa0\xd6\x19\x2c\xdd\ +\xb0\x20\x68\xf6\x3e\x9a\x77\x7b\x2f\x1b\xf5\x42\x8f\xa7\x17\x30\ +\x6b\xf5\x20\x2c\xab\x0c\x41\x72\xb2\x9d\x5e\xb4\x3f\x15\xf9\xd8\ +\x47\xea\xde\xf9\x75\x5f\xc8\x3c\xe7\x7a\x9a\x4f\x2e\x79\xde\xca\ +\x57\xae\x89\xd3\xb8\x89\x8f\xa4\xef\x25\xd8\x0b\xe9\x3d\x41\xda\ +\x9c\xfe\xeb\xfd\x4f\x8f\x87\x05\x66\x49\x32\xfd\xbd\xac\x3e\xf4\ +\xeb\x05\x81\x37\x88\xe7\xe5\x06\xc8\x8e\x1e\x07\xf1\x2c\x4d\xa6\ +\x48\x74\x48\x00\x8f\xd9\x0a\x54\xf6\x39\xf2\xef\x48\x6c\xb3\xc9\ +\x51\x71\x66\xec\xc1\x39\x4e\xda\x4d\x5b\xb9\x2e\x63\x5e\xbd\x36\ +\xd2\x64\x95\xf9\x41\x93\x7f\x37\x59\x9e\xff\xec\x17\x39\x78\x7c\ +\x32\x69\xd6\xe4\xee\xb1\x5d\xb3\xfb\xd9\x7b\x31\x39\xb8\x71\x70\ +\x72\x72\xe2\xe5\x6c\xd2\xc3\xd0\x3e\x2d\x8f\xf0\x9c\x45\xc3\x70\ +\xc2\x79\x3c\x77\xa0\xe6\x2f\x5e\x19\x5c\x68\x97\x55\xb9\x59\xaf\ +\xca\xd4\x1d\x86\x0f\xb0\xba\xa4\x19\xce\xac\xd9\xe7\xd0\x2f\xe0\ +\xc6\xf4\x9d\xb3\xf1\x9c\xaa\x7b\xff\x10\x1e\xf2\xc3\x94\x76\x8f\ +\xd5\x26\x47\xfa\x7b\x76\x45\x99\xa6\xf7\x75\x53\x95\x1f\xdc\xf4\ +\x1d\x35\xa9\x5a\x2c\x0e\x8f\x5d\x14\x4c\x59\x44\xb8\x25\x5a\x08\ +\xd6\xcb\x01\x95\xab\x72\xd0\xb4\x99\x8a\x5e\x96\xc6\xc8\x2f\x55\ +\x15\xef\xa7\x05\x6e\xfb\x5e\x3a\xac\x79\xc6\x50\xbf\x5d\xb0\xc2\ +\x0e\xc2\xfe\x8e\x39\xb2\x71\xb8\x60\x8e\xa2\x33\x66\xee\x4f\x1f\ +\x2a\xa8\x44\x04\xca\x33\x76\x22\x84\x09\x8f\xa4\xd2\x44\x73\x35\ +\x9c\xe5\x6c\x1d\x37\x4f\x57\xa1\xb2\xed\x67\x40\xa2\xcb\xcd\xe7\ +\x48\x70\x20\xa1\xa5\x64\x6a\xbd\xeb\x15\x79\x56\x38\x1c\xcd\x74\ +\xbe\x69\x9a\x53\xd9\x7f\xca\xac\x98\xb6\x38\xdd\x86\xc2\xc7\x48\ +\x40\xd5\x58\x07\x49\x40\xc6\xd4\x1c\xff\x3a\x43\xcb\xef\x98\x6b\ +\x65\x43\x75\x14\x0f\x19\xb6\x2c\xb0\x7e\x53\x56\x21\x72\xed\x73\ +\xdc\x6c\x2a\xe7\x63\xfa\xf3\xde\x1a\xe2\xbf\x9f\xf1\x96\x2b\xa1\ +\xb5\x52\xf4\x15\xdd\xd5\x63\x2a\x71\x28\x02\x5f\x78\x4d\xcd\x98\ +\x1c\xff\xba\xf4\xda\x08\xfd\x8a\x3e\x0b\xc3\x35\xd7\x83\xcf\x4c\ +\xf8\xef\x4b\x9f\x19\xb7\x42\x0b\xfe\xdf\x3b\xfc\x35\x41\x01\x7f\ +\xff\x19\x50\x11\x11\xad\xb5\xe5\x63\xaa\x22\x49\x95\xd6\x01\x93\ +\x91\x11\x42\x80\x23\x32\xa2\x82\x58\x4b\xe9\x25\x48\x38\xc7\x57\ +\x04\x09\x15\xe8\x82\xb1\x2f\xcf\x18\xd7\x50\x44\x01\x22\x85\x20\ +\xc6\x7e\x0a\x9b\xdb\x28\x08\x61\x0c\x67\x63\x46\x23\x25\x24\x67\ +\x36\xd0\x91\xe2\xd6\x30\x39\x46\xa1\x21\x35\x15\x8c\x07\x3f\x42\ +\x48\x84\x22\x4c\x8f\x99\x89\x88\x31\x08\xfd\x40\x46\x8a\x31\x8c\ +\x1d\x7b\xdc\x94\xb1\xd4\x42\x44\xac\xc4\x91\x7a\x11\x52\x8e\x30\ +\x32\xf8\x25\xe0\x91\xd1\xf0\x13\x4b\xf0\xc8\x82\xe0\x42\x62\x3e\ +\xd0\x5d\x30\x49\xa5\x17\x0a\xa2\x19\xb1\x10\x51\xae\x09\x97\x7e\ +\x2b\xd6\x4a\xcc\x0d\x91\x06\xe0\xdd\xee\x84\x36\x82\xe9\x20\x0f\ +\x54\x64\x88\x25\x44\x8f\x43\x89\x72\x56\x11\xcb\x7d\x44\x47\x5a\ +\x2a\x29\xcd\x18\xb5\xb8\x92\x46\x48\x15\xa0\xd2\x25\xd4\x08\xeb\ +\x45\x9a\x2a\x82\xcd\x30\x1c\xb0\x31\x52\x79\x11\x65\x0c\xf5\x17\ +\x12\x00\xc2\x21\x02\xa8\x98\xdc\x8b\x89\xa2\x84\xc1\x90\x69\x69\ +\xe8\x98\x61\x73\x4a\x19\xe4\x89\xc8\x48\x8a\x08\xf1\x12\x70\x05\ +\xdb\x85\xad\xe4\x88\x58\x36\x06\x8d\xa9\xd4\x1c\x22\xea\x7f\x29\ +\xcd\x21\x42\xc0\x73\x61\x82\x8f\x17\xa9\x18\x4b\xc9\x2f\x66\xd0\ +\x40\x9a\xa1\x0c\xc0\x75\xe4\x6f\x4e\x54\x5c\x75\xfb\x49\x3e\xd6\ +\x47\x9e\xb9\x3c\xcf\xd6\xb5\xbb\x4a\xb5\x03\x75\xbe\x98\x6a\xd7\ +\x92\x14\x5c\x06\xd7\x08\xdc\x7f\xad\xcb\xa9\x8d\x29\xcb\x78\xc8\ +\x07\x71\x53\xc5\x45\xed\xcb\x0c\x64\xb0\xb8\xa9\xb2\xdd\x77\xfe\ +\x58\xa4\x54\x8c\xb2\xf6\x7c\xad\xc5\xf9\x52\xb0\xcc\xff\xd6\x4a\ +\x70\x21\xa5\xff\x0d\xec\x0d\x28\x24\xc7\x38\xd3\xef\x87\xe9\xda\ +\x82\x1a\x2c\x63\x4a\x58\x75\x5c\xc5\x57\xd2\xa1\xf0\x7c\x50\x18\ +\x73\x76\xb9\xf9\x54\xcc\x38\xe1\x67\x97\x1b\x8b\x2c\x98\xc1\xe9\ +\xe7\x83\xfa\xc4\xe9\x36\xc0\xf1\x79\x89\x22\x3a\x4f\xce\xd8\x9b\ +\xa4\x3d\x10\xd9\x52\x2e\xad\xbf\x19\x04\x27\x0c\xd1\x83\x4c\x68\ +\x18\x97\x6d\x94\x71\xa9\xb8\xd1\x17\x47\x24\x8d\x55\xe1\xe9\x21\ +\x7d\x4d\xea\x6b\xbb\xae\x01\x9a\x34\xab\xd7\x28\xaf\xd0\x33\x7b\ +\x97\xef\x4b\x34\xab\x8b\xbc\xdc\x4e\x9f\xb3\x3a\x9b\xe7\xee\xbe\ +\xfd\x37\xcb\xbd\x2f\xbd\xe8\x12\xe6\xb9\xf3\xdf\x97\x30\x6b\xf4\ +\x58\x08\x63\xf1\x2d\x71\xf6\xd2\x72\xb1\xa8\x5d\x33\x25\x17\xd8\ +\xdf\xaf\xe2\xea\x83\xab\xba\x01\xae\x88\xb1\xf9\x70\x1e\x27\x1f\ +\x7c\x65\x59\xa4\xd3\x38\x41\x63\xb5\xc9\xe3\xc6\x5d\x64\x65\x85\ +\xcb\x53\xd1\x31\xb5\x91\x30\xd6\x58\x1d\x58\xa4\x67\xa6\x6c\x9b\ +\x45\xa5\xb0\xf2\xd6\x11\xd1\x57\xbc\x9d\x98\xa2\x48\x96\x2f\x53\ +\x46\x8f\x79\xa2\xfd\xf7\x2d\x30\xbf\x55\xdc\xb1\xc8\x67\x03\x0f\ +\x1b\xae\x74\x8b\xe4\x1f\x84\xbe\x50\x45\xc2\x1e\x83\xe3\xd2\x2a\ +\x22\x6e\xc2\x16\xda\xd7\x03\xee\x0b\x32\x80\x36\xcc\x68\x66\xd4\ +\x1b\xa4\x80\x63\x99\xe3\x5f\x24\x28\x2a\x94\xf5\x05\x21\xbd\x49\ +\xa9\x57\x44\xe6\x46\xc1\x73\x82\x95\xd7\xfe\x65\x8a\x44\xe6\x19\ +\x65\x88\x42\x4d\x82\xb2\x82\x4a\xcb\xa5\xcf\xa0\xb8\x48\x8d\x46\ +\x06\xc5\xb5\xc4\x04\xd5\x97\xe9\xd2\x57\x89\xe1\x2b\x16\xd3\x7f\ +\x65\x42\xb5\x71\x87\x68\xb3\x40\xc9\xa2\xd4\x63\x82\x5b\x1a\x18\ +\xdc\x24\x04\x25\x16\x38\x86\x8a\x8a\x6a\x66\x6f\xb2\xeb\x35\x3b\ +\xad\x33\xa0\xae\x55\x30\x34\x22\xa8\x68\x95\xa0\xf4\x2d\x80\x22\ +\x91\x90\x8c\x0a\x04\x1b\x9a\x5b\xe9\x21\xeb\x81\xe2\x3d\x50\x97\ +\xe5\xd1\x80\x93\x0d\xd9\x57\x22\xd5\x57\x91\xdd\xdb\xac\xb8\x4a\ +\x46\xdf\xe4\x6a\xfe\x6c\x5b\x03\xac\x3e\xba\xaa\x3c\xb6\x35\xdc\ +\xc8\x23\x75\x0f\x94\xfe\x1f\xba\xb5\x8f\x95\xec\xc9\x6b\x96\x01\ +\xed\xb6\x02\x45\x68\xa0\x6d\xa2\xea\x8a\x1a\xd5\xa5\x8d\x38\x30\ +\x30\xea\xca\xe8\xae\x22\xd5\x16\xdd\xd2\x95\xc1\xdd\x7b\x17\x8b\ +\x89\xb9\xe1\xe7\x6c\x0b\x95\xef\xc6\xf4\x78\x98\x3b\x88\x83\x7e\ +\xa2\xf1\x30\x26\xf0\xaf\xdd\x69\x10\xfa\x56\x0b\x5d\x92\x90\x9d\ +\x0a\xcd\x11\xfd\xa4\xb5\x11\xaa\xed\xdf\xfc\x4f\xa2\x34\x7a\xc3\ +\xdb\xe6\x1c\x9d\x22\xca\x18\x36\xc6\x75\x8c\xc2\x97\x23\x9f\xa3\ +\x8f\x43\x0b\xa6\x14\x21\xc6\x9b\x53\x8d\x84\x2a\x4f\xba\xa5\xc1\ +\xc1\xba\x89\xab\xe6\x6a\x2b\xe4\x8a\xd4\xbf\x88\x42\x7b\x86\xc5\ +\x8f\xd0\x5c\x6f\x1f\xd0\x9f\xe2\x0a\x51\x5d\xfb\xa0\x51\xd7\x08\ +\x3e\x6e\x7f\xa2\x5c\x91\x5d\xdf\x87\x46\x58\x2b\xdb\x35\x0f\xff\ +\x0f\x9f\xb7\x0a\x9f\xf0\x46\x00\xa1\x37\x31\x56\xa0\xeb\xbb\x1e\ +\x40\x21\x13\xe8\xda\xa4\x22\xd7\x62\xe4\x10\x41\xd4\x72\xa2\x6f\ +\x87\x90\x7f\x1f\x70\x1e\x41\xa8\x94\x40\x2e\xca\xd0\x69\x0e\xd3\ +\x1f\x82\xa8\x9d\x6b\xdc\x0f\x3b\x0d\x22\x25\x4d\xa7\x00\xa7\xd5\ +\x27\x6d\xfd\x5b\x0a\x34\x62\x6d\x04\x69\x4e\x6f\xdb\xb6\xf1\xc3\ +\xb9\x38\xc4\x0f\xa6\x3e\x84\x8f\xb4\x86\xb5\xe1\x83\x82\xee\x5b\ +\x46\x0f\x91\x86\x09\x22\xda\x88\x41\xf7\xcd\x49\xd7\x7b\xfb\xdf\ +\x92\xb6\x3d\x39\xf1\xef\xa0\x38\xb2\xcd\x49\xf8\xcc\x26\xcb\xc7\ +\xbb\x99\xff\xbf\x07\x8f\x77\x7f\x02\x11\xca\xfc\x10\ +\x00\x00\x06\x3a\ +\x00\ +\x00\x24\xc9\x78\x9c\xdd\x59\x6d\x8f\x9b\x46\x10\xfe\x9e\x5f\x81\ +\x7c\xaa\x74\xa7\x7a\x81\xe5\xc5\x06\x62\x5f\x3e\x34\xaa\x54\x29\ +\x55\xab\x26\x69\xa5\x7e\xa9\xd6\xb0\xc6\x34\x18\xd0\xb2\x3e\xdb\ +\xf9\xf5\x9d\x5d\x58\x0c\xf8\x25\x71\x65\x5f\x7c\x01\x45\xe7\x9d\ +\x99\x7d\x99\x67\x66\x9e\x1d\x94\xc9\x9b\xcd\x32\xd5\x9e\x28\x2b\ +\x93\x3c\x9b\x0e\xb0\x6e\x0e\x34\x9a\x85\x79\x94\x64\xf1\x74\xf0\ +\xf1\xc3\xcf\xc8\x1b\x68\x25\x27\x59\x44\xd2\x3c\xa3\xd3\x41\x96\ +\x0f\xde\x3c\xbe\x9a\x94\x4f\xf1\x2b\x4d\xd3\x60\x72\x56\x06\x51\ +\x38\x1d\x2c\x38\x2f\x02\xc3\x28\x56\x2c\xd5\x73\x16\x1b\x51\x68\ +\xd0\x94\x2e\x69\xc6\x4b\x03\xeb\xd8\x18\xec\xcc\xc3\x9d\x79\xc8\ +\x28\xe1\xc9\x13\x0d\xf3\xe5\x32\xcf\x4a\x39\x33\x2b\xef\x5a\xc6\ +\x2c\x9a\x37\xd6\xeb\xf5\x5a\x5f\xdb\xd2\x08\xfb\xbe\x6f\x98\x96\ +\x61\x59\x08\x2c\x50\xb9\xcd\x38\xd9\xa0\xee\x54\x38\xe3\xa1\xa9\ +\x96\x69\x9a\x06\xe8\x76\x96\x5f\x67\x15\x6c\xd2\x24\xfb\x74\xf4\ +\x30\x52\xdb\xde\x1d\x30\x2c\xe0\x5f\x33\x41\x09\xf4\x32\x5f\xb1\ +\x90\xce\x61\x26\xd5\x33\xca\x8d\xb7\x1f\xde\x36\x4a\x64\xea\x11\ +\x8f\x5a\xcb\xc0\xa2\x65\x48\x0a\xda\xd9\x57\x09\x2b\xbc\xc8\x92\ +\x96\x05\x09\x69\x69\x28\xb9\x9c\xbf\x4e\x22\xbe\x98\x0e\x6c\x47\ +\xc7\x36\x3c\xae\x14\x2e\x68\x12\x2f\x78\x5f\x9a\x44\xd3\x01\xf8\ +\x6a\xf9\x5e\x35\x6e\xe5\x03\xae\x0c\xea\x85\x83\x76\xa6\xe8\x96\ +\x76\x4f\xbd\x51\xe8\x8d\x4d\x6f\xec\x0f\x35\xcb\xb4\x30\x32\x31\ +\xc2\xee\x83\x9c\xa4\x7c\x0a\xa2\x3c\x14\x87\x84\x3d\xe8\x32\x21\ +\x2b\x9e\x2f\x21\xe8\x61\x98\x92\xb2\x4c\xe6\x49\x08\x83\x3c\x2b\ +\xd2\x55\x9c\x64\xff\xb0\x55\xa6\x2b\xd4\x9b\x4d\xe9\xa6\xc8\x19\ +\x47\x9b\xa8\x00\x34\xb1\x3a\x73\x4f\xbb\x6d\xb4\x8f\xa0\x9e\x44\ +\x74\x5e\x0a\xb3\xca\x39\x31\x02\xef\xc6\x52\x07\xda\x30\x4d\x8a\ +\xdf\x09\x5f\x54\x16\x9a\xa6\xc6\x1f\xb3\x84\x43\x3a\xac\x4a\xca\ +\xde\x0b\x48\x7f\xcb\x3e\x96\x15\x9a\x6a\x25\x65\x89\xb1\xe3\xd6\ +\xab\xc1\x7a\x30\x41\x19\x41\xe0\xa6\x03\x73\xb0\x1b\x6e\xbb\x43\ +\x99\x27\xc1\x82\x51\xc8\xeb\xbb\x18\x96\xc1\x2d\xa5\xd8\x01\xd6\ +\x02\xe9\xb8\x25\xad\x23\x89\x4d\xf3\x87\x96\x54\x85\x52\x8a\x35\ +\xa3\xf6\xcc\x50\x07\xbc\x9c\xa7\x1e\x14\xd9\x08\x5e\xeb\x12\xfe\ +\x7a\xd8\x43\x1e\x46\xb0\xa4\x77\xc0\x6f\xcf\x72\x90\x6b\x22\xc8\ +\xa1\x9b\x73\xff\xa2\xce\x9f\x70\xfd\xc6\x1c\xbf\x9c\xdb\x47\x7d\ +\xbe\x31\x8f\x91\x7d\xc9\x50\x1f\x8f\xb4\x7f\x09\xbf\x27\x86\xa0\ +\x36\xf9\xab\xa1\x5b\xc1\xb5\xd1\x53\x42\xd7\x3b\xfe\x9b\x91\xc6\ +\xe5\x82\xc4\x70\xdd\xa6\x39\x83\x63\xce\xe5\x53\x2b\x66\x39\x8b\ +\x28\x53\xaa\x91\x7c\x3a\xaa\x1c\xd0\x4b\xf8\xb6\xea\x12\xea\xb5\ +\x15\x09\x8b\x55\x1b\xbd\x79\x58\x5f\x2e\x48\x94\xaf\xa7\x03\xab\ +\xaf\xfc\x9c\xe7\xcb\xe9\xc0\xd5\x5d\xdf\xf3\x4d\xd3\xeb\xab\x43\ +\x00\x1e\xe1\x91\x6e\x63\xc7\xaf\xc9\xbf\xad\x85\x0d\x3d\x1d\xbb\ +\x63\xd7\xf6\xfc\x3d\xe5\x8a\x31\x68\x41\x50\x4a\xb6\x14\xbc\x92\ +\x7f\x54\x22\x96\x8b\x7c\x1d\x33\x81\x0e\x67\x2b\xda\x9f\x29\x34\ +\x68\x36\xcb\x37\x87\xd5\x70\xa5\xad\x44\x73\x83\x56\x55\x76\x15\ +\x9b\xf6\xaa\xab\x24\xa2\x20\x9c\x93\xb4\xdc\x9b\xb9\x4e\x32\x40\ +\x01\xa9\x88\xdb\x0d\xc8\x7d\x0b\x15\xfd\xb1\x79\xcc\xa2\x95\x90\ +\x7d\xd5\xf6\xb8\x6a\x49\x36\xc9\x32\xf9\x4c\xc1\x71\xdc\x37\x29\ +\x33\x52\xa0\x38\xcd\x67\x24\xfd\x82\xdf\x2c\xe7\xf2\xde\x16\xfb\ +\xd4\x89\xd9\xc1\x4e\x65\x31\xdf\x8a\xde\x65\xb3\x15\xb2\x4e\xd1\ +\x09\x81\x3d\x1e\xb9\x8d\x30\x67\x09\x74\x00\x9d\x22\xab\x44\x9d\ +\x42\x13\x9d\x0e\xf4\xa6\x1b\x99\x85\x32\x47\xc7\x7d\xdd\xb6\xad\ +\xab\xca\x66\x62\xec\x57\x87\x94\x2f\x29\x27\x11\xe1\x64\x57\x2a\ +\x4a\x62\xf9\x7e\xe3\x19\xb4\x98\xc1\x1f\x6f\x7f\x6e\x68\x21\x0c\ +\x83\xbf\x72\xf6\x69\x57\xa9\xc2\x80\xcc\xf2\x15\x84\xab\x21\x0f\ +\xd1\x84\x84\x01\xb4\x79\xd0\xed\x3c\x26\x4b\x28\x00\xd1\x4f\xfe\ +\x08\x6d\x1d\x14\x6d\xa3\xe8\x18\x0b\xb0\x76\x8b\x56\xcb\x32\x5a\ +\xf5\x8b\x07\x5b\xec\x28\x5c\x26\x62\x92\xf1\x9e\x27\x69\xfa\x8b\ +\xd8\xa4\x21\x8a\x66\xd1\x84\xa7\x74\x27\x04\xfe\xa8\x4e\xaf\xe8\ +\xa4\xe5\xdc\xc4\x50\xde\xcb\x51\xbc\x43\xa5\x53\x39\x4d\xa0\x53\ +\x32\xa3\x90\x28\xef\x84\x52\xdb\xd3\xc6\x2c\x5f\x15\xcb\x3c\xa2\ +\xf5\x74\x85\x66\xd1\x22\xe9\x92\x6f\x53\xd0\xcf\xe1\xf4\xc1\x9d\ +\x29\x9f\xd7\x62\x80\x6a\x32\x09\xf0\xeb\x92\xb3\xfc\x13\x95\xda\ +\x11\x68\xab\x61\x55\x3f\x81\xa9\x03\x23\x38\xd8\x29\x36\x4a\x0e\ +\x2c\x4c\x61\xf7\x60\xb6\xe2\xbc\x2d\xfb\x37\x4f\xb2\x00\xc0\xa2\ +\x4c\x49\x9b\x1d\x9a\xfc\x01\x3f\x7f\xd5\xac\xaa\x31\xb6\x9d\xa1\ +\xad\x5b\xf2\x40\x8e\xf6\xa7\x66\xdb\x55\x46\x79\x5a\xaa\x59\xbe\ +\xee\xc9\xe4\x1a\x0d\x81\x96\xb4\xcf\x9d\xb4\x16\xce\x79\x0e\x86\ +\x4b\xa4\x21\xec\xa3\xfe\x3a\xfe\xc8\x19\xcd\x8e\xf9\x5b\x91\x73\ +\xdf\xdf\x91\xed\x9e\xef\xaa\x1c\xa4\x50\xf5\x3c\x70\x94\x2c\x22\ +\xc0\xc7\x8c\x91\x6d\x90\xc1\x87\xdd\x17\x40\xc1\xba\xef\x7a\x8e\ +\x65\xfa\xc3\x1a\x1e\x0b\x0b\x50\x2c\xed\x9d\x66\x63\xdd\xb3\x5c\ +\xd3\xf3\x87\x40\xd1\x12\x2f\xac\xfd\x7d\x08\x92\x1d\x20\x71\x87\ +\x07\xa0\xd9\xb5\x1b\x7b\x71\xb7\x21\x31\x01\xae\x4a\x96\xde\xdf\ +\xb5\xdb\xed\x87\xc6\x8a\x33\x92\x95\xa2\x80\xa0\x5c\x09\x67\xc9\ +\xe6\x5e\x00\x23\xde\xf1\xd0\x14\x6f\x33\x82\xef\x29\xcb\x37\x7d\ +\x6c\xfb\xfe\xd0\xd7\x47\x3e\xbc\x23\xef\x61\x77\xc1\xc7\xbb\x72\ +\xeb\x67\xf5\x4f\xb0\x75\xef\xf6\xae\xda\xf5\x56\x79\xc5\xed\x6a\ +\xad\x2c\x3c\xcb\x84\x1e\xc2\x47\xed\xde\xe0\x84\x5f\x4d\x73\xfd\ +\xd0\xb1\xef\xd5\x85\x6d\x7b\x47\xeb\x62\x1e\x89\xb7\x9b\x27\xd6\ +\x25\x22\xdf\x43\x5a\xfe\x4c\x09\xa7\xf7\xc8\xd3\x5d\x59\x23\x43\ +\x34\xd6\x1d\x51\x0a\xae\xfd\xd0\x82\xa5\x0f\xcc\x17\xb1\x6d\xa1\ +\x77\xf0\xf3\xe0\x5b\x23\xf2\xd8\x39\xca\x84\xd1\x90\x77\x0f\x77\ +\x3b\x01\x53\x50\x8a\x33\x8e\x5d\x8c\x1c\x64\x21\x67\xcf\xa2\xee\ +\x3e\xea\x38\x76\x3e\x36\xab\x47\x35\x1f\x2a\xd2\xfd\x68\xc8\x6e\ +\xd8\x72\xf5\xd1\x9e\x5c\xdc\xbe\xe3\xfa\xfa\xed\xdc\x45\x2f\x0e\ +\x3a\x0b\x8d\x05\x7c\x57\x04\x4f\xb0\xe5\xfe\xfa\xdb\x1a\xd9\x17\ +\x0e\x1e\x7c\xe1\x20\x1b\xed\x27\xc8\x65\xe0\x53\x39\xb6\xaf\x3c\ +\x0c\xdf\xc4\x88\x5b\xbc\xdd\x19\x1c\x27\xf1\xb3\x28\xfc\x04\x81\ +\x3b\xce\xd8\xb3\xf0\x0d\x11\xb8\xab\x4b\x64\x6d\x3c\x44\x8e\x6e\ +\xc9\x5a\xbd\x38\x83\x9f\xe2\xef\x67\x06\xe4\xdc\x3a\xfa\x86\xf1\ +\x52\x40\xb6\xf8\xfb\x05\xb1\xf7\x0d\x01\x27\xd9\xfb\x05\x71\xf7\ +\x4d\x41\x27\xb9\xfb\xe5\x32\xf7\x19\xbc\x7d\x82\xb5\x09\x91\x9f\ +\xa3\x87\x43\x70\x0e\xdb\xd6\xdf\x4c\xd8\x85\xef\xc5\xca\x77\xd7\ +\xbd\x28\xdb\x9e\xa2\xda\xaf\xf4\xe2\xdc\x74\x3d\xb9\x6c\x95\x9f\ +\xc2\x57\xdf\x74\xce\xe4\xbb\x17\xc4\x76\xd7\xc2\x00\xa8\xeb\x05\ +\x11\xd7\xf5\x50\x30\x7b\x1d\xd8\xe5\x70\x78\x8e\xee\xf1\x1c\x16\ +\x42\xf6\xff\xe5\xa1\x67\x69\x17\xaf\x4e\x60\x7b\x4d\xce\xb3\x02\ +\x70\x85\x8c\xbf\x62\x3f\xf8\x9d\x31\xe4\x55\x1b\x40\xf7\xfb\xe2\ +\xd1\x2b\x77\x7c\xe6\x8d\xb3\x6d\xf3\xb3\xfe\x21\xff\x4c\xc4\xff\ +\xaa\x3c\xbe\xfa\x0f\x0c\xb7\xae\xe8\ +\x00\x00\x0d\x9d\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\ +\x64\x5f\x73\x65\x61\x72\x63\x68\x2e\x73\x76\x67\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\ +\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\ +\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\ +\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\ +\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ +\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\x30\x66\x65\x66\x66\x3b\x73\ +\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x73\x74\x6f\x70\x33\x37\x38\x33\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\ +\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\x30\x36\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\ +\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x62\x62\x66\x61\x66\x66\ +\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\ +\x34\x37\x30\x35\x38\x38\x32\x34\x3b\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\ +\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ +\x23\x38\x37\x66\x36\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x30\x33\x39\x32\x31\x36\x3b\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\ +\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\x68\x72\x65\ +\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ +\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\ +\x74\x33\x37\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\ +\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x63\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x66\x78\x3d\x22\x34\x2e\ +\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x3d\x22\x31\x34\x2e\x32\x31\x36\x38\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\ +\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\ +\x72\x69\x78\x28\x31\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x32\x35\ +\x36\x33\x2c\x30\x2c\x2d\x30\x2e\x30\x37\x31\x30\x35\x30\x33\x35\ +\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\ +\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\x70\x61\ +\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\ +\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x39\x34\x2e\x32\x37\x36\x34\x33\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x31\x39\x2e\x31\x31\x38\x33\x31\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ +\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ +\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x65\ +\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x72\ +\x61\x64\x69\x61\x6c\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\ +\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ +\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\ +\x33\x37\x35\x38\x35\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x63\x79\x3d\x22\x35\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x32\x31\x36\ +\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\ +\x33\x2e\x33\x39\x35\x34\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x30\x2e\x39\x35\x36\x34\x37\x39\x35\x37\x2c\x30\x2c\ +\x30\x2c\x30\x2e\x39\x34\x33\x37\x32\x36\x35\x31\x2c\x31\x34\x2e\ +\x30\x33\x32\x34\x34\x32\x2c\x38\x2e\x32\x36\x36\x32\x34\x35\x36\ +\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x37\x2e\x38\x36\x30\x36\ +\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x34\x2e\x31\x39\x37\x32\x35\x32\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x35\x2e\x35\x35\x34\x32\ +\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x39\ +\x2e\x39\x34\x38\x33\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x31\x2e\x30\x38\x33\x37\x38\x33\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x34\x38\x37\x38\ +\x31\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ +\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\ +\x39\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0c\xd5\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x70\x6f\x69\x6e\x74\ +\x65\x72\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ +\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x33\x36\x2e\x32\x32\x31\x31\x30\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x31\x30\x2e\x38\x33\x32\x31\x39\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ +\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ +\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\ +\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\ +\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ +\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ +\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ +\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ +\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ +\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ +\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\ +\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\ +\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\ +\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\ +\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ +\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\ +\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\ +\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\ +\x38\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x35\x2e\x32\x30\x30\x30\x30\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x2e\x31\x33\x33\x33\x33\x33\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ +\x38\x34\x31\x37\x34\x35\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x62\x30\x35\x37\ +\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\ +\x36\x34\x37\x30\x35\x38\x38\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x66\x66\x35\x65\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x32\x2e\x32\x34\x37\x34\x36\x36\x38\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x33\ +\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x33\x2e\x30\x36\x36\x36\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x35\x30\x38\x30\x34\x38\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ +\x39\x33\x31\x37\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\x39\x39\x39\x39\x39\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x39\x33\x30\x30\x30\x30\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x32\ +\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\ +\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ +\x6d\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x2c\x37\x2e\x39\x33\ +\x31\x30\x34\x34\x33\x20\x63\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\ +\x39\x39\x39\x37\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\x39\x39\x39\ +\x37\x20\x30\x2c\x31\x39\x2e\x31\x39\x39\x39\x39\x39\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ +\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ +\x39\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x39\ +\x33\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x33\x2e\x35\x38\x39\x30\x39\x35\x31\x32\x70\x78\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ +\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ +\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\x36\x36\x36\x36\x36\ +\x37\x2c\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x63\x20\x31\x39\ +\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\ +\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\x32\x30\x30\x30\x30\ +\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x0c\x37\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x6d\x6f\x76\x65\x5f\x75\x70\x2e\x73\x76\x67\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\ +\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\ +\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\ +\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\ +\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x78\x3d\x22\x31\x39\x2e\x38\x35\x37\x36\x32\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x31\x34\x2e\x32\x37\x32\x35\x32\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ +\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ +\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x37\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\ +\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\ +\x75\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\ +\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\ +\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\ +\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ +\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ +\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\ +\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\ +\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\ +\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\ +\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\ +\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\ +\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\ +\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\ +\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\ +\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\ +\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ +\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x3d\x22\x31\x2e\x32\x37\x39\x36\x32\x32\x32\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x32\x32\x34\x34\x30\x31\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\ +\x39\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\ +\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\ +\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\ +\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\ +\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\ +\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\ +\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\ +\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\ +\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\ +\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\ +\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\ +\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\ +\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\ +\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\ +\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\ +\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\ +\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\ +\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\ +\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\ +\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\ +\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\ +\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\ +\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\ +\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\ +\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\ +\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\ +\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\ +\x69\x6c\x6c\x3a\x23\x65\x37\x65\x37\x66\x66\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x34\x2e\x30\x37\x30\x38\x38\x3b\x6d\x61\ +\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\ +\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\ +\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ +\x3d\x22\x6d\x20\x31\x34\x2e\x31\x32\x37\x30\x37\x37\x2c\x32\x36\ +\x2e\x39\x32\x32\x36\x38\x36\x20\x34\x2e\x39\x32\x37\x37\x35\x35\ +\x2c\x30\x2e\x30\x33\x38\x31\x33\x20\x31\x2e\x36\x34\x32\x35\x38\ +\x33\x2c\x30\x2e\x30\x31\x32\x37\x31\x20\x2d\x30\x2e\x34\x37\x30\ +\x33\x39\x35\x2c\x2d\x36\x2e\x36\x37\x32\x32\x33\x32\x20\x36\x2e\ +\x33\x35\x32\x34\x32\x37\x2c\x30\x2e\x30\x34\x31\x33\x35\x20\x2d\ +\x39\x2e\x30\x31\x38\x36\x35\x39\x2c\x2d\x31\x32\x2e\x35\x39\x34\ +\x30\x31\x37\x31\x20\x2d\x38\x2e\x39\x37\x39\x38\x38\x30\x32\x2c\ +\x31\x32\x2e\x34\x37\x36\x36\x39\x30\x31\x20\x36\x2e\x33\x35\x32\ +\x34\x32\x36\x32\x2c\x30\x2e\x30\x34\x31\x33\x35\x20\x7a\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ +\x30\x31\x33\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\ +\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0b\xbd\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x63\ +\x61\x6c\x63\x5f\x65\x78\x70\x72\x65\x73\x73\x69\x6f\x6e\x2e\x73\ +\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ +\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\ +\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\ +\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x2e\x39\x37\x39\x35\x31\x30\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x78\x3d\x22\x2d\x32\x33\x35\x2e\x37\x30\x38\x33\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x2d\x31\x36\x2e\x38\x33\x32\x37\x35\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\ +\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\ +\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ +\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ +\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ +\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x39\x39\x39\x39\x39\ +\x39\x3b\x66\x69\x6c\x6c\x3a\x23\x38\x30\x62\x33\x66\x66\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x64\x33\x64\x33\x64\x33\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x2e\x32\x37\ +\x37\x35\x35\x39\x32\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ +\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x33\x37\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x34\x30\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x78\x3d\x22\x2d\x33\x2e\x37\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x72\x79\x3d\x22\x31\x32\x2e\x31\x39\x30\x34\x37\x38\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\ +\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\ +\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ +\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x73\x69\x7a\x65\x3a\x31\x37\x2e\x31\x36\x32\x33\x32\x36\ +\x38\x31\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ +\x3a\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\ +\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x6c\x65\x74\x74\x65\ +\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\ +\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\x39\x39\x39\x39\x39\ +\x39\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x34\x33\x30\x31\x39\x33\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x2e\x32\x30\ +\x34\x38\x38\x31\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ +\x22\x32\x31\x2e\x30\x39\x35\x33\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x74\x65\x78\x74\x33\x39\x31\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ +\x3d\x22\x73\x63\x61\x6c\x65\x28\x30\x2e\x39\x35\x33\x34\x36\x32\ +\x36\x33\x2c\x31\x2e\x30\x34\x38\x38\x30\x38\x38\x29\x22\x3e\x3c\ +\x74\x73\x70\x61\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\x69\ +\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x74\x73\x70\x61\x6e\x33\x39\x31\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x2e\x32\x30\x34\x38\x38\x31\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\ +\x31\x2e\x30\x39\x35\x33\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\ +\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\ +\x69\x7a\x65\x3a\x31\x34\x2e\x33\x30\x31\x39\x33\x39\x30\x31\x70\ +\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\ +\x32\x35\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\ +\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\ +\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\ +\x64\x27\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x31\x2e\x34\x33\x30\x31\x39\x33\x39\x22\x3e\x31\x2a\x32\x3c\x2f\ +\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\x0a\x20\x20\ +\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\x2a\ +\x00\ +\x00\x2f\xfb\x78\x9c\xed\x5a\x59\x8f\xdb\xc8\x11\x7e\x9f\x5f\xc1\ +\xc8\x2f\x36\xa2\xa6\xfa\x66\x37\x67\xc6\xfb\xb0\x8b\x0d\x16\xd8\ +\x20\x40\x6c\x23\x8f\x0b\x8a\x6c\x49\x8c\x29\x52\x20\xa9\x91\xe4\ +\x5f\x9f\x6a\x52\xbc\x24\xce\xa1\x19\x7b\xb2\x71\x2c\xc3\xb0\xba\ +\xaa\xfa\xaa\xaa\xaf\x8e\x96\x6f\x7e\xda\xaf\x13\xe7\xce\xe4\x45\ +\x9c\xa5\xb7\x13\xe2\xe2\x89\x63\xd2\x30\x8b\xe2\x74\x79\x3b\xf9\ +\xf4\xf1\x57\xa4\x26\x4e\x51\x06\x69\x14\x24\x59\x6a\x6e\x27\x69\ +\x36\xf9\xe9\xfd\xd5\xcd\x5f\x10\x72\x7e\xce\x4d\x50\x9a\xc8\xd9\ +\xc5\xe5\xca\xf9\x2d\xfd\x5c\x84\xc1\xc6\x38\x6f\x57\x65\xb9\xf1\ +\x67\xb3\xdd\x6e\xe7\xc6\x47\xa2\x9b\xe5\xcb\xd9\x3b\x07\xa1\xf7\ +\x57\x57\x37\xc5\xdd\xf2\xca\x71\x1c\xd8\x37\x2d\xfc\x28\xbc\x9d\ +\x1c\x27\x6c\xb6\x79\x52\x09\x46\xe1\xcc\x24\x66\x6d\xd2\xb2\x98\ +\x11\x97\xcc\x26\x9d\x78\xd8\x89\x87\x76\xf7\xf8\xce\x84\xd9\x7a\ +\x9d\xa5\x45\x35\x33\x2d\xde\xf4\x84\xf3\x68\xd1\x4a\xdb\xd3\xec\ +\x58\x25\x44\xb4\xd6\x33\x4c\x67\x94\x22\x90\x40\xc5\x21\x2d\x83\ +\x3d\x1a\x4e\x85\x33\x8e\x4d\xa5\x18\xe3\x19\xf0\x3a\xc9\xa7\x49\ +\xf9\xfb\x04\x54\x71\xef\x61\x2a\x6e\x7f\x77\x50\xff\x06\xfe\xb6\ +\x13\x1a\x82\x5b\x64\xdb\x3c\x34\x0b\x98\x69\xdc\xd4\x94\xb3\x5f\ +\x3e\xfe\xd2\x32\x11\x76\xa3\x32\xea\x2d\xd3\x68\x7f\xb0\xef\xc0\ +\x24\x69\xb0\x36\xc5\x26\x08\x4d\x31\x6b\xe8\xd5\xfc\x5d\x1c\x95\ +\xab\xdb\x09\xe3\x2e\x61\xf0\x11\x15\x71\x65\xe2\xe5\xaa\x3c\xa5\ +\xc6\xd1\xed\x04\xee\x4a\xb5\xaa\xc7\x3d\x57\x22\xb5\xc0\x71\x61\ +\xbf\xe5\x60\x57\x53\x97\x38\x39\x11\xcc\xab\x65\x9a\x2b\xf8\x51\ +\x16\xda\x33\xc1\x92\x66\x1d\x07\xdb\x32\x5b\x83\x8d\xc3\x30\x09\ +\x8a\x22\x5e\xc4\x21\x0c\xb2\x74\x93\x6c\x97\x71\xfa\x47\x98\xc4\ +\x9b\x3f\xca\x2c\x4b\xdc\x46\xd5\xed\x4e\x66\xbf\xc9\xf2\x12\xed\ +\xa3\x0d\xa8\x50\x7a\xa3\xcc\x43\xc3\x7c\x0f\xdc\x9b\xc8\x2c\x0a\ +\x2b\x55\xdf\xc7\x8e\xe0\x42\x35\x0f\xb8\x60\x1e\x13\xe4\x7f\xcb\ +\x83\x28\x06\xa7\xac\xe5\x7a\x2b\x86\x59\x92\x98\x10\x34\x13\x24\ +\xbb\xe0\x50\x4c\x5a\x01\x58\x6a\x38\x95\x63\x26\x8f\x8b\xc2\xb2\ +\x45\x99\x6d\x1a\x59\xd0\x41\x79\x48\xec\xc5\x81\x88\x60\xc5\x2c\ +\xf7\xdf\xe0\xea\x73\x5d\x91\x32\x30\x53\x5c\x1e\x7c\x72\x3d\xe9\ +\xe6\x64\x8b\x45\x61\x60\x63\xdc\xa3\x55\x06\x81\x19\xb0\x17\x40\ +\x77\xf6\xb2\xdd\xf0\xd8\x6e\x64\x74\x37\x8e\xdb\xdd\x6e\x66\xc3\ +\x6b\x7f\x7d\x35\x52\x75\x91\x1a\xf9\x5c\x93\xe7\xab\x11\x5f\xa8\ +\xc6\xf3\xdd\x2e\x50\x23\xa3\xcf\x54\xe3\x99\x96\x98\x52\xfa\xb5\ +\xb4\xc4\x94\x26\xf7\x6b\xa9\x27\xe5\x8d\x2d\xe8\xca\xda\xf7\xe8\ +\xe4\x39\x27\x7c\x35\xe3\xc0\xf1\xd9\x37\xf2\xf1\x2a\x03\xf8\xab\ +\xdc\x40\xc6\x7a\x33\x62\xc6\x87\xac\xac\x45\xb7\x0c\xb9\x9d\x50\ +\xd9\x0e\x0f\x30\x24\xdd\x70\x4f\x81\xdb\x09\x1f\x60\x48\x3a\x63\ +\x2e\x8f\x0b\x7e\x4a\xe3\x12\xd2\xda\xb6\x30\xf9\x07\x9b\x1a\xfe\ +\x91\x7e\x2a\xcc\x99\xd4\xc7\x3c\x48\x0b\xc8\x43\x6b\x50\x4d\x18\ +\x24\xe6\x2d\x54\x0e\xd2\x7e\xbc\x77\x9d\x8a\x2e\xf1\x54\x74\x59\ +\x60\x7c\xa1\xaf\x22\xfd\x34\x6f\x45\xe4\x7f\xdc\x5f\x7b\x17\xbd\ +\xc8\x63\x4f\x9c\xe3\xd4\x75\x4e\x1c\x6b\xe8\x76\x4f\xf3\xa4\x11\ +\x37\x80\x5a\xe8\xa9\x88\x40\xdd\x76\x8f\x82\x6b\xc4\x67\xa1\xac\ +\xc8\xe3\xfd\x5b\xec\x52\x25\x09\x15\x1e\x9b\x82\xff\x52\x4f\x78\ +\xdc\x9b\xa2\xee\x6b\x8f\x4f\x3d\x17\x2c\xce\x89\x9a\x22\xe1\x2a\ +\xc1\x24\xa6\xe2\x71\x57\x7f\x01\xee\xab\x24\xf7\x60\x29\xc1\x07\ +\x06\x60\xd2\x25\x12\x72\xbe\x1e\x58\x89\xc1\x0d\x3c\x4d\xc4\xc0\ +\x92\x8c\xb9\x4a\x32\xae\x87\xb1\x00\xee\x25\x19\x15\x98\x89\x97\ +\xc7\x84\x4e\xbf\xda\x83\x7b\x50\x50\xa5\xfd\xe3\x0a\xcc\xa9\x04\ +\xb7\x04\x75\x7b\x9e\x56\x58\x8a\x29\xd2\x2e\x25\x1a\x10\xf5\xad\ +\xd5\xc9\xe4\x83\xea\xe4\x74\xa8\x4e\xea\x32\x46\x29\x63\x03\x75\ +\x22\x42\x5c\xe1\x69\xfe\x7f\xa2\xcf\xf1\x0a\x16\xe1\xd7\xac\x61\ +\x91\x78\xdd\x2a\x16\x91\x57\xad\x63\x11\x7f\xcd\x4a\x16\xb1\xd7\ +\xad\x65\xd1\x33\x0b\xa6\x7b\xf0\x73\x0f\xd8\xc6\x81\x39\x0a\xe2\ +\xe7\xe6\x26\x8e\x25\x7b\x6a\x98\x41\x9d\xf6\x5f\x96\x9b\x46\xb1\ +\x4e\xa7\xd0\xe8\x2b\xce\x20\xff\x78\x6a\x0a\xd7\xe6\x9a\x33\xf6\ +\x28\xd6\x2f\xd6\xe8\x79\xe6\x18\x4d\x32\x2f\x50\xa8\x78\x9a\x42\ +\x2b\x8c\xfc\xd7\x14\x7a\x33\xb3\xaf\x01\xd5\xb7\xf6\x95\xc2\x3e\ +\x51\x44\x77\xb1\xd9\x5d\xb5\x97\x9b\x07\xed\x6d\x37\xc1\xd2\x54\ +\xf8\x81\xbb\x2c\xaa\xcf\x91\x31\xcf\xf2\xc8\xe4\x0d\xab\xaa\x96\ +\xe5\x80\x75\x84\x58\xfd\x0c\x77\x35\xbc\xaf\x5d\xb5\xe5\xe3\x71\ +\x7e\xb1\x0a\xa2\x6c\x07\xb5\xd8\x29\xf3\x4b\x96\x81\x1e\xe0\x6a\ +\x44\x7b\x0a\x9f\xb1\xc3\xbd\x05\x10\x73\x99\xf4\x08\x3b\x63\xc2\ +\x7e\x14\xc0\x45\x31\x21\xe4\x8c\xb9\xcd\x73\x50\x36\x4a\x82\x83\ +\x81\x4b\x55\xff\x34\x42\xc5\x2a\xdb\x2d\x73\xab\x9c\x32\xdf\x9a\ +\xd3\x99\x96\x83\xe6\xf3\x6c\x3f\xce\x8e\xb2\x70\x6b\x5f\x00\xd1\ +\xb6\xf6\xab\xcd\xbe\xbf\xea\x36\x8e\x4c\x31\x3e\xb1\x48\x83\x0d\ +\x5a\x26\xd9\x3c\x48\xc6\x05\x76\x71\x0a\x4a\x42\xc7\x27\x2e\xc2\ +\x5a\x1b\x9c\x4a\x34\xef\x5d\x1e\x56\xf7\x48\xec\xbb\x40\x7b\xca\ +\x3a\xdc\xcf\x5a\x07\xfb\x78\x1d\x7f\x31\x51\x17\x36\x3b\xad\xd8\ +\x9b\xf5\xd5\x72\xc4\xf4\x40\x6d\x8d\xab\x97\x07\xfb\xb6\xb7\x3f\ +\x58\xda\x00\x69\x96\x40\x75\xaf\xd7\xce\xf2\x78\x19\xa7\xfb\x7e\ +\x5e\xa8\x49\x87\x3e\xc9\xbe\x04\xc6\xe9\x72\x5f\xf9\x5f\xdd\xcc\ +\x9d\xf2\x0e\x7d\x5e\x03\x90\x73\x5c\x54\xf4\xb5\x29\x83\x28\x28\ +\x83\x0e\x24\x0d\x05\xce\xd6\x94\x10\x37\x79\xb4\xf0\xff\xf9\xcb\ +\xaf\x6d\x4e\x0a\x43\xff\x5f\x59\xfe\xb9\x4b\x27\x56\x20\x98\x67\ +\x5b\xb0\x44\x9b\x29\xed\x8b\x5d\xe8\x5b\x74\x07\xe5\xfb\x78\x0d\ +\xae\x6f\xdf\x5b\xff\xba\x5f\x27\x00\xd7\x96\x31\x10\xb6\xca\xea\ +\x16\xad\x97\xcd\x4d\xfd\x9e\x3a\xfa\x04\x1d\x85\xeb\xd8\x4e\x9a\ +\x7d\x28\xe3\x24\xf9\xcd\x6e\xd2\xcb\x9d\xc7\x45\xe3\x32\x31\xbd\ +\x84\x3a\x3b\x9e\xbe\xc9\x78\xbd\xcb\xdd\xcc\x9a\xdb\x57\xa3\x65\ +\xa7\x95\x01\x68\x5a\x43\x27\xc1\xdc\x80\x07\xff\x6e\x99\xce\xb9\ +\x9f\xe4\xd9\x76\xb3\xce\x22\x73\x9c\xde\x68\xd3\x24\x49\xbc\x29\ +\xda\x8b\x1e\x53\xfa\xb0\x34\x8a\xe2\x62\x03\x93\xfc\x38\xb5\x91\ +\xf6\x3a\xbb\x33\xf9\x22\xc9\x76\xfe\x5d\x5c\xc4\xf3\xc4\x5c\x57\ +\xff\xc6\x89\xcd\xf5\x0d\x69\x01\x1a\xf0\xd3\x0c\xa4\x8b\x32\xcf\ +\x3e\x1b\xff\x8d\x16\x86\x2d\x16\xc7\x61\x0d\x26\x9f\xba\x92\x08\ +\xca\x09\x16\x0d\xdd\x6e\x00\xe7\xf5\xe7\xdb\xb2\xec\xd3\xfe\x9d\ +\xc5\xa9\x0f\xea\x35\x79\x43\xad\x06\x09\xe0\xa2\xf4\x79\x43\x8b\ +\x02\x08\x68\x79\x0e\x47\xed\x6d\x5d\x51\xeb\xb2\xc3\xc7\x0d\xad\ +\xab\x85\xd6\x41\xfe\xd9\xe4\xf5\x04\x93\x06\x70\x78\x34\x0f\xc2\ +\xcf\x56\x5f\x69\xe4\x07\x21\x44\x95\x6d\x12\x94\xc3\xcc\xb4\x09\ +\xca\x15\xc3\x5c\x22\x81\xb8\x2d\x59\x5a\x80\x8d\xe4\x10\xad\xa4\ +\x82\x48\xc8\x20\x7f\x10\x49\x34\x93\xca\xa6\x0f\x88\xab\x94\x30\ +\x41\xa7\x56\x00\x4a\x00\x2c\xa4\x4d\x31\xef\xda\xa5\x6c\x88\xd5\ +\xae\xe4\x98\x68\xd1\xb5\x75\x36\xb6\x42\xdc\x05\xaa\xa4\x5d\x8e\ +\xcb\x41\x96\xbb\x0c\x4b\xdd\x95\x55\xf9\xc1\x66\x64\x48\x51\x12\ +\xb6\xe9\x72\xbd\x3d\xf9\x83\xc6\x5e\x64\x10\x43\x2b\x0e\xe8\x04\ +\x50\x91\xd4\x94\xbb\x20\x8f\x83\xb4\x1c\xd0\x76\x55\xbc\x1b\x90\ +\x40\xbd\xa6\x0c\x57\x43\x1a\x84\x2e\x1f\x70\x1e\x6f\xd7\xd7\xd6\ +\x96\xc7\x38\x39\x90\x59\x04\xeb\x38\x39\xf8\x1f\x40\x7d\xd7\xa8\ +\x71\x5a\x54\x4f\xdf\x98\xb0\x7d\xca\xaf\x25\x4a\xb3\x2f\x41\x2a\ +\x82\x70\x0f\x26\xad\x46\x41\x12\x2f\x53\xbf\x28\x83\xbc\xac\x09\ +\x11\xa4\xd4\xbc\x9e\x53\xd9\xf6\x84\x58\x79\x55\xcd\x49\x4c\x09\ +\xae\x84\x8e\x01\xab\x39\xd6\x0e\x12\xec\x29\xad\x5a\xa3\xb5\x71\ +\x3d\x7b\x97\xc7\x25\x88\x20\x8b\x2d\x3f\xc9\x51\x39\x07\xbc\xe4\ +\x50\x68\xd8\x9d\x93\x32\xbf\xb6\x89\xbe\xba\x76\xb1\x8a\x17\xa5\ +\xdf\x0c\x8f\xc7\x4e\xc3\x15\x28\xbf\x3e\xf7\x73\x71\xd6\x60\xcb\ +\x0e\x7a\x9e\x7d\x44\x5e\x1f\x0a\x35\xec\xc0\x7f\xa4\xe7\x31\x46\ +\xf8\xe5\xde\x0f\xce\xff\x77\x87\x81\xd3\xda\x1f\x74\xa0\x8b\xc4\ +\x6e\x1d\xdb\x9d\x9f\x1d\x42\xa7\xd6\x35\x2b\x86\x03\x8c\x2a\xea\ +\x7b\x96\xa6\x4f\x87\xbf\x5b\x82\x9c\x12\xcf\x65\xb5\x78\xe8\x80\ +\xf3\x3b\x84\xbb\x50\x5b\x51\x57\xd5\x44\x0a\x55\x56\x3d\x09\x41\ +\x6d\x59\xed\xe3\xd0\x66\x67\x04\x0d\xac\xc3\xad\xb4\x57\x1f\x00\ +\x40\x25\x2c\x87\x5b\x69\xee\x7c\x39\x07\xac\x92\x14\x75\x25\x64\ +\xaf\x30\x4c\x21\xe8\x94\x59\x8e\xa0\x38\xb9\x0b\xca\x6d\x6e\x06\ +\x49\xae\x4d\x56\x60\x61\x1b\xdf\xa1\x8e\x08\xed\xe7\x07\xa8\xbe\ +\x67\x50\x41\x62\x7f\x7b\xfa\x8c\xa8\xb5\x7e\xf7\x7a\x28\xa3\xbc\ +\x76\x68\x36\xa5\xb2\x87\x32\xe9\x7a\x0a\x30\x30\xd5\x90\x4e\x34\ +\x13\x0c\xc0\x25\x5c\x45\x09\x91\x6c\xea\x01\xfc\x28\x16\xdc\x1b\ +\xa5\x01\xea\x20\xe3\x0a\xe9\xd1\xa9\xb2\xc8\x52\x58\x37\xc8\x93\ +\xb0\x95\x12\x9c\x4f\x41\x42\x43\xc6\x81\x93\x3b\xca\xf5\x38\x87\ +\xee\x67\x4a\xb4\x4b\x21\x8f\x78\xd8\x03\xf8\x71\xca\x05\x87\x23\ +\x41\xed\xaf\x15\x51\x0e\x73\x3d\xa6\x28\x50\x98\x0b\xe5\x3e\x85\ +\x33\xc2\x17\x06\x1d\x34\xb1\x10\xe5\x54\x28\xc2\xee\x03\xa3\xf7\ +\x2d\xc0\x68\xdd\xe4\x04\x8c\x75\x94\xc4\x58\x88\x88\x9f\xda\xaf\ +\x1a\xe6\x5b\x40\xa6\xb9\x33\xb0\x6a\xd4\x56\x2c\xed\xc3\x50\xcf\ +\xa8\x04\x7a\x5c\xa6\x15\x97\xf2\xf2\x3a\xa4\xdd\x73\xa0\x0c\x7b\ +\x5c\x28\x6f\xbb\x1a\xa2\xe9\x33\xc0\x54\x58\x41\x91\xd0\x32\x9a\ +\xf6\x02\x42\x27\x17\x94\xf4\x1e\x73\x6f\x27\x12\xbc\x42\x50\xd1\ +\x7f\x71\xbf\x9d\x08\xb0\x84\x86\x76\x55\x0c\x0a\x05\xe8\xcc\x30\ +\xf5\x14\xf7\x06\xa5\x02\x50\x15\xe1\xbd\x27\xfa\xf3\x52\x86\x40\ +\x81\x62\x1b\x5f\xc1\x3c\x09\xa2\xb6\x1f\xa6\x10\xd4\x39\x78\xcd\ +\xa0\x72\x79\xf0\x57\xf5\x31\x81\xf6\x97\xf5\x87\x02\xea\x79\x45\ +\x39\x66\x1f\x48\x4c\x84\x60\x70\x78\xb6\xd9\x5f\x5e\x53\x9e\x5b\ +\xc8\xf6\x20\x0e\x34\xb3\xec\x08\x44\x0f\xbc\xbd\xca\x4d\x50\x9a\ +\x01\x06\xaa\xff\xd6\xc0\xcf\x9c\x9b\x63\x2d\x91\xba\xc0\xbd\x47\ +\x9d\xf7\x7e\x0b\x60\xe2\x81\x01\x95\xb5\x80\xf6\x24\xd4\x91\x27\ +\x16\xa8\x0d\x2a\xc1\x53\xb9\x7c\xcc\xf8\xb6\x4c\xd4\x2e\xd3\x44\ +\xf5\x7f\x4b\xa9\x9c\x07\xb6\x61\xbd\x47\xee\xd6\xff\x88\x4b\xa8\ +\x56\x8f\x3b\x6c\xe3\xde\xe0\x2f\xbd\xbe\x70\x08\xc9\x20\xb0\xe9\ +\xf1\x65\x90\x24\x15\x20\xf1\x8b\x20\xf9\xe7\x77\x3d\x9b\x4f\xaa\ +\x1c\xd0\x73\x3d\x76\x8f\xeb\xbd\xcc\xf1\x06\x26\x5a\x2c\xea\x0a\ +\xe6\x85\x26\x62\x5a\x08\x45\xbf\x66\xd0\x04\xaf\xd2\x17\x04\x4d\ +\xe2\x42\x24\x24\xbd\x58\x68\x7b\x26\x6a\xf3\xaa\x92\xb2\x8f\x06\ +\xaa\x5c\xaa\x25\xeb\x39\xf8\x43\x51\xd3\xd3\x9a\x42\x83\xf7\x78\ +\xd8\xf4\x04\x66\x0a\x00\x35\xb5\x15\x33\xc1\x98\xdb\xaf\x16\xb4\ +\xad\x09\xbe\x65\x2b\x3e\x52\xcd\xd8\x1f\xb0\xee\xab\x66\x46\xc5\ +\x19\x7f\xf7\xdd\xb5\xef\x0f\x76\xee\x10\x59\xa1\x66\xf0\x34\x98\ +\xcc\x53\x4c\x61\x08\xb6\x75\xf8\x15\x50\x0c\xc9\x2a\xfa\xda\xb7\ +\x71\xe5\x9d\x77\xee\xf6\x51\xd8\xfe\x90\xd0\x79\x96\xed\xdc\x11\ +\xd4\x71\x5a\x41\x29\xf5\xa3\x73\xff\xd1\x64\xdc\xd7\x64\x28\x2d\ +\x5e\xb1\xc9\x60\x4d\x03\x6f\x7f\xc7\x20\xb6\xbf\x20\xc7\x12\xc7\ +\x76\xea\xaa\xc9\x38\x6a\x0a\xbd\x39\x6b\x4a\x9f\xfe\x28\x71\x70\ +\xd3\xa6\x1c\x9b\x7f\x3e\xd6\xcd\xf3\x91\x6e\xde\x7b\x42\x37\xcf\ +\x1e\xea\xe6\xbf\x45\xfb\xf0\xea\x51\x58\xb2\x8b\xa2\xb0\x14\xdf\ +\x5f\x14\x46\xbd\x2a\xf3\x2b\x3f\xa1\x42\xa3\x4b\x30\xd3\xbd\x4a\ +\xa9\x7a\x42\xe5\x50\xdc\x42\x10\x17\x5f\x29\x10\xff\x29\x2a\x44\ +\xdb\xa6\x3f\x5e\x1c\x5e\x58\x1a\xde\xcc\x96\xef\xaf\x6e\xec\x8f\ +\x25\xef\xaf\xfe\x03\xc5\x8d\xf3\xce\ +\x00\x00\x06\xc9\ +\x00\ +\x00\x4c\x0c\x78\x9c\xed\x5c\x5b\x93\x9b\x36\x14\x7e\xdf\x5f\xa1\ +\xb2\x2f\xed\x74\x25\x10\x17\x73\x89\xed\x3c\x34\x93\x69\x66\xd2\ +\x97\x36\x4d\x67\xfa\x92\x61\x41\xb6\x69\x30\x72\x05\xac\xed\xfc\ +\xfa\x4a\xdc\x8c\x6d\xb6\xe3\x5d\x20\xa3\x4d\x4c\x66\x67\xc3\x39\ +\x47\x42\x7c\xdf\xb9\x48\x02\x76\xfa\x7a\xb7\x8e\xc1\x03\x61\x69\ +\x44\x93\x99\x82\x91\xa6\x00\x92\x04\x34\x8c\x92\xe5\x4c\xf9\xf3\ +\xc3\x5b\xe8\x28\x20\xcd\xfc\x24\xf4\x63\x9a\x90\x99\x92\x50\xe5\ +\xf5\xfc\x66\xfa\x03\x84\xe0\x17\x46\xfc\x8c\x84\x60\x1b\x65\x2b\ +\xf0\x2e\xf9\x9c\x06\xfe\x86\x80\x1f\x57\x59\xb6\xf1\x54\x75\xbb\ +\xdd\xa2\xa8\x12\x22\xca\x96\xea\x4f\x00\xc2\xf9\xcd\xcd\x34\x7d\ +\x58\xde\x00\x00\xf8\x75\x93\xd4\x0b\x83\x99\x52\x35\xd8\xe4\x2c\ +\x2e\x0c\xc3\x40\x25\x31\x59\x93\x24\x4b\x55\x8c\xb0\xaa\x1c\xcc\ +\x83\x83\x79\x20\xae\x1e\x3d\x90\x80\xae\xd7\x34\x49\x8b\x96\x49\ +\x7a\xdb\x32\x66\xe1\xa2\xb1\x16\xa3\xd9\x1a\x85\x11\x76\x5d\x57\ +\xd5\x74\x55\xd7\x21\xb7\x80\xe9\x3e\xc9\xfc\x1d\x3c\x6e\xca\xc7\ +\xd8\xd5\x54\xd7\x34\x4d\xe5\xba\x83\xe5\x65\x56\x5e\xca\x01\xdd\ +\xf0\x9f\xc6\xbc\x16\xa0\x94\xe6\x2c\x20\x0b\xde\x8e\xa0\x84\x64\ +\xea\x9b\x0f\x6f\x1a\x25\xd4\x50\x98\x85\xad\x6e\x6a\x3c\x8f\xae\ +\x7a\x04\x72\xe2\xaf\x49\xba\xf1\x03\x92\xaa\xb5\xbc\x68\xbf\x8d\ +\xc2\x6c\x35\x53\x0c\x13\x61\x83\x1f\x56\x21\x5c\x91\x68\xb9\xca\ +\x4e\xa5\x51\x38\x53\xf8\xe8\x75\xd7\x29\xcf\x5b\xce\x81\x4b\x83\ +\xaa\x63\xaf\xd1\x68\xc8\xd5\x11\x06\x0c\x5b\x86\x5d\xda\xd4\xb7\ +\xe0\x85\x34\x10\x63\xe2\x5d\x92\x75\xe4\xe7\x19\x5d\x73\xd6\x82\ +\x20\xf6\xd3\x34\x5a\x44\x01\x3f\xa1\xc9\x26\xce\x97\x51\xf2\xa9\ +\x10\x7e\xca\xe8\x27\x4e\x6a\x46\x19\xff\x1f\x8d\x51\x8d\x63\x73\ +\x51\xb2\xdb\x50\x96\xc1\x5d\xb8\xe1\x68\x4e\xec\x4e\xe5\xbe\x56\ +\xce\xb9\x76\x1a\x92\x45\x2a\xac\xca\x5b\x13\x67\xfc\xde\x6c\x05\ +\xa8\x85\xb6\x19\xa9\x18\x66\xf8\x10\x91\xed\xc1\xf6\xde\x4f\x4b\ +\xf8\x00\xd8\xf8\x4b\xee\x6a\x31\x65\x33\xe5\x76\x51\x1c\x95\xe2\ +\x9e\xb2\x90\xb0\x5a\x35\x29\x8e\x23\x15\xe5\x74\x44\xd9\xbe\x0c\ +\xae\xaa\xef\x7a\xbc\xa2\xd7\x46\xaf\x75\xeb\xd3\x95\x1f\xd2\xed\ +\x4c\xd1\x4f\x95\x5f\x28\x5d\xf3\x5e\x39\x2d\xae\xed\x68\x67\xea\ +\x60\x37\x53\x20\x76\x90\x63\x1b\x66\xc5\x4a\x5b\x2b\x06\x64\x71\ +\xa5\xee\xd8\xd6\x99\x32\x67\x8c\x87\x1f\x8c\xfd\x3d\xe1\x77\x55\ +\xfc\xaa\x7b\x48\x57\x74\xbb\x64\x02\x9d\x8c\xe5\xe4\xb4\xa5\xd0\ +\xc0\xfb\x7b\xba\xeb\x56\x73\x6f\xc8\x45\x60\xc3\x3c\x89\x32\x1e\ +\x3c\x9b\x5d\xbb\xd7\x3c\x0a\x49\xda\xdd\x30\x4d\xfc\x0d\x5c\xc6\ +\xf4\xde\x8f\xbb\x0d\xb6\x51\xc2\x51\x82\x95\x9f\x63\xa3\x21\xe1\ +\xd4\xa2\x76\x7a\x5b\x73\x1e\xb1\xe0\x63\x3f\x23\xa2\x52\xed\x1f\ +\x57\xad\xfd\x5d\xb4\x8e\xbe\x10\x0e\x0c\x2e\xfc\x8e\xfb\xd6\x11\ +\x2c\x65\x33\x00\xb2\xbd\x08\xe0\xdd\x5e\xc8\x94\x5a\x28\xf0\x14\ +\x02\xdd\x75\xed\x46\x48\x59\xc4\xe3\xa2\x35\x9c\x5a\xb4\x6f\x8b\ +\x44\xb8\xf3\x6c\xbd\x2b\x1c\xac\x70\x3f\xfb\x54\xb7\x6f\xeb\x2a\ +\xbf\x57\xcf\x1d\xbf\x90\xaf\x49\xe6\x87\x7e\xe6\x1f\xa2\xa0\x96\ +\xf0\xb1\x69\xf5\x9d\xf1\xcc\xe9\xfd\xfe\xe6\xed\xbc\xba\xd0\x34\ +\x08\xbc\xbf\x28\xfb\x5c\x5f\x17\x00\x61\xe0\xdf\xd3\x9c\x23\xad\ +\xcc\x1b\xf1\x34\x0c\x3c\x9e\xeb\x78\x0e\x98\x47\x6b\xee\xdb\x22\ +\x4d\xfe\xcc\x73\xdb\x54\x3d\x28\x8e\x8c\x05\x58\x87\x4e\xcb\x6e\ +\x19\x29\x93\x66\x67\xe5\x08\x83\x75\x24\x1a\xa9\x7f\x64\x51\x1c\ +\xbf\x13\x17\xa9\xee\xb8\xd5\x69\x94\xc5\xe4\x20\x9c\xaa\xd5\xe8\ +\xab\x7b\x53\x5b\x37\x37\x55\xeb\xbb\x2f\xce\x96\x07\x54\x8e\x82\ +\xa2\x21\x3a\xf6\xef\x09\xf7\xd0\xf7\x42\x09\xce\xb4\x4b\x46\xf3\ +\xcd\x9a\x86\xa4\x6a\xde\xa0\xc9\x13\x5e\x43\x59\xb6\x8f\xb9\x7e\ +\xc1\x47\xef\xdd\xea\xba\x65\x69\xda\x2b\x71\x02\xab\x3c\xe1\xe1\ +\xf2\x94\xe5\x31\xcf\x77\x0f\x24\xa1\x61\xf8\x2a\xcd\x18\xfd\x4c\ +\xbc\x5b\x8d\xe7\xa5\x60\x51\x9d\x96\xc1\xe0\x69\xc8\xb1\x8c\x22\ +\xbd\xd7\x72\x8e\x10\x61\x31\xf7\xd6\xcc\x33\x6b\x59\xe8\xf3\x3c\ +\xc3\x98\xbf\xf7\x12\x5e\xe7\x6b\x69\x73\xcd\x23\x47\x15\xc3\xb5\ +\x1c\xc3\x85\x18\x3a\xd0\x6c\x54\x55\xec\x59\xc8\x30\x0e\xd5\x44\ +\x1c\x75\xc8\x99\xc8\x2d\x34\x87\x26\xdc\x69\x0d\xad\x94\xea\x8d\ +\x70\x2f\x2c\x8b\x82\xd4\x12\xb2\xa3\x30\x60\x85\x47\x4f\x4c\x71\ +\x4c\x0e\x63\xfb\xbf\x1a\xd1\x65\xd0\xd4\x89\xda\x19\x5e\x34\x13\ +\x18\xba\x63\x70\xc1\x67\x21\x8e\x56\x1c\xf8\xca\xc6\xe5\x6c\xb8\ +\x50\x1f\x83\x0d\x6c\x5e\x49\x78\x4a\x48\x58\xd0\x1e\x83\x06\xb7\ +\x2a\xa7\x93\x2b\x1b\x97\xb3\x61\x8f\x53\x2c\x74\x03\x39\xc7\xd3\ +\x9e\x2b\x17\x97\x44\x86\x05\xb5\x51\x32\x94\x73\x2a\xbc\xd2\x71\ +\x41\xb5\x18\x29\x38\x0c\x03\xd9\xc7\x96\x57\x36\x2e\x2a\x1b\xda\ +\x38\xb3\x29\xdd\x41\xb6\x2b\x0e\x69\xf8\xb0\xac\xd0\x94\x98\x8f\ +\xbe\x2c\xe8\x1a\xd2\x8f\x2b\xb5\x94\xeb\x0b\xd3\xf4\x7d\x89\x59\ +\xc0\xd0\xec\x9b\x9e\x74\x0b\x5d\x39\xe8\xc9\x01\x74\x06\x26\x41\ +\xc6\xc5\x9d\xe4\x09\xa9\xff\x96\x47\x67\x4a\x92\x68\x61\x27\x7d\ +\x1c\x38\x0e\x9c\x0c\x1c\x08\x12\xc1\x2f\xb9\xff\x6b\x3c\x0d\xe1\ +\x51\x42\x40\xbe\x45\xb5\xf4\x91\x60\x42\x1d\x1a\x03\x87\x82\x7c\ +\x34\xc8\x1e\x11\x46\xff\xba\xdc\x15\x0f\xf2\x6d\x6c\x48\x1f\x0f\ +\x93\xc1\x0b\x83\x7c\x24\xc8\x1e\x0d\xd0\xee\xbd\xf5\xdd\x3d\x43\ +\x92\x6e\x63\x49\xfa\x70\x30\x79\x40\x0c\x5d\x1e\xae\x34\x3c\x67\ +\xbe\xda\xff\xe1\xdc\x29\x0f\xf2\xed\xec\x49\x9f\x98\x4c\xc1\xc5\ +\x28\x95\x5a\xba\x5d\x3d\xe9\x63\x42\xcc\x5c\xed\xde\x0f\xe7\xce\ +\xaa\xb5\x74\x44\xbc\x88\xa0\x18\x60\x63\xa9\x2b\x2c\xae\x29\xea\ +\x59\x6c\xe8\xe3\x6c\x7a\xcb\xb8\xd7\xf7\xd4\x87\x41\xe5\xab\x97\ +\x27\x7c\x8c\x51\xb1\x7b\x12\xe0\xa2\x49\x81\xb4\xd9\x26\xc0\x44\ +\xa5\xdf\x18\x17\xc1\xff\x82\xc1\x83\x78\x0c\xf8\xb8\xff\x9a\x4f\ +\xf1\xdf\x97\x0c\x60\xdf\x04\xd0\x09\x20\x36\xd1\x65\x99\xf8\x25\ +\x23\x87\xa1\x35\x06\x76\x2e\x32\x8b\x84\x7a\xd9\xaa\xe7\x25\x03\ +\xd8\x77\x4a\xd6\x09\x9f\x6e\x9e\x16\xa4\x6f\x15\x3e\xf1\x62\xcd\ +\x28\xc1\xeb\xa2\x13\xcb\x6f\x15\x41\x77\x1c\x17\x3c\xfe\xca\xe5\ +\x5b\x06\xb0\x78\x7d\x65\x94\x28\x76\x91\xfe\x8c\xfa\xbb\xf1\xb3\ +\x55\x27\x84\x65\x35\xef\x07\x21\x46\xba\x6b\x68\xb6\xed\x36\xb3\ +\xf1\x38\x4a\x08\x9f\x8e\x7a\xe9\xbf\xb9\xcf\x48\x5b\xfa\x0f\x8d\ +\x12\xaf\x80\xfa\xe9\xb8\x0b\x29\x5d\x2c\x52\x92\x1d\x58\x3b\xe7\ +\x82\x53\xf1\x1b\x10\x13\x15\x1d\xbb\x3a\x9f\xed\xdd\x61\x03\x4d\ +\xdc\x89\x6b\x83\x5f\x01\x9e\x80\x8f\xc0\x2e\x69\xd0\x2d\xf0\x1e\ +\x18\x1a\x32\x26\x2e\x76\xac\x3b\x6c\x23\x0b\x8b\x7f\xdc\xe8\x4e\ +\xb7\xab\x26\x1f\x81\x8e\x2b\xd6\x78\xf3\x56\xaf\xe0\xef\x33\xf2\ +\x0d\x07\xb7\x3c\xa2\xf9\x90\x87\x26\x49\xf1\x31\x15\x0c\x72\xf6\ +\xe0\x67\x39\x23\x47\x9f\x8e\x34\x9f\x80\xd0\x90\x88\xaf\x26\xd2\ +\x99\x12\x54\xc7\x08\x8b\xa9\xaf\x12\x01\x3d\xfd\x1e\x9e\x7f\x44\ +\x33\xc2\xcc\xfd\xa9\xbb\x33\x5f\x29\x77\xf4\xc4\xae\xae\xf1\xee\ +\x77\x08\x5d\xef\x97\x42\x3a\xc1\x1b\x7e\xc9\x23\x65\xcc\xf6\x5e\ +\x6e\x77\x47\xed\x80\xeb\x1d\x59\xbd\xce\xe9\x8b\x5c\xa7\xdb\x0d\ +\x08\x9c\x9c\xfe\xa6\xf5\x0e\xd7\x6e\x8f\x1b\x7a\x95\x28\xab\xdb\ +\x99\xbd\x9f\xf0\x76\xfa\xdd\xd0\xf0\x49\xea\x7c\x7d\x9f\xc8\x76\ +\xfb\xde\xd0\x4b\x6c\x59\x7d\xaf\xef\x0b\x1e\x9d\x9e\x37\x34\x78\ +\x92\x7a\x5e\xef\x95\xf5\x23\x85\x76\xe0\xbd\x09\x59\x5d\xcf\x1c\ +\xc7\xf9\xbe\x17\xf8\x9c\xfe\x0f\x06\x3a\xf1\x1b\x7a\x67\x47\xd6\ +\xe0\x35\x7b\xc3\xf7\x48\xe5\x78\xde\xb6\xce\x8b\xf3\xbf\xe2\x95\ +\x83\x51\xaa\xc7\xc0\x00\x4a\xec\x80\x23\x4d\x9c\xbf\xa3\x10\xee\ +\x3d\x75\xee\x46\xf0\x79\x5b\x05\x53\x75\x39\xbf\x99\x8a\x3f\xc3\ +\x32\xbf\xf9\x0f\xb1\xb1\x20\x51\ +\x00\x00\x0f\x08\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x74\x61\x63\x6b\ +\x5f\x72\x61\x73\x74\x65\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x2d\x34\x33\x2e\x32\x35\x33\x31\x39\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x35\x2e\x31\x34\x39\x30\x32\x30\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ +\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ +\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ +\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x39\x2e\x38\x31\x33\x33\x33\x33\x35\x31\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\ +\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ +\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\ +\x6d\x20\x32\x2e\x32\x30\x35\x36\x34\x32\x37\x2c\x32\x33\x2e\x34\ +\x36\x36\x39\x31\x32\x20\x2d\x30\x2e\x30\x37\x32\x33\x30\x39\x2c\ +\x31\x30\x2e\x36\x36\x36\x34\x32\x31\x20\x33\x31\x2e\x39\x39\x39\ +\x32\x36\x34\x33\x2c\x30\x2e\x32\x31\x37\x30\x32\x34\x20\x30\x2e\ +\x30\x37\x32\x33\x31\x2c\x2d\x31\x30\x2e\x36\x36\x36\x34\x32\x31\ +\x20\x76\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x32\x39\x39\x32\x2d\x33\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ +\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ +\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ +\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x31\x31\x36\ +\x30\x36\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ +\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ +\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\ +\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x78\x3d\x22\x34\x33\x2e\x34\x37\x31\x32\x36\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x33\x33\x37\x30\x37\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ +\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\ +\x30\x31\x2c\x30\x2e\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\ +\x2e\x38\x39\x37\x30\x34\x31\x32\x39\x2c\x30\x2e\x34\x34\x31\x39\ +\x34\x36\x37\x34\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ +\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\x30\x31\x2c\x30\x2e\ +\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\x2e\x38\x35\x31\x34\ +\x33\x35\x37\x33\x2c\x30\x2e\x35\x32\x34\x34\x35\x38\x39\x36\x2c\ +\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x32\x2e\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x36\x2e\x38\ +\x31\x37\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x32\x39\x2e\x38\x36\x35\x30\x37\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\ +\x33\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x37\x32\x32\ +\x37\x33\x32\x33\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ +\x6c\x3a\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ +\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x35\x39\x33\x33\x33\x30\x33\ +\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\ +\x31\x33\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x31\x39\x2e\x31\x35\x33\x36\x39\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x34\x2e\x32\x36\x39\x36\x30\x34\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ +\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x33\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ +\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x34\x30\x37\x33\x30\x31\x2c\ +\x30\x2e\x31\x30\x38\x37\x31\x34\x35\x38\x2c\x2d\x30\x2e\x38\x30\ +\x35\x34\x35\x35\x32\x33\x2c\x30\x2e\x35\x39\x32\x36\x35\x36\x36\ +\x32\x2c\x30\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x39\x2e\x38\x31\x33\x33\x33\ +\x33\x35\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ +\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x4d\x20\x33\x34\x2e\x31\x33\x32\x30\x35\x33\x2c\ +\x31\x31\x2e\x37\x33\x37\x32\x38\x20\x33\x34\x2e\x31\x33\x33\x33\ +\x35\x33\x2c\x31\x2e\x30\x37\x30\x36\x31\x33\x33\x20\x32\x2e\x31\ +\x33\x33\x33\x35\x33\x33\x2c\x31\x2e\x30\x36\x36\x36\x36\x33\x33\ +\x20\x32\x2e\x31\x33\x32\x30\x34\x33\x33\x2c\x31\x31\x2e\x37\x33\ +\x33\x33\x33\x20\x76\x20\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ +\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ +\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x05\xc9\ +\x00\ +\x00\x25\xd3\x78\x9c\xed\x5a\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ +\xd4\x97\x0d\x0b\x29\x52\xb2\xae\xb5\xdd\x87\x15\xc3\x0a\x74\x2f\ +\x5b\xd7\x01\x7b\x29\x68\x89\xb6\xb5\xca\xa2\x47\x51\xb1\xdd\x5f\ +\xbf\x43\xdd\x6c\xd9\x4e\x17\x37\xf3\x06\x14\x56\x10\x24\x3a\x17\ +\xf2\xf0\xfb\xce\x25\x09\x33\x7e\xb5\x5d\xe5\xe8\x41\xa8\x32\x93\ +\xc5\xc4\x62\x84\x5a\x48\x14\x89\x4c\xb3\x62\x31\xb1\x7e\x7b\xf7\ +\x23\x0e\x2d\x54\x6a\x5e\xa4\x3c\x97\x85\x98\x58\x85\xb4\x5e\x4d\ +\xef\xc6\xdf\x60\x8c\x7e\x50\x82\x6b\x91\xa2\x4d\xa6\x97\xe8\x4d\ +\xf1\xb1\x4c\xf8\x5a\xa0\x6f\x97\x5a\xaf\x63\xdb\xde\x6c\x36\x24\ +\x6b\x85\x44\xaa\x85\xfd\x1d\xc2\x78\x7a\x77\x37\x2e\x1f\x16\x77\ +\x08\x21\xd8\xb7\x28\xe3\x34\x99\x58\xad\xc3\xba\x52\x79\x6d\x98\ +\x26\xb6\xc8\xc5\x4a\x14\xba\xb4\x19\x61\xb6\xb5\x37\x4f\xf6\xe6\ +\x89\xd9\x3d\x7b\x10\x89\x5c\xad\x64\x51\xd6\x9e\x45\xf9\xe2\xc0\ +\x58\xa5\xf3\xde\xda\x44\xb3\x71\x6b\x23\x16\x45\x91\x4d\x1d\xdb\ +\x71\x30\x58\xe0\x72\x57\x68\xbe\xc5\x43\x57\x88\xf1\x9c\xab\x43\ +\x29\xb5\x41\xb7\xb7\x7c\x9a\x55\x5c\x02\xa0\x6b\xf8\xec\xcd\x3b\ +\x01\x29\x65\xa5\x12\x31\x07\x3f\x41\x0a\xa1\xed\xd7\xef\x5e\xf7\ +\x4a\x4c\x49\xaa\xd3\x83\x65\x3a\x3c\x07\xbb\x0e\x40\x2e\xf8\x4a\ +\x94\x6b\x9e\x88\xd2\xee\xe4\xb5\xff\x26\x4b\xf5\x72\x62\xb9\x23\ +\xc2\x5c\x78\xbc\x5a\xb8\x14\xd9\x62\xa9\x8f\xa5\x59\x3a\xb1\x20\ +\x7a\x27\x0a\x9b\xf7\x83\xe4\x60\x8d\x41\xbb\x70\xdc\x6b\x28\x89\ +\x1c\xc2\x90\x62\x9e\x1b\x34\x36\xdd\x11\xe2\x54\x26\x26\x26\x58\ +\x52\xac\x32\x5e\x69\xb9\x02\xd6\x92\x24\xe7\x65\x99\xcd\xb3\x04\ +\x5e\x64\xb1\xce\xab\x45\x56\x7c\x00\x2e\xb5\x54\x1f\xb4\xfc\xa0\ +\x78\xa9\x85\xf9\x4e\xe6\xa4\x03\xb2\xdf\x55\x6c\xd7\x52\x69\xbc\ +\x4d\xd7\x00\xa7\x1f\x9c\x55\xee\x3a\xe5\x14\xb4\xe3\x54\xcc\x4b\ +\x63\xd5\x9c\xcd\xbc\xc1\xe1\x02\x0b\xd9\xb5\xb6\x0f\xd5\xc4\x99\ +\x3e\x64\x62\xb3\xb7\x9d\xf1\xb2\xc1\x0f\xa1\x35\x5f\x40\xae\xe5\ +\x52\x4d\xac\x17\xf3\xfa\x69\x15\x33\xa9\x52\xa1\x3a\x95\x5f\x3f\ +\x03\x95\x04\x3e\x32\xbd\x6b\xaa\xab\x5d\xbb\x8b\xd7\xac\xda\xeb\ +\xe9\x79\x7d\xb9\xe4\xa9\xdc\x4c\x2c\xe7\x58\xf9\x49\xca\x15\xb0\ +\x47\x22\x2f\xa2\x0e\x8d\x8e\xd5\xc9\x76\x62\x61\x46\x61\x55\xc6\ +\x58\x78\xa2\x85\x0d\x5d\xd0\xd1\xd0\x73\xdc\x13\x65\xa5\x14\xd4\ +\x1f\xce\xf9\x4e\xc0\xa9\xea\x2f\xac\x35\x2a\x97\x72\xb3\x50\x06\ +\x1d\xad\x2a\x71\xec\x69\x34\x78\x36\x93\xdb\xf3\x6a\x48\x87\xca\ +\x54\x36\xae\x8a\x4c\x43\xf5\xac\xb7\x87\xab\x56\x59\x2a\xca\xf3\ +\x8e\x65\xc1\xd7\x78\x91\xcb\x19\xcf\xcf\x1b\x6c\xb2\x02\x50\xc2\ +\x6d\xa2\x33\xb7\x27\xe1\xd8\xa2\xcb\xfa\x80\x9e\x60\xd2\x5a\x40\ +\xec\x27\x44\xb4\xaa\xdd\xe3\xaa\x15\xdf\x66\xab\xec\x93\x00\x60\ +\x58\x9d\x77\x90\x5b\x03\x58\x1a\x37\x84\xf4\xce\x54\xf0\x76\x67\ +\x64\x56\x27\x34\x78\x1a\x81\x13\x45\x41\x2f\x94\x2a\x83\xc2\x38\ +\x08\xa7\x13\xed\x0e\x45\xa6\xde\xa1\x5d\x6f\xeb\x04\xab\xd3\x2f\ +\x38\xd6\xed\x0e\x75\x6d\xde\xdb\xa7\x89\x5f\xcb\x57\x42\xf3\x94\ +\x6b\xbe\xaf\x82\x4e\x02\xb1\xd1\xee\x64\xd0\x3a\xe3\x5f\x5e\xff\ +\x38\x6d\x37\x1a\x27\x49\xfc\xbb\x54\x1f\xbb\x7d\x11\x32\x06\x7c\ +\x26\x2b\x40\xda\x9a\xf6\xe2\x71\x9a\xc4\xd0\xec\xa0\x09\x4c\xb3\ +\x15\xe4\xb6\xe9\x93\xdf\x43\x73\x1b\xdb\x7b\xc5\xc0\xd8\x80\xb5\ +\x5f\xb4\x59\x56\x89\xa6\x6b\x9e\x1d\x1d\x69\xb2\xca\x8c\x93\xfd\ +\xab\xce\xf2\xfc\x8d\xd9\xa4\x3d\xf1\xc1\xa2\x99\xce\xc5\x5e\x38\ +\xb6\xdb\xe8\xdb\xb3\xd9\x07\x87\x1b\xdb\xdd\xe9\xeb\xb7\xc5\x1e\ +\x95\x41\x51\xf4\x44\xe7\x7c\x26\x20\x43\xdf\x1a\x25\x3a\xd1\x2e\ +\x94\xac\xd6\x2b\x99\x8a\xd6\xbd\x47\x13\x5a\x5f\x4f\x99\xde\xe5\ +\xa0\x9f\x43\xf4\x31\x74\x1a\x21\x38\x7f\x69\x5e\x70\xdb\x27\x62\ +\xf6\xb2\xd4\x4a\x7e\x14\xf1\x0b\x4a\x45\x30\x9f\xb7\xaf\x4d\xea\ +\xc7\x94\x8c\x9c\x9a\xe8\xb0\x93\x03\x1e\x42\xe5\x90\x9b\x3a\x1e\ +\x75\xb2\x94\x43\x57\x51\x8a\xef\xe2\x02\xc6\x7a\x27\xed\x77\x18\ +\xa4\xa5\x09\xce\x0d\xdd\x51\x2f\x6c\x6b\xcc\x73\x89\x99\x1a\xae\ +\xd3\x2b\xba\xd2\x1a\x39\xa4\x09\xa1\xd7\x34\xad\x88\x1c\x65\x27\ +\xa4\x25\x76\xc9\xde\x5f\xd5\x79\xea\x8f\xcc\xe3\xf7\xac\x3d\x8e\ +\x4e\x3a\x82\x51\x4b\x8f\xd1\xa9\x5f\x55\x95\xc3\x34\x78\x10\x85\ +\x4c\xd3\x1e\x2f\x27\x9c\xcf\x53\x7a\x8c\x57\xe8\xd5\xc7\xf0\xfe\ +\x4d\xbc\xbc\xd0\x8d\x30\xc3\xa3\x53\xd0\x1a\xcc\xda\x59\x3b\x00\ +\x8d\x44\xb5\x66\x74\x08\x9a\x13\x92\x20\x32\xcf\x21\x66\x2e\x09\ +\x9a\x45\xf6\xc0\x0d\x7a\xc4\x10\xc6\x3e\xb4\xcf\x0d\xd0\x73\x06\ +\xfd\x10\xfd\x0a\x88\x08\x43\xec\x5f\x83\x0a\xe6\x12\xff\xc6\xc2\ +\x93\xcb\x01\x3b\xd8\xbd\x06\x0d\xe1\x71\x67\xb9\x51\xf1\x0f\x54\ +\xf8\xd7\xa9\x07\xc7\x25\xa3\x1b\x13\x17\x16\x85\x7f\x9d\xa2\x60\ +\x21\xf1\x6e\x63\xe2\xe2\x06\x15\xe0\xe0\x2a\x95\x11\x92\xd1\x8d\ +\x88\x27\xcf\x6b\x1c\x61\xe7\x99\x34\x0c\xff\xac\xd1\x15\xc5\x6d\ +\x60\x5f\x44\x03\xc3\xde\xb3\xeb\xe1\x2c\x11\xb7\x91\x7d\x39\x19\ +\x01\x7e\xee\xef\x13\x67\xa9\xb8\x0d\xed\x2f\x2b\x0c\x0f\xd3\xab\ +\xb4\xa8\xdb\xdc\xfe\xb2\x3e\x45\x71\x74\x95\xf2\xb8\x4d\xee\x27\ +\x53\x11\x3e\xbb\x43\x9d\x36\xa3\xdb\xd4\xbe\x88\x02\x0a\x3f\xc5\ +\xb2\xab\xb0\x70\x1b\xd9\x17\x32\xe1\xe2\xf0\x1a\x3c\xdc\xe6\xf5\ +\xc5\x25\x11\x3c\xfb\xb7\x89\xf3\x7d\xe9\x36\xaa\xbf\xa0\x39\x5d\ +\xa9\x2a\xfe\x87\x31\xbd\xe6\x7a\x79\x96\x06\x4a\x2f\xa3\xa1\xb9\ +\x51\x1e\xd2\xc0\x88\x13\xb9\x34\x08\xa2\x9e\x86\x3c\x2b\x04\x04\ +\x14\x97\x7f\x55\x5c\x89\x43\xe9\x9f\x32\x2b\xe2\x9a\xa5\xcb\x29\ +\x33\x52\x39\x9f\x97\x42\xc7\xf4\x71\x1a\x81\xc5\x9f\x11\x36\xb7\ +\x4b\x2c\x72\x20\x3d\xee\xcd\x4c\x8e\xfc\x28\x40\x3f\x21\xe6\xa3\ +\xf7\x28\x68\x6f\x83\x3c\xf4\x16\xb9\x94\xb8\x7e\xc4\x42\xef\x9e\ +\x05\xc4\x63\xe6\x03\x8c\xee\x9d\xa0\x75\x79\x8f\x1c\xd6\x52\x0e\ +\xee\x07\xab\xa2\x3f\x4e\xf2\xc6\x0d\x19\x3b\xa5\x24\x91\x45\x51\ +\xff\xbf\x00\x4e\x2a\xf5\xc0\x75\xa5\xc4\xe0\x4e\xb4\xbf\xdb\x94\ +\xa9\x30\xd7\x81\xe5\xc4\x4a\xda\xe7\x09\xf4\xb5\x55\xf4\xb9\x7b\ +\x36\x46\xe0\x78\x94\x32\x37\x58\x6f\x8f\xf9\x99\x55\x5a\x7f\x9e\ +\x9d\xc7\xf0\x0d\x49\xe0\xf9\x0e\x1d\x85\xf7\x2e\xc0\xeb\xf8\x2e\ +\x0b\x11\x86\xd4\xf5\xc3\x80\xfa\xec\xde\x03\x30\xc3\xc8\x0b\x23\ +\xe4\x91\x30\x70\x1c\x8f\x06\xf7\xa6\x76\x9c\x11\x0d\x5d\x04\x8c\ +\x84\x75\x59\x18\xe7\xfa\xb6\x37\x38\xbb\xe2\x00\x62\x83\x81\x4b\ +\x47\xf4\xc9\x10\x7f\x2d\x3d\xe8\xd9\x7f\xd6\x80\xe6\xcf\x86\xcd\ +\xbf\xe9\x42\x47\xc2\xff\xa2\x15\x8d\xed\xc5\xf4\x6e\x6c\x2e\xd3\ +\xa7\x77\x7f\x03\x12\x53\xa0\x4a\ +\x00\x00\x0a\xb6\ +\x00\ +\x00\x2d\x07\x78\x9c\xed\x5a\xdb\x6e\xe3\xd6\x15\x7d\x9f\xaf\x20\ +\xe4\x97\x19\x54\xa4\xce\xfd\xa2\xd8\x93\x87\x06\x29\x02\x24\x28\ +\xd0\x24\x28\xd0\x97\x80\x22\x29\x9b\x1d\x8a\x14\x48\x6a\x2c\xe7\ +\xeb\xbb\x0e\x25\x52\xa4\x44\xd9\xb2\x2d\x14\x98\xa2\xe2\x0c\x46\ +\x3c\xfb\x5c\xd7\x5e\xfb\x76\x34\xb7\xdf\x6f\x57\x99\xf7\x35\x29\ +\xab\xb4\xc8\xef\x26\x34\x20\x13\x2f\xc9\xa3\x22\x4e\xf3\xfb\xbb\ +\xc9\xef\xbf\xfd\xe8\x9b\x89\x57\xd5\x61\x1e\x87\x59\x91\x27\x77\ +\x93\xbc\x98\x7c\xff\xf9\xc3\x6d\xf5\xf5\xfe\x83\xe7\x79\x18\x9c\ +\x57\xf3\xa2\x5a\xdc\x4d\x1e\xea\x7a\x3d\x9f\xcd\x1e\x1f\x1f\x83\ +\x62\x9d\xe4\xd5\x63\x58\x47\x0f\x8b\xa2\xf8\x12\x14\xe5\xfd\x6c\ +\x53\xa6\x33\x46\x88\x9d\xa1\xef\xe4\x30\x32\x8e\xba\x81\xeb\x4d\ +\x99\x35\x5d\xe3\x68\x96\x64\xc9\x2a\xc9\xeb\x6a\x46\x03\x3a\xeb\ +\x75\x8f\x0e\xdd\xa3\x32\x09\xeb\xf4\x6b\x12\x15\xab\x55\x91\x57\ +\xcd\xc8\xbc\xba\xe9\x75\x2e\xe3\xe5\x60\x57\x8f\xbc\xe9\x44\xad\ +\xb5\x33\xc2\x66\x8c\xf9\xe8\xe1\x57\x4f\x79\x1d\x6e\xfd\xe1\x50\ +\x9c\x6e\x6c\x28\x0e\x40\x66\x90\x1d\x7a\x5e\xd6\x6b\xbe\xcd\xd2\ +\xfc\xcb\xd9\xcd\x34\xd2\xfe\xea\x40\x7f\x8d\xbf\xdd\x80\xb6\x21\ +\xa8\x8a\x4d\x19\x25\x4b\x8c\x4c\x82\x3c\xa9\x67\x3f\xfc\xf6\x43\ +\x27\xf4\x49\x10\xd7\x71\x6f\x1a\x4c\x5a\x45\xe1\x3a\x19\xac\xdb\ +\x36\xee\xf0\x0a\x57\x49\xb5\x0e\xa3\xa4\x9a\xb5\xed\xcd\xf8\xc7\ +\x34\xae\x1f\xee\x26\x5c\x04\x94\xe3\x23\x9b\xc6\x87\x24\xbd\x7f\ +\xa8\x8f\x5b\xd3\xf8\x6e\x82\xb3\x32\x6b\x75\xf3\xde\x63\x12\xdd\ +\x75\xd8\x4f\x3c\xef\x73\x2c\x60\xde\xc7\xc4\xa8\xc8\x68\x62\xb4\ +\x9d\x7a\x8c\x30\xea\x13\xea\x53\xf9\xa9\x19\xd4\x9e\x69\x1e\x17\ +\x91\xdb\x24\xd6\x48\x56\x69\xb8\xa9\x8b\x15\x94\x1e\x45\x59\x58\ +\x55\xe9\x32\x8d\xf0\x52\xe4\xeb\x6c\x73\x9f\xe6\x7f\x64\xe0\x68\ +\x15\xd6\xe6\x8f\xba\x28\xb2\xa0\xc5\xbf\x5b\x3e\xd9\xae\x8b\xb2\ +\xf6\xb7\xf1\x1a\xb8\x2a\x3d\x2a\x7c\x6a\x85\x9f\x21\xbd\xed\x36\ +\xe1\x76\x10\x7f\x4d\x93\x47\x37\x66\x77\xe4\x45\x58\xed\xa0\xf2\ +\xbc\x75\x78\x0f\x12\x66\x45\x79\x37\xb9\x59\x36\x9f\xbd\x60\x51\ +\x94\x71\x52\xb6\x22\xd5\x7c\x06\xa2\x02\xd0\xa7\xf5\xd3\xce\xea\ +\xf6\x73\xb7\x3b\x72\xb3\x76\x72\x32\x2e\xaf\x1e\xc2\xb8\x78\xbc\ +\x9b\xb0\x63\xe1\x9f\x45\xb1\xba\x9b\xe8\xc0\x52\x43\x04\xd5\xc7\ +\xe2\x68\x7b\x37\x91\x81\x31\xc2\x52\x6e\x4e\x84\x58\x8f\xe9\x80\ +\x13\xc2\x34\x3f\x11\x6e\xca\x12\x76\xe9\x67\xe1\x53\x82\x43\x35\ +\xff\xd0\x7d\xa7\xea\xa1\x78\xbc\x2f\x1d\x38\x75\xb9\x49\x8e\x47\ +\x3a\x89\xbf\x58\x14\xdb\x71\x31\xf4\xbc\x71\x16\xef\x6f\xf2\xb4\ +\x86\x55\xad\xb7\xfd\x59\x37\x69\x9c\x54\xe3\x03\xab\x3c\x5c\xfb\ +\xf7\x59\xb1\x08\xb3\xf1\x0e\x8f\x69\x0e\x90\xfc\x3d\xa5\x29\xef\ +\x74\x70\xdc\xa3\xe5\xb7\x26\xe7\x7a\x60\xef\x27\x7a\xd8\x8b\x9e\ +\xce\x8b\x56\xe1\x36\x5d\xa5\x7f\x26\x00\x86\x9e\x3d\x76\x59\xd4\ +\x0d\x97\xdd\x34\x9f\x9b\x4e\xb7\x03\xe8\x76\xe3\x76\xdc\x73\xef\ +\x50\x8f\x9c\xb4\x8d\xf5\x93\x33\xf2\xed\x93\x13\x74\x8d\x45\x99\ +\xc2\x2a\x7a\x5b\x6e\x9b\x9e\xfa\x4d\xce\xfa\xe1\xe9\xb7\x0d\x07\ +\x1b\x86\xea\x63\xd9\x53\x5f\xe6\xcd\x1a\xd3\x98\x9d\xda\x46\xd3\ +\x1e\x27\xcb\xea\x60\x24\xee\x0d\x8e\xc1\xb6\x27\x82\x9b\x4b\xc2\ +\xf2\x6f\x65\x18\xa7\x38\x73\xff\x48\x43\x89\x22\x42\xed\xc7\x38\ +\x33\xac\x8b\x75\xdb\x77\xef\x6f\xd0\x82\x3e\x66\x72\x68\x2e\x96\ +\xcb\x2a\xa9\xfb\x27\xc3\xfe\xeb\xa7\x2c\xd9\xf5\xf6\x1b\x2b\x9c\ +\xdf\x68\xe5\x9e\xef\x9a\xa6\xbd\x75\xcd\xe9\x77\xfb\x53\x3d\xbb\ +\x9a\x24\x23\xab\xd1\xe7\x57\xe3\x4c\x48\x65\xce\xae\x76\x3b\x1b\ +\x1e\xfb\x95\x28\x49\xb3\x77\x54\x23\xfb\x1e\xd9\x4c\x1c\xc7\x36\ +\xb6\x27\x9b\x79\x1e\xc2\xf6\xfc\x58\xcb\x9e\x47\x69\x64\x35\x15\ +\xb9\xe7\x82\xd5\xe8\xe8\x6a\x9a\x5e\x0f\x25\x69\x5f\x81\x92\x8d\ +\xc2\x90\x90\xb7\xa3\x44\x5f\x85\x12\xfc\x6f\x4c\x17\x6f\x46\x49\ +\xf1\xeb\xa1\xc4\x0e\x4b\x20\x43\x43\x78\x49\x73\xac\x5b\x15\x19\ +\x5c\xca\xe5\x07\x5a\x2a\xe4\x3e\x47\xf0\x91\x40\x1b\xc3\xb8\xe4\ +\xaf\xc0\x91\x5d\xf1\x64\x54\x5e\xe5\x64\xcb\x85\x5e\xe8\x37\x13\ +\x83\xea\xab\x1d\x48\xd3\xb3\xce\x71\x64\xdf\x92\x68\x66\xc4\x5b\ +\xf7\xad\xa9\x79\xd9\x39\x4a\xac\xf0\x7a\xe7\x48\x17\xce\x45\x1c\ +\x53\x45\x58\x43\xb8\x65\xec\x19\x9f\x3c\xe6\x68\xb5\x89\x4d\x7c\ +\x34\xd7\xc5\x76\xa4\x19\x79\xa3\x72\xba\xb4\xa8\xc8\xb2\x24\xc2\ +\xfc\x61\xf6\x18\x3e\x55\xdd\x22\x4d\x62\x3f\x7f\x28\x13\x14\x22\ +\x37\x23\x6a\x7c\x4e\xcb\x8c\x1d\xa6\xa1\x77\x13\x13\x30\x66\x8c\ +\x22\xb6\x6b\x7d\x42\x2b\xb5\x81\x55\x56\x1f\x62\xf6\x96\x21\x7b\ +\x13\x01\xac\xcd\xf9\xa2\xae\x2b\x1b\xe9\x7a\xbf\x5f\xea\xf7\x5d\ +\xc6\xb5\xa9\x92\xf2\x57\x57\x0b\xfc\x3d\xff\xbd\xcb\x6d\x5d\x12\ +\x80\x3a\x2b\xfe\x25\xa9\x1f\x0a\x6c\x72\x1d\xc6\x27\xe3\x7f\x2b\ +\xc3\xbc\x42\x49\x82\x8c\x13\xc9\x79\x99\x6e\x3f\x76\xe9\xc2\x94\ +\xe0\x39\xbc\xf9\x22\x90\x86\x1b\xc2\xd8\xd4\xa7\xa8\x0f\x14\x97\ +\x4c\x7f\x3a\x60\x3f\x8e\xf2\x73\xeb\x50\x2d\x09\x93\x74\xea\xb3\ +\x80\x53\x6a\x98\x4c\x7c\x83\x05\xa5\xe0\x56\xf0\xfd\x0b\xd5\x96\ +\x50\xcd\xd1\x47\x05\x46\x3b\x51\xb3\xba\x25\x5a\x30\xfa\xe9\x79\ +\x8c\xce\xc0\x39\x8a\xfc\xa8\x92\x5e\x86\xef\x79\xf8\xc7\x98\x61\ +\xd8\x25\x04\x6b\x92\xa8\x17\x99\xfa\x02\xf6\xef\x62\xb8\x8b\xbc\ +\xcf\xa6\x2f\x72\x00\x1e\x74\xa2\xa9\x50\xbd\xbc\xd6\xe1\x8c\xd2\ +\x87\x4a\x4a\x88\xb0\x6a\xa0\x15\x4e\x03\x83\x12\x85\xf0\x81\x02\ +\xc7\x7a\x5f\x06\xf4\x79\x96\x21\x7e\x11\xad\x05\xf8\x34\xc5\x57\ +\xf8\x27\x21\x2c\xd8\x44\xc0\x20\xcb\xc0\x21\x8b\x66\x29\x91\x57\ +\x52\x6b\xa6\xbe\x09\xa4\x2b\x8e\xc5\xe1\x1b\xed\x31\xdc\x2d\x12\ +\x66\xd7\x45\xb9\x97\xb1\x3b\x94\x87\x4b\x20\x95\x3a\x20\xe4\xea\ +\xbe\x9e\x5b\x71\x95\x1e\xc5\x2e\xbb\x86\xe5\x50\xbe\x3c\x96\x97\ +\xae\xa6\x24\xb6\xf9\x5c\x04\x9c\xa1\xb0\x32\x45\x76\x7e\x80\x04\ +\x0a\x06\x07\x3f\x00\xf0\xb8\x80\xf5\x18\x23\xa7\x3c\xd0\x9c\xa0\ +\x10\x65\x9f\x2e\xd4\xd7\x4b\x84\x1d\x4b\x6d\xb4\x4f\xfc\xb3\x49\ +\x60\x2f\xe9\xb0\xbe\xf6\xfb\x11\xe2\xc2\xa2\x62\x19\x52\x3a\x92\ +\x33\xbe\x1c\x37\x0d\xa7\xd8\xd9\x1b\x62\xe7\x52\x2d\x97\x27\x69\ +\xd6\x8b\x85\xc5\xf5\xc9\x37\xf4\x31\x27\xe4\xe3\x46\xbe\x36\xdc\ +\x9c\x67\x93\xcf\x03\xc6\x9b\x67\xca\x02\x41\xb9\x50\xc6\x19\xa1\ +\xa1\x44\x59\x17\x50\x60\x8f\x42\x1a\xa2\xa5\x9d\x5a\x1e\x28\x78\ +\x1f\xc6\xa7\x54\x22\xe2\x48\xad\xed\xa7\x81\x11\xb8\xe6\xa1\x19\ +\x68\x58\xb6\x30\x56\x0f\x6c\x61\xd0\x6d\x39\xda\xad\xdc\x99\x88\ +\x62\xb2\x2b\x8d\x5d\xd5\xdb\x7c\x5b\x25\x75\x18\x87\x75\xf8\xa1\ +\x83\xa7\x6d\x71\x97\x2b\x6d\x51\x5c\xc6\xcb\xf9\x3f\x7e\xf8\xb1\ +\xe3\x4a\x14\xcd\xff\x59\x94\x5f\x0e\xfa\x77\x1d\xc2\x45\xb1\x81\ +\x66\x3a\x0e\xbb\x52\x3b\x9a\x3b\x7c\xc2\xfa\x73\xba\x0a\xef\x13\ +\x77\xe1\xf8\x97\xed\x2a\xc3\xfa\x9d\x60\xd0\xd9\x5d\x12\x1c\x26\ +\xdd\x4d\x5b\x26\xbb\x0b\xc5\xd1\x3b\xd8\x38\x5a\xa5\x6e\xd0\xec\ +\xd7\x3a\xcd\xb2\x9f\xdc\x22\x3d\x4e\xef\x27\x4d\xeb\x2c\xe9\x11\ +\x7d\xb6\xdf\x7d\xcb\xc3\xde\xe1\x6e\x67\xed\xe9\x9b\xb7\xfb\x0f\ +\x43\xf6\xdd\x97\xc5\x66\xbd\x2a\xe2\x64\x7f\xab\x74\x7c\x53\x92\ +\x85\x8b\x24\xbb\x9b\xfc\xec\x64\x5e\x77\x8f\x12\x77\x77\x50\xfb\ +\x15\x93\x2c\x4b\xd7\x55\x77\xd0\xbd\xed\x2c\x71\x80\x39\x8e\xf6\ +\xf1\xe6\x94\xa0\x9f\xbe\x73\xd2\x9e\xe1\x36\xaf\xe5\x26\x4b\xe6\ +\xc9\xd7\x24\x2f\x62\x97\x57\x96\xc5\x97\x64\x7e\x43\xc8\xbe\xba\ +\x71\xaf\xbb\x1b\xa5\x79\xf7\x0a\xb0\x92\x32\x4b\xf1\xcf\x5c\xb4\ +\x6d\x71\x58\x3d\x84\x65\x19\x3e\xcd\xf3\x22\x4f\xda\xd6\x6e\xa9\ +\x81\xe9\xac\xc3\xfa\x41\x29\xce\x86\xde\xda\x06\x94\x53\xce\xec\ +\x80\xad\x5c\xb9\xdc\xc9\x9a\x83\xed\x95\xae\xaf\x38\xbc\xba\x3b\ +\x3c\x58\x49\x2f\xf0\xc0\xb2\xcf\x82\x72\x9a\x60\xbc\x17\x94\x80\ +\x52\xad\x09\xbb\x16\x36\x6e\xf7\x82\x49\xe2\x1f\x4e\xdc\xde\xe7\ +\x19\x97\x06\x08\x72\x80\xad\xbd\xc6\x43\x2e\x86\x92\x93\x91\x03\ +\x2a\xc0\xc8\x87\x05\x03\x4e\x63\x7a\xc9\x9c\x0b\x6a\xc8\x19\x90\ +\x70\xab\x01\x80\x1c\xf1\x5b\x13\x49\xf5\x00\xe5\x2e\xe7\x3c\xdc\ +\xbe\x8d\x04\x3e\x85\xcc\x44\x50\xd5\xb8\x25\xa4\x0c\x42\x09\x4d\ +\x11\x00\x0d\x91\x0c\x09\xa8\x70\x19\x83\x65\x78\xa4\x74\x81\xf1\ +\xe0\x9c\x3a\xba\x77\x93\xfa\x11\x54\x92\x94\x7e\xb3\x79\xe8\xdd\ +\x72\x6a\xe9\x05\xfd\x71\x00\x1f\x14\x30\x5a\x29\xf8\xe8\xb7\xf1\ +\x80\x5d\x81\x07\x2e\xf7\xd7\xd7\xe6\xc1\x09\x0b\xf4\xae\xc6\x30\ +\x27\x2c\xd0\x81\x38\xba\xd5\x04\x90\x22\x60\x8a\x70\x2a\x45\x9f\ +\x04\x2a\x10\x44\x20\x7d\x67\x47\x24\x60\x47\xea\x3f\xbe\x25\xed\ +\xa9\xbf\xb9\xc4\x4d\x3e\x3a\xdc\x15\x70\x77\x49\x4d\x07\xbc\x33\ +\xef\x4b\x81\x47\x66\xfc\x6e\xe0\x89\x51\x96\x8a\x67\x2d\xf0\x14\ +\x63\x40\xfc\x8b\xb7\xcf\x5b\x99\x44\x9c\x6d\x7e\xe8\xe1\xd4\x83\ +\x99\xed\xbe\x4e\x29\x38\xe5\x45\x1e\xb8\xcc\x35\x35\x0a\x4c\xb6\ +\x9c\x30\x2a\x3d\xc4\x67\x22\xb4\x05\xcf\x1d\xeb\x28\x72\x1b\x0f\ +\xf5\x1e\x91\xd0\x8a\x42\x9a\xa7\x28\x43\x94\xf4\x32\xcf\x95\x6a\ +\x02\x73\x4a\x94\x66\xa8\xbc\xb5\xc6\x6c\x3e\x60\x25\x18\xa4\x5d\ +\x86\x2d\xdc\x8d\x85\x9b\x0e\xa9\xb5\xd0\x42\xb6\x4b\x08\x37\x1f\ +\x6b\xd0\x47\x9b\xf7\xb3\x9b\x69\xb7\x29\x39\x6d\xd5\x4c\xf7\x93\ +\x35\x2a\x52\xa8\xf3\x02\x6a\x24\xfe\x1c\x1a\x61\x92\xd0\x29\xc6\ +\x26\x7e\x53\x90\xee\x26\xf4\x60\x85\xde\xae\xa9\x9d\xd4\x6b\x65\ +\xbb\x11\x3b\x94\x39\x6a\x3b\xc2\xb9\xf1\xfe\xea\xa9\x80\xbb\x3c\ +\x18\x39\x6c\x37\xb7\xf5\xe0\x49\xf4\x0e\xbb\x96\x28\x74\x14\xcf\ +\x7f\x8d\xd0\x5a\xc8\x53\xb3\x8e\x8a\x3c\x87\xb0\x28\xfd\x68\x53\ +\x7e\x0d\xeb\x4d\x99\x0c\x6e\xef\xbb\x5b\x78\x04\x4e\x17\xab\x91\ +\x58\x55\xcd\x27\xfa\xb3\x57\xdb\xbd\x2e\x28\xba\x92\xe1\xfd\x76\ +\x8f\x2a\x9f\xc8\x6b\xc6\x46\x6e\x19\xf7\xf9\x33\x5e\xd7\x87\x87\ +\x75\xfe\x96\x39\xde\x33\xe1\x9c\xac\x95\x4a\x5a\x21\xd4\xd0\xc9\ +\x46\x7b\x5f\x6a\x85\x85\x2f\x1f\xe6\x81\x12\x44\x25\x96\x0f\x8d\ +\x5e\xa2\x48\xe1\x92\x1f\x05\x58\x01\xce\x11\x47\x91\x97\x8d\xbc\ +\x77\xc2\x73\x80\xf1\xce\x54\x9d\x33\x80\xf2\xe7\x8b\x4d\x5d\xf7\ +\xdb\xfe\x5d\xa4\xf9\xbc\x41\xf2\x1a\xb0\x36\xa6\xde\x92\x5d\xc0\ +\x40\x69\x53\xd6\x51\x6f\x6f\x4a\x88\x4c\x94\x07\xa6\xff\xa3\xe5\ +\x41\x17\xd2\xd8\xd1\xbb\x85\x51\xb2\x7e\xb3\xe8\xf4\x2c\xdc\x06\ +\x3b\xcb\x17\x70\x11\x1e\x48\xb2\xab\x81\xa7\x14\x91\xfe\x3c\x42\ +\x3d\xb6\x5e\x8c\xd1\xb9\xf8\x7c\x93\x28\xf7\xbc\xdb\x2c\x91\x3d\ +\x88\x6b\x46\x63\x69\xe9\x69\x4e\x06\xdf\xc7\x0c\xac\xf0\x24\x1a\ +\x4b\xc4\x03\xc0\x38\x8c\xc6\xa0\x1e\xb3\x86\xf6\x6c\x6e\x77\xef\ +\xa0\x24\x42\x81\x39\x8a\xbe\x5c\x1b\x45\x05\x3f\x8a\xd1\x1a\x09\ +\x9d\x21\xcf\xa7\x64\x56\x59\x63\x38\x91\x8d\x8b\x10\x5c\x6a\x4a\ +\xcc\xd4\x79\x0b\xa1\x34\xa1\x4d\x94\x91\x52\x5a\x28\x79\xe7\x2d\ +\xfe\x5b\x2a\x41\x04\x54\xda\x5c\x5b\x27\xbe\x38\xd6\x8a\x23\xad\ +\xa6\x82\x9c\x6a\x05\xd1\x8d\x5a\x69\x7b\x17\x45\xee\x57\x63\x04\ +\x78\x62\xa8\xec\x25\xc5\xcd\x7f\x44\x40\x20\xa4\xda\x0c\x73\x62\ +\x17\xb4\xad\x42\x62\x26\x07\x7a\x71\x65\xba\x00\xea\x2f\xa4\xca\ +\x42\x23\x4d\xd7\xce\x5d\x6b\xc5\xe0\xb8\xdd\x75\xae\xfb\x0e\xa6\ +\xb8\x62\xde\xf5\xe0\x20\x93\xcb\x9a\x2f\x4e\x95\x31\x5e\x73\x78\ +\x7e\x7d\x41\xf7\x86\x41\x42\x10\xd4\xf0\xf6\x9b\xd7\xba\x6f\xdf\ +\xa9\x77\x64\x2b\x06\xc0\x31\xde\x57\xbb\xef\x3c\x87\x40\xbc\x34\ +\xf2\xff\x8a\x7f\xa7\xe2\x91\x26\x62\xbd\x6b\x6a\x5e\x11\x72\xa2\ +\x75\x38\x55\x54\x00\xb4\x27\x68\xb5\xce\x02\x14\xba\x1c\x69\xd1\ +\xd0\xda\x11\xdf\x34\x2a\x55\xd3\x57\xbb\x08\x38\x45\x9b\x16\x47\ +\x4a\x47\xc2\x00\xb6\xd1\x61\xa5\xe4\xaa\x5b\xc3\x2d\xef\x55\x55\ +\x63\x5a\xc7\x40\xc9\xad\xdc\x55\xc3\x8a\x69\x45\x1a\xad\x73\xf7\ +\x6b\x01\x35\xba\x49\xf6\x1d\xd5\xc4\xeb\xb4\x6e\xdd\x8f\x39\x4c\ +\x8c\x44\xdc\xd1\xca\x18\xfb\x30\x8c\x72\xcd\xe8\xb7\xae\xf8\xde\ +\x85\xf5\xdb\x54\x6f\x51\x7a\x29\x26\xe8\x40\xf3\x08\xa9\xd8\x2f\ +\x11\xf6\x5b\xd1\x3c\xbf\xf4\x4e\xa4\xd5\x3c\xd1\xdf\xbc\xe6\xd9\ +\x3b\x35\x8f\xea\x1c\x05\x90\x50\x7c\x68\xf3\x92\x71\xa1\x7a\xfe\ +\xff\x7f\x56\xf3\xb7\xb3\xfb\xcf\x1f\x6e\xdd\xc5\xf9\xe7\x0f\xff\ +\x01\x96\x31\x5a\x62\ +\x00\x00\x08\xf1\ +\x00\ +\x00\x5b\x07\x78\x9c\xed\x5c\x59\x73\xe3\x36\x12\x7e\xf7\xaf\xc0\ +\xca\x2f\x49\xad\x40\xe1\xe0\x6d\xd9\xa9\xda\x4c\xa5\x92\xaa\xe4\ +\x25\xc7\x6c\xd5\xbe\x6c\x51\x24\x24\x71\x4d\x91\x2a\x92\xb2\xa4\ +\xf9\xf5\xdb\x0d\x5e\xba\x3c\x71\xd6\xce\x8e\xed\x80\x1a\xc9\x44\ +\x77\x83\x00\x1a\xfd\x75\x37\x48\x0c\xa7\xdf\xec\x56\x19\x79\x50\ +\x65\x95\x16\xf9\xed\x88\x5b\x6c\x44\x54\x1e\x17\x49\x9a\x2f\x6e\ +\x47\xbf\xfd\xfa\x1d\xf5\x47\xa4\xaa\xa3\x3c\x89\xb2\x22\x57\xb7\ +\xa3\xbc\x18\x7d\x73\x77\x35\xfd\x1b\xa5\xe4\xdb\x52\x45\xb5\x4a\ +\xc8\x36\xad\x97\xe4\x87\xfc\xbe\x8a\xa3\xb5\x22\x5f\x2d\xeb\x7a\ +\x1d\x4e\x26\xdb\xed\xd6\x4a\x5b\xa2\x55\x94\x8b\xc9\xd7\x84\xd2\ +\xbb\xab\xab\x69\xf5\xb0\xb8\x22\x84\x40\xbb\x79\x15\x26\xf1\xed\ +\xa8\xad\xb0\xde\x94\x99\x16\x4c\xe2\x89\xca\xd4\x4a\xe5\x75\x35\ +\xe1\x16\x9f\x8c\x06\xf1\x78\x10\x8f\xb1\xf5\xf4\x41\xc5\xc5\x6a\ +\x55\xe4\x95\xae\x99\x57\xd7\x07\xc2\x65\x32\xef\xa5\xb1\x37\x5b\ +\xa9\x85\x78\x10\x04\x13\x26\x26\x42\x50\x90\xa0\xd5\x3e\xaf\xa3\ +\x1d\x3d\xae\x0a\x7d\xbc\x54\x55\x30\xc6\x26\xc0\x1b\x24\x9f\x26\ +\x15\x56\xa0\xd0\x35\x7c\x7b\xf1\x8e\x60\x55\xc5\xa6\x8c\xd5\x1c\ +\xea\x29\x2b\x57\xf5\xe4\xc3\xaf\x1f\x7a\x26\x65\x56\x52\x27\x07\ +\x97\xe9\xf4\x79\xd4\xea\x91\x92\xf3\x68\xa5\xaa\x75\x14\xab\x6a\ +\xd2\xd1\x75\xfd\x6d\x9a\xd4\xcb\xdb\x91\xb4\x2d\x2e\xe1\x70\x34\ +\x71\xa9\xd2\xc5\xb2\x3e\xa5\xa6\xc9\xed\x08\x7a\x2f\x02\xbf\x29\ +\x1f\x18\x07\x6f\x04\xda\x0b\x87\x3d\x87\x59\x81\xb0\x38\x29\xb9\ +\x23\xbd\x46\xa6\x1b\x42\x98\x14\x31\xf6\x09\x2e\xa9\x56\x69\xb4\ +\xa9\x8b\x15\xcc\x5a\x1c\x67\x51\x55\xa5\xf3\x34\x86\x42\x91\xaf\ +\xb3\xcd\x22\xcd\xff\xbd\x2c\x56\xca\xea\xf4\xd6\x37\xa2\x76\xeb\ +\xa2\xac\xe9\x2e\x59\x83\xf6\x5c\xef\x22\x73\x7f\xc8\x7c\x48\xd5\ +\xf6\x1f\xc5\x0e\x7a\x45\x18\x91\x02\xfe\x8d\xee\x80\x3e\x4d\xd4\ +\xbc\x42\x7e\x33\x42\x2c\xc1\x10\xbd\x11\x99\x68\x6e\xdf\x61\xec\ +\x6d\x82\xd7\x18\x64\x67\x51\xd5\x68\x91\x90\x75\xb4\x00\x8b\xcb\ +\x8a\xf2\x76\x74\x3d\xd7\x47\xcb\x98\x15\x65\xa2\xca\x8e\xe5\xea\ +\xe3\x88\x55\xc0\xac\xa4\xf5\xbe\xc1\x58\x7b\xed\x6e\x18\x78\xd5\ +\x9e\xcf\x2e\xf3\xab\x65\x94\x14\xdb\xdb\x91\x38\x65\x7e\x2a\x8a\ +\xd5\xed\xc8\xb1\x9c\xc0\x0f\x18\x3f\xe5\xc6\xa0\x08\x6a\xfb\x96\ +\xf4\x1d\x21\xfd\x33\x2e\xb4\xe7\x59\x8e\xf4\x3d\xee\x9c\x57\xdd\ +\x94\x25\x80\x90\x66\xd1\x5e\xc1\xa0\xf4\x9f\x4e\xa8\x5a\x16\xdb\ +\x45\x89\xca\xa9\xcb\x8d\x3a\xad\x89\x1c\x3a\x9b\xe1\x24\x5c\x62\ +\x83\x4d\x6c\x10\xde\x74\x93\xa7\x35\x40\x68\xbd\x3b\xbc\xea\x26\ +\x4d\x54\x75\xb9\x62\x95\x47\x6b\xba\xc8\x8a\x59\x94\x5d\x16\xd8\ +\xa6\x39\x28\x89\xb6\xd6\xce\x65\x3f\x07\xa7\x12\x9d\xe9\x7b\xec\ +\x4c\x27\xad\x04\x1a\xd0\x23\xac\xfd\xe3\xac\x55\xb4\x4b\x57\xe9\ +\x27\x05\x8a\x39\xd3\xa7\x1e\xd9\xa1\x5a\xee\xb4\xc0\xf4\x48\x6d\ +\x4d\x1d\x42\xea\x3d\xc2\x7c\xb7\x47\xda\xa8\x23\xa2\xbe\x91\x20\ +\x82\xc0\xeb\x89\x45\x99\x02\x7a\x0e\xba\xdb\x91\xf6\x87\x24\x74\ +\x0a\xe0\xd3\x77\x43\xbf\x7a\x1a\xda\x64\x07\x83\xc9\x39\x0e\x34\ +\x7d\xa5\xea\x28\x89\xea\x68\x00\x45\x47\x81\xbe\xb0\x6e\x24\xe0\ +\x4f\xc3\x9f\x3f\x7c\x77\xd7\x36\x30\x8d\xe3\xf0\x9f\x45\x79\xdf\ +\xb5\x47\x08\x0a\x44\xb3\x62\x03\x9a\x1f\xdd\xf5\xe4\x69\x12\x87\ +\xe0\x01\xc1\x33\xdc\xa5\x2b\x30\x75\x74\x9e\x7f\x07\x8f\x37\x9d\ +\x0c\x8c\x23\x61\x54\xce\x70\xd1\xe6\xb2\xa5\x6a\x5c\xe9\xc5\x78\ +\x92\xc4\xab\x14\x2b\x4d\x7e\xa9\xd3\x2c\xfb\x01\x1b\x69\x47\x7c\ +\x70\xd1\xb4\xce\xd4\x40\x9c\x4e\xda\xde\xb7\x63\x9b\x1c\x0c\x6e\ +\x3a\xe9\x46\xaf\x4b\x8b\x41\x2b\x47\x20\xe9\x27\x36\x8b\x66\x0a\ +\x2c\xf6\x47\x64\x92\x73\xbb\x28\x8b\xcd\x7a\x55\x24\xaa\xad\xde\ +\x69\x73\x1d\xd5\xcb\x7e\xaa\xea\x7d\x06\xfc\x39\xf4\x3e\xbc\xb6\ +\x13\xfc\xdc\x60\x81\xb6\x6e\x23\xe4\x4d\xb1\xdc\x64\xe0\x15\x1f\ +\x54\x5e\x24\xc9\x4d\x55\x97\xc5\xbd\x0a\xaf\x3d\x17\x3f\x6d\xb1\ +\x01\x47\xc8\xba\x22\x28\x46\x95\x19\x18\x6d\x1d\xda\x1d\x2d\x89\ +\xc0\xdb\x94\x65\xb4\x0f\x73\x08\xfa\x1d\xb5\x6f\xaa\x37\x20\x34\ +\x03\x22\xb8\x65\xdb\xc2\x96\xce\x58\x5a\x0e\x79\x20\xc2\x27\xdf\ +\x13\xce\x2d\x3f\x70\x03\x9f\x64\x84\x8d\xa9\x0b\x14\xd7\xe2\x6e\ +\xe0\x31\x2f\x00\x11\x20\x64\x84\x3a\x96\x27\xf0\x13\x38\x63\x86\ +\x44\x09\x24\x42\x7d\xf2\xe9\xc8\xde\x4b\x15\xd7\x32\x10\x92\x3a\ +\x03\xb9\xf7\x50\x45\x9e\x03\xbb\x28\x29\xf8\xaa\x87\xa8\xde\x94\ +\xea\xc8\xe6\x7b\x5b\x06\xe5\xe2\xf4\x83\x5b\x89\x87\xa3\xb7\x80\ +\xc7\x35\x2d\x65\x14\xb3\xe7\x6a\xda\xe2\xe0\x5c\x25\xe7\xfc\x73\ +\x2a\x7f\x44\xb9\xb2\x57\x2e\x24\x03\x0e\xe8\x52\x32\xb2\x24\x14\ +\x7c\xb6\x8b\x2a\xe3\x12\x34\x6b\x37\x22\xb6\xd6\x2c\xf7\x2e\xea\ +\x8f\xfb\x2f\xa9\xbd\x27\x68\x6e\xee\x47\x73\x9b\xbf\x1a\x1b\x75\ +\x3b\x35\xf2\xce\x46\x41\x8b\x9c\x35\xb6\xb8\xc4\x1f\x7d\x76\xa2\ +\xcc\xcf\x5b\xe4\x9f\x67\x8f\x8b\x3e\x0a\x94\x51\x5e\xa1\x07\x84\ +\x56\x8b\x1a\xb2\xed\xaf\x02\x36\xe6\xb6\x15\x78\x5c\x70\x6f\xcc\ +\x1d\xcb\xd6\x67\x5f\x1f\x87\x08\xdb\x73\x7c\x7a\xe0\xe7\xcf\x9d\ +\x47\xef\x7d\x8f\x66\xf0\xf3\x93\x3e\x48\x3d\x75\xc0\x4d\x77\xb0\ +\x05\xd0\xa8\x43\x83\x03\x06\xd0\x7f\x22\x62\x1c\xa0\xca\xc9\xb7\ +\xc4\x1e\xfb\x16\x0f\xbc\x80\xbb\x1e\x9c\x7b\x96\xcf\x04\xf3\xa5\ +\xc4\x73\x98\x12\xdf\xb5\x1d\x28\xc1\xb9\x03\x99\xaa\x63\x83\x14\ +\x9c\xbb\xf0\xfd\x48\x1c\xac\x6d\xb9\x4d\xdd\xb1\x43\xa4\x25\x9b\ +\xba\x70\x2e\xf4\xd7\xb5\x84\x0c\xb0\x3e\x9c\x7b\x96\xe7\x32\xac\ +\xaf\xdb\xfe\xd7\x41\x87\x5a\x25\xe9\x0c\x2e\xbc\x66\xfa\xb8\x99\ +\x17\x90\xa5\x68\x0e\x28\x04\xe2\x50\xd6\x50\x1e\xa2\x32\x8d\xf2\ +\xfa\x88\xb6\xd5\x19\xc5\x11\x09\x6c\x52\xd5\xf1\xf2\x98\x06\xc9\ +\x41\x08\x91\x35\xdd\xac\x6e\xb2\x34\x57\x6d\x26\x72\x24\x33\x8f\ +\x56\x69\xb6\x0f\x7f\x81\xb9\xbf\xa1\x9d\xae\x69\x53\x7d\xad\xe2\ +\x3e\x6f\x6e\x24\x6a\xb5\xab\x41\x2a\x81\x84\x0a\x10\xa3\x4b\x51\ +\x96\x2e\xf2\x10\x96\x6d\x65\xdd\x10\x12\x48\x5a\xcb\xa6\x8e\x46\ +\xcb\x09\x91\x62\x4f\x1a\x4e\xa6\x6a\xc0\x1a\x6d\x53\x83\xae\x5b\ +\x5b\x48\x61\x4f\x69\xfa\x1a\xbd\x81\x36\xb5\xb7\x65\x5a\x83\x08\ +\xc5\x68\x16\x66\x25\xad\x67\x37\x49\x8a\x78\xc1\x96\xb3\xba\xbc\ +\xc1\x54\x5a\x0f\xbb\x5a\xa6\xf3\x3a\xec\x8a\x6d\xb7\xf3\x78\x09\ +\xca\x6f\xfa\x9d\xa4\xd5\x1a\xc2\x21\xac\x79\xb4\x40\x01\x8b\x8d\ +\x79\x56\x6c\xc3\x87\xb4\x4a\x67\x99\xba\xd1\x7f\xd3\x0c\xc1\xde\ +\x91\xfe\xa7\xe8\x78\xe8\x3d\x1a\xb7\xc3\x2d\xc8\x69\xf0\x70\x6e\ +\x56\x51\x79\xaf\xca\x46\x46\xe5\x11\x34\x42\x67\x51\x7c\x8f\x11\ +\x3b\x4f\xc2\x28\x86\x3c\x76\x93\x01\x2c\x0f\x92\x89\xa7\x02\xea\ +\x99\x70\x92\x0e\xb5\xcf\xe1\xc4\x9d\x1e\x4f\x5c\x36\xa0\x40\x3c\ +\x71\xd1\x82\x02\xcf\x39\x88\x08\x12\x43\x2c\xe1\x1d\x95\x8d\x45\ +\x27\xcc\xc6\xf6\x81\xbb\x33\xb0\x30\xb0\xf8\xff\xc2\xe2\xd9\xc0\ +\x10\x1e\xf5\x8e\x81\xb1\x22\xdc\x1d\x0b\x07\x4c\x1e\x72\x28\xdb\ +\xf5\x3d\xcc\x37\x29\x24\x02\x92\x0b\x7d\x2a\x74\xfe\x89\x98\x80\ +\xb5\x39\xe3\xb0\x50\x06\x82\xb4\x98\xed\x0a\xc6\xe1\xd4\x86\x2f\ +\xc3\x04\xcc\xc7\xbb\x24\x08\x17\x2a\x21\x9b\x85\x03\xf1\x42\x6d\ +\x4c\x20\x1a\x44\x31\xab\x8d\x34\x08\xae\x36\xd0\x00\xb8\x0c\xa2\ +\x0c\xa2\xde\x5e\xa0\xe9\x57\x5e\x1e\xf5\x4f\x11\xe5\x8f\x85\x87\ +\x16\xdf\x25\x6a\x1a\x30\x78\x67\x15\xb2\x52\x00\x0c\xc0\x08\x41\ +\xf5\x23\xe1\xa2\x47\x5e\x23\x89\x78\x93\x5d\xaa\x87\x05\x04\x97\ +\x81\x87\x81\xc7\x5b\x0d\x38\xc2\x95\x94\x9d\xc2\x43\xe0\xda\x04\ +\xe1\xa1\xd7\x2d\x68\xf4\x10\x6e\x20\x1a\x68\x93\x17\x3a\x9c\xf0\ +\xf6\x2b\x20\x7a\x34\xc1\x03\x42\x12\x67\xae\xf4\xa5\x8d\x05\x61\ +\x05\x0e\x83\xb1\x07\x4d\x88\x01\x00\x05\x92\x33\x29\x5a\x00\xf9\ +\x8e\x0c\x02\x83\x1f\x83\x9f\xcf\xe1\x47\xda\x3e\x4e\xff\xab\xc6\ +\x8f\x64\x9c\xca\x33\xfc\x34\xe1\x05\xd2\xb1\xc0\xb1\x99\xad\xef\ +\x7e\x41\x66\xe6\x12\xd9\xa6\x63\x1f\x89\xc0\x85\xbf\xd3\x26\x71\ +\x50\xb0\xdb\xd4\x0e\x4f\xdb\x1f\xbb\xff\x91\xc3\x9a\x47\x2f\x76\ +\x3c\xdf\xf1\xb8\x6d\x16\x3b\x06\x3b\x5f\x14\x3b\x2f\x91\x9a\x79\ +\x54\x9c\x27\x67\x4f\xcd\xcd\x10\x43\x9c\x37\xe9\x18\xde\x3c\xf3\ +\xfb\x3a\x70\x0e\x5f\x73\x83\xcc\x80\xe3\x2d\xaf\x5b\xec\x83\xa7\ +\x46\xdd\xbd\x00\xfb\x08\x1d\x8f\x82\x03\xcd\xff\xf2\xba\xc5\x2c\ +\x5b\x0c\x3a\xde\x07\x3a\xf8\xf9\xc2\x5e\xb0\x27\xc1\x43\xd8\x06\ +\x1e\x06\x1e\xef\x10\x1e\xfd\xd3\x15\x87\xba\xe7\xcf\x57\x04\x1f\ +\x9e\xaf\x04\x07\xcf\x57\xfc\x83\xe7\x2b\x9e\x79\xbe\x62\x80\xf1\ +\x6a\x81\xf1\x52\x8b\x0e\xfb\x42\xe8\x70\xf1\xf9\xe3\xef\xc7\x0e\ +\xc9\xf0\x21\xa4\x0e\x1e\x02\x16\x58\x82\x77\xcf\x60\x68\x73\x67\ +\x8c\xf5\x77\xc6\xa8\x66\xf5\x7c\x83\x1b\x83\x9b\xb7\x8f\x9b\x4b\ +\xc8\x61\x18\x59\x9e\x94\x75\x71\xcf\x20\xc7\x20\xe7\xcb\x23\x67\ +\x3a\x59\x9c\x6e\x56\xeb\xb7\x9e\xf5\xc6\x76\x79\xfb\x9a\x73\x61\ +\xfb\xda\x17\xd8\x8e\x66\x36\xa3\x19\x8c\xfe\xe9\x18\x65\x7c\x96\ +\x24\xc1\xab\x8f\x6e\xcf\x5e\x2e\x99\xad\x68\x06\x14\xef\x0d\x14\ +\x2f\xb0\x15\xcd\x6c\x44\x33\x78\x32\x78\x7a\xb9\x5b\xd6\x66\x1b\ +\x9a\x01\xc7\xfb\x04\xc7\x0b\x6c\x43\x33\x9b\xd0\x0c\x7a\x5e\x21\ +\x7a\xde\xc8\x26\x34\xb3\x05\xcd\x20\xe7\x2f\x88\x9c\x17\xb9\xab\ +\x6d\x36\xa0\x19\x68\xbc\xbf\x94\xec\x45\xb6\xd8\x98\xed\x67\x06\ +\x1b\x06\x1b\x97\xb1\x71\x9e\x73\x99\xcd\x67\x06\x1c\x7f\x61\x70\ +\x0c\x9b\xcf\xcc\xd6\x33\x03\x8b\xf7\x06\x8b\x17\xdb\x42\x63\x36\ +\x9e\x19\xd4\x18\xd4\xfc\xf1\x8d\x67\x66\xdb\x99\xc1\xcd\x1b\xc7\ +\xcd\xb0\xed\xec\xf1\x37\xcf\xe9\x63\x78\xb1\x9c\x8f\x9f\x47\x5e\ +\x2c\x87\x43\x87\xc9\x0f\x67\x9b\xba\x3e\xa4\xfd\xa7\x48\xf3\x50\ +\xbf\x75\xee\xec\xc5\x72\x4f\x7f\x27\xdd\xf1\x2b\xe8\x82\xb1\x67\ +\x39\xda\xea\x1d\xb2\x24\x3e\xf9\x08\x6b\x7c\x48\xd7\x9a\xf7\xcc\ +\x59\xb6\x56\x08\x3e\x85\xb1\x02\x06\x1f\x8e\x7c\xae\xf9\xc3\x2d\ +\xb0\x2e\x45\xf4\x9d\xe1\xbf\x7c\xfe\x9e\x47\x78\xc2\x9b\xfa\x8e\ +\xf5\xd5\x22\xf3\xb9\xfa\x7a\xe6\x2b\xfb\x7e\x22\xe0\x83\x6c\xcb\ +\xe7\xf0\x11\x04\x3c\x0e\x97\x48\x81\xcc\xb7\x21\x5d\xd0\x89\xfd\ +\x07\x75\xa2\x4d\x69\x8a\xef\x1a\xbd\xbb\xfa\x2f\xbb\x92\xfa\xa3\ +\ +\x00\x00\x0d\x1f\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x72\x65\x73\x65\x74\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ +\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\ +\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\ +\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\ +\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\ +\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\ +\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x78\x3d\x22\x33\x2e\x36\x33\x38\x31\x34\x39\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ +\x22\x33\x39\x2e\x34\x34\x35\x37\x33\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ +\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\ +\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ +\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ +\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\ +\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ +\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\ +\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ +\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ +\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ +\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ +\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ +\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ +\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ +\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ +\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x66\x32\x66\x32\x66\x32\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x32\x65\x32\x65\x32\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x38\x34\x37\x36\ +\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\ +\x3d\x22\x4d\x20\x30\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\ +\x48\x20\x33\x32\x20\x56\x20\x33\x32\x2e\x30\x30\x30\x30\x30\x31\ +\x20\x48\x20\x30\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x38\x2d\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x67\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x33\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x32\x31\x36\ +\x36\x36\x36\x37\x2c\x30\x2c\x30\x2c\x31\x2e\x32\x31\x36\x36\x36\ +\x36\x37\x2c\x2d\x37\x2e\x32\x32\x32\x32\x32\x32\x34\x2c\x2d\x37\ +\x2e\x36\x38\x34\x34\x34\x34\x36\x29\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\ +\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\ +\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\ +\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\ +\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x65\ +\x39\x63\x36\x61\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\ +\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ +\x66\x30\x30\x31\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\x2e\x38\x33\x32\ +\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\ +\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\ +\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x38\ +\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ +\x74\x68\x3d\x22\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x37\x2e\x33\x33\x33\x33\ +\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x31\x39\x2e\x34\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x79\x3d\x22\x37\x2e\x31\x36\x38\x38\x33\x30\ +\x39\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\ +\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x66\x66\x30\x30\x31\x33\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x38\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ +\x20\x32\x31\x2e\x33\x33\x33\x33\x33\x33\x2c\x32\x33\x2e\x34\x36\ +\x36\x36\x36\x37\x20\x38\x2c\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ +\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x30\x30\ +\x31\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x31\x2e\x38\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x39\x2e\x33\x33\x33\x33\ +\x33\x33\x2c\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\x2d\x38\x2c\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\xad\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x70\x65\x6e\x5f\ +\x66\x69\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x2d\x38\x31\x2e\x31\x30\x30\x32\x37\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x2d\x32\x2e\x36\x31\x31\x30\x33\x35\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ +\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\ +\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\ +\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\ +\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ +\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\ +\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\ +\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\ +\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ +\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ +\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ +\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ +\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ +\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ +\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ +\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\ +\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\ +\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\ +\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ +\x6c\x3a\x23\x38\x30\x38\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\x39\x32\x35\x36\x39\x36\x31\ +\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ +\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\x39\x2e\x32\ +\x34\x34\x34\x34\x34\x38\x20\x48\x20\x32\x36\x2e\x36\x36\x36\x36\ +\x36\x37\x20\x56\x20\x33\x35\x2e\x39\x31\x31\x31\x31\x31\x20\x48\ +\x20\x30\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x33\x30\x32\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x33\x37\x63\x38\x37\x31\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ +\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x30\x2e\x36\ +\x36\x36\x36\x36\x37\x2c\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x20\ +\x48\x20\x33\x32\x20\x56\x20\x32\x38\x2e\x38\x20\x48\x20\x31\x30\ +\x2e\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\x38\x2d\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ +\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x30\ +\x30\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ +\x35\x30\x32\x38\x33\x31\x35\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\ +\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x4d\x20\x30\x2c\x39\x2e\x32\x34\x34\x34\x34\x34\x38\x20\x35\ +\x2e\x33\x33\x33\x33\x33\x33\x33\x2c\x31\x36\x2e\x33\x35\x35\x35\ +\x35\x36\x20\x56\x20\x34\x31\x2e\x32\x34\x34\x34\x34\x35\x20\x4c\ +\x20\x30\x2c\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\x76\x20\x2d\ +\x32\x34\x2e\x38\x38\x38\x38\x38\x38\x32\x20\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x32\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ +\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x17\xc8\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x65\x61\x72\x63\x68\x5f\ +\x69\x6d\x61\x67\x65\x73\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ +\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ +\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ +\x33\x37\x37\x39\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ +\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x66\ +\x30\x66\x65\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x33\x37\x38\x33\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ +\x6f\x70\x33\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x2e\x34\x39\x33\x31\x35\ +\x30\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\ +\x23\x62\x62\x66\x61\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x30\x2e\x34\x37\x30\x35\x38\x38\x32\x34\x3b\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\ +\x6f\x70\x33\x37\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\ +\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x38\x37\x66\x36\x66\x66\x3b\x73\ +\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x39\x38\ +\x30\x33\x39\x32\x31\x36\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x61\x64\x69\x61\x6c\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ +\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\ +\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\ +\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x61\x64\x69\x61\x6c\ +\x47\x72\x61\x64\x69\x65\x6e\x74\x33\x37\x37\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\ +\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x35\ +\x2e\x36\x35\x35\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x66\x78\x3d\x22\x34\x2e\x33\x37\x35\x38\x35\x38\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x66\x79\x3d\x22\x35\x2e\x36\x35\x35\ +\x35\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x3d\x22\ +\x31\x34\x2e\x32\x31\x36\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2e\x30\x32\x30\ +\x32\x34\x34\x39\x2c\x30\x2c\x30\x2c\x31\x2e\x30\x31\x39\x32\x38\ +\x38\x2c\x31\x34\x2e\x39\x36\x37\x39\x33\x38\x2c\x38\x2e\x37\x34\ +\x35\x38\x30\x36\x34\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ +\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ +\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ +\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\ +\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\ +\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\x36\x33\x36\x33\x36\x33\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x32\x3d\x22\x33\x2e\x31\x38\ +\x31\x38\x31\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\ +\x3d\x22\x31\x31\x2e\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\x32\x37\ +\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\ +\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\ +\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x36\ +\x34\x2c\x30\x2c\x30\x2c\x30\x2e\x36\x31\x33\x33\x33\x33\x33\x33\ +\x2c\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x2c\x32\x2e\x37\x32\x29\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\ +\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ +\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\ +\x22\x61\x6c\x77\x61\x79\x73\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ +\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\ +\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ +\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\x66\x66\ +\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ +\x3b\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\ +\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x3c\x2f\ +\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ +\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x31\x39\x2e\x35\x37\x35\x38\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x31\x39\x2e\x32\x38\x36\x34\x39\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\ +\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\x73\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ +\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\ +\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\ +\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\ +\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ +\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ +\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ +\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ +\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\ +\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\ +\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x62\x33\x66\x66\x38\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x38\x35\x38\x31\ +\x35\x32\x39\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\ +\x35\x2e\x32\x38\x34\x35\x30\x36\x2c\x31\x2e\x36\x38\x35\x37\x36\ +\x38\x32\x20\x33\x32\x2e\x34\x34\x37\x35\x36\x35\x2c\x31\x30\x2e\ +\x32\x36\x37\x32\x39\x38\x20\x32\x33\x2e\x38\x36\x36\x30\x33\x35\ +\x2c\x32\x37\x2e\x34\x33\x30\x33\x35\x37\x20\x36\x2e\x37\x30\x32\ +\x39\x37\x35\x34\x2c\x31\x38\x2e\x38\x34\x38\x38\x32\x38\x20\x5a\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ +\x30\x30\x36\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ +\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x64\x3d\x22\x6d\x20\x32\x32\x2e\x37\x39\x33\x33\x34\x34\ +\x2c\x36\x2e\x31\x31\x30\x36\x31\x39\x36\x20\x2d\x33\x2e\x30\x39\ +\x34\x33\x30\x32\x2c\x33\x2e\x34\x36\x35\x36\x31\x37\x32\x20\x2d\ +\x31\x2e\x37\x33\x32\x38\x30\x38\x2c\x33\x2e\x33\x37\x32\x37\x38\ +\x39\x32\x20\x2d\x30\x2e\x38\x36\x36\x34\x30\x36\x2c\x33\x2e\x33\ +\x34\x31\x38\x34\x35\x20\x76\x20\x35\x2e\x30\x31\x32\x37\x36\x38\ +\x20\x32\x2e\x35\x30\x36\x33\x38\x36\x20\x4c\x20\x36\x2e\x37\x30\ +\x32\x39\x37\x35\x34\x2c\x31\x38\x2e\x37\x39\x37\x32\x35\x37\x20\ +\x31\x35\x2e\x33\x36\x37\x30\x32\x2c\x32\x2e\x30\x38\x38\x30\x32\ +\x37\x34\x20\x32\x30\x2e\x33\x37\x39\x37\x38\x39\x2c\x34\x2e\x35\ +\x30\x31\x35\x38\x32\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x30\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ +\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x75\x72\x6c\x28\x23\x72\x61\x64\x69\x61\x6c\x47\x72\x61\x64\ +\x69\x65\x6e\x74\x33\x37\x37\x35\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ +\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x32\x36\x38\x34\x30\x39\ +\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x39\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x31\x39\ +\x2e\x34\x33\x32\x33\x38\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x63\x79\x3d\x22\x31\x34\x2e\x35\x31\x30\x34\x33\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x33\x2e\x34\x38\x34\ +\x34\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ +\x31\x33\x2e\x34\x38\x34\x34\x35\x33\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x35\x35\x32\x32\ +\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ +\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x30\x35\x31\ +\x33\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x34\x2e\x34\x37\x37\x30\x36\x38\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x37\x2e\x32\x35\x37\ +\x38\x36\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\ +\x31\x2e\x32\x37\x38\x32\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x72\x78\x3d\x22\x31\x2e\x31\x35\x36\x30\x33\x35\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x32\x30\ +\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x33\x39\ +\x2e\x37\x39\x37\x38\x37\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x69\x76\x65\x6c\ +\x6c\x6f\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x61\x79\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\ +\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\ +\x31\x2e\x30\x32\x32\x33\x33\x34\x32\x2c\x30\x2c\x30\x2c\x30\x2e\ +\x39\x37\x36\x33\x34\x38\x33\x36\x2c\x2d\x31\x2e\x32\x30\x34\x35\ +\x35\x30\x32\x2c\x32\x31\x2e\x34\x30\x37\x32\x34\x32\x29\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x35\x39\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\x72\x6c\x28\ +\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\ +\x30\x32\x39\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\ +\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ +\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x30\x2e\x36\x32\x36\x35\x32\x34\x38\x31\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x37\x2e\x37\ +\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x63\x79\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x36\x2e\x34\x30\ +\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x36\x2e\x31\x33\x33\x33\x33\x33\x32\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\ +\x31\x37\x39\x33\x39\x35\x38\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ +\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\ +\x3d\x22\x32\x37\x2e\x34\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x36\x2e\x34\x30\x30\x30\ +\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\ +\x3d\x22\x32\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x35\x2e\x38\x36\x36\x36\ +\x36\x36\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\ +\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x32\ +\x36\x37\x34\x32\x37\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x63\x78\x3d\x22\x32\x37\x2e\x37\x33\x33\x33\x33\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x36\ +\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x33\x33\x33\x33\x33\x33\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x35\ +\x2e\x38\x36\x36\x36\x36\x36\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ +\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x30\x2e\x31\x38\x35\x34\x31\x33\x31\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x30\x30\x35\ +\x39\x34\x30\x32\x37\x2c\x30\x2e\x39\x39\x39\x39\x38\x32\x33\x36\ +\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x34\x30\x30\x31\x31\ +\x33\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\ +\x22\x2d\x32\x37\x2e\x38\x32\x38\x36\x39\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x34\x30\x30\x30\ +\x37\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x36\x2e\x32\x36\x36\x36\x32\x30\x36\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x12\xab\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x61\x64\x64\x5f\x62\x61\x6e\x64\x73\x65\x74\x5f\x74\x6f\x6f\ +\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\ +\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\ +\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\ +\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\ +\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x31\x35\x2e\x30\x35\x34\x35\x38\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x32\x37\x2e\x36\x31\x36\x37\x35\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x67\x33\x37\x31\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ +\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ +\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\ +\x37\x32\x32\x33\x35\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\x39\x38\x34\x36\x35\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x36\x2e\x37\x36\x34\x34\x39\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x34\x38\x2e\x39\x34\x39\x35\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x32\x2e\x36\x31\x30\x34\ +\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ +\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x72\x79\x3d\x22\x32\x2e\x35\x33\x36\x34\x37\x39\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ +\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\ +\x38\x34\x33\x36\x37\x38\x34\x38\x2c\x30\x2e\x35\x33\x36\x38\x34\ +\x38\x37\x39\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ +\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ +\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x38\x39\x33\x37\x32\x39\ +\x33\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\x39\x38\x2c\x30\x2c\x30\ +\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ +\x37\x31\x30\x39\x37\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x36\x2e\x30\x36\x32\x32\ +\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x33\ +\x2e\x37\x33\x32\x30\x34\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\x2e\x39\x31\x37\x38\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x39\x2e\x39\x38\x34\x36\x35\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x39\x31\x34\x34\x32\x31\ +\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\ +\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\ +\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ +\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\ +\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x31\x2e\x38\x32\x33\x34\x33\x35\x34\x33\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x2e\ +\x39\x38\x34\x36\x35\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x32\x31\x30\x36\x32\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x31\x2e\x38\ +\x36\x33\x30\x39\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ +\x22\x31\x31\x2e\x38\x32\x31\x39\x32\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x39\ +\x30\x36\x35\x38\x31\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ +\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\x35\x30\x38\x39\ +\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\x30\x2c\x30\x29\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\ +\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\x30\x33\x34\x38\x33\ +\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x33\x2e\x30\x31\x31\x30\x32\x39\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\ +\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x2d\ +\x33\x2e\x37\x38\x37\x36\x32\x39\x38\x65\x2d\x31\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x33\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x39\ +\x30\x30\x39\x36\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x39\x2e\x39\x38\x34\x36\x35\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\ +\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\x63\x63\x63\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x37\ +\x38\x38\x33\x39\x38\x33\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\ +\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x67\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x33\x37\x30\x37\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x33\x37\x31\x32\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x33\x37\x31\x37\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x72\x65\ +\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x33\x2e\x38\x30\x39\x35\x32\x33\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\ +\x32\x2e\x31\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x78\x3d\x22\x31\x31\x2e\x38\x37\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x34\ +\x39\x36\x34\x36\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\ +\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\ +\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x31\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x63\x61\x70\x3a\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ +\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\ +\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ +\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\ +\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x4d\x20\x31\x34\x2e\x38\x37\x34\x39\x39\x39\x2c\ +\x32\x32\x2e\x31\x32\x35\x20\x48\x20\x32\x38\x2e\x38\x37\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x34\x2e\x32\x33\x34\ +\x34\x36\x31\x37\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\ +\x63\x63\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ +\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x34\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\ +\x31\x2e\x38\x37\x35\x2c\x31\x35\x2e\x31\x32\x35\x20\x76\x20\x31\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\ +\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\ +\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\ +\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x3c\x2f\ +\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0b\xf9\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x6f\x70\x74\x69\x6f\ +\x6e\x73\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\ +\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\ +\x30\x20\x33\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\ +\x39\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x66\x69\x6c\x74\x65\ +\x72\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\ +\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x63\x6f\x6c\x6f\x72\x2d\x69\x6e\x74\x65\x72\x70\x6f\x6c\x61\ +\x74\x69\x6f\x6e\x2d\x66\x69\x6c\x74\x65\x72\x73\x3a\x73\x52\x47\ +\x42\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x66\x69\ +\x6c\x74\x65\x72\x34\x35\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x78\x3d\x22\x2d\x30\x2e\x30\x32\x33\x37\x34\x38\x36\x32\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x2e\x30\x34\x37\x34\x39\x37\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x2d\x30\x2e\x30\x32\x34\x32\x35\x36\x37\x35\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x31\x2e\x30\x34\x38\x35\x31\x33\x35\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x66\x65\x47\x61\x75\x73\x73\x69\x61\x6e\x42\ +\x6c\x75\x72\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ +\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x64\x44\x65\x76\x69\x61\x74\x69\x6f\x6e\x3d\x22\x30\x2e\ +\x32\x37\x39\x32\x33\x37\x32\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x66\x65\x47\x61\x75\x73\x73\x69\x61\ +\x6e\x42\x6c\x75\x72\x34\x35\x30\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x2f\x66\x69\x6c\x74\x65\x72\x3e\x0a\x20\x20\x3c\x2f\ +\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ +\x31\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x35\x31\x2e\x31\x36\x39\x34\x34\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x2d\x36\x2e\x35\x33\x38\x34\x34\x37\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\ +\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\ +\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ +\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\ +\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ +\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\ +\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x33\x33\x33\x33\x33\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x33\x31\ +\x32\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ +\x70\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x74\x65\x72\x3a\ +\x75\x72\x6c\x28\x23\x66\x69\x6c\x74\x65\x72\x34\x35\x30\x35\x29\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\ +\x74\x34\x35\x30\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\ +\x64\x74\x68\x3d\x22\x32\x37\x2e\x35\x38\x37\x33\x31\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\ +\x38\x2e\x31\x37\x39\x33\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x78\x3d\x22\x2d\x33\x30\x2e\x30\x36\x39\x36\x34\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x39\x33\x30\x30\ +\x32\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ +\x73\x66\x6f\x72\x6d\x3d\x22\x72\x6f\x74\x61\x74\x65\x28\x2d\x39\ +\x30\x2e\x30\x38\x33\x30\x39\x34\x29\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x32\x66\x66\x32\x32\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x39\ +\x39\x39\x39\x39\x37\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x34\x2e\x37\x39\x32\x32\x32\ +\x36\x32\x2c\x31\x34\x2e\x31\x39\x37\x30\x34\x33\x20\x63\x20\x30\ +\x2c\x30\x20\x38\x2e\x36\x38\x39\x38\x39\x33\x38\x2c\x31\x36\x2e\ +\x33\x36\x33\x30\x30\x38\x20\x39\x2e\x33\x37\x31\x38\x32\x38\x38\ +\x2c\x31\x32\x2e\x35\x33\x36\x38\x37\x33\x20\x43\x20\x31\x37\x2e\ +\x39\x37\x32\x39\x38\x34\x2c\x35\x2e\x33\x36\x33\x31\x37\x38\x33\ +\x20\x32\x38\x2e\x38\x31\x32\x39\x30\x33\x2c\x34\x2e\x30\x39\x38\ +\x31\x35\x36\x32\x20\x32\x38\x2e\x38\x31\x32\x39\x30\x33\x2c\x34\ +\x2e\x30\x39\x38\x31\x35\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x34\x35\x30\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\ +\x3d\x22\x63\x73\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x16\x70\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x62\x61\x6e\x64\x73\ +\x65\x74\x5f\x73\x74\x64\x5f\x64\x65\x76\x5f\x73\x74\x72\x65\x74\ +\x63\x68\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\ +\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x2d\x31\x37\x2e\x36\x32\x38\x30\x38\x34\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x31\x37\x2e\x39\x39\x37\x31\x35\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\ +\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\ +\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ +\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ +\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ +\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ +\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ +\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ +\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x66\x69\x6c\x6c\x3a\x23\x39\x31\x62\x64\x66\x66\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ +\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x38\x33\x37\ +\x30\x35\x30\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\ +\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\ +\x32\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ +\x74\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\ +\x2e\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x78\x3d\x22\x35\x32\x2e\x32\x31\x32\x38\x32\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x34\x35\x2e\x34\x35\x31\x31\x34\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\ +\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\ +\x34\x33\x36\x37\x38\x34\x38\x2c\x30\x2e\x35\x33\x36\x38\x34\x38\ +\x37\x39\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ +\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x38\x39\x33\x37\x32\x39\x33\ +\x2c\x30\x2e\x36\x31\x33\x39\x31\x33\x39\x38\x2c\x30\x2c\x30\x29\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\ +\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x37\x2e\x37\x39\x39\x37\x36\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x35\x2e\ +\x39\x38\x30\x38\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x38\x66\x66\x66\x38\x66\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x30\x34\x32\x30\x34\x39\ +\x31\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\ +\x66\x66\x61\x33\x61\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\ +\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\ +\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\ +\x64\x74\x68\x3a\x31\x2e\x39\x34\x34\x39\x39\x37\x37\x39\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\ +\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\ +\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\x33\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x32\x33\x2e\ +\x33\x32\x30\x36\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ +\x3d\x22\x31\x32\x2e\x36\x31\x30\x30\x35\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\ +\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ +\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x33\x36\x32\x35\x30\x38\ +\x39\x2c\x30\x2e\x36\x37\x36\x37\x30\x38\x36\x38\x2c\x30\x2c\x30\ +\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ +\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\ +\x37\x31\x30\x37\x31\x31\x35\x32\x2c\x30\x2e\x37\x30\x33\x34\x38\ +\x33\x35\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x72\x79\x3d\x22\x33\x2e\x32\x31\x31\x37\x36\x34\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\ +\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x2d\x34\x2e\x30\x34\x30\x31\x33\x38\x34\x65\x2d\x31\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x33\x2e\x38\x36\x36\ +\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x32\x31\x2e\x32\x32\x37\x36\x39\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x31\x2e\ +\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x65\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x31\x2e\x39\x30\x37\x36\x32\x34\x39\x36\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\ +\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\ +\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\ +\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\ +\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\ +\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ +\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ +\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\ +\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\ +\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\ +\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\ +\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\ +\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\ +\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\ +\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\ +\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\ +\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\ +\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\ +\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\ +\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ +\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\ +\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\ +\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x38\x30\x30\x30\x30\ +\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\ +\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\ +\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\ +\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ +\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x20\x63\x20\ +\x2d\x34\x2e\x30\x37\x34\x32\x30\x34\x2c\x30\x2e\x30\x30\x31\x34\ +\x20\x2d\x38\x2e\x33\x37\x31\x35\x35\x35\x35\x2c\x33\x2e\x39\x39\ +\x32\x38\x32\x33\x36\x20\x2d\x39\x2e\x36\x2c\x36\x2e\x34\x20\x43\ +\x20\x35\x2e\x31\x37\x31\x35\x35\x35\x35\x2c\x39\x2e\x38\x37\x33\ +\x38\x34\x33\x20\x33\x2e\x30\x38\x34\x32\x38\x33\x2c\x31\x38\x2e\ +\x39\x31\x31\x35\x36\x34\x20\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x2c\x32\x35\x2e\x36\x20\x30\x2e\x30\x35\x37\x38\x35\x38\x36\x37\ +\x2c\x32\x38\x2e\x39\x34\x34\x32\x31\x38\x20\x2d\x31\x2e\x38\x30\ +\x38\x38\x30\x38\x2c\x33\x30\x2e\x32\x37\x37\x35\x35\x31\x20\x2d\ +\x32\x2e\x33\x35\x36\x36\x30\x36\x2c\x33\x30\x2e\x37\x37\x34\x38\ +\x33\x20\x2d\x32\x2e\x39\x30\x34\x34\x30\x34\x31\x2c\x33\x31\x2e\ +\x32\x37\x32\x31\x30\x39\x20\x2d\x33\x2e\x32\x2c\x33\x30\x2e\x39\ +\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x32\x2c\x33\x30\x2e\x39\x33\ +\x33\x33\x33\x33\x20\x63\x20\x30\x2e\x37\x30\x36\x38\x37\x35\x37\ +\x2c\x30\x2e\x31\x35\x38\x36\x32\x39\x20\x30\x2e\x34\x34\x30\x34\ +\x38\x31\x33\x2c\x31\x2e\x30\x31\x35\x33\x37\x32\x20\x30\x2e\x31\ +\x33\x30\x35\x36\x35\x31\x2c\x31\x2e\x38\x30\x34\x30\x38\x37\x20\ +\x2d\x30\x2e\x33\x30\x39\x39\x31\x36\x32\x2c\x30\x2e\x37\x38\x38\ +\x37\x31\x33\x20\x2d\x30\x2e\x36\x36\x33\x33\x35\x34\x31\x2c\x31\ +\x2e\x35\x30\x39\x33\x39\x39\x20\x2d\x30\x2e\x31\x33\x30\x35\x36\ +\x35\x31\x2c\x31\x2e\x33\x39\x35\x39\x31\x33\x20\x30\x2c\x30\x20\ +\x30\x2e\x32\x36\x30\x34\x35\x35\x36\x2c\x31\x2e\x35\x33\x32\x30\ +\x34\x31\x20\x32\x2e\x31\x33\x33\x33\x33\x33\x33\x2c\x30\x20\x31\ +\x2e\x38\x37\x32\x38\x37\x37\x37\x36\x2c\x2d\x31\x2e\x35\x33\x32\ +\x30\x34\x20\x35\x2e\x33\x35\x38\x31\x37\x37\x36\x2c\x2d\x33\x2e\ +\x39\x39\x34\x38\x32\x37\x20\x36\x2e\x34\x2c\x2d\x38\x2e\x35\x33\ +\x33\x33\x33\x33\x20\x43\x20\x37\x2e\x34\x31\x36\x39\x37\x38\x31\ +\x2c\x31\x36\x2e\x35\x32\x32\x39\x38\x38\x20\x39\x2e\x35\x37\x36\ +\x37\x38\x34\x2c\x35\x2e\x32\x38\x32\x39\x30\x35\x31\x20\x31\x36\ +\x2e\x31\x37\x35\x35\x34\x39\x2c\x35\x2e\x33\x32\x34\x32\x38\x35\ +\x20\x32\x32\x2e\x34\x2c\x36\x2e\x34\x20\x32\x31\x2e\x33\x33\x33\ +\x33\x33\x33\x2c\x39\x2e\x36\x20\x32\x36\x2e\x36\x36\x36\x36\x36\ +\x37\x2c\x32\x33\x2e\x34\x36\x36\x36\x36\x37\x20\x63\x20\x32\x2e\ +\x34\x31\x37\x33\x38\x34\x2c\x36\x2e\x32\x38\x35\x32\x20\x36\x2e\ +\x34\x2c\x39\x2e\x36\x20\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x2c\ +\x31\x30\x2e\x36\x36\x36\x36\x36\x36\x20\x36\x2e\x34\x2c\x31\x2e\ +\x30\x36\x36\x36\x36\x37\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\ +\x30\x20\x35\x2e\x33\x33\x33\x33\x33\x34\x2c\x30\x20\x43\x20\x34\ +\x34\x2e\x38\x2c\x33\x32\x20\x34\x33\x2e\x37\x33\x33\x33\x33\x33\ +\x2c\x33\x35\x2e\x32\x20\x34\x32\x2e\x36\x36\x36\x36\x36\x37\x2c\ +\x33\x30\x2e\x39\x33\x33\x33\x33\x33\x20\x34\x31\x2e\x39\x32\x34\ +\x35\x30\x33\x2c\x33\x31\x2e\x31\x38\x30\x37\x32\x31\x20\x33\x35\ +\x2e\x30\x35\x38\x33\x34\x37\x2c\x33\x32\x2e\x33\x32\x36\x32\x35\ +\x32\x20\x33\x32\x2c\x32\x35\x2e\x36\x20\x32\x38\x2e\x39\x34\x31\ +\x36\x35\x33\x2c\x31\x38\x2e\x38\x37\x33\x37\x34\x38\x20\x32\x37\ +\x2e\x34\x38\x30\x35\x39\x35\x2c\x31\x31\x2e\x33\x30\x39\x36\x35\ +\x33\x20\x32\x35\x2e\x36\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\ +\x20\x32\x33\x2e\x37\x31\x39\x34\x30\x35\x2c\x33\x2e\x36\x32\x33\ +\x36\x38\x20\x32\x31\x2e\x37\x35\x39\x31\x38\x37\x2c\x31\x2e\x31\ +\x31\x34\x34\x33\x35\x35\x20\x31\x36\x2c\x31\x2e\x30\x36\x36\x36\ +\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\ +\x7a\x73\x73\x63\x73\x63\x73\x73\x63\x73\x63\x63\x63\x73\x7a\x63\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x74\x65\x78\x74\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\ +\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\ +\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\ +\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\ +\x2d\x73\x69\x7a\x65\x3a\x31\x32\x2e\x38\x30\x30\x30\x30\x30\x31\ +\x39\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\ +\x30\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\ +\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x2d\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\ +\x63\x61\x74\x69\x6f\x6e\x3a\x27\x53\x61\x6e\x73\x20\x42\x6f\x6c\ +\x64\x27\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\ +\x67\x3a\x30\x70\x78\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\ +\x6e\x67\x3a\x30\x70\x78\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\ +\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x39\x33\ +\x33\x33\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x74\x65\x78\x74\x33\x37\x39\x35\x22\x3e\x3c\x74\x73\x70\x61\ +\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x72\x6f\x6c\x65\x3d\x22\x6c\x69\x6e\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\x73\x70\ +\x61\x6e\x33\x37\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x78\x3d\x22\x36\x2e\x34\x30\x30\x30\x30\x30\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x30\x2e\x39\x33\ +\x33\x33\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\ +\x32\x35\x2e\x36\x30\x30\x30\x30\x30\x33\x38\x70\x78\x3b\x6c\x69\ +\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\x2e\x32\x35\x3b\x66\ +\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x73\x61\x6e\x73\x2d\ +\x73\x65\x72\x69\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\ +\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\x22\x3e\xcf\ +\x83\x3c\x2f\x74\x73\x70\x61\x6e\x3e\x3c\x2f\x74\x65\x78\x74\x3e\ +\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x05\x23\ +\x00\ +\x00\x11\x8e\x78\x9c\xd5\x58\x59\x6f\xe3\x36\x10\x7e\xcf\xaf\x10\ +\x94\x97\x16\x8d\x0e\x52\x27\x15\xdb\xfb\xb2\x58\xa0\x40\xfb\xd2\ +\x6e\xd1\xc7\x05\x2d\xd1\x36\x1b\x49\x14\x28\xca\xc7\xfe\xfa\x0e\ +\x75\xcb\x76\x16\x1b\xf4\xc0\xae\x82\x20\xe0\x37\x33\xe4\xcc\x7c\ +\x9c\x19\x22\xab\x77\xe7\x22\x37\x8e\x4c\xd6\x5c\x94\x6b\x13\xd9\ +\xae\x69\xb0\x32\x15\x19\x2f\xf7\x6b\xf3\x8f\x8f\x1f\xac\xd8\x34\ +\x6a\x45\xcb\x8c\xe6\xa2\x64\x6b\xb3\x14\xe6\xbb\xcd\xc3\xaa\x3e\ +\xee\x1f\x0c\xc3\x00\xe3\xb2\x4e\xb2\x74\x6d\x1e\x94\xaa\x12\xc7\ +\xa9\x1a\x99\xdb\x42\xee\x9d\x2c\x75\x58\xce\x0a\x56\xaa\xda\x41\ +\x36\x72\xcc\x49\x3d\x9d\xd4\x53\xc9\xa8\xe2\x47\x96\x8a\xa2\x10\ +\x65\xdd\x5a\x96\xf5\xe3\x4c\x59\x66\xbb\x51\xfb\x74\x3a\xd9\x27\ +\xaf\x55\x42\x84\x10\xc7\xc5\x0e\xc6\x16\x68\x58\xf5\xa5\x54\xf4\ +\x6c\x2d\x4d\xc1\xc7\x7b\xa6\xd8\x75\x5d\x07\x64\x93\xe6\xd7\x69\ +\x25\x35\x64\xa5\x82\xdf\x51\x7d\x00\xec\x5a\x34\x32\x65\x3b\xb0\ +\x63\x76\xc9\x94\xf3\xfe\xe3\xfb\x51\x68\xb9\x76\xa6\xb2\xd9\x36\ +\xbc\x7c\xa9\x53\x5a\xb1\xc5\xa9\x03\xd8\x65\x80\x16\xac\xae\x68\ +\xca\x6a\x67\xc0\x5b\xfb\x13\xcf\xd4\x61\x6d\x7a\xbe\x8d\x3c\xf8\ +\x82\x16\x3c\x30\xbe\x3f\xa8\x6b\x94\x67\x6b\x13\xbc\xc7\x24\xee\ +\xd6\x33\x86\x51\xa7\xd0\x6f\x9c\xcc\xb9\xb7\xb1\xf1\x03\x8b\xc3\ +\x34\x8e\xdc\x38\x22\x4f\x06\x76\x31\xb2\x5c\x64\xa1\xe0\xc7\xd6\ +\x68\x88\x29\xc9\x44\xaa\x9d\x84\x33\x58\xc1\x69\xa3\x44\x01\x34\ +\xa6\x69\x4e\xeb\x9a\xef\x78\x0a\x0b\x51\x56\x79\xb3\xe7\xe5\xa7\ +\x9a\x1e\xd9\x27\x29\x20\x49\x7d\x32\xc7\x93\xd9\xb9\x12\x52\x59\ +\xe7\xac\x82\x94\x86\xd1\x5d\xe1\x65\x10\x6e\x40\xba\xca\xd8\xae\ +\xd6\x5a\x5d\x7c\x7a\x05\x01\x46\xa6\xe1\xb4\xd2\xd1\x3b\xed\x5a\ +\x76\xe4\xec\x34\xe9\x6e\x69\xdd\xe5\xd0\x30\x2a\xba\x87\xfb\x96\ +\x0b\xb9\x36\x1f\x77\xed\xd7\x0b\xb6\x42\x66\x4c\x0e\xa2\xb0\xfd\ +\x16\x22\x01\x9c\x70\x75\xe9\xca\xa4\xdf\x7b\xf0\x57\xef\x3a\xca\ +\xdd\xfb\xf2\xfa\x40\x33\x71\x5a\x9b\xf8\x5a\xf8\x59\x88\x62\x6d\ +\x46\x36\x41\xb1\xeb\xa3\xe8\x5a\x9c\x9e\xe1\x48\xcf\x76\x03\xe2\ +\xa1\x1b\xdb\x14\xce\xc3\xd8\x0e\xb5\xf0\xd6\xb2\x91\x12\x4a\xd0\ +\xca\xe9\x85\x41\x50\xed\x1f\xd4\x2b\xd5\x07\x71\xda\x4b\x9d\x1c\ +\x25\x1b\x76\x6d\xa9\x25\xd6\x76\x2b\xce\xf7\xc5\x70\x01\x1a\x5d\ +\xdc\x56\x53\x72\x05\x05\x54\x9d\xe7\xbb\x36\x3c\x63\xf5\x7d\xc3\ +\xba\xa4\x95\xb5\xcf\xc5\x96\xe6\xf7\x15\x4e\xbc\x84\x24\x59\xfd\ +\x5d\x47\xde\xc8\xc1\xb5\xc6\x70\xf1\x23\xf7\x35\x0d\xf0\xfd\x86\ +\x87\x5e\x74\x79\x5d\x54\xd0\x33\x2f\xf8\x67\x06\x89\x41\xaf\x86\ +\x2d\x85\x6a\x2f\xb9\xde\x66\xd3\x2a\xad\x16\xa9\xeb\xec\x0c\x43\ +\x5d\x74\xa1\x9f\x2f\x1a\x33\x07\x50\xe7\x5c\x03\x98\x90\x68\x04\ +\x85\xe4\x50\x2e\x33\x97\x07\xe8\x32\x87\x74\x5b\x80\xd6\x7c\x6e\ +\xef\x60\x7b\x43\xa3\x6b\xd9\x65\x2e\xeb\x4b\xc3\xb9\xad\x8d\x16\ +\x2f\x98\xa2\x19\x55\x74\x2a\x94\x01\x01\xdf\xc6\xc8\xa0\xc3\x26\ +\xbf\xbd\xff\xb0\xe9\x0f\x5a\xa5\x69\xf2\xa7\x90\x2f\xc3\xb9\x86\ +\xa1\x15\xe8\x56\x34\xc0\x86\xb9\x19\xe1\x55\x96\x26\xd0\x13\xa1\ +\x35\x6c\x78\x01\xd7\x5f\xb7\xd3\x9f\xa0\x07\xae\x9c\x49\xb0\x50\ +\xd6\xc9\x9a\x36\xed\xb6\x95\xac\x6b\xae\x77\x27\x4c\x96\x16\x5c\ +\x1b\x39\xbf\x2b\x9e\xe7\x3f\xeb\x43\xfa\x88\x67\x9b\x72\x95\xb3\ +\x09\x5c\x39\xbd\xf7\x7d\x6c\xce\x2c\xb8\x95\x33\x44\xdf\xae\xf6\ +\x53\x56\x16\x85\x33\x12\x9d\xd3\x2d\x83\x5b\xfc\x8b\x16\x1a\x37\ +\xd2\xbd\x14\x4d\x55\x88\x8c\xf5\xe6\x63\x36\x59\xaa\x46\xca\xd4\ +\x25\x07\x79\xdb\x73\x92\x47\xb7\xfd\x9e\x33\x5e\x57\x60\x01\x83\ +\x22\xe7\x25\x7b\x16\xd0\xa1\x77\xb9\x38\x25\x47\x5e\xf3\x6d\xce\ +\x9e\xdb\xbf\x3c\x87\xc8\x47\x68\x07\xe1\x27\x8f\x94\xb6\xf6\x7a\ +\x61\xf5\xbd\x28\x41\xdd\x52\x36\x39\x4b\x4a\x51\x7e\x86\x2e\xf6\ +\x5c\x2b\x29\x5e\xd8\x78\x5e\xb7\xec\x2a\x2e\xc1\xb6\x1f\xc5\xc4\ +\xf3\xd0\x00\x6b\x1f\x20\x9e\x64\xdb\x28\x35\xc7\xfe\x12\xbc\x4c\ +\x20\xfd\x4c\x0e\x68\xbb\xc8\xa1\x76\x54\xe2\x0f\x58\x46\xa1\xe9\ +\x49\x09\xd1\xc0\xe1\x6c\x8e\x8a\xdd\xae\x66\x0a\xce\x8b\x3d\x1c\ +\xbb\x28\x88\x07\xe1\xe4\x79\x41\xe5\x0b\x93\x9d\x25\x2b\x29\x04\ +\x6a\x6d\x69\xfa\xa2\x13\x5b\x66\x09\x4d\xa1\x16\x9b\x9c\x2a\xb6\ +\x28\x2c\x9d\x5e\x98\x0a\xe1\x08\x0e\x53\x13\x8f\xc8\x38\x32\x27\ +\xe8\x6e\x41\x5d\xee\x81\x12\x54\xb1\x1d\x05\x7a\x44\x06\x13\xda\ +\xea\x12\x17\xfb\x1e\xc1\xe3\x1d\xfc\x0f\xb9\xde\x7a\xfa\xe7\x9f\ +\x72\x1d\x21\x12\x61\x1c\x05\xdf\x33\xd9\x5e\x14\x7c\x0d\xd9\x30\ +\x40\xe3\x25\x93\x6f\xe3\x1c\xe6\x6f\xe8\xf9\x9e\xbb\xe4\x1c\x03\ +\xea\x92\x28\x88\x27\xce\x2b\xaa\x0e\x57\x9c\xb7\x94\xcd\x72\x72\ +\x9f\x8e\xf1\x5c\x5c\x9d\xdf\x4e\xc8\x98\xc9\xd1\x3f\xc8\xcf\xaf\ +\x46\x68\x47\xc4\x07\xc7\xa3\x27\xdf\xc6\x28\xf0\x22\x9f\x18\x38\ +\xb2\x23\xfd\x54\xf4\x34\x76\x15\xaa\xce\xaa\x8e\xc0\xd3\x31\x8d\ +\xe0\xf8\x9e\x10\x25\xf8\xa3\x84\xb4\xe0\x65\x71\xa4\xaa\x91\x4c\ +\x4f\xa7\x6f\x3e\xf6\xc8\xf6\x6f\x62\x07\xec\x0b\xb1\x5b\xde\xf7\ +\x1d\x7d\x31\x8b\x1e\xb9\x76\xa8\xc3\x0f\xe0\x41\x6f\x13\x2f\x0e\ +\x49\xec\x3d\xc1\x1b\x35\x40\x98\xdc\x0f\x9e\xbc\x3d\xf8\x6f\xbb\ +\xd5\x21\xdb\x0b\x3d\xcf\xff\x5f\xfb\xdc\xbf\xdc\xe3\x66\x37\x72\ +\x78\x1c\xfb\xc0\x26\x7c\xe8\xa6\xd9\xf5\x77\x3b\x5a\x0c\x38\x62\ +\x87\x6d\x66\xfc\x79\xb3\xc3\x81\x1d\x2e\xfa\x1c\xb2\x7d\x4c\x40\ +\x31\xba\x9a\x6d\x48\xb7\xb9\xf0\xcb\xb3\xad\xe3\x8b\x11\xba\x45\ +\xe1\xeb\x7c\xb1\x23\x2b\x45\x96\x8d\x7c\xa1\x38\x0b\x77\xbb\x25\ +\x5f\x70\x4f\x7d\x1c\xb8\x41\xe0\xbf\x9d\x88\xdb\x7a\x98\xde\x05\ +\x84\xdc\x24\xf1\x66\x2e\x7c\x79\x62\x10\x5b\xff\x6b\xc0\x45\x8b\ +\x89\x71\x03\x76\xaf\x04\xcf\x25\x31\x0e\xc3\xab\x4c\x86\x7e\x1c\ +\xc5\xee\xf4\x36\xdf\x6f\x1e\x56\xfa\x6d\xbc\x79\xf8\x1b\x1c\xcb\ +\x3e\xac\ +\x00\x00\x0b\x09\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x69\x6d\x70\x6f\x72\x74\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\ +\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x37\x2e\x34\x39\x35\x31\x37\x32\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x37\x2e\x38\x36\x37\x37\x34\x35\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ +\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\ +\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\ +\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ +\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ +\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ +\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ +\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ +\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ +\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x37\x38\x39\x62\x61\x32\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ +\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ +\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\x35\ +\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x33\x64\x32\x37\x34\x36\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x64\x3d\x22\x6d\x20\x31\x34\x2e\x36\x38\x36\x37\x34\x37\x2c\x32\ +\x2e\x35\x37\x30\x39\x31\x39\x35\x20\x63\x20\x2d\x30\x2e\x39\x34\ +\x32\x31\x30\x33\x2c\x30\x20\x2d\x31\x2e\x36\x39\x35\x37\x34\x38\ +\x2c\x30\x2e\x37\x35\x33\x36\x34\x36\x36\x20\x2d\x31\x2e\x36\x39\ +\x35\x37\x34\x38\x2c\x31\x2e\x36\x39\x35\x37\x34\x37\x32\x20\x56\ +\x20\x31\x36\x2e\x35\x39\x36\x37\x35\x39\x20\x48\x20\x36\x2e\x35\ +\x35\x32\x39\x30\x37\x39\x20\x63\x20\x2d\x31\x2e\x38\x33\x39\x34\ +\x35\x34\x38\x2c\x30\x20\x31\x30\x2e\x31\x31\x37\x30\x30\x30\x31\ +\x2c\x31\x33\x2e\x37\x39\x35\x39\x31\x31\x20\x31\x30\x2e\x31\x31\ +\x37\x30\x30\x30\x31\x2c\x31\x33\x2e\x37\x39\x35\x39\x31\x31\x20\ +\x6c\x20\x30\x2e\x39\x31\x39\x37\x32\x37\x2c\x30\x2e\x39\x31\x39\ +\x37\x32\x38\x20\x30\x2e\x39\x31\x39\x37\x32\x38\x2c\x2d\x30\x2e\ +\x39\x31\x39\x37\x32\x38\x20\x63\x20\x30\x2c\x30\x20\x31\x31\x2e\ +\x39\x35\x36\x34\x35\x36\x2c\x2d\x31\x33\x2e\x37\x39\x35\x39\x31\ +\x31\x20\x31\x30\x2e\x31\x31\x37\x2c\x2d\x31\x33\x2e\x37\x39\x35\ +\x39\x31\x31\x20\x48\x20\x32\x32\x2e\x31\x38\x38\x32\x37\x32\x20\ +\x56\x20\x34\x2e\x32\x36\x36\x36\x36\x36\x37\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x39\x34\x32\x31\x30\x30\x36\x20\x2d\x30\x2e\x37\x35\ +\x33\x36\x34\x35\x2c\x2d\x31\x2e\x36\x39\x35\x37\x34\x37\x32\x20\ +\x2d\x31\x2e\x36\x39\x35\x37\x34\x38\x2c\x2d\x31\x2e\x36\x39\x35\ +\x37\x34\x37\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\x38\x2d\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\ +\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\xf7\ +\x00\ +\x00\x18\xf1\x78\x9c\xed\x58\x5b\x8f\xeb\x36\x0e\x7e\x9f\x5f\xa1\ +\xcd\x79\xe9\x62\x23\x5b\x92\xaf\x72\x2e\x7d\xd8\x83\x02\x05\xce\ +\xbe\x6c\xbb\x2d\xb0\x2f\x85\x62\x2b\x89\x3a\xb6\x95\x95\x95\x49\ +\xd2\x5f\x5f\xca\xb7\xc4\x99\x4c\x31\xc5\xb6\x40\x1f\x46\xc0\x4c\ +\x22\x92\xa2\x28\x92\x9f\x48\x65\xf9\xf5\xb9\x2a\xd1\x8b\x34\x8d\ +\xd2\xf5\x6a\x46\x3d\x32\x43\xb2\xce\x75\xa1\xea\xdd\x6a\xf6\x9f\ +\xef\xbf\xc1\xe9\x0c\x35\x56\xd4\x85\x28\x75\x2d\x57\xb3\x5a\xcf\ +\xbe\x5e\x3f\x2d\xff\x86\x31\xfa\xa7\x91\xc2\xca\x02\x9d\x94\xdd\ +\xa3\x6f\xeb\xe7\x26\x17\x07\x89\xbe\xda\x5b\x7b\xc8\x7c\xff\x74\ +\x3a\x79\xaa\x27\x7a\xda\xec\xfc\xbf\x23\x8c\xd7\x4f\x4f\xcb\xe6\ +\x65\xf7\x84\x10\x82\x7d\xeb\x26\x2b\xf2\xd5\xac\x5f\x70\x38\x9a\ +\xb2\x15\x2c\x72\x5f\x96\xb2\x92\xb5\x6d\x7c\xea\x51\x7f\x76\x15\ +\xcf\xaf\xe2\xb9\xdb\x5d\xbd\xc8\x5c\x57\x95\xae\x9b\x76\x65\xdd\ +\x7c\xba\x11\x36\xc5\x76\x94\x76\xd6\x9c\x82\x56\x88\x72\xce\x7d\ +\xc2\x7c\xc6\x30\x48\xe0\xe6\x52\x5b\x71\xc6\xd3\xa5\x60\xe3\xa3\ +\xa5\x8c\x10\xe2\x03\xef\x2a\xf9\x3e\xa9\xac\x01\x87\x1e\xe0\x6f\ +\x14\x1f\x08\x5e\xa3\x8f\x26\x97\x5b\x58\x27\xbd\x5a\x5a\xff\xf3\ +\xf7\x9f\x47\x26\x26\x5e\x61\x8b\x1b\x35\x83\x3f\x27\xbb\x4e\x9c\ +\x5c\x8b\x4a\x36\x07\x91\xcb\xc6\x1f\xe8\xed\xfa\x93\x2a\xec\x7e\ +\x35\x0b\x42\x8f\x06\x30\xa2\x96\xb8\x97\x6a\xb7\xb7\xf7\x54\x55\ +\xac\x66\x60\x3d\xe3\x69\x37\xbf\x49\x0e\xda\x09\xf4\x8a\xb3\x91\ +\x43\x3c\xce\x3c\x8a\x0c\x8d\x82\xa4\x93\x19\x8e\x90\x15\x3a\x77\ +\x36\x81\x4a\x59\x29\x71\xb4\xba\x82\xa8\xe5\x79\x29\x9a\x46\x6d\ +\x55\x0e\x13\x5d\x1f\xca\xe3\x4e\xd5\x3f\x6d\x95\xfd\xe9\x50\x6a\ +\xeb\x0d\xbe\x1b\x37\x92\xe7\x83\x36\x16\x9f\x8b\x03\x78\x30\x4e\ +\x1e\x32\x2f\x03\x73\x0d\xdc\x65\x21\xb7\x8d\x93\xea\x8e\xe3\x66\ +\x70\x9e\x64\x86\xfc\x96\x3b\x5a\xe7\x4c\x2b\x5e\x94\x3c\x5d\x65\ +\x37\xa2\xe9\x5c\x86\xd0\x41\xec\x20\xbd\x4a\x6d\x56\xb3\x4f\xdb\ +\x76\xf4\x8c\x8d\x36\x85\x34\x03\x2b\x6e\xc7\x84\xa5\x21\x04\xca\ +\x5e\x3a\x40\xf5\xba\x07\x7b\x9d\xd6\x91\x4f\x1e\xf3\x9b\xbd\x28\ +\xf4\x69\x35\x63\xf7\xcc\x5f\xb4\xae\x56\xb3\xc4\xe3\x34\x25\x21\ +\x4d\xee\xd9\xf9\x79\x35\xc3\x34\xf1\xa2\x30\x0c\x5e\x33\x61\x3f\ +\x96\x7a\x94\x90\x90\x44\xaf\x98\x47\x63\x00\x71\xb8\x14\x17\x09\ +\x87\x6a\x3f\x68\x2f\xd4\xec\xf5\x69\x67\x9c\x73\xac\x39\xca\xfb\ +\x95\x8e\x83\x37\x1b\x7d\x7e\xcc\x86\x04\x38\x3a\x2c\xe3\x63\xad\ +\x2c\xe0\xe5\x70\xbe\xd5\x7a\x54\x85\x6c\x1e\x2f\x3c\xa9\x1a\x7c\ +\x80\xfb\xcc\xa5\xc1\xe8\xe2\x7b\x89\x21\x8d\x13\x92\xbe\x21\x01\ +\xa6\xbd\x72\x73\xcf\xba\xbc\xcd\xaa\xc4\x59\x55\xea\x17\x09\xe7\ +\xa6\xf7\x22\x4d\x2d\x0e\x78\x57\xea\x8d\x28\x7b\xeb\xd7\xad\xc4\ +\x72\xe2\x96\x6e\x11\x42\xf6\xe2\x30\x7b\xbe\x38\xda\x6c\x20\x3a\ +\x7f\x3a\x42\x90\xc4\xd1\x48\xd4\x46\x01\x14\x6e\xec\x1d\x48\x97\ +\x5b\x92\x43\x38\x5c\xd0\xe7\x36\xbf\xda\xec\x4b\xee\x79\x97\x5b\ +\x5e\x9f\xf6\xfe\xeb\xbc\x6f\xe9\x95\xb4\xa2\x10\x56\x5c\x41\x30\ +\x50\x18\xe7\x64\x38\x19\x5c\x96\xd9\xbf\x3f\x7f\xb3\xee\x37\x5a\ +\xe6\x79\xf6\xa3\x36\xcf\xc3\xbe\x08\x39\x01\xb1\xd1\x47\x08\xc5\ +\x6c\x3d\x92\x97\x45\x9e\xc1\xf5\x06\xb0\x5f\xab\x0a\x52\xdb\xdd\ +\x8c\xff\x80\xeb\x6c\xe9\x5f\x19\x13\x61\xe7\xac\xab\xd2\x4e\xad\ +\x91\xdd\x3d\xf9\xb0\x58\x14\x79\xa5\xdc\x22\xff\x3b\xab\xca\xf2\ +\x5b\xb7\x49\x7f\xe2\x1b\xa5\xca\x96\xf2\x4a\x5c\xfa\xbd\xf5\xfd\ +\xd9\xfc\x9b\xc3\x2d\xfd\xe1\xf4\xed\x6c\x77\xf5\xca\x04\x14\x63\ +\xa0\x4b\xb1\x91\x90\x04\x5f\x1c\x13\xbd\xe2\xee\x8c\x3e\x1e\x2a\ +\x5d\xc8\x7e\xf9\xe8\x4d\x99\xdb\x31\x64\xf6\x52\x02\x7f\x0b\xd6\ +\x67\xfd\x45\xb3\x70\x13\xdc\x5f\x13\x19\xed\xa6\xe6\x58\xc2\x75\ +\xf7\x22\x6b\x5d\x14\x8b\xc6\x1a\xfd\x2c\xb3\x4f\x80\xe6\x94\x90\ +\x7e\xda\xa1\x25\x1b\xa7\xa5\xaa\x25\x98\x91\x35\xff\x3b\x0a\x23\ +\x6f\xa9\x3f\x6b\x55\x67\xe0\x37\x69\x06\x6a\x3b\x29\x21\xe3\x6d\ +\x16\x0e\xb4\x42\xc0\x4d\x64\x8c\xb8\x64\x35\x54\xff\x5b\xaa\xde\ +\x6e\x1b\x69\xaf\x3b\x0d\xa6\x12\x2f\xe8\xc7\x24\xd1\xdd\x71\x03\ +\xce\xe9\x48\x7c\x58\x90\xdc\x78\x5c\x94\xdc\x98\xa0\x02\xf2\x9b\ +\x7b\x61\x12\x70\x12\xc4\x12\xd3\x78\x64\x98\x89\x98\x01\xb9\xc0\ +\x0b\xa0\x30\xc5\x3c\x1d\xb3\x62\x79\x10\x76\xff\xc8\xfb\x37\xa7\ +\x74\x9e\x4d\xe5\xbd\x67\x47\x4c\xb1\xc3\xf9\xde\xc9\x9b\xa3\xb5\ +\xbf\xed\xe2\x31\x9e\xa3\x7d\x0e\x6b\x08\x8f\x5a\xe7\x8c\x79\x21\ +\x0a\x3c\x36\x1f\x68\x09\x8a\xbd\x70\x8e\x53\x2f\x6a\x9d\x8a\xa2\ +\xde\xbf\xc9\x8d\xc4\x40\x9b\x73\x2f\xbe\x4e\x58\xe7\xbf\x10\x7d\ +\x41\x01\x9b\xb3\xc4\x4b\x3a\x0d\x25\x1a\x94\xcd\x61\xa3\x49\x94\ +\x9c\x5b\x42\x12\x5c\x2f\x93\x6b\x79\xd0\x35\x1c\xd2\x6a\x83\xa1\ +\x50\xbc\x08\x7b\x34\xd2\xb9\xf9\xff\x77\x68\xe4\x31\xe6\x4e\xc1\ +\x83\xdf\xef\xce\xf7\x67\xec\x6f\x64\xe7\xab\x08\xd0\x5e\x66\x12\ +\x86\x78\x12\x86\xf0\x41\x18\xe2\x69\x18\xbe\x20\x16\x0e\x6e\xee\ +\x82\x0a\x31\x88\xbd\x6e\x93\xf7\xc4\x00\x07\xef\x8e\xc2\x2b\x39\ +\x6b\x44\xdd\xb8\xbb\x15\xe7\x50\x79\xa5\xc1\x6d\xa5\x88\xdf\x21\ +\x78\x71\xfd\xc3\x5d\xdd\x78\x1c\xde\xb6\xfb\x71\x31\x75\x63\xb1\ +\xd5\x50\xe1\x5b\x0e\xf8\x1d\xee\xf4\xb2\xa3\xbc\x08\xa3\x44\x6d\ +\x27\xb4\x53\x0b\xf0\x09\x09\xa2\x24\x6d\xbe\x9f\xd2\xa0\xf2\x66\ +\x50\xa5\xd4\xb1\x5a\xb8\xf0\xf7\x65\x7e\x22\xb3\x15\x95\x2a\x2f\ +\xd9\x77\x70\x88\x05\x1e\x0e\x85\xbb\xe5\x07\x99\x8f\x0d\x66\x27\ +\x61\xe5\xd9\x82\x54\x01\x27\x85\x7b\xab\x9d\x89\x52\xed\xea\x0c\ +\xde\x37\xc6\x76\x84\x02\x1a\x3e\xd3\xad\x69\xf3\xe7\x8e\xd8\x26\ +\x62\xc7\x29\xa5\x75\x0e\xeb\xcb\xed\x60\xd6\x09\xda\xbf\x7b\x5a\ +\xab\x63\xf4\x74\xb7\xfa\x64\x94\x05\x11\xec\x2a\x43\x56\x1a\x6c\ +\x37\x8b\x42\xb9\x4b\xd2\xed\x5c\x5a\xb3\x70\x6d\x68\x7b\xec\x66\ +\xaf\xb6\x36\x1b\xa6\xbd\xd9\x75\xbe\x07\xe7\x77\x76\x17\xaa\x39\ +\x40\x69\x81\xc7\x41\x2b\xa0\xa1\x2b\xdf\x96\xfa\x94\xbd\xa8\x46\ +\x6d\x4a\xb9\x68\x3f\x55\xe9\xd2\x7f\x20\x75\x95\x86\xe6\x74\xcb\ +\xc2\xfb\x4a\xd3\x83\xf5\x16\x3d\x1d\x52\x03\x8f\x87\x90\x15\x51\ +\x14\x2c\x2a\x61\x9e\xa5\xe9\x64\x64\x2d\x40\x25\xde\x88\xfc\xd9\ +\xd5\xba\xba\xc8\x44\x0e\x1d\xdf\xb1\x84\xb7\xe1\x14\x64\x00\x88\ +\xb4\x4d\xfa\x39\xc0\x90\x01\xbc\x48\x38\x77\xff\x1c\x56\x18\x74\ +\xb4\x51\x12\xcd\xdd\x2d\x15\xb3\x38\x48\x11\x80\x85\xb3\x30\x0a\ +\xd9\x9c\x12\x2f\x24\x69\xc2\x29\x0a\xe0\xa1\xd1\xa1\x06\xd0\x08\ +\x20\xba\xaa\xf8\x01\xb5\x3a\xff\xfb\x0a\x4a\x01\x21\xfc\x77\x03\ +\xe9\xda\x27\x41\x78\x5c\x6b\x01\x2d\x6a\xde\x8f\x0f\x50\x7c\x80\ +\xe2\x0f\x03\xc5\xbf\xa0\x0e\x30\x92\xa6\x1c\x0a\x49\x10\x79\x94\ +\x47\x3c\xe5\x63\x21\x81\xe2\xc0\x10\x64\x7f\x14\x84\x80\x08\x57\ +\xc2\x53\xce\x68\xe8\x5a\x02\x68\x40\x58\x1c\x42\xb5\x8a\x3c\x42\ +\x19\x89\x19\x82\x1a\x13\x25\x49\xc2\xe2\x39\xbc\xf1\xe0\x71\x48\ +\x28\xc2\x00\x1c\x9a\x24\x69\x4a\x63\x27\x18\x93\x94\x30\x47\x4c\ +\x79\x1a\x06\x34\x4e\xe7\xd0\x63\x25\xd4\x69\x7f\x03\x38\x98\x7e\ +\x40\xe7\x03\x3a\x7f\x55\xe8\xb8\x46\x25\x60\x00\x13\x0e\x1d\x17\ +\xa5\x9c\x07\x51\x84\xa8\xc7\x79\xec\x7e\xe2\x83\x12\x41\xe2\x34\ +\xa2\x8c\x03\x5c\x02\x4e\x69\x42\xe9\x9c\xc2\x12\xc6\xa3\x34\x45\ +\x1c\xaa\x46\x0a\x5f\x38\x94\x1c\x42\x49\x02\x08\x02\x28\x31\x78\ +\x51\x84\xa9\x2b\x29\x34\x21\x1c\xd0\x92\x7a\x24\x0a\x18\x74\x79\ +\x04\xf6\x0a\x03\xd8\xee\xb6\x57\x24\x6f\xe2\x06\xb3\x0f\xe4\x7c\ +\x20\xe7\xaf\x89\x9c\x0a\xc1\xbd\x0f\xa9\xce\x79\xea\x9e\x24\x50\ +\x15\xe2\x10\xd2\x1a\x92\x1e\xde\xd2\x89\x7b\x91\x90\x24\x82\x1a\ +\x81\x70\xe8\x85\x41\x44\xd2\x60\x0e\xdf\x38\x8b\x00\x1d\x08\x33\ +\x2f\x86\x4f\x36\x07\x15\x21\x61\x80\x38\xf8\x12\xc5\x00\x33\x58\ +\xc7\xa1\xc4\x00\xb6\x1e\xa8\xfa\x82\x86\xf7\x7c\xe0\x0a\xdd\x5b\ +\x9d\x1a\x0e\xff\x0c\xd8\x2c\xfd\xdd\xfa\x69\xe9\x7e\x78\x5a\x3f\ +\xfd\x0a\x4c\x29\xd2\x0a\ +\x00\x00\x08\xc4\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x74\x72\x61\x69\x6e\ +\x69\x6e\x67\x5f\x69\x6e\x70\x75\x74\x2e\x73\x76\x67\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\ +\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ +\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\ +\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\ +\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ +\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\ +\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\ +\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\ +\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x31\x34\x2e\x39\x31\x38\x38\ +\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x79\x3d\x22\x32\x31\x2e\x39\x38\x36\x31\x39\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\ +\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\ +\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ +\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\ +\x35\x30\x31\x32\x38\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\ +\x69\x64\x74\x68\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\ +\x3d\x22\x35\x2e\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\x37\x38\x35\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\ +\x67\x3e\x0a\ +\x00\x00\x0c\x27\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x6d\x6f\x76\x65\x5f\x64\x6f\x77\x6e\x2e\x73\x76\x67\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\ +\x39\x37\x38\x30\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x31\x30\x2e\x37\x31\x36\x30\ +\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x79\x3d\x22\x31\x37\x2e\x30\x32\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ +\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\ +\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\ +\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\ +\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ +\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ +\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ +\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\ +\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\ +\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\ +\x73\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ +\x22\x31\x2e\x32\x37\x39\x36\x32\x32\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x79\x3d\x22\x31\x2e\x32\x32\x34\x34\x30\x31\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\ +\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ +\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\ +\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\ +\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\ +\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\ +\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\x6d\x3b\x6c\x69\ +\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\ +\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x53\x61\x6e\ +\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\ +\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x53\ +\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\x65\x6e\x74\x3a\ +\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x73\x74\x61\ +\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\ +\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\ +\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\x3a\x6e\x6f\x6e\ +\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\ +\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\x2d\x73\x70\x61\ +\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x74\x65\x78\x74\ +\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\x6f\x6e\x65\x3b\ +\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\x3a\x6c\x72\x2d\ +\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x3a\x6c\x74\x72\ +\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\x69\x66\x74\x3a\ +\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\x74\x2d\x61\x6e\ +\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\x69\x73\x70\x6c\ +\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\ +\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\ +\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\ +\x6c\x6c\x3a\x23\x65\x37\x65\x37\x66\x66\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x34\x2e\x30\x37\x30\x38\x38\x3b\x6d\x61\x72\ +\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\ +\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\ +\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x6d\x20\x32\x30\x2e\x33\x35\x31\x39\x32\x39\x2c\x38\x2e\x35\ +\x33\x33\x32\x38\x33\x33\x20\x68\x20\x2d\x34\x2e\x39\x32\x37\x39\ +\x30\x32\x20\x2d\x31\x2e\x36\x34\x32\x36\x33\x33\x20\x6c\x20\x30\ +\x2e\x35\x32\x32\x30\x30\x32\x2c\x36\x2e\x36\x36\x38\x33\x39\x32\ +\x37\x20\x2d\x36\x2e\x33\x35\x32\x35\x35\x35\x37\x2c\x30\x2e\x30\ +\x30\x37\x38\x20\x39\x2e\x31\x31\x35\x38\x32\x36\x37\x2c\x31\x32\ +\x2e\x35\x32\x33\x38\x35\x38\x20\x38\x2e\x38\x38\x33\x30\x38\x31\ +\x2c\x2d\x31\x32\x2e\x35\x34\x35\x37\x39\x32\x20\x2d\x36\x2e\x33\ +\x35\x32\x35\x35\x36\x2c\x30\x2e\x30\x30\x37\x38\x20\x7a\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ +\x30\x31\x33\x2d\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\x63\ +\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x05\xad\ +\x00\ +\x00\x17\x86\x78\x9c\xed\x58\x59\x6f\xe3\x36\x10\x7e\xcf\xaf\x10\ +\x14\x14\xdb\x4b\xf7\x65\xc9\xc7\x02\x45\xb0\x40\x81\x3e\x75\xb7\ +\xe8\xe3\x82\x96\x68\x87\x0d\x25\xaa\x24\x15\xdb\xfb\xeb\x3b\xa4\ +\x0e\x4b\xb6\x12\x2c\xe0\xa2\x5b\x60\xd7\x41\xe0\x68\x0e\x92\xf3\ +\x7d\x33\xc3\x51\x56\x6f\x8f\x25\x35\x9e\x31\x17\x84\x55\x6b\xd3\ +\xb3\x5d\xd3\xc0\x55\xce\x0a\x52\xed\xd7\xe6\x1f\x1f\xde\x59\x0b\ +\xd3\x10\x12\x55\x05\xa2\xac\xc2\x6b\xb3\x62\xe6\xdb\xcd\xdd\x4a\ +\x3c\xef\xef\x0c\xc3\x00\xe7\x4a\x64\x45\xbe\x36\x1f\xa5\xac\x33\ +\xc7\xa9\x1b\x4e\x6d\xc6\xf7\x4e\x91\x3b\x98\xe2\x12\x57\x52\x38\ +\x9e\xed\x39\xe6\xd9\x3c\x3f\x9b\xe7\x1c\x23\x49\x9e\x71\xce\xca\ +\x92\x55\x42\x7b\x56\xe2\x7e\x64\xcc\x8b\xdd\x60\x7d\x38\x1c\xec\ +\x43\xa0\x8d\xbc\x34\x4d\x1d\xd7\x77\x7c\xdf\x02\x0b\x4b\x9c\x2a\ +\x89\x8e\xd6\xd4\x15\xce\x38\xe7\xea\xbb\xae\xeb\x80\xee\x6c\xf9\ +\x79\x56\x99\x00\x54\x6a\xf8\x1d\xcc\x7b\x81\x2d\x58\xc3\x73\xbc\ +\x03\x3f\x6c\x57\x58\x3a\x0f\x1f\x1e\x06\xa5\xe5\xda\x85\x2c\x46\ +\xcb\x90\xea\x49\xe4\xa8\xc6\x93\x5d\x7b\x61\x8b\x00\x2a\xb1\xa8\ +\x51\x8e\x85\xd3\xcb\xb5\xff\x81\x14\xf2\x71\x6d\x06\xa1\xed\x05\ +\xf0\x89\xb4\xf0\x11\x93\xfd\xa3\xbc\x94\x92\x62\x6d\xc2\xe9\xfd\ +\x74\xd1\x3e\x8f\x18\xf6\x5a\x83\x6e\xe1\x6c\xcc\xbd\xed\x1b\xdf\ +\xe3\x45\x9c\x2f\x12\x77\x91\xa4\x3f\x1b\xbe\xeb\x7b\x96\xeb\x59\ +\x5e\xf4\x83\x76\xea\x63\xca\x0a\x96\xab\x43\xc2\x1e\xb8\x24\xa8\ +\x91\xac\x04\x1a\xf3\x9c\x22\x21\xc8\x8e\xe4\xf0\xc0\xaa\x9a\x36\ +\x7b\x52\x7d\xdc\x42\xee\xe4\x88\xe6\x1f\x25\x63\xd4\xee\x11\x1d\ +\xb6\xc7\xc7\x9a\x71\x69\x1d\x8b\x1a\x70\x8d\x93\x59\xe5\xa9\x57\ +\x6e\x40\xbb\x2a\xf0\x4e\x28\xab\x36\x48\xf5\x04\x51\x26\xa6\xe1\ +\x68\xed\x70\x44\x75\xbe\xe2\x99\xe0\xc3\xd9\x76\x8b\x44\x0b\xa4\ +\x61\xd4\x68\x0f\x49\x47\x19\x5f\x9b\xf7\x3b\xfd\xe9\x14\x5b\xc6\ +\x0b\xcc\x7b\x55\xac\x3f\x13\x15\x03\x62\x88\x3c\xb5\xb5\xd2\xad\ +\xdd\x9f\x57\xad\x3a\xe8\xdd\x79\xbd\x78\x44\x05\x3b\xac\x4d\xff\ +\x52\xf9\x89\xb1\x72\x6d\x46\x76\x94\x2e\x52\xd7\xbb\x52\xe7\x47\ +\xe0\xd8\xb5\xe3\x85\x1f\x25\xe9\x95\x12\xf6\xf3\x3d\x3b\x71\x7d\ +\x3f\x0c\xaf\x94\x0d\xe7\x50\x87\x16\x45\x27\x0c\x41\xe9\x2f\xaf\ +\x33\x12\x8f\xec\xb0\xe7\x0a\x1c\xc9\x1b\x7c\xe9\xa9\x34\xd6\x76\ +\xcb\x8e\xf3\x6a\xc8\x82\x46\x55\xb8\xd5\x54\x44\x42\x15\xd5\xc7\ +\xf1\xaa\x0d\x29\xb0\x98\x77\x14\x15\xaa\xad\x3d\x65\x5b\x44\xe7\ +\x0d\x0e\xa4\x02\x90\xac\x2e\xe1\xbd\x60\xe0\xe0\xd2\xa2\xcf\xfe\ +\xc4\x7d\xc9\x02\xce\x7e\xc5\x43\xa7\x3a\xbd\xac\x2a\xd1\x91\x94\ +\xe4\x13\x06\x60\xbc\x2b\x54\x54\x64\x9f\x03\x0b\x67\x52\x57\x82\ +\xda\x66\xa3\x8d\x56\x13\x68\x5b\x3f\xc3\x90\x27\xd5\x0d\x8e\x27\ +\x25\x33\x7b\xa1\xe2\x44\x09\xfc\x34\x4d\x06\x21\xe3\x04\x6a\x6a\ +\x14\x52\x2f\x3a\x8d\x45\xaa\x77\x40\xff\x3e\xea\x1c\xd5\x19\x9c\ +\x5c\xea\x4e\x63\x5d\x57\x3a\xce\x75\xed\x68\x79\x89\x25\x2a\x90\ +\x44\xe7\x42\xea\x25\x70\xb6\x21\x32\x68\xc3\xd9\xef\x0f\xef\x36\ +\xdd\x46\xab\x3c\xcf\xfe\x64\xfc\xa9\xdf\xd7\x30\x94\x01\xda\xb2\ +\x06\xd8\x32\x37\x83\x78\x55\xe4\x19\x34\x4e\xe8\x1f\x1b\x52\x42\ +\x79\xa8\x9e\xfb\x13\x34\xca\x95\x73\x56\x4c\x8c\x15\x58\xe7\x45\ +\xdb\x65\x39\x6e\x3b\xf0\xec\x35\x54\xe4\x25\x51\x4e\xce\x7b\x49\ +\x28\xfd\x55\x6d\xd2\x45\x3c\x5a\x94\x48\x8a\xcf\xc2\x95\xd3\x9d\ +\xbe\x8b\xcd\x19\x05\xb7\x72\xfa\xe8\xf5\xd3\xfe\x8c\xca\xa4\xb0\ +\x06\xa2\x29\xda\x62\xc8\xf2\xdf\x94\xd2\xb8\xce\x25\xce\x9a\xba\ +\x64\x05\xee\xdc\x07\x34\x71\x2e\x07\xca\xe4\x89\x82\x7e\x07\xa7\ +\xcf\xee\xd3\x68\x81\x71\xb2\x54\x0f\x56\xd7\x6a\x32\xaf\x7d\xe4\ +\x0d\x85\x96\xf9\x8c\x2b\x56\x14\x4b\x21\x39\x7b\xc2\xd9\x3d\x8e\ +\xd5\x4f\xf7\xd8\x16\x54\xe6\xda\x69\x14\xba\xd1\x20\xa5\xa4\xc2\ +\x70\x9a\x4c\xfc\xdd\x20\x8e\xc7\xd2\xbf\x18\xa9\x32\x80\x0f\xf3\ +\x5e\xaa\x1f\x28\xd4\x86\xcc\xc2\x5e\x56\x20\x68\x6a\x9c\xa3\x53\ +\x56\xc1\x8c\x30\x96\xb2\xdd\x4e\x60\x99\xb9\xbd\x6c\x38\xf1\x24\ +\xcd\x55\xb0\xc1\x22\x88\xad\xc8\x0a\x06\x45\x57\xfb\x91\x1d\x04\ +\xe7\x6b\x4d\x7d\xfa\x92\xf7\xdb\xfb\x2e\x08\x07\x0d\x24\xbc\x1f\ +\xd8\xe1\x34\xe1\xdb\xce\x78\x61\xc9\x75\xbd\xf4\x84\xcf\xa1\xad\ +\x6f\x80\xec\xde\xd5\x9f\x65\x41\x44\x0d\xfc\xc0\xdd\xad\x50\x59\ +\x32\xb8\x34\x77\x94\x1d\xb2\x67\x22\xc8\x96\xe2\xa5\xfe\x26\x54\ +\x85\xd6\x8b\x5a\xba\xc2\x34\x0e\xe3\xed\xcb\x74\x01\x60\x9f\xe0\ +\x4e\x79\x95\x2e\xcf\xf6\x53\xa8\xb4\x28\x08\x2e\x09\xdb\x36\x52\ +\xfe\x27\x74\x2d\x4b\xc4\x9f\x30\x6f\x1d\x70\x85\x20\x40\x6b\x8b\ +\xf2\x27\x95\xbe\x55\x91\xa1\x1c\x3a\x5e\x43\x91\xc4\xd7\xbc\xba\ +\x5e\x7c\xc9\x69\xe0\x5f\x91\x39\x9d\x5e\x3a\x32\xaf\xbb\xd7\x69\ +\x4e\xa8\xc8\x0c\xed\xd8\x07\x6f\x6f\x94\x58\xaf\x4d\x18\x73\x06\ +\xc3\x94\xf1\x5a\x5a\xb4\xac\x16\x81\xfa\xf9\xfc\x22\xec\xec\x27\ +\xac\xfa\x76\xe8\xb9\x41\x1c\x84\xe1\xff\xaa\x0c\x93\xc5\x15\x5d\ +\xd7\x35\xd5\xb3\xe6\xc1\x3c\x32\xd5\x1c\xe7\x2a\x16\xf8\x09\x6c\ +\xff\x82\x2f\x28\xc7\x20\x85\xdc\x78\x0d\xed\x29\xb6\xff\x6a\xf3\ +\x8b\x92\xab\x6a\xfa\xd2\xed\xef\xc6\xd6\x17\xdb\xa1\x6e\x56\xde\ +\xad\xad\xef\xeb\x42\xdd\x8a\xbe\xc8\x95\x23\xf1\x71\xc0\x1d\xc6\ +\x9d\x4c\xbf\xef\xc1\x08\x0d\xa3\x0c\xe6\xcf\xe7\x3e\xda\xf7\x1d\ +\x06\xf3\xa4\xfe\x1b\xc2\x85\xa1\x88\x2e\xb5\xe4\xa0\x0f\x36\x11\ +\x09\x98\x5a\x33\xcf\xb7\x17\xf5\x71\xa9\xd0\xec\x46\xe4\xcc\xfd\ +\xae\xd5\xef\x50\x49\xe8\x29\x13\xa8\x12\x16\x6c\x45\x76\x4b\x8a\ +\x25\xc0\x6b\x75\x93\x61\xe6\x82\xe3\x01\x5e\x75\x26\x82\x36\x13\ +\xba\xdb\xf0\x22\x13\x3a\xde\xc7\x34\xf4\x17\x97\x7b\xd9\x1c\x92\ +\x16\xab\x8b\x96\x0e\x6f\x2e\x53\xb0\xf4\x0b\x09\x20\x04\x1d\x02\ +\x06\xcc\x95\x84\xa3\x54\xe7\xa1\x6f\x98\x53\x39\x53\xd8\xa8\x28\ +\xcd\xb3\x56\xfb\x2a\x07\x70\xf6\x47\xf2\xd9\xdd\x5f\xd8\x7f\x8a\ +\x7b\x87\xf2\x96\xd1\x62\x8c\xb1\x6e\x7e\xc9\x05\xcc\x70\x59\x47\ +\x2f\x01\x6d\xf5\x57\x8e\xd5\xae\x52\xe3\x7c\x78\x5b\xce\xde\xbc\ +\x07\x43\xe3\x17\xd8\xe3\xcd\x3c\x8a\x1b\xef\x47\x7f\xe5\xe8\xc8\ +\x36\xf0\x0d\xe8\x7c\xe5\xb3\xe2\xad\x0d\xd3\x0b\xed\x54\x4b\x6f\ +\x6d\x98\x5f\x05\xda\xc9\xed\x6d\xf2\x42\xa8\xd0\x8e\xed\x68\xba\ +\xc6\x37\xb4\x15\xda\xb7\xbe\x06\xcd\xcf\x02\xdf\xc0\x7e\xa1\x91\ +\xdc\x3c\x03\xcc\xb7\x92\xb8\x9d\x8e\x17\xb3\x78\xaf\x9c\xfd\xe6\ +\x6e\xa5\xfe\xdd\xb1\xb9\xfb\x07\xdb\x97\x10\x3f\ +\x00\x00\x06\x33\ +\x00\ +\x00\x4e\xa2\x78\x9c\xe5\x5c\xdd\x8f\xa3\x36\x10\x7f\xdf\xbf\x82\ +\xb2\x2f\xad\x2a\x9b\xcf\x24\xc0\x25\xb9\x87\xae\x4e\x3a\xa9\x4f\ +\xed\x55\x7d\x3c\x11\x70\x12\x6b\x01\x47\x86\x6c\x92\xfb\xeb\x3b\ +\xe6\x2b\x21\x61\xa5\x56\x06\x89\xad\x59\x9d\x56\xcc\x8c\x8d\xfd\ +\xe3\x37\xb6\x67\x86\xbd\xe5\xe7\x73\x9a\x68\x6f\x84\xe7\x94\x65\ +\x2b\xdd\xc2\xa6\xae\x91\x2c\x62\x31\xcd\x76\x2b\xfd\xaf\x6f\x5f\ +\x90\xa7\x6b\x79\x11\x66\x71\x98\xb0\x8c\xac\xf4\x8c\xe9\x9f\xd7\ +\x4f\xcb\x9f\x10\xd2\x7e\xe3\x24\x2c\x48\xac\x9d\x68\xb1\xd7\xbe\ +\x66\xaf\x79\x14\x1e\x88\xf6\xf3\xbe\x28\x0e\x81\x61\x9c\x4e\x27\ +\x4c\x6b\x21\x66\x7c\x67\xfc\xa2\x21\xb4\x7e\x7a\x5a\xe6\x6f\xbb\ +\x27\x4d\xd3\xe0\xb9\x59\x1e\xc4\xd1\x4a\xaf\x1b\x1c\x8e\x3c\x29\ +\x0d\xe3\xc8\x20\x09\x49\x49\x56\xe4\x86\x85\x2d\x43\xbf\x9a\x47\ +\x57\xf3\x48\x3c\x9d\xbe\x91\x88\xa5\x29\xcb\xf2\xb2\x65\x96\x3f\ +\xdf\x18\xf3\x78\xdb\x5a\x8b\xd1\x9c\x9c\xd2\xc8\xf2\x7d\xdf\x30\ +\x6d\xc3\xb6\x11\x58\xa0\xfc\x92\x15\xe1\x19\x75\x9b\xc2\x18\xfb\ +\x9a\xda\xa6\x69\x1a\xa0\xbb\x5a\xfe\x3b\xab\x20\x07\x40\x0f\xf0\ +\xaf\x35\x6f\x04\x38\x67\x47\x1e\x91\x2d\xb4\x23\x38\x23\x85\xf1\ +\xf2\xed\xa5\x55\x22\x13\xc7\x45\x7c\xd3\x4d\x83\x67\xe7\xa9\x1d\ +\x90\xb3\x30\x25\xf9\x21\x8c\x48\x6e\x34\xf2\xb2\xfd\x89\xc6\xc5\ +\x7e\xa5\x3b\x2e\xb6\x1c\xb8\x66\xa5\x70\x4f\xe8\x6e\x5f\xdc\x4b\ +\x69\xbc\xd2\x61\xf4\xb6\xef\x55\xf7\x37\xe4\xb0\x2a\x83\xba\xe3\ +\xa0\xd5\x98\xd8\xb7\xb1\xa5\x71\x6b\xe6\x2c\x2a\x9b\x66\x0a\x41\ +\xcc\x22\x31\x26\xe8\x92\xa4\x34\x3c\x16\x2c\x85\xb7\x16\x45\x49\ +\x98\xe7\x74\x4b\x23\xb8\x61\xd9\x21\x39\xee\x68\xf6\xbd\x2b\xfc\ +\x9e\x53\xf2\x46\x70\x83\x63\xfb\x50\x72\x3e\x30\x5e\xa0\x73\x7c\ +\x00\x34\xe7\x8b\x5e\xe5\xa5\x51\xae\x41\xbb\x8c\xc9\x36\x17\x56\ +\xd5\xd4\xc4\x1d\xcc\x6d\xa1\x6b\x46\xa9\x6d\x47\x2a\x86\x19\xbf\ +\x51\x72\xba\xda\x6e\xc2\xbc\x82\x4f\xd3\x0e\xe1\x0e\xa8\x96\x30\ +\xbe\xd2\x9f\xb7\xe5\x55\x2b\x36\x8c\xc7\x84\x37\xaa\x79\x79\x75\ +\x54\x0c\x5e\x07\x2d\x2e\x95\x73\xd5\x7d\x37\xe3\x15\xbd\xb6\x7a\ +\xb3\x5f\x9f\xef\xc3\x98\x9d\x56\xba\x7d\xaf\xfc\xc1\x58\xba\xd2\ +\x67\x78\xe6\x7b\xbe\x69\xdd\x6b\xa3\xf3\x4a\x47\xb3\x05\xf6\x7c\ +\xd7\xf7\x1f\xb5\xf0\x3c\xd7\xc6\xee\xc2\xb4\xe7\x8f\xca\x23\xe7\ +\xe0\x7d\x28\x09\x2f\x04\x26\x55\xfe\x6a\x8c\xf2\x3d\x3b\xed\xb8\ +\x00\xa7\xe0\x47\x72\xdf\x52\x68\xd0\x66\xc3\xce\xfd\x6a\x20\xc3\ +\x51\xf8\x35\x3a\x66\xb4\x00\xdf\x39\x9c\x6f\x7b\x3d\xd2\x98\xe4\ +\xfd\x0d\xf3\x2c\x3c\xa0\x5d\xc2\x36\x61\xd2\x6f\x70\xa2\x19\x80\ +\x84\x6a\x9a\x5b\x4e\xfb\x0e\xee\x2d\x1a\xce\x2f\x4c\xef\x1d\x0b\ +\x18\xfb\xc3\x7b\xa8\x55\x97\xf7\x55\x69\x78\xa6\x29\xfd\x41\x00\ +\x18\xab\xa4\x1d\x50\xab\x03\x4b\xd5\x4c\xd3\x8a\x8b\xf0\xdf\xf3\ +\x45\xc8\xf4\x46\x28\xf0\x14\x02\xdb\xf7\x17\xad\x90\x71\x0a\x6e\ +\x71\x33\x9c\x46\x74\xb9\x15\x09\x6f\x87\xc5\xfa\x5c\xf2\xab\x64\ +\xdf\xe2\x5e\x77\xb9\xd5\xd5\xb4\x37\x1e\x79\x5f\xca\x53\x52\x84\ +\x71\x58\x84\x57\x27\x68\x24\x30\x36\xb3\x99\x19\x2c\x9c\xc1\x1f\ +\x2f\x5f\xd6\xf5\x83\x96\x51\x14\xfc\xcd\xf8\x6b\xf3\x5c\x4d\x13\ +\x06\xe1\x86\x1d\x01\x69\x7d\xdd\x8a\x97\x71\x14\xc0\x52\x07\x4b\ +\xc0\x9a\xa6\x40\x6d\xb1\x4a\xfe\x0a\x4b\xdb\xd2\xb8\x2a\x3a\xc6\ +\x02\xac\x6b\xa7\x55\xb7\x9c\x54\x6b\x66\xef\xc6\x11\x47\x29\x15\ +\x8d\x8c\x3f\x0b\x9a\x24\x5f\xc5\x43\xea\x19\xdf\x74\x4a\x8b\x84\ +\x5c\x85\x4b\xa3\x1e\x7d\x3d\x37\xe3\x66\x72\x4b\xa3\x99\x7d\x79\ +\xb7\xbb\xa2\xd2\x71\x8a\xf6\x45\x27\xe1\x86\x00\x43\x7f\x17\x4a\ +\xed\x41\xbb\xe3\xec\x78\x48\x59\x4c\xea\xe6\x2d\x9a\x24\x2a\xda\ +\x57\x56\x5c\x12\xd0\x6f\x61\xf4\xc1\xb3\x69\xba\xfe\xc6\xfe\x24\ +\x6e\x50\xbd\x4c\x04\x56\x75\xcb\x8f\x09\x2c\x77\x6f\x24\x63\x71\ +\xfc\x29\x2f\x38\x7b\x25\xc2\x5e\x5c\xf5\x6d\xe5\x0c\x81\x89\x5d\ +\xc7\x77\xc5\xbb\x6f\xe4\x80\x10\xe1\x09\xb0\xb5\x08\xdc\x46\x16\ +\x87\xb0\xcc\x70\x1e\x5e\x82\x0c\xb6\xf9\x46\xda\x3e\xb3\x43\x54\ +\x31\xdc\x99\xe7\xf8\xc8\x42\x5e\xab\xa8\x3d\x6f\x86\x1d\xe7\xba\ +\x95\x88\xab\x71\x38\x17\xfb\xa5\xc6\x6d\x35\x82\xb2\x26\xbe\xa3\ +\x2c\x70\xd5\xc1\x5e\x67\x19\x85\xd7\xde\x71\x02\x5e\xf2\x79\xee\ +\x8a\x6b\xde\xbe\xdd\xf7\x51\xdc\x38\xe2\x67\xca\x28\x22\x6b\x0c\ +\x1c\xd1\xe3\x82\x20\x07\xe4\xf4\xe9\x88\xfc\x31\x80\xb4\x1c\xbc\ +\xe8\x5a\xca\xe1\x28\x4e\x0f\x80\xcb\x94\x71\xb4\xd0\x6c\x0c\x24\ +\x3d\xec\x95\x73\xb1\xd5\x41\x72\x31\x06\x8e\xb6\x83\x87\x5a\x1d\ +\x3f\x80\x53\x03\x19\x47\x61\xa3\xe5\x61\xd5\x36\x1a\x7f\x1c\x3e\ +\x3a\x0e\x76\x15\xdb\x69\x80\x94\xc8\x1c\xc5\xb7\x3d\x3c\x2b\x4d\ +\x95\x60\xa5\x24\x82\x66\x87\x85\x03\x1f\x1c\xa7\xce\x42\x49\xec\ +\x1e\xcd\x55\x3c\x7c\xbb\x63\xa0\x38\xf8\xd1\x7b\xe2\x30\xca\xc6\ +\x81\x1d\x37\x1e\xfa\xb8\x3d\x75\x37\x46\x9e\x2c\x7c\xbd\x1c\x1c\ +\x1a\xc6\x89\x53\xd0\x94\xf6\xe4\x0e\x09\x87\x8e\x54\x26\x4f\x42\ +\x17\xd9\x63\xb0\x70\x68\x1c\xa7\xce\x42\x67\x48\x12\xaa\x14\xe6\ +\xcd\xc7\x60\xdf\x80\x00\x4e\x9d\x78\xd2\x81\x5d\x77\x0f\x1e\x38\ +\x34\x9e\x3c\xfd\xdc\x71\x08\xa8\x5e\x8a\x41\x3e\x99\xdd\x1f\x97\ +\x0c\x9c\x61\x98\x38\x90\x70\x9a\x91\xc6\xb1\xbb\x95\x0c\x9c\x55\ +\xf8\x00\x0e\x6d\x4b\x2f\x89\xfd\x7b\x8a\x52\xf9\x99\x8a\x89\xc3\ +\x9e\xad\x55\xf4\x65\xe9\xd3\x75\x07\x41\xd5\xf2\x0b\x22\xe1\xea\ +\xca\x72\xd0\x9e\xdf\xef\xc5\x65\xbe\x6b\xe1\x28\xe4\xcd\x55\xe6\ +\x5a\x76\x5d\xec\x45\x12\x38\xa9\x48\x90\x57\x15\x52\x64\x93\xff\ +\xbd\x20\x5a\xca\x04\x2c\x4d\x0d\x45\xb6\xb2\xd7\x0b\xa3\x77\x5f\ +\x57\xf9\x9f\x1f\x76\x3c\xb4\x90\xde\x60\x7a\x81\xb4\x95\x2c\xec\ +\xcd\x90\x29\x1b\x0d\xf6\x7b\xb7\x5a\x47\xc7\xba\xe0\x3c\x0e\x33\ +\xe1\x10\x59\x5a\x2a\x93\xa0\xad\x4b\xce\xd2\x47\xf1\x7e\x3f\xf7\ +\xb0\x22\xe5\x16\xe9\xef\x1f\xd4\x3e\x3e\x4a\xfb\xb2\x85\xef\x84\ +\x2a\xa2\xe8\x22\x5b\xb6\xe6\xd7\x0b\xe4\x80\x67\xf0\x89\xbb\xb1\ +\x87\x64\x2b\x2d\x96\xba\x07\x6f\x79\xf0\x7a\xd9\x37\x20\x86\x13\ +\x67\x5f\x99\xd2\x71\xa5\xbf\x7e\x1f\x33\x66\x99\x3c\x0b\x45\x82\ +\x76\x94\x45\x50\xad\xe0\xcf\x74\x06\x3e\xd2\x0c\x1d\xf2\x4d\xfe\ +\x1b\xed\xb9\x7c\x0e\xa2\x8f\x86\x8a\x85\xce\x26\x04\x7a\xc3\x2e\ +\x88\x43\x47\xcb\x13\x07\xb0\xac\x41\x23\x47\xb6\xea\xd7\xbf\x33\ +\x2b\x97\x78\x10\xd1\xb2\x2f\x9d\xa2\xed\x0d\x56\xd4\x4a\x3c\x54\ +\xd5\x2b\x6f\xd8\xd3\xb6\x3a\xe9\x86\xba\x10\x2d\x5d\xcc\xef\xdf\ +\x62\x86\x83\x71\xe2\x1e\x5d\x57\xa1\xe5\xff\x2a\x6d\xd4\x1c\xe2\ +\x87\x00\xd1\x46\xbe\x6c\x72\xdb\x52\xb8\xf0\xe7\xca\x7f\x28\x7b\ +\xc3\x37\x15\x93\x5f\x65\x05\x5a\xfa\x73\xbb\x2e\x88\x6a\x71\x50\ +\xb8\xb2\xec\x59\xbb\x8b\x9f\x52\xe9\xaf\xaa\xee\x2c\xbd\x25\x77\ +\x11\x54\x2d\x7d\x53\x96\x9c\xa5\x53\x0f\x5d\x0c\x87\x0e\x99\x3f\ +\x00\x88\x75\xb5\x79\xe0\x3d\x45\xbd\x78\xaf\x2a\x34\x4b\xe7\xb5\ +\xef\xb6\x66\xb5\xce\x87\x37\x35\x66\xe9\x2a\xf3\x9d\x63\xff\xb7\ +\x40\x65\x69\xec\xd6\x4f\x4b\xf1\xbf\x03\xad\x9f\xfe\x01\xed\x59\ +\x64\x2c\ +\x00\x00\x0c\x67\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x73\x70\x6c\x69\x74\ +\x5f\x72\x61\x73\x74\x65\x72\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\ +\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x2d\x36\x36\x2e\x34\x38\x32\x37\x34\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x35\x2e\x31\x34\x39\x30\x32\x30\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\ +\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\ +\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ +\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ +\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ +\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x23\x30\x30\x35\x35\x64\x34\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x39\x31\x31\x36\x30\ +\x36\x37\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ +\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ +\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\ +\x39\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x37\x2e\ +\x38\x38\x32\x31\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x3d\x22\x34\x32\x2e\x38\x35\x36\x30\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x79\x3d\x22\x35\x38\x2e\x35\x30\x31\x32\x35\x35\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\ +\x30\x36\x38\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x32\x2e\x37\x30\x35\x35\x37\x38\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\ +\x61\x74\x72\x69\x78\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\ +\x2c\x2d\x30\x2e\x37\x39\x31\x31\x33\x38\x38\x2c\x2d\x30\x2e\x30\ +\x39\x31\x33\x30\x32\x37\x38\x2c\x30\x2e\x39\x39\x35\x38\x32\x33\ +\x31\x38\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\ +\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ +\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\x2c\x2d\x30\x2e\x37\ +\x39\x31\x31\x33\x38\x38\x2c\x30\x2e\x30\x30\x32\x38\x38\x31\x37\ +\x34\x2c\x30\x2e\x39\x39\x39\x39\x39\x35\x38\x35\x2c\x30\x2c\x30\ +\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\ +\x38\x39\x31\x37\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\x37\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x33\x32\x2e\x30\x32\x36\x37\ +\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x38\ +\x2e\x39\x35\x36\x30\x36\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x39\x2e\x31\x31\x32\x33\x34\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x32\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x23\x30\x30\x61\x61\x30\x30\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x37\x32\x32\x37\x33\ +\x32\x33\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\ +\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ +\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x66\x66\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x32\x2e\x35\x39\x33\x33\x33\x30\x33\x38\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\ +\x31\x2e\x33\x31\x36\x39\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x34\x39\x31\x33\ +\x33\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x31\x2e\ +\x34\x35\x36\x37\x38\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x3d\x22\x31\x30\x2e\x33\x37\x38\x31\x39\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x35\x34\x30\x36\x38\ +\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ +\x2e\x31\x30\x30\x33\x35\x33\x35\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\ +\x69\x78\x28\x30\x2e\x36\x31\x31\x36\x33\x36\x36\x36\x2c\x2d\x30\ +\x2e\x37\x39\x31\x31\x33\x38\x38\x2c\x30\x2e\x30\x38\x35\x30\x35\ +\x32\x34\x36\x2c\x30\x2e\x39\x39\x36\x33\x37\x36\x34\x37\x2c\x30\ +\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x3d\ +\x00\ +\x00\x54\xb5\x78\x9c\xe5\x9c\x4b\xaf\xa3\x36\x14\xc7\xf7\xf7\x53\ +\x50\x66\xd3\xaa\x63\x30\xaf\xf0\x98\x24\xb3\xe8\xa8\x52\xa5\xae\ +\xda\xa9\xba\xac\x1c\x70\x12\x3a\x04\x23\x20\x37\x49\x3f\x7d\x6d\ +\x5e\x81\xe0\x3b\xed\xc8\x8e\x64\x25\x91\x46\x23\x7c\x8e\xc1\xfc\ +\xf0\xb1\xff\x1c\xfb\xb2\xfc\x78\x3e\x64\xda\x2b\x2e\xab\x94\xe4\ +\x2b\xdd\x32\xa0\xae\xe1\x3c\x26\x49\x9a\xef\x56\xfa\x1f\x9f\x7f\ +\x06\x81\xae\x55\x35\xca\x13\x94\x91\x1c\xaf\xf4\x9c\xe8\x1f\xd7\ +\x2f\xcb\xef\x00\xd0\x7e\x2a\x31\xaa\x71\xa2\x9d\xd2\x7a\xaf\xfd\ +\x92\x7f\xa9\x62\x54\x60\xed\xfb\x7d\x5d\x17\x91\x69\x9e\x4e\x27\ +\x23\xed\x0a\x0d\x52\xee\xcc\x1f\x34\x00\xd6\x2f\x2f\xcb\xea\x75\ +\xf7\xa2\x69\x1a\xbd\x6e\x5e\x45\x49\xbc\xd2\xbb\x0a\xc5\xb1\xcc\ +\x1a\xc7\x24\x36\x71\x86\x0f\x38\xaf\x2b\xd3\x32\x2c\x53\xbf\xba\ +\xc7\x57\xf7\x98\x5d\x3d\x7d\xc5\x31\x39\x1c\x48\x5e\x35\x35\xf3\ +\xea\xdd\xc8\xb9\x4c\xb6\x83\x37\x6b\xcd\xc9\x69\x9c\xac\x30\x0c\ +\x4d\x68\x9b\xb6\x0d\xa8\x07\xa8\x2e\x79\x8d\xce\x60\x5a\x95\xb6\ +\x91\x57\xd5\x86\x10\x9a\xd4\x76\xf5\xfc\x7f\x5e\x51\x45\x81\x16\ +\xf4\xdf\xe0\xde\x17\x18\x15\x39\x96\x31\xde\xd2\x7a\xd8\xc8\x71\ +\x6d\x7e\xfa\xfc\x69\x30\x02\x68\x24\x75\x32\x3a\x4d\xcf\x73\x72\ +\xd5\x09\xe4\x1c\x1d\x70\x55\xa0\x18\x57\x66\x5f\xde\xd4\x3f\xa5\ +\x49\xbd\x5f\xe9\x8e\x6b\x58\x0e\xfd\x79\x4d\xe1\x1e\xa7\xbb\x7d\ +\x7d\x5b\x9a\x26\x2b\x9d\xb6\xde\x0e\x83\xf6\x78\xd4\x39\xac\xd6\ +\xa1\x3b\x71\x34\x58\xa0\x11\xda\x86\xa5\x95\x96\xe7\xf8\xad\x4f\ +\x7f\x0b\x51\x42\x62\xd6\x26\x7a\x4a\x7c\x48\xd1\xb1\x26\x07\xfa\ +\xd4\xe2\x38\x43\x55\x95\x6e\xd3\x98\x1e\x90\xbc\xc8\x8e\xbb\x34\ +\xff\xab\x28\xf1\x6b\x8a\x4f\x46\x8f\x6e\xb8\x0e\x3e\x17\xa4\xac\ +\xc1\x39\x29\x28\xc0\x85\xcf\x35\x5e\x7a\xe3\x9a\x5a\x97\x09\xde\ +\x56\xcc\xab\xbd\x1b\x76\x44\x6f\xc7\xd7\x35\xb3\xb1\x0e\x8d\x63\ +\x2d\x4b\xd8\x35\xaf\xbe\x1b\x54\xb5\xc4\x34\xad\x40\x3b\xda\xbb\ +\x32\x52\xae\xf4\x77\xdb\xe6\xd7\x19\x36\xa4\x4c\x70\xd9\x9b\x16\ +\xcd\x6f\x62\x22\xf4\x09\xa4\xf5\xa5\x8d\xa7\xee\xdc\x7d\x7b\xd9\ +\x59\x07\x3b\xe4\xdb\xab\x3d\x4a\xc8\x69\xa5\xdb\xb7\xc6\x7f\x08\ +\x39\xac\x74\xdf\x08\xad\x00\xba\x96\x7f\x6b\x8e\xcf\x2b\x1d\x38\ +\x8e\x61\x3b\xd0\xf7\x9c\x99\x95\x35\xc8\x35\x1c\x3f\x70\xec\xd9\ +\x99\xe3\x63\x59\xd2\x88\x03\x19\xba\x60\x7a\x57\xcd\x7f\x56\xe7\ +\x54\xed\xc9\x69\x57\x32\x3a\x75\x79\xc4\xb7\x35\x99\x05\x6c\x36\ +\xe4\xcc\x37\xd3\x0e\x70\x64\xb1\x0c\x8e\x79\x5a\xd3\x78\x29\xce\ +\xe3\xb3\x1e\xd3\x04\x57\xfc\x8a\x55\x8e\x0a\xb0\xcb\xc8\x06\x65\ +\x7c\x87\x53\x9a\x53\x4a\xa0\xeb\xda\x96\x33\x3c\x84\x5b\x8f\xbe\ +\x9f\xfb\x30\x78\xc3\x83\xb6\x7d\xf6\x20\x3a\xd3\xe5\x6d\xd3\x01\ +\x9d\xd3\x43\xfa\x0f\xa6\x60\xac\xa6\xdf\xd1\xbe\x35\xc1\xd2\x56\ +\xd3\xb4\xfa\xc2\x62\xf6\x7c\x61\x65\x7a\x5f\xc8\x78\xb2\x02\x3b\ +\x0c\xfd\xa1\x90\x94\x29\x0d\x85\x51\x73\xfa\xa2\xcb\xb8\x88\x45\ +\x38\x1d\xa0\xcf\x4d\x07\x6b\xba\x9f\x7f\x6b\xbb\x8c\x6d\x5d\xbf\ +\x37\xe7\x1d\xbf\x29\x3f\xe0\x1a\x25\xa8\x46\xd7\x28\xe8\x4b\x68\ +\xdb\x60\x7f\x67\x74\xb0\x8c\x7e\xfb\xf4\xf3\xba\xbb\xd0\x32\x8e\ +\xa3\x3f\x49\xf9\xa5\xbf\xae\xa6\x31\x07\xb4\x21\x47\x4a\x5a\x5f\ +\x0f\xc5\xcb\x24\x8e\xe8\xf0\x46\xc3\x7e\x9d\x1e\x68\xdf\x66\x23\ +\xe3\x8f\x74\x38\x5b\x9a\x57\xc3\xc4\x99\xc1\xba\x9e\xb4\x3d\x6d\ +\x89\xdb\x71\x92\x3b\x59\x24\xf1\x21\x65\x95\xcc\xdf\xeb\x34\xcb\ +\x7e\x61\x17\xe9\xee\x78\x74\xd2\xb4\xce\xf0\xb5\x70\x69\x76\xad\ +\xef\xee\xcd\x1c\xdd\xdc\xd2\xec\xef\xbe\x39\xda\x5d\xa9\x4c\x82\ +\x62\x78\xd0\x19\xda\x60\xda\x43\x7f\x65\x46\x6d\x66\xdd\x95\xe4\ +\x58\x1c\x48\x82\xbb\xea\x03\x4d\x1c\xd7\xc3\x23\xab\x2f\x19\xb5\ +\x6f\x69\xeb\xa3\x77\x10\xc6\xf1\x76\xfb\x81\x1d\x80\x6e\x9c\x88\ +\xac\xf6\xb0\x3c\x66\x74\xbc\x7b\xc5\x39\x49\x92\x0f\x55\x5d\x92\ +\x2f\x38\xea\x46\xa6\xee\xb0\x0d\x86\x08\xf6\x87\x14\x0c\x2e\x33\ +\xda\x49\xeb\xc8\xed\xcb\x12\x44\x87\x97\xb2\x44\x97\x28\xa7\x33\ +\x7a\x5f\x3a\x5c\x6a\xd2\x3f\x59\x2b\xbd\xc0\x09\x87\xc2\x2e\xd8\ +\x5c\xc3\x6e\xba\xd6\xd5\xd0\xc7\xd8\xdc\x32\xe9\xcc\x17\x9e\x47\ +\x39\x71\x29\x9b\xae\xeb\xda\xec\xe7\x0c\x0f\xf2\x6b\xc0\x10\x4a\ +\x5c\xc5\x80\x01\x4b\x10\xd9\xbc\xf0\x2e\xe8\x16\x8b\x00\x2a\x87\ +\x0e\x04\x82\xf0\x02\xc3\x63\x7a\xc6\x09\xee\x0b\xcf\x75\x3d\x4f\ +\x3d\x78\x50\x10\x9e\x65\x1b\x77\xe5\xb6\xdd\xda\xc8\x46\xca\x71\ +\x73\x44\xb1\xf9\xed\x74\xfb\x8c\xec\x80\x2f\x08\xcf\xb6\x8c\x26\ +\x60\xdd\x67\x84\x17\x00\x4f\x14\x9f\x67\x2c\x9e\x91\x1c\x04\xa2\ +\x51\x6b\x87\x46\x30\xd5\xcf\xcf\xa3\x50\x80\x2b\x08\x8f\xab\x51\ +\xa0\x34\x68\x8a\x6a\x13\x61\x69\xc7\x55\x27\xf2\xb0\x29\xaa\x4a\ +\x84\xe7\x88\x5b\x5d\x22\x8b\xd8\x76\x1b\x86\x0a\x12\x73\xc0\x42\ +\x14\x18\x4f\x91\x3c\x38\x35\xe0\x03\x5b\x10\x1b\x57\x8b\x3c\x3a\ +\x36\xaa\x41\x80\xe8\x5b\xfe\xad\x0a\x91\x37\xa4\x29\x98\x11\x11\ +\x7e\x47\x9d\xe4\x44\x26\x63\xdb\x63\x8a\x8d\x40\x14\x18\x57\x6d\ +\x48\x05\xa7\xaa\xe0\x10\x0d\x4c\xae\xe0\x90\x4a\x4e\x55\xcd\x21\ +\x3c\x85\xde\x68\x0e\x89\xd0\x02\xc8\x7e\xca\x41\x73\x84\xe7\x4f\ +\xae\xec\x78\x7c\x70\x54\x79\x08\xbf\x8c\xf2\x94\xc7\x13\x90\x63\ +\xe2\x43\x74\x76\xb8\x15\x1f\x4f\x80\x0d\x02\x47\x3c\xf1\xc6\xcb\ +\x7f\x48\x9d\x1a\x54\xd4\x6e\x50\x38\xf5\x31\x51\x6f\xf3\xf9\xf5\ +\x31\x25\x9c\x2b\x3c\x37\x70\x35\x9c\x7c\x7c\xaa\x0a\x39\x4b\x38\ +\xd3\xcb\x95\x72\xf2\x01\xaa\xaa\xe7\x7c\x61\x2d\x7c\xab\xe8\x64\ +\xb3\x4b\x5c\x25\x27\x0b\x07\x2c\xee\x23\xec\x9e\x84\x1f\xcb\x2b\ +\xdd\x67\x95\xeb\x59\x00\x36\x19\x26\xe1\xc5\xe9\x5b\x99\xf7\x2c\ +\xf4\x98\xd6\xb3\x85\x57\x1e\xb8\x6a\x4f\x36\x42\x36\xf9\xaa\x87\ +\x10\x8a\xbe\x9c\x4d\x14\xdf\x3c\x92\x1f\x91\x99\x25\x9c\x3f\xe1\ +\xea\xbd\x67\x81\x17\x08\x4f\x18\x5c\xb5\xf7\x2c\xf8\xa0\x70\x4e\ +\xe0\x56\xeb\xc9\x26\x07\x21\x7d\x34\xea\x91\xa3\x33\x85\xf0\x5a\ +\x2b\x4f\xea\xc9\xc7\xe7\xba\x48\xc1\x5d\x25\xbe\xf8\x7e\x1c\x9e\ +\xd0\x93\x8d\xcf\x46\xfe\x56\xbd\xd4\x4a\x2b\xf4\x84\x33\xa1\x37\ +\x32\x4f\x36\xbb\xc0\x47\x28\xc1\xea\xb1\x6b\x52\x7a\x77\xd9\xd3\ +\x24\x9b\x20\xcb\x10\xa8\x37\x6b\x88\xef\x32\x99\x2e\xcb\xce\x86\ +\xc1\x47\x84\xc6\x12\x7b\x77\x11\x7a\xcf\x82\xaf\x49\xec\xdd\x25\ +\xb3\xf7\x2c\x04\x59\x66\x4f\x34\x25\x3f\x5b\xab\x95\xcc\x4e\x59\ +\xb5\xb7\x10\xd6\x2b\xfc\x25\x5b\xe9\xfc\x54\x95\x7b\xb6\xf0\xf0\ +\xc7\x5f\xb9\x95\x0c\x50\x65\xc1\x17\x4a\x97\x7c\xb2\xe9\xa9\x2c\ +\xf9\x6c\xf1\xbc\x28\x77\x1d\x57\x32\xc2\x4d\x9c\x38\x9e\x8a\x1d\ +\x50\x7c\x4f\x36\x3f\x51\x35\x83\xfa\xa0\xfc\x68\xf8\xde\x27\x55\ +\xf5\x24\x00\x21\x9d\x83\x65\x6f\x35\x93\xcd\x4e\x59\xf9\x62\xdf\ +\x47\xbe\xc8\xe7\xa7\xaa\x7c\x71\x84\xa5\x33\x3f\x5f\x25\x19\xa0\ +\xca\xf2\x45\xfe\x9f\xe0\xc9\xa6\x17\x04\x08\xa9\xf7\xe6\x06\x81\ +\x2b\x3c\xf5\x4e\x17\xd6\xc6\x18\x1f\x91\x58\xb3\x8b\x4a\x78\xb6\ +\xe5\xcb\x95\xc7\x67\xd7\x64\x5a\x84\xc5\x32\x5f\xab\x3c\x3e\xbd\ +\x66\xff\x94\xf0\x8b\xda\x4c\xa8\xc8\x03\xa7\xac\x46\x59\x48\x78\ +\x45\xe3\xab\x14\x99\xf0\x54\x15\x28\x74\xbc\xbb\xcf\xde\x29\x89\ +\xf4\x54\x56\x27\x6c\x9e\x95\xbd\x71\x4a\xe6\x70\xa7\x74\x66\xc5\ +\xba\xcf\xae\xa9\x6f\xe7\x57\xa0\x7a\xcf\xe5\xd7\x7d\x5d\xe1\x6b\ +\x78\x1c\xc3\x76\x21\xf4\x16\xd0\x2d\xce\xbd\x25\x4b\x73\x1c\xa3\ +\x22\xda\x1c\xeb\x7a\x5c\xf6\x37\x49\xf3\xa8\xc1\xf8\x36\x29\xf6\ +\x89\x2f\xad\x1f\x90\xfc\xf7\x81\x11\x86\xbe\x6f\xc1\x50\x8b\x35\ +\xf8\xde\x0a\x0d\xbb\xf9\x93\x07\xeb\xed\x83\x09\x73\x76\x67\x8e\ +\xbf\x08\x47\xef\xc0\xd7\xef\xca\x91\x9c\x36\xb3\x26\x25\x88\x8f\ +\xe5\x2b\xaa\x8f\x25\x66\xac\xfe\x9b\x4a\xb7\x54\xf1\x75\x2a\x5e\ +\x10\xc2\xd0\xb3\x6c\x89\x54\x7c\xc3\x5d\xb4\x54\xac\xa0\xfd\x2c\ +\xa2\x43\xa9\x0c\x77\xee\xbc\x87\x6f\x1f\xcc\xa9\x04\xae\xff\xed\ +\x4c\xde\x8a\xb4\x51\xef\x67\xc3\x7d\xb3\x53\x71\x02\xc4\x36\x2c\ +\xdf\x83\x96\x1d\x38\x32\xc3\xc9\x0e\xc3\xd9\xae\x6b\xc7\x9e\xc5\ +\xce\xa8\x88\xfb\x61\xba\x0b\xaf\x90\x45\x8e\x47\x47\x76\xe8\x8c\ +\xbf\xb6\x41\x5d\x1d\x23\x80\x6e\xe0\x07\xde\xf0\xf1\xba\xdd\xfa\ +\x65\xc9\x3e\x1e\xb7\x7e\xf9\x17\x80\x2a\x7a\x3f\ +\x00\x00\x06\xf6\ +\x00\ +\x00\x20\xf9\x78\x9c\xdd\x59\x59\x93\x9b\x46\x10\x7e\xf7\xaf\xa0\ +\xb4\x2f\x49\x45\xc0\x5c\xcc\x81\x57\xce\x8b\x2b\x47\x55\xf2\x92\ +\x38\xc9\xa3\x0b\xc1\x48\x4b\x8c\x18\x65\x40\x2b\xc9\xbf\x3e\x3d\ +\x20\x0e\xad\x58\x27\x6b\x2b\x89\xb3\xa8\xb6\x04\xdd\x3d\xd7\xd7\ +\xdd\x5f\x37\xda\xdb\xaf\x0f\x9b\xc2\xbb\xd7\xb6\xca\x4d\xb9\x98\ +\xe1\x00\xcd\x3c\x5d\xa6\x26\xcb\xcb\xf5\x62\xf6\xcb\x9b\x6f\x7c\ +\x39\xf3\xaa\x3a\x29\xb3\xa4\x30\xa5\x5e\xcc\x4a\x33\xfb\xfa\xd5\ +\x8b\xdb\xea\x7e\xfd\xc2\xf3\x3c\x18\x5c\x56\x71\x96\x2e\x66\x77\ +\x75\xbd\x8d\xc3\x70\xbb\xb3\x45\x60\xec\x3a\xcc\xd2\x50\x17\x7a\ +\xa3\xcb\xba\x0a\x71\x80\xc3\xd9\x60\x9e\x0e\xe6\xa9\xd5\x49\x9d\ +\xdf\xeb\xd4\x6c\x36\xa6\xac\x9a\x91\x65\x75\x33\x32\xb6\xd9\xaa\ +\xb7\xde\xef\xf7\xc1\x9e\x36\x46\x58\x29\x15\x22\x12\x12\xe2\x83\ +\x85\x5f\x1d\xcb\x3a\x39\xf8\xe7\x43\x61\x8f\x53\x43\x09\x42\x28\ +\x04\xdd\x60\xf9\xf7\xac\xe2\x0a\x50\xd9\xc2\x5f\x6f\xde\x09\x82\ +\xca\xec\x6c\xaa\x57\x30\x4e\x07\xa5\xae\xc3\xd7\x6f\x5e\xf7\x4a\ +\x1f\x05\x59\x9d\x8d\xa6\xc9\xcb\x77\x55\x9a\x6c\xf5\xd9\xaa\x9d\ +\xb0\x45\x20\xd9\xe8\x6a\x9b\xa4\xba\x0a\x3b\x79\x33\x7e\x9f\x67\ +\xf5\xdd\x62\x46\x59\x80\x29\x5c\x51\x23\xbc\xd3\xf9\xfa\xae\x7e\ +\x28\xcd\xb3\xc5\x0c\x76\x4f\x94\x6c\x9f\x47\x1e\xc6\xad\xc1\x69\ +\xe2\x78\xec\xfb\x80\x78\x5f\x68\xc9\x53\x29\x90\x14\x6a\xee\x11\ +\x44\xb0\x8f\xb0\x8f\xa3\x2f\x9b\x41\xdd\x99\xe2\xcc\xa4\x6e\x93\ +\xb0\x86\xde\xe4\xc9\xae\x36\x1b\x70\x63\x9a\x16\x49\x55\xe5\xab\ +\x3c\x85\x07\x53\x6e\x8b\xdd\x3a\x2f\xdf\xea\xc3\xd6\xd8\xfa\x6d\ +\xb5\xd5\x69\x6d\x93\xe2\x6d\x91\x2f\x6d\x62\x8f\x41\x87\x6d\xbf\ +\x91\xd6\xd0\x3f\x64\x5b\x40\x98\x8b\x49\xe5\xb1\x53\xbe\x02\xed\ +\x6d\xa6\x57\x95\xb3\x6a\x8f\xeb\x9e\xe0\xbc\xad\x0e\xb4\x45\x5e\ +\xea\xc4\x7e\x6b\x93\x2c\x87\x28\x6c\xed\x5a\xcb\x73\x4d\xa4\x04\ +\x3e\x8d\x81\x51\x55\x6d\xb6\x9d\x2d\x1c\xb8\x3e\x16\xee\x94\x20\ +\xf4\x53\x53\x18\x1b\xdf\xa4\x18\x22\x03\xbd\x6c\x44\x06\x9c\x94\ +\xd7\xc7\x18\xbf\x9c\x0d\x63\xcc\x6a\x55\x69\x70\x08\x1a\xc9\x1a\ +\x77\xc0\x08\x58\x8b\xce\xbc\xf0\xef\xaf\x26\xd1\xe5\x6a\x68\x6a\ +\x35\x3c\xbd\x5a\xd4\xaf\x76\x1b\x9e\x1f\xbb\x41\x30\x74\xa0\x35\ +\x77\xbd\x6b\x9d\x5f\xb3\xfb\x5c\xef\x07\x64\x97\x49\xa5\x4f\xd3\ +\x6f\x93\xb5\x6e\xb6\xb6\x98\xdd\xac\x9a\xeb\xa4\x58\x1a\x9b\x69\ +\xdb\xa9\x78\x73\x9d\xa9\x4e\xbb\x6f\x39\xe6\x34\x77\xe7\x5d\x37\ +\x6b\xaf\x47\xd3\xfa\xea\x2e\xc9\xcc\x7e\x31\x23\x0f\x95\xef\x8d\ +\xd9\x2c\x66\x2c\x50\x8c\x13\x4e\xf9\x43\x75\x7a\x80\x31\x2c\xe0\ +\x44\x72\x82\x2f\x94\xc7\x46\x29\x31\x62\x92\x5e\x28\x77\xd6\x02\ +\x50\x7e\x91\x1c\x35\x1c\xaa\xf9\xea\x66\xa8\xee\xcc\x7e\x6d\x1d\ +\x38\xb5\xdd\xe9\x87\x23\x9d\xc6\x5f\x2e\xcd\x61\x5a\x0d\xd9\xb3\ +\x73\xcc\xe8\xef\xca\xbc\x06\xf6\xd9\x1e\xc6\xb3\xee\xf2\x4c\x57\ +\xd3\x03\xf7\x79\x09\x18\xf8\x27\x1e\xc0\x94\x5f\x9c\xf6\x64\xd1\ +\x91\x82\x40\x8f\x59\x1c\x86\x00\x7d\xa8\x3a\x3e\xae\xda\x24\x87\ +\x7c\x93\xbf\xd7\xd9\x10\x70\xbd\x49\x55\x26\x5b\x7f\x5d\x98\x65\ +\x52\xfc\xc5\xb1\xad\xa9\x1b\x86\x70\xeb\x9c\x82\xf3\x0c\xba\x2e\ +\x92\xeb\xa3\x63\xc9\xc3\xd1\xc9\xfa\xf0\x76\x98\x3b\x01\x15\x3c\ +\xea\x85\xc6\xe6\xc0\x35\x87\x71\xd2\xb5\xa2\xe3\x58\xe4\x38\x15\ +\xea\xda\xa1\x89\xc1\x26\x42\xc5\x43\xdd\x71\xac\x6b\x53\xe7\x36\ +\xbc\xcc\x8d\x46\xbe\xd1\x75\x92\x25\x75\x32\x24\x4a\x27\x21\x4a\ +\xf5\x27\x83\xf2\x14\xff\xf4\xfa\x9b\x3e\xe5\xd3\x34\xfe\xcd\xd8\ +\x77\x43\xb6\x3a\x83\x64\x69\x76\xe0\xae\x9e\x86\x1c\xb9\xa5\x31\ +\x14\x14\xe0\xd5\x57\xf9\x06\xc2\xdf\xd5\xa2\xaf\xa0\x80\x40\xca\ +\xf6\x8a\x33\x63\x07\xd6\x30\x69\x3b\xad\xd5\x6d\x65\x9a\x2c\xcf\ +\x59\xba\xc9\xdd\xa0\xf0\xe7\x3a\x2f\x8a\xef\xdd\x22\x23\x6a\x3a\ +\x4d\x9a\xd7\x85\x1e\xf1\x55\x78\xda\x7d\x47\x29\xa3\xc3\xdd\x86\ +\xdd\xe9\x9b\xa7\xf5\x80\xca\x59\xe2\xf4\x8e\x2e\x92\xa5\x86\x40\ +\xf9\xc1\x29\xbd\x0b\xed\xda\x9a\xdd\x76\x63\x32\x7d\x1a\xde\xa3\ +\x09\x55\xa4\x77\x59\x4b\x97\x2b\xd8\x7d\x7c\x23\xa4\x5a\x26\xe4\ +\xa5\x7b\x18\xd1\x72\xf3\x68\x77\x05\x14\x90\x7b\x5d\x9a\x2c\x03\ +\x26\xb5\xe6\x9d\x8e\x6f\x34\x77\x9f\xd3\x63\x9b\x51\x31\x09\x58\ +\x27\x70\x5c\x09\x1b\x89\xab\x3f\x76\x89\xd5\x63\xe9\xef\x26\x2f\ +\x63\x40\x4e\xdb\x4e\xda\x3c\x14\x90\x17\x75\xdc\x8f\xcf\x12\xe0\ +\x2b\x6b\x93\x63\x5c\x42\xdb\x34\x96\xb6\x84\x1d\xa3\x4e\xd6\x6f\ +\xf6\x2c\xc2\xdd\x39\x29\xc2\x43\xec\x76\xb5\x9f\xf4\x92\xbe\xf0\ +\x0f\xa2\x26\xb2\x89\x62\x82\x2b\xd9\x0b\x1b\x4a\x95\x5c\x32\xd1\ +\x53\x1c\x44\x07\x48\x79\x80\x54\x44\xa8\x24\x43\x8d\xd8\x26\xf5\ +\xdd\x14\xbc\xa3\x43\x40\x4d\xd2\x48\x21\x74\x0e\x1d\x0e\x14\x89\ +\x04\x7f\x08\xdf\x72\x57\xd7\xd7\x02\xef\x12\x28\x97\x71\x1e\x1c\ +\x58\x70\xce\x04\x99\x93\x28\x50\x2e\x71\x95\x47\x02\x44\x24\x65\ +\x14\xcf\xa1\xfb\xe2\x04\x2e\xea\xb1\x00\x45\x9c\x4b\xce\xe6\x3e\ +\xd4\x0a\x01\x17\xf7\x68\x40\x25\x8a\x04\xa6\xbd\x1d\xe9\x64\x64\ +\x1e\x05\x11\x34\x99\x4a\x0e\x12\x58\x8a\xb9\x0b\xe6\x12\x94\xc8\ +\x39\xc4\x8b\x94\x52\x79\x51\xc0\x90\x54\x98\x83\x81\x1c\x17\xbe\ +\xd6\x95\x0e\x53\x86\xe8\x40\x35\x43\x81\x31\x25\xc0\x54\x1b\xeb\ +\x43\xa9\xb9\x4f\xea\x9d\xd5\x8e\xae\x9e\xe6\x8d\x15\x01\x7f\x7c\ +\x36\xde\x00\xac\x10\x03\xf6\xa3\x73\x22\x02\xd2\xa0\xd3\x39\x83\ +\x8c\x40\xee\x9c\x41\x27\x9c\x41\x46\x4e\xeb\x64\x17\xce\xa0\x9d\ +\x33\xa2\x47\x9c\x11\x7d\xd8\x19\x3e\xfd\x87\xdc\xa1\xd5\x8a\x7c\ +\x3e\xee\x80\xbe\x47\x11\x09\xe7\x9d\x13\x15\x08\xd7\x4a\x92\x09\ +\x7f\x0c\xc9\x81\x27\xfc\xf1\x01\x77\xa8\x0b\x77\x7c\x64\x6e\xf8\ +\xd4\xe7\xd7\x73\xc8\xcd\x92\x61\xe8\xd2\x3f\xb5\x18\x00\xcb\x09\ +\x71\x35\x57\x40\x9b\x89\x95\x50\x8c\xcc\x29\x74\xb8\x24\x92\xcc\ +\x4b\x81\xbc\x10\x51\x11\xa4\x01\x82\x5b\x19\x51\x2c\x98\x83\x5b\ +\x44\x94\x33\x39\x12\x61\xf0\x63\x24\x98\xf0\x7e\xf5\x30\xd0\xb6\ +\xbb\xb0\x77\xe7\x89\x00\xd1\x48\x48\x98\x08\x76\x8b\x11\x21\x0c\ +\x26\xf2\x31\x76\xde\x24\x44\xc0\x38\x1a\x08\x15\x29\x8c\xe9\x63\ +\xe2\x02\x14\x30\x61\x84\x71\xe3\x68\x05\x7b\x24\xb2\x97\xc1\xc6\ +\x3a\x51\xea\xa1\x66\x72\xea\xda\x23\xc6\x14\x78\x74\x62\xf2\x88\ +\x8d\xc5\xdf\xc1\x6e\xbd\x7b\x0f\x93\x80\x52\x84\x14\x69\x27\x81\ +\x4e\x9d\x20\x88\x1d\xa8\x4a\x84\x72\x58\xb7\x3f\xdd\xe9\xc0\x7c\ +\x90\xbc\xbf\xa8\x8a\x11\x65\xf2\x63\x82\x65\x7d\xd6\x40\x62\x24\ +\x86\xda\x0a\xef\xa5\x65\xe5\x7a\x2a\xf0\x53\x52\xdb\xfc\xf0\x05\ +\x6c\x2d\x52\x54\x44\xc0\x63\xc8\x7d\x02\x8e\x09\x10\x1b\x87\xb8\ +\x86\xd3\x45\x2e\x8f\x00\x45\x14\x30\xd8\x2e\x81\x97\xe3\xbe\x41\ +\x1a\x87\xe4\x07\x58\x02\x75\xaf\x75\x67\x01\xd7\xbc\xbf\xff\xbb\ +\x2c\xd1\x04\xe7\x8f\x9e\x0f\xd1\x19\xb9\xd5\xd9\x9c\x46\x01\x69\ +\x89\xe2\x57\x8f\xab\x80\x0e\xbf\x29\x9c\xa7\x2d\xf4\xb8\x7c\x2c\ +\xfe\x0b\x3f\x8c\x40\xe9\xbb\x69\x68\xef\x5c\x03\x0a\x2f\x3b\x69\ +\x3a\x7e\x2b\xfe\x9f\x82\xa8\x4e\xa4\x38\xef\x61\x83\x04\x18\x90\ +\x9d\xc6\x50\x7e\x7e\x18\x42\xb9\x52\x1c\xd1\xed\xe1\xe9\x28\x3e\ +\x82\xcd\x06\x60\xa0\x01\x6b\xde\xaa\xe6\x9c\xb5\x04\x46\x1a\xda\ +\x6a\xdc\xe5\xf8\x6f\xf2\x76\x02\x33\x2a\x04\xf1\xd1\x13\x50\xbb\ +\x5a\x60\x61\x11\xb1\xeb\x82\x82\x55\x9b\x6b\x78\x2e\x80\x4b\x3a\ +\x50\x90\x2b\xc2\xa4\x01\xeb\xb1\xfb\x29\x5c\x24\x7b\x2e\xa8\xd0\ +\xb6\x55\x10\x57\x42\xc5\x7f\x4a\x8e\x7d\xc6\xb8\xd0\xeb\x06\x8b\ +\xaf\x9e\x05\x2c\x3d\x59\x5c\x09\x95\xe7\x91\x44\xa2\x65\x5b\x7e\ +\x2d\x54\xe8\xb3\x40\xc5\x97\x5d\x97\x73\x25\x58\x9e\xd2\x01\xfd\ +\x2f\x8a\x73\x24\x03\xde\xfe\x86\xf2\x09\xc5\xd9\x27\xcf\x0e\x16\ +\xda\x75\x74\x9f\x02\x0b\x7e\x6e\xb0\x30\x79\x85\x56\xee\x3f\xe0\ +\x96\x7f\x1a\x16\x72\x8d\x24\x62\xcf\x0d\x16\x2a\xae\x91\x44\x1f\ +\xd3\xb5\xdc\x86\xeb\xf6\x5f\x14\xf0\x75\xeb\xfe\x93\xf2\xea\xc5\ +\x9f\x19\xdf\x54\x8b\ +\x00\x00\x07\x4c\ +\x00\ +\x00\x1f\xb7\x78\x9c\xdd\x59\x5b\x6f\xeb\xb8\x11\x7e\xcf\xaf\x60\ +\x9d\x97\x5d\xd4\xa4\x2e\xd4\x85\x52\x9c\xec\x43\x0f\x16\x3d\xc0\ +\x29\x0a\xec\x6e\x51\x60\x5f\x16\xb4\x44\xdb\x6c\x64\xc9\xa0\xe8\ +\xdb\xfe\xfa\x0e\x25\x51\x17\xdb\x49\x4f\x80\x14\x38\x27\x04\x02\ +\x8b\x33\x43\x72\xf8\xcd\x37\x43\x12\x59\xfc\x74\xda\x16\xe8\x20\ +\x54\x2d\xab\xf2\x71\xe6\x11\x77\x86\x44\x99\x55\xb9\x2c\xd7\x8f\ +\xb3\x7f\xfd\xf6\x33\x66\x33\x54\x6b\x5e\xe6\xbc\xa8\x4a\xf1\x38\ +\x2b\xab\xd9\x4f\x4f\x77\x8b\xbf\x60\x8c\xfe\xa6\x04\xd7\x22\x47\ +\x47\xa9\x37\xe8\x73\xf9\x5c\x67\x7c\x27\xd0\x0f\x1b\xad\x77\xa9\ +\xe3\x1c\x8f\x47\x22\x3b\x21\xa9\xd4\xda\xf9\x11\x61\xfc\x74\x77\ +\xb7\xa8\x0f\xeb\x3b\x84\x10\xac\x5b\xd6\x69\x9e\x3d\xce\xba\x01\ +\xbb\xbd\x2a\x1a\xc3\x3c\x73\x44\x21\xb6\xa2\xd4\xb5\xe3\x11\xcf\ +\x99\x0d\xe6\xd9\x60\x9e\x99\xd5\xe5\x41\x64\xd5\x76\x5b\x95\x75\ +\x33\xb2\xac\xef\x47\xc6\x2a\x5f\xf5\xd6\xc6\x9b\x23\x6d\x8c\xbc\ +\x24\x49\x1c\xd7\x77\x7c\x1f\x83\x05\xae\xcf\xa5\xe6\x27\x3c\x1d\ +\x0a\x3e\xde\x1a\xea\xbb\xae\xeb\x80\x6e\xb0\xfc\x3a\xab\xb4\x06\ +\x40\x77\xf0\xd7\x9b\x5b\x01\xa9\xab\xbd\xca\xc4\x0a\xc6\x09\x52\ +\x0a\xed\x7c\xfa\xed\x53\xaf\xc4\x2e\xc9\x75\x3e\x9a\xc6\xe2\x39\ +\x59\x75\x02\x72\xc9\xb7\xa2\xde\xf1\x4c\xd4\x8e\x95\x37\xe3\x8f\ +\x32\xd7\x9b\xc7\x19\x0d\x88\x47\xa1\x85\x8d\x70\x23\xe4\x7a\xa3\ +\x2f\xa5\x32\x7f\x9c\x81\xf7\x7e\xc2\xda\xfe\x88\x1c\x5e\x6b\xd0\ +\x4d\x9c\xf6\x1a\x97\x24\x3e\xf1\x90\xf2\x42\x1a\xb7\x36\x76\x0b\ +\x69\x5e\x65\xc6\x27\x98\x52\x6c\x25\xdf\xeb\x6a\x0b\x51\xcb\xb2\ +\x82\xd7\xb5\x5c\xc9\x0c\x3a\x55\xb9\x2b\xf6\x6b\x59\xfe\xb1\xe5\ +\xe5\x9e\x17\x7f\xfc\xf2\xcf\xcf\xc4\xa2\xd7\x2f\x25\x4e\xbb\x4a\ +\x69\x7c\xca\x77\x80\x61\x14\xdf\x54\x9e\xad\xf2\x09\xb4\x8b\x5c\ +\xac\x6a\x63\xd5\x6e\xc8\xf4\x60\x47\xf1\x0c\x39\x8d\xb6\xf7\xcf\ +\x38\x97\x1f\xa4\x38\x0e\xb6\x4b\x5e\xb7\xa0\x21\xb4\xe3\x6b\x20\ +\x58\x51\xa9\xc7\xd9\xfd\xaa\x69\x9d\x62\x59\xa9\x5c\x28\xab\x8a\ +\x9a\x36\x51\x55\x10\x04\xa9\xcf\x6d\x4a\x75\x73\x5b\x7f\xcd\xac\ +\xbd\xde\xbd\xad\xaf\x37\x3c\xaf\x8e\x8f\x33\xff\x52\xf9\x67\x55\ +\x6d\x61\x56\x08\x46\x12\x33\xf7\x4a\x9d\x9d\x1e\x67\x38\x20\x49\ +\x12\x53\xca\xa2\x2b\xad\x71\x28\x82\x68\x47\x7e\xe4\x5d\x29\xf7\ +\x4a\x41\xd2\xe1\x82\x9f\x05\xec\xaa\xf9\xb1\x46\xf5\xa6\x3a\xae\ +\x95\x41\x47\xab\xbd\xb8\x1c\x69\x34\x78\xb9\xac\x4e\xb7\xd5\xc0\ +\x81\xbd\x49\x67\xbc\x2f\xa5\x86\x94\xd9\x9d\xc6\xb3\xee\x65\x2e\ +\xea\xdb\x03\xeb\x92\xef\xf0\xba\xa8\x96\xbc\xb8\x6d\x70\x94\x25\ +\xa0\x84\x3b\x76\xc3\xb6\xae\x76\xdc\x59\x58\xaa\xc7\x2e\x7b\xc1\ +\x02\x7c\xbf\x0a\x44\xa7\x3a\xbf\xac\xda\xf2\x93\xdc\xca\x3f\x05\ +\x00\xe3\x35\xbc\x03\x6e\x4d\x60\x69\x87\x21\xa4\xcf\x26\x6d\x4f\ +\x67\x23\x9b\x59\xa1\xc1\xd3\x08\x7c\x08\x57\x2f\xac\x94\x84\x6c\ +\x18\xb9\x63\x45\xe7\xb1\xc8\x24\x39\xd4\xe8\x53\x43\xb0\x86\x7e\ +\xf1\xa5\xee\x3c\xd6\x75\xbc\x77\xae\x89\xdf\xc8\xb7\x42\xf3\x9c\ +\x6b\x3e\x64\x81\x95\x80\x6f\xae\xdd\x19\xd4\xcb\xf4\x97\x4f\x3f\ +\x3f\x75\x0b\x2d\xb2\x2c\xfd\x77\xa5\x9e\xed\xba\x08\x19\x03\xbe\ +\xac\xf6\x80\xf4\xec\xa9\x17\x2f\xf2\x2c\x85\x0a\x07\x99\xff\x24\ +\xb7\xc0\x6d\x53\x1c\xff\x0a\x15\x6d\xe1\x0c\x8a\x89\xb1\x01\x6b\ +\x98\xb4\x9d\x56\x89\xb6\x54\xde\x3c\x2f\xf2\x6c\x2b\xcd\x20\xe7\ +\x57\x2d\x8b\xe2\xb3\x59\xa4\xdb\xf1\x68\x52\xa9\x0b\x31\x08\x17\ +\x4e\xe7\x7d\xb7\x37\x67\xb4\xb9\x85\x63\x77\xdf\xf4\xd6\x03\x2a\ +\x93\xa4\xe8\x03\x5d\xf0\xa5\x00\x86\x7e\x31\x4a\x74\xa5\x5d\xab\ +\x6a\xbf\xdb\x56\xb9\xe8\x86\xf7\x68\x8a\x4c\xf7\x21\xd3\xe7\x02\ +\xf4\x2b\xf0\x3e\xbd\x17\x09\x5f\x7a\xd1\x83\xe9\xe0\xae\x4e\xa4\ +\x5e\xdb\x55\xfb\x02\xea\xdd\x41\x94\x55\x9e\x3f\xd4\x5a\x55\xcf\ +\x22\xbd\xf7\x58\x1e\xad\x56\x5d\xb7\x4d\x86\xd4\xb5\x5d\x00\x46\ +\xa8\x02\x48\xaa\xd3\xc0\xca\x72\x0e\xe5\x45\x29\x7e\x4e\x4b\x38\ +\xd4\xad\xb4\x5f\x6a\xc2\x4f\xe3\x25\x70\x20\xc1\x0c\xd3\x5e\x61\ +\x13\x2e\x20\x11\x8b\x59\x14\xf6\x0a\x9b\x67\x8c\xb0\x30\x71\x43\ +\x16\xf4\x1a\x60\xaa\x1f\x11\xe6\x07\x34\x1e\xe6\x69\xea\x5f\x4c\ +\x59\x12\x85\xf1\x30\x89\x32\xb6\x24\x08\xa2\xc8\x8b\x07\x67\x54\ +\xcb\xe7\x90\xd2\x88\x26\xbd\x54\x2b\x5e\xd6\x86\x43\xc0\x58\xae\ +\x95\x3c\xfd\x00\x13\x86\x2c\x49\x58\xe4\xcf\x5d\x12\x85\x9e\x9b\ +\xf8\x3e\x9d\xc3\x59\x1a\xc7\x31\x75\xa9\xe7\x19\xb1\x9f\x78\x7e\ +\xe4\xb3\xb9\x3b\x77\x7f\xec\x99\xf2\xfd\x45\x24\xbe\x0e\x89\x47\ +\x42\x3f\x09\x99\x77\x15\x12\x2f\x24\xae\x17\xc5\x21\x1d\x87\x04\ +\x84\x01\x83\x36\x8e\x08\x66\x84\x26\xd4\xf5\xc2\x64\x12\x11\x0f\ +\x0e\x79\x37\xf4\x59\x72\x11\x91\x98\x85\x20\x65\xaf\x46\x24\xf1\ +\x03\x2f\x8c\x92\x18\xa0\xa7\xcc\x77\x3d\xf0\xb0\x89\x88\x89\x8d\ +\xc7\x20\x0c\xf0\x19\xc0\x85\x83\x06\xdf\x7d\x44\x30\xbb\x0c\x89\ +\x1f\x03\xc5\xa1\x05\x57\x21\x09\x88\xdf\x94\xe7\x64\x1c\x92\x6b\ +\x21\xc0\xec\x33\x12\x27\xa6\x4d\x42\x02\xe9\xe7\x41\xea\x50\x7f\ +\x12\x12\x97\x84\x6e\x4c\x21\x75\x92\xef\x19\xc7\xff\x07\x8a\xd7\ +\x47\xe5\xc7\x46\xf1\x0a\x43\x8f\xd0\xdb\x18\x8e\x36\x7f\xf3\x4a\ +\xf1\x22\x78\x94\x84\x21\x0d\xe3\x24\x9a\x80\x47\x09\x73\x03\x38\ +\x19\xc2\x01\xbb\x1d\xd7\x9b\x0b\xec\x9a\xeb\x73\x7a\xef\x36\xed\ +\x61\x55\xc1\x0d\xb1\xd1\xc0\x1e\xe1\x4e\x50\xb4\x92\x03\x57\x92\ +\x97\x7a\x22\x3b\x36\x5e\x4f\x44\x80\x88\xd0\xd9\x66\x2a\x83\x8b\ +\x59\x0a\xb7\x1c\xb9\xdf\x3e\x14\xb2\x14\xdd\x2d\x70\x62\xb3\xe2\ +\x5b\x59\x9c\xd3\x5f\xa1\x66\x3d\x60\x7b\x64\xe3\x76\xf8\x4e\x64\ +\xfd\x1b\xa5\xb5\xd0\xe2\xa4\xc1\x2a\x87\xcb\x2c\xc4\xab\xe9\xf1\ +\x42\xae\xcb\x14\x9e\xc8\x4a\xb7\x82\x1c\x5e\x0c\xaa\x1d\xd3\xc4\ +\xea\x42\x88\x8d\x27\xad\xa6\x10\x1a\x22\x8d\xbb\xeb\x9a\x75\xeb\ +\x08\xef\x87\x4b\x59\x33\x47\x5f\x58\xdb\xd1\x47\x25\x35\x98\x60\ +\x73\xb3\x48\x0b\x85\xf5\xf2\x21\x97\x26\xf6\x66\xe5\x42\xab\x07\ +\xf3\x8e\x69\xb6\x5d\x6f\xe4\x4a\xa7\xb6\xdb\xb9\x5d\x66\x1b\x00\ +\xbf\xf5\x3b\x97\xf5\x0e\xae\x26\xf0\xbe\x6c\x0c\x2a\x78\xd8\xad\ +\x8a\xea\x98\x1e\x64\x2d\x97\x85\x78\x68\x7e\x65\x61\xa8\x66\x45\ +\x2d\xef\x3b\x1e\x7f\x2d\xef\xc7\xdc\x6d\x49\x0f\xcf\xc6\x38\x84\ +\xf3\x80\xd1\x87\x2d\x57\xcf\x42\xb5\x36\xa2\xe4\xb0\x08\x5e\xf2\ +\xec\xd9\xdc\x9e\xca\x3c\xe5\x19\xbc\x21\xf6\x05\xd7\xa2\x27\x9a\ +\xb9\xa4\x22\x38\x45\x5c\xda\xb6\xf9\xe8\x1b\x1d\x10\xbc\x90\x5a\ +\x66\x51\x44\x7d\x62\x3f\x41\x8a\x36\xaf\xe8\x0e\x08\x9b\x9f\x2f\ +\xc8\x3e\x8a\xe9\x9c\xc2\xf9\xd5\x4e\xea\x53\x12\x34\x29\x30\xf7\ +\x12\xe2\x1b\xdb\x88\x04\xa8\x40\x1e\xdc\x28\x9a\x36\xc7\x09\x89\ +\x50\xe7\xc6\x1c\xfb\xdd\x14\xb4\x9b\xd6\x2e\xb4\x69\x17\xf9\x3b\ +\xea\x73\x0a\xfd\x8e\xfe\x81\xc0\xbc\xed\xcd\xfb\x2f\xb0\xa1\x70\ +\xf0\xb6\xdf\x5f\x90\x4d\x60\x3a\x87\x73\x3e\xb6\x53\x33\x12\x36\ +\x59\xdd\x79\xd2\x7c\x37\x06\x30\x7a\x98\xe9\xf7\x9b\x45\x62\x10\ +\xf6\xcf\xc0\xaa\x2c\x41\x59\x29\x0c\x0f\xc2\x03\xd7\x7b\x25\x26\ +\x0f\x8f\xfe\x01\x01\xbc\x33\x77\x6e\x78\xbb\x65\x2f\xb4\x57\xb3\ +\xbf\x65\x10\x03\x40\x98\x7b\xc9\x20\x5b\x27\x57\x6d\x69\x98\x50\ +\xc6\x23\x2c\x88\x43\xdf\x65\x74\x77\xb2\x1a\x43\x5b\x70\x3e\x5d\ +\xee\xb5\x1e\xcb\xfe\x53\xc9\x32\x6d\xea\xe9\xcb\x25\xb3\xa1\x91\ +\xef\xb6\xe7\x05\x44\x96\x75\x41\x43\x19\x82\xe8\xce\x4d\x84\x2f\ +\x7e\x27\x40\x9a\x9d\xd1\xc4\x0d\xbe\x1a\xc8\xff\x8d\x89\xeb\x46\ +\xd4\xbb\xca\xaa\xd7\x30\xb1\x44\x0b\x82\xf7\xc4\x24\x22\xd1\x35\ +\x26\xd8\x82\x71\xf5\x71\x0b\x96\xe8\x1d\x61\xf9\xe6\xa8\x12\xb7\ +\xd5\x00\x72\xab\xa7\x4a\x97\xe0\xaf\xf4\x6e\x92\x07\xfb\x1f\x99\ +\x3e\x63\x9c\xf0\x14\x9a\x57\xbb\x37\x09\x85\xbd\x0f\x48\xa9\x84\ +\xb0\x16\x2a\x3c\x9c\x08\x6f\x2b\x3f\xd8\x7f\x57\x60\xbe\x11\x0e\ +\xd1\xc8\xe6\xda\x04\x98\x37\xd6\x20\xec\x7d\x44\xd2\x0c\xb7\x8b\ +\xf1\x45\xe3\xcd\xac\x89\x3f\x1e\x6b\xec\xdb\x2f\x9e\x02\xf3\x76\ +\xd6\x7c\xfd\xed\xe8\xfb\x61\x4d\x9f\x47\xf3\xbe\xea\xbc\x9d\x34\ +\xef\x09\xcc\x37\x42\x9a\x90\xd8\x67\xc4\x18\x97\xb7\x73\xe6\x3d\ +\x2f\x82\xdf\x08\x67\x86\xe3\xc9\x67\x84\xbd\x9d\x2d\x1f\xf0\x72\ +\x33\x1c\x4c\x1d\x24\x6f\x27\xca\x5b\xaf\xc6\x0b\x67\xfd\x74\xb7\ +\x30\xff\x3b\x79\xba\xfb\x2f\x49\x7d\x2d\x30\ +\x00\x00\x05\xe3\ +\x00\ +\x00\x1d\xa4\x78\x9c\xe5\x58\xdd\x73\x9c\x36\x10\x7f\xcf\x5f\xa1\ +\xc1\x2f\xed\xf4\x00\x21\xf1\x9d\xbb\xcb\x4b\x26\x93\xce\xa4\x2f\ +\x6d\xda\x3e\x66\x38\xd0\x9d\x69\x00\x51\x21\x7c\x77\xf9\xeb\xbb\ +\x02\x04\xdc\x87\xa7\x4e\xec\x36\x4d\x2d\x8f\xc7\x68\x77\xb5\xec\ +\xfe\xb4\xfb\x93\xf0\xf2\xd5\xa1\x2c\xd0\x1d\x13\x4d\xce\xab\x95\ +\xe1\x58\xd8\x40\xac\x4a\x79\x96\x57\xbb\x95\xf1\xeb\xfb\x37\x66\ +\x68\xa0\x46\x26\x55\x96\x14\xbc\x62\x2b\xa3\xe2\xc6\xab\xf5\x8b\ +\x65\x73\xb7\x7b\x81\x10\x82\xc5\x55\x13\x67\xe9\xca\xb8\x95\xb2\ +\x8e\x6d\xbb\x6e\x45\x61\x71\xb1\xb3\xb3\xd4\x66\x05\x2b\x59\x25\ +\x1b\xdb\xb1\x1c\xdb\x98\xcc\xd3\xc9\x3c\x15\x2c\x91\xf9\x1d\x4b\ +\x79\x59\xf2\xaa\xe9\x56\x56\xcd\xcd\xcc\x58\x64\xdb\xd1\x7a\xbf\ +\xdf\x5b\x7b\xda\x19\x39\x51\x14\xd9\x98\xd8\x84\x98\x60\x61\x36\ +\xc7\x4a\x26\x07\xf3\x74\x29\xc4\x78\x6d\x29\xc1\x18\xdb\xa0\x9b\ +\x2c\x1f\x66\x15\x37\x80\x4a\x0d\xbf\xa3\xb9\x16\x58\x0d\x6f\x45\ +\xca\xb6\xb0\x8e\x59\x15\x93\xf6\xeb\xf7\xaf\x47\xa5\x89\xad\x4c\ +\x66\x33\x37\x79\xf5\xb1\x49\x93\x9a\x9d\xbc\x55\x0b\x7b\x04\x92\ +\x92\x35\x75\x92\xb2\xc6\xd6\xf2\x6e\xfd\x3e\xcf\xe4\xed\xca\xa0\ +\xae\xe5\x50\x18\x5e\x27\xbc\x65\xf9\xee\x56\x9e\x4b\xf3\x6c\x65\ +\x40\xf4\x24\x0a\xfb\xf9\x6c\x87\x9d\xde\x60\x70\x1c\xcf\xf7\xde\ +\x22\xe8\x3b\x16\xfa\x69\x18\xe0\x30\x88\x16\x88\x60\xe2\x98\xd8\ +\x31\x1d\xef\xfb\x6e\x91\xce\x29\xce\x78\xaa\x82\x84\x77\xb0\x32\ +\x4f\x5a\xc9\x4b\xd8\xc6\x34\x2d\x92\xa6\xc9\xb7\x79\x0a\x13\x5e\ +\xd5\x45\xbb\xcb\xab\x0f\x4d\x72\xc7\x3e\xd4\x05\x97\x1f\xf2\x32\ +\x01\x7c\x34\xa6\x63\x00\xec\x50\x73\x21\xcd\x43\x56\x03\xb2\x7e\ +\x70\x55\x79\xd4\xca\x35\x68\x97\x19\xdb\x36\xca\xaa\x4f\x53\xcd\ +\x20\xcf\xc0\x40\x76\xa7\x1d\x83\x54\x11\x66\x77\x39\xdb\x4f\xb6\ +\x9b\xa4\xe9\xa1\x44\xa8\x86\x60\x52\x5e\x70\xb1\x32\x6e\xb6\xdd\ +\x18\x14\x1b\x2e\x32\x26\xb4\xca\xef\xc6\x89\x8a\xc3\xd6\xe4\xf2\ +\xd8\x77\xcb\xe0\x5b\xc7\xab\xbc\x8e\x7a\x7c\x5d\xdf\xdc\x26\x19\ +\xdf\xaf\x0c\x72\xae\xfc\xc4\x79\x09\x5e\x61\x8b\xa2\x20\xc4\x17\ +\xea\xf4\x00\x4a\xd7\x0a\x9c\x28\xa4\x97\x4a\x15\x8f\x67\xb9\x81\ +\x47\x70\x78\xa1\x6c\x85\x80\x4e\x34\x8b\xe4\xc8\x20\xa9\xee\x8f\ +\x33\x18\x35\xb7\x7c\xbf\x13\x0a\x1c\x29\x5a\x76\xbe\x52\x69\xcc\ +\xcd\x86\x1f\xae\xab\xa1\x0e\x5a\xd5\xe3\x66\x5b\xe5\x12\xfa\xa8\ +\x3e\xcc\xbd\xb6\x79\xc6\x9a\xeb\x0b\xf7\x79\x05\x18\x98\x43\x45\ +\x3b\x74\x84\xf8\xdc\x42\x97\x77\x80\xef\xb3\x80\xd0\x2e\x60\x1e\ +\x54\xc7\xfb\x55\x65\x72\xc8\xcb\xfc\x13\x83\xbc\x9d\x73\x93\xa6\ +\x4a\x6a\x73\x57\xf0\x4d\x52\xfc\x4d\xda\x82\xcb\xae\xd6\xd5\x7b\ +\xd6\x9d\xd1\xf2\x04\xba\x7e\x1d\x42\xf2\xa8\xfa\xfd\x70\x54\x32\ +\x43\x0b\x15\xe6\x4a\x40\x03\xdf\x1b\x85\x5c\xe4\xd0\x35\xb3\x9c\ +\xb4\xe8\x38\x17\x29\x76\x00\x86\x3e\x74\x35\xd8\x55\x68\x70\xae\ +\x3b\xce\x75\x43\x6b\xd8\x97\xbd\xd1\xc9\x4b\x26\x93\x2c\x91\xc9\ +\xd4\x28\x5a\x42\xa2\x68\xcc\x0c\x88\x36\xfe\xf9\xf5\x9b\xf5\xf0\ +\xa2\x65\x9a\xc6\xbf\x73\xf1\x51\xbf\x17\x21\x65\x90\x6c\x78\x0b\ +\xdb\x65\xac\x47\xf1\x32\x4b\x63\xa0\x46\x60\x88\x75\xc7\x00\x8a\ +\x55\x7f\x00\x2a\x5c\xda\x93\xe2\xc4\x58\x81\x35\x39\xed\xdd\x0a\ +\xd6\x73\xec\xd5\x83\x26\x4b\xcb\x5c\x2d\xb2\x7f\x91\x79\x51\xfc\ +\xa8\x5e\x32\x64\x3c\x73\x9a\xcb\x82\x4d\xc2\xa5\x3d\x44\x3f\xe4\ +\x66\xcf\x92\x5b\xda\x3a\xfb\x6e\xb6\x9b\x50\x39\x69\x9c\x71\xa3\ +\x8b\x64\xc3\xa0\x50\xde\x29\x25\xba\xd0\xee\x04\x6f\xeb\x92\x67\ +\x6c\x58\xae\xd1\xac\x13\x79\x3b\x6e\x99\x3c\x16\xa0\xdf\x42\xf4\ +\xf1\x8d\x1b\xf9\xae\xbf\x79\xa9\x26\xe6\x40\x25\xb1\xd3\x4f\x45\ +\x5b\x00\x25\xde\xb1\x8a\x67\xd9\xcb\x46\x0a\xfe\x91\xf5\x2d\x14\ +\x8f\x5b\x4d\x06\x79\x7c\xc3\x7c\xf5\xa3\xcd\x46\x4f\x63\x9d\xa8\ +\x5d\x46\x0e\xb5\xa8\xe2\xfa\x60\x41\xc0\x03\x89\x28\x0d\x51\x8a\ +\x4c\x70\x87\x83\x20\xf4\x17\x58\x3d\x87\x0e\x8d\x82\x60\x81\xad\ +\x10\xfb\x4e\x84\x9d\x99\x6c\x78\xf0\xd0\x6f\xc8\x09\xfa\x18\x02\ +\xf4\x16\xb9\x96\x8f\x61\xb9\x43\x7b\x67\x91\x1f\x04\x98\xb8\xe0\ +\xcd\x01\x27\x84\x50\xdf\x85\xa5\x40\x65\x5e\x10\x80\xfd\x55\x61\ +\x81\xb0\x05\x44\x17\x7a\x64\xa1\x1f\xb4\xc4\x59\x98\xa3\x28\x45\ +\x58\xb9\x25\x56\x10\x61\xec\x07\x0b\xf3\xd2\x2d\x99\x0b\xdf\x22\ +\xe2\x58\xb4\x1b\x10\x33\xb5\xc2\xc0\x8f\x70\x18\x76\x7e\x74\xda\ +\x6e\x84\xcc\x21\x59\x67\x61\x8e\x29\x8e\x4f\x33\xd9\xa7\x93\x6e\ +\x16\x2c\x95\x1e\x75\xc3\x49\x38\x32\x30\xaf\x2a\x50\x72\x61\x02\ +\x17\xdf\x25\xb2\x15\x4c\xf5\xb3\x2e\xc8\xa5\x5a\x79\xb5\x1a\xfa\ +\xa3\xe9\xa1\xd5\x10\xdf\x60\xec\x86\x18\x9f\x16\xc7\x38\x2d\x72\ +\x08\x22\xa9\xe3\xe6\xcf\x36\x11\x6c\x2e\xfd\x83\xe7\x55\x0c\x5d\ +\xc4\x84\x96\x76\x93\x02\x38\x52\xc6\xae\x96\x65\x09\x9c\x5d\x42\ +\x24\xc7\xb8\x82\xcb\xe0\x5c\xca\xb7\xdb\x86\xc9\xe9\x4d\x3a\x54\ +\x3c\x60\x4d\xe9\x05\x50\x34\x8a\xa6\x62\xd4\x07\x01\xec\x4d\x00\ +\x63\x42\x50\xf3\xff\xa5\x06\xc8\x4f\x6f\xa5\x3b\x0a\x81\xf5\x08\ +\xb5\xdc\x53\x46\x14\x27\x74\x2a\x3a\x66\x74\xb0\xe7\x10\x88\x6a\ +\xdc\x81\xfb\xfa\x71\x96\xa9\x42\x57\x8d\xf3\xd6\xf3\x28\x01\xcc\ +\x71\x78\x0e\xf3\xa6\x95\xf2\xa9\x40\xbe\xda\xbf\x3f\x4d\xc5\xbc\ +\x18\xd3\x56\x65\xed\x5a\xa1\x0b\xc3\x3b\x01\x5d\x65\x08\x7c\xee\ +\x3f\xb8\x3a\x47\x38\xc6\x53\x03\x68\x4c\x11\x2d\x1c\xea\x69\xfa\ +\x04\xd0\x01\xe7\x84\x54\x5d\xe5\xbf\x06\x74\x94\x5a\x41\x57\x51\ +\x0b\x7d\x75\xa6\x8a\x1d\x88\xe5\x5e\x43\xed\xe1\x3d\xfd\x7f\x46\ +\xad\x54\x05\xe7\x87\x30\xa2\x05\xe0\x37\xf0\x3d\x70\x27\xdc\x4a\ +\xd5\x00\x2a\xbe\xfa\x78\x81\x28\xf4\x32\x31\xf1\xe7\xf3\xe4\x37\ +\x0a\x1a\x14\xd8\x58\x6a\x6e\x07\x9f\x3e\x70\x5c\xa2\xc6\x7d\xcf\ +\x97\xb8\x85\xee\x3f\x87\x5a\xc8\x2e\xb9\xcd\xa7\x9e\xfa\x14\x26\ +\x5f\x03\x35\xd8\x33\xc5\x62\xee\x82\xc2\x97\x69\x8f\x8d\xbe\xe7\ +\xa8\x1b\x00\xf5\xd4\x40\xa4\x6f\x5e\x77\x61\x92\x81\xf5\xc0\x6a\ +\xe8\xec\xc9\x6a\x14\x51\x8b\xe8\x89\xba\xd2\xf4\x15\x8a\xde\xa1\ +\xb1\x9c\x17\x94\x20\xea\x59\x51\x57\xb9\xa3\xf4\x62\x27\x5c\x4c\ +\x83\x67\x53\xbf\x00\x47\x07\xe3\x93\xd4\xaf\xf9\x05\xf7\xa3\x6f\ +\x14\xb7\xc8\xf2\x7a\x06\x7c\x12\xdc\xa2\xe7\x82\x1b\x75\x2c\x32\ +\x1c\x32\x4f\x81\xdb\xb3\x39\x67\x66\x1c\xf6\x14\xb8\xd1\xe7\x82\ +\x1b\x09\xac\xa0\xbf\x45\x3f\x09\x6e\x0f\xbf\x61\x7f\xd3\x5f\x1f\ +\x27\x97\x41\xdd\xb1\x5f\x7e\x19\x34\xc9\xf3\x83\x6d\x3c\x20\x1e\ +\x01\x9b\xf3\x0c\x61\xd3\xfd\xfa\x08\xd8\xfe\x4d\x72\xfb\xaf\xc0\ +\xa6\xaf\x71\x8f\x80\xcd\x7d\x86\xb0\xe9\xaf\xb7\x47\xc0\xf6\xb9\ +\x57\xb7\xa5\xbd\x5b\xbf\x58\xaa\x7f\x95\xaf\x5f\xfc\x05\x87\x4e\ +\xb1\x31\ +\x00\x00\x0c\x2f\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x65\x78\x70\x6f\x72\x74\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\ +\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\ +\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\ +\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\ +\x74\x35\x39\x37\x31\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\ +\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\ +\x63\x31\x30\x30\x30\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x39\x37\ +\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\ +\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x38\x30\ +\x30\x30\x30\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\x39\x37\x35\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\ +\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x3c\x2f\x64\x65\ +\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x78\x3d\x22\x2d\x35\x2e\x34\x37\x30\x36\x34\x34\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ +\x22\x39\x2e\x36\x33\x35\x38\x32\x39\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ +\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ +\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\ +\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ +\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ +\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\ +\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\ +\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\ +\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x37\x38\x39\x62\x61\x32\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\ +\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x31\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x31\x2e\x34\x36\x33\x34\x32\x35\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x30\x2e\x35\x34\x30\x36\x36\x35\x39\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x36\x2e\x30\x39\ +\x35\x32\x33\x38\x32\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x62\x34\x31\x31\x30\x30\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\ +\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x32\x30\x2e\x38\x38\x39\x32\x38\x34\x2c\ +\x33\x31\x2e\x32\x30\x30\x36\x31\x20\x63\x20\x30\x2e\x39\x34\x32\ +\x31\x30\x33\x2c\x30\x20\x31\x2e\x36\x39\x35\x37\x34\x38\x2c\x2d\ +\x30\x2e\x37\x35\x33\x36\x34\x37\x20\x31\x2e\x36\x39\x35\x37\x34\ +\x38\x2c\x2d\x31\x2e\x36\x39\x35\x37\x34\x37\x20\x56\x20\x31\x37\ +\x2e\x31\x37\x34\x37\x37\x31\x20\x68\x20\x36\x2e\x34\x33\x38\x30\ +\x39\x20\x63\x20\x31\x2e\x38\x33\x39\x34\x35\x35\x2c\x30\x20\x2d\ +\x31\x30\x2e\x31\x31\x37\x2c\x2d\x31\x33\x2e\x37\x39\x35\x39\x31\ +\x31\x35\x20\x2d\x31\x30\x2e\x31\x31\x37\x2c\x2d\x31\x33\x2e\x37\ +\x39\x35\x39\x31\x31\x35\x20\x6c\x20\x2d\x30\x2e\x39\x31\x39\x37\ +\x32\x37\x2c\x2d\x30\x2e\x39\x31\x39\x37\x32\x38\x20\x2d\x30\x2e\ +\x39\x31\x39\x37\x32\x38\x2c\x30\x2e\x39\x31\x39\x37\x32\x38\x20\ +\x63\x20\x30\x2c\x30\x20\x2d\x31\x31\x2e\x39\x35\x36\x34\x35\x36\ +\x32\x2c\x31\x33\x2e\x37\x39\x35\x39\x31\x31\x35\x20\x2d\x31\x30\ +\x2e\x31\x31\x37\x30\x30\x30\x32\x2c\x31\x33\x2e\x37\x39\x35\x39\ +\x31\x31\x35\x20\x68\x20\x36\x2e\x34\x33\x38\x30\x39\x31\x32\x20\ +\x76\x20\x31\x32\x2e\x33\x33\x30\x30\x39\x32\x20\x63\x20\x30\x2c\ +\x30\x2e\x39\x34\x32\x31\x20\x30\x2e\x37\x35\x33\x36\x34\x35\x2c\ +\x31\x2e\x36\x39\x35\x37\x34\x37\x20\x31\x2e\x36\x39\x35\x37\x34\ +\x38\x2c\x31\x2e\x36\x39\x35\x37\x34\x37\x20\x7a\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\ +\x38\x2d\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ +\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\x74\ +\x00\ +\x00\x40\xa3\x78\x9c\xed\x5b\x59\x8f\xab\xc8\x15\x7e\xef\x5f\x41\ +\x7c\x15\x69\x46\x69\x8a\xda\x58\xdb\xf6\x3c\xe4\x6a\x94\x91\x66\ +\x5e\x92\x49\xf2\x38\xc2\x50\x76\x93\xc6\x94\x05\x78\xbb\xbf\x26\ +\xbf\x25\xbf\x2c\xa7\xca\x80\xc1\xc6\x69\x7b\xda\xd7\x69\x5f\x35\ +\x52\xcb\x70\xce\xa9\xe5\x7c\x67\x65\xe9\xe1\x0f\x9b\x79\x6a\xac\ +\x44\x5e\x24\x32\x1b\x0d\x08\xc2\x03\x43\x64\x91\x8c\x93\x6c\x36\ +\x1a\xfc\xfd\xd7\x1f\x4d\x6f\x60\x14\x65\x98\xc5\x61\x2a\x33\x31\ +\x1a\x64\x72\xf0\xc3\xf8\x61\xf8\x07\xd3\x34\xfe\x9c\x8b\xb0\x14\ +\xb1\xb1\x4e\xca\x67\xe3\xa7\xec\xa5\x88\xc2\x85\x30\xbe\x7b\x2e\ +\xcb\x45\x60\x59\xeb\xf5\x1a\x25\x15\x11\xc9\x7c\x66\x7d\x6f\x98\ +\xe6\xf8\xe1\x61\x58\xac\x66\x0f\x86\x61\xc0\xba\x59\x11\xc4\xd1\ +\x68\x50\x0d\x58\x2c\xf3\x54\x0b\xc6\x91\x25\x52\x31\x17\x59\x59\ +\x58\x04\x11\x6b\xb0\x17\x8f\xf6\xe2\x91\x5a\x3d\x59\x89\x48\xce\ +\xe7\x32\x2b\xf4\xc8\xac\xf8\xd4\x12\xce\xe3\x69\x23\xad\x76\xb3\ +\x66\x5a\x88\xf8\xbe\x6f\x61\x6a\x51\x6a\x82\x84\x59\x6c\xb3\x32\ +\xdc\x98\xdd\xa1\xb0\xc7\xbe\xa1\x14\x63\x6c\x01\x6f\x2f\x79\x9e\ +\x54\x50\x00\xa0\x0b\xf8\x6b\xc4\x6b\x02\x2a\xe4\x32\x8f\xc4\x14\ +\xc6\x09\x94\x89\xd2\xfa\xfc\xeb\xe7\x86\x69\x62\x14\x97\x71\x6b\ +\x9a\x1a\xcf\xce\xaa\x1d\x90\xb3\x70\x2e\x8a\x45\x18\x89\xc2\xaa\ +\xe9\x7a\xfc\x3a\x89\xcb\xe7\xd1\x80\x71\x44\x18\x1c\xb6\x26\x3e\ +\x8b\x64\xf6\x5c\x1e\x52\x93\x78\x34\x80\xdd\x53\xdf\xdb\x5d\xb7\ +\x9c\x83\xec\x04\xaa\x89\x83\x86\x83\x91\x4f\x11\x31\x72\x62\x33\ +\x77\x27\x53\xab\x10\xc4\x32\x52\x7b\x82\x29\xc5\x3c\x09\x97\xa5\ +\x9c\x83\xd5\xa2\x28\x0d\x8b\x22\x99\x26\x11\x5c\xc8\x6c\x91\x2e\ +\x67\x49\xf6\x5b\x18\x45\xcb\x3c\x8c\xb6\xbf\x95\x52\xa6\xa8\x06\ +\xb0\x59\x4d\x6c\x16\x32\x2f\xcd\x4d\xbc\x00\x18\x1d\xb7\x97\xb9\ +\xad\x99\x63\xe0\x0e\x63\x31\x2d\x94\xd4\x4e\x27\x75\x05\x4a\xb9\ +\x03\xc3\xd2\xdc\x66\x8b\x6a\x7f\xf1\x2a\x11\xeb\xbd\xec\x24\x2c\ +\x76\xb8\x19\xc6\x22\x9c\x81\x8f\xa5\x32\x1f\x0d\x3e\x4d\xf5\x51\ +\x31\x26\x32\x8f\x45\x5e\xb3\x1c\x7d\x74\x58\x12\xec\x90\x94\xdb\ +\x5d\x54\x55\x73\xd7\xfb\x55\xb3\x36\x7c\xdc\xcf\x2f\x9e\xc3\x58\ +\xae\x47\x03\x7a\xc8\xfc\x22\xe5\x7c\x34\xb0\x91\xed\x7b\x3e\x26\ +\x87\xdc\x68\x33\x1a\x98\x8c\x21\xee\x71\x97\x7a\x47\x5c\x58\x8f\ +\x12\xe4\x3a\x8c\x91\xa3\x89\x01\xff\x1c\xc2\xce\x4c\xc3\xad\x00\ +\xa5\xf4\x4f\x3d\x7f\xf1\x2c\xd7\xb3\x5c\x81\x53\xe6\x4b\x71\x38\ +\x52\x71\xcc\xc9\x44\x6e\xfa\xd9\xe0\x05\x4b\x15\xd0\xe6\x32\x4b\ +\x4a\x08\x9a\xc5\xa6\x3d\xeb\x32\x89\x45\xd1\x3f\xb0\xc8\xc2\x85\ +\x39\x4b\xe5\x24\x4c\xfb\x05\xd6\x49\x06\x20\x99\x95\x7f\x13\xd6\ +\xd8\xe0\x50\xa2\x76\x76\x17\x1f\x61\x52\x49\xc0\xde\x8f\xec\x50\ +\xb1\xb6\xa7\x59\xf3\x70\x93\xcc\x93\x2f\x02\x80\x21\xda\xed\xc0\ +\xb5\x3a\xb0\xec\x86\x19\x46\xb9\x55\x81\xbb\xd9\x2a\xda\xa0\x26\ +\x2a\x3c\x15\x81\xfa\xbe\xdb\x10\x65\x9e\x40\x3c\xb4\xb6\x53\x93\ +\xb6\x6d\x92\x0a\x73\xc8\xd2\x1b\xed\x5f\xda\xfb\xdc\x43\xde\xb6\ +\xcd\xab\xdc\xde\x3a\xf6\x7b\x4d\x9f\x8b\x32\x8c\xc3\x32\xdc\x07\ +\x41\x4d\x81\xbd\xe1\x5a\x33\xc8\x98\xc1\x5f\x3f\xff\x38\xae\x16\ +\x1a\x46\x51\xf0\x4f\x99\xbf\xd4\xeb\x1a\x86\x12\x08\x27\x72\x09\ +\x48\x0f\xc6\x0d\x79\x18\x47\x01\xe4\x38\x88\xfd\x71\x32\x07\xd7\ +\x56\xe9\xf1\x4f\x90\xd3\x86\xd6\x9e\xd1\x11\x56\x60\xed\x27\xdd\ +\x4d\x9b\x8b\x5d\xb2\xec\xad\x18\x71\x34\x4f\xd4\x20\xeb\x6f\x65\ +\x92\xa6\x3f\xa9\x45\x2a\x8d\x5b\x93\x26\x65\x2a\xf6\xc4\xa1\x55\ +\xed\xbe\xd2\xcd\x6a\x29\x37\xb4\x6a\xed\xf5\xd5\x6c\x8f\x4a\x27\ +\x28\x1a\x43\xa7\xe1\x44\x80\x87\xfe\xac\x98\xc6\x11\x77\x96\xcb\ +\xe5\x62\x2e\x63\x51\x0d\x6f\xd0\x14\x51\xd9\x98\xac\xdc\xa6\xc0\ +\xd7\xf9\x24\xf8\x84\xf5\xf1\x14\x27\xc5\x02\x46\x40\xe2\x4f\x93\ +\x4c\x3c\x49\xc8\xb8\xd3\x54\xae\x83\x55\x52\x24\x93\x54\x3c\xe9\ +\xdf\x24\x05\xcd\x1b\xd2\x14\xd4\x0f\xaa\x4c\xa5\x2f\xcc\x2a\xcf\ +\x04\x64\x77\x99\x2f\x53\x11\x64\x32\xfb\x02\x19\xea\xa9\x28\x73\ +\xf9\x22\xb4\xfc\x64\x3a\xa9\x2e\x77\xd1\x14\x40\x56\xc7\xcc\x73\ +\x99\xcb\x6b\xba\xda\x04\x28\x14\x4c\x96\x65\xd9\xa6\xfd\x4b\x26\ +\x59\x00\xf8\x8b\xbc\xa6\xea\x8b\x14\x02\xa3\x0c\x9a\xd1\x71\x08\ +\x19\x2d\xcf\x41\x1d\x58\x5d\xb4\xa9\x72\x3a\x2d\x44\x19\xe0\x9a\ +\xb6\xdf\xf1\x3c\xcc\x5f\x44\xbe\x1b\x20\xb2\x10\x14\x34\x27\x61\ +\xf4\xa2\x00\xcd\xe2\x40\x55\x8c\xf9\x32\x85\x2e\xa4\x13\x50\x0a\ +\x56\xe6\x7a\xc4\xc4\xe6\x3e\x5c\xea\x0c\xc1\x91\x47\xb8\x47\x9c\ +\x86\x51\x27\x06\x62\x23\x46\x3c\x9b\x78\x0d\x07\x42\x8b\x62\xe4\ +\x72\xec\x72\xda\x10\x21\xa6\x18\x45\x98\xfa\x0e\xf5\x1b\x62\x0e\ +\xa2\x2e\x72\x6c\x0c\xc1\xd6\xa2\xea\x78\xad\x1d\xee\x9d\x5b\x9b\ +\x20\xc6\x61\xf7\x84\x93\xfb\xb5\xb6\x6b\x7a\x47\xf6\x76\x90\x36\ +\x95\x7b\x64\x6f\x86\x91\xc3\x5c\x5c\x75\x3d\x95\xbd\x39\xe2\xfa\ +\xe8\xd8\x9b\x78\x88\x60\x10\xe5\x1d\x7b\x7b\x88\x13\x1b\xbb\x8c\ +\xdf\xab\xbd\xa9\xeb\x51\x50\xca\xbb\x63\x7b\x9f\x1f\xdd\xbd\xd6\ +\x66\xd0\x43\xa9\x83\xb5\xad\x4d\x91\xab\xb2\x00\x77\xbe\xa5\xe8\ +\xfe\x06\x72\xf9\xd7\xc8\xe4\xb5\xad\xf9\x7b\xb1\xb5\x43\xa6\x53\ +\xc6\xdf\x6a\x6b\x8f\xb8\xb6\xc7\x6d\xf7\x5e\x6d\x4d\x4c\xe7\x02\ +\x6b\x53\x64\xab\xbb\x57\xfe\x6a\x64\xbf\xbb\xba\x7d\x25\x6b\x3b\ +\xc4\xc3\xbe\xcb\xee\xd6\xda\x17\xd8\x9a\x21\x9f\xda\x3e\x75\x5f\ +\x8d\xec\xfe\x9a\x7d\xf7\xb6\xbe\xf3\x2c\xfe\xc6\x1c\x6e\xef\xac\ +\x6f\xbb\x3d\x39\xdc\x26\x6f\xb6\xf4\xe9\x72\x8b\x5b\x86\x12\x2b\ +\x91\xc9\x38\x6e\x0c\x55\x39\x46\xc7\x50\x0e\xf2\x98\x43\x09\xa6\ +\xf6\xe5\xf0\x37\x50\x1f\x21\x08\x37\xe2\xfe\x21\x82\x36\x46\xaa\ +\xad\x69\xe9\x59\x23\xc8\x3d\x1d\x16\xac\x5b\x05\x91\xca\x7f\xed\ +\x14\xa8\x9f\x11\xb0\x1d\xae\x07\xfd\x2d\x03\x6f\xf3\x6d\xda\x41\ +\xd0\x46\xae\x6f\x33\x9f\xed\x27\x68\xee\x72\xcb\x3c\xcc\x0a\x75\ +\x33\x6f\x46\x22\x03\x6d\xd5\x03\x15\xd3\x41\x2e\x71\xa0\xc9\x74\ +\xcf\x90\xdf\x6a\x79\xee\x7b\xae\xe3\xd8\x7b\x4b\x2d\xc2\xf2\xb9\ +\xcf\x52\x2d\xd0\xfa\xad\x40\x10\x67\x0e\xe3\xbe\xc3\x16\x9b\xcb\ +\x03\xe6\xd8\x0e\xea\x99\x88\x51\x67\x9b\x47\x8e\x88\xab\x0e\xcf\ +\x58\x19\x9c\x20\x7d\xee\x52\x03\x77\xcc\xa6\xf6\xce\x5c\x97\x1d\ +\x6b\x1f\xc9\x0c\x76\x52\xca\xdc\x8c\x96\xf9\x2a\x2c\x97\xb9\xe8\ +\xf8\xe7\x7b\xd2\xfa\x17\xa3\xae\xa7\x76\x4b\xed\x7f\x18\x1c\x02\ +\x52\x53\xfb\x74\xb6\xef\x5d\xe7\xfa\x5e\xd0\x7e\xac\x8b\x89\x6d\ +\xfc\xc5\x80\xb0\xf2\xd4\xe1\xf7\xe9\xdc\xe3\xe5\xf7\xaa\x73\xd3\ +\x2c\xbd\xa6\x73\x4f\x26\x78\x4d\xe7\x52\x6c\x9a\xdc\xbb\x99\xa7\ +\x81\x7e\x63\x01\x13\xe6\xa2\x10\xf9\x6a\x5f\x3a\x6a\x3c\x64\x56\ +\x9a\xfa\x1c\x50\xc9\xe7\x61\xfa\xa4\x29\x6b\x9d\xe8\x3a\xa4\x22\ +\xf9\x22\x02\x68\x08\x3d\x8d\x17\xf1\x01\x19\xa5\x7e\xf5\xf0\x37\ +\xc0\x7f\xdc\x89\x4d\xc3\x79\x92\x6e\x83\x02\xf2\x8f\x09\x2b\x26\ +\xd3\xa7\x54\x94\x2a\x03\x55\xcf\x4d\x03\x0c\x03\xd7\x32\x8f\x3b\ +\x84\x5d\x79\xa8\x4c\x71\x50\xc7\x2b\x43\xb5\xf3\x78\x6d\x25\xdc\ +\x79\x35\xa0\xb3\xb0\x87\x74\xcb\xe6\xf0\x4e\x16\x56\xa9\xd5\x87\ +\xb6\xbd\x03\xb2\x82\x8a\x79\x64\x0f\x72\x93\x35\x47\x03\x00\x3b\ +\x15\xdf\xc1\x0a\x8c\x70\x4a\xe8\x23\xb4\x07\x0e\x24\x67\xe7\xfb\ +\x63\x8b\xf4\xbd\x3c\xe9\x13\xd8\xbf\x40\x19\x96\xa0\x7b\xb6\x7f\ +\x06\xdb\x3c\x36\xce\xa5\xb2\x89\x82\x75\xb0\xe7\xea\xad\xaa\x01\ +\xcc\xa3\xa4\x45\xef\x55\xf6\x84\xba\x07\xf6\xae\x4c\x09\xcd\x1e\ +\xe1\xf6\x81\x21\x09\x82\xca\x7a\xc2\x94\x27\xe0\x1f\xbb\x43\x4b\ +\xef\x70\x0c\xbf\x00\xea\x87\x2b\xee\x1a\x02\x40\xd8\x23\xb6\xdf\ +\x71\x45\x86\x11\x71\xda\x77\x54\x6d\x4f\x34\xe9\x65\xbe\xf8\x16\ +\x4f\x32\x59\xd7\x97\x8e\x77\xdb\xbf\xdf\xaf\xec\x4a\xde\x87\x2b\ +\xf5\xb8\x12\x73\x11\xe3\x36\xf6\x3a\xbd\x25\xe7\xc8\xa6\x8e\x77\ +\xca\x95\xcc\x0b\x13\xdb\xdb\x9c\xa9\xf5\xc0\xf0\xc4\x8e\xfb\xf7\ +\xfc\x95\xdd\x89\x36\xee\x74\x91\x72\xa7\x15\x70\x30\x72\x3c\x1b\ +\xba\xd1\x1b\x69\xd0\x0b\x38\xb4\xf0\xe3\xff\xfc\xfb\x23\x52\xce\ +\x4d\xba\xff\xbb\xfe\x43\xa8\xe0\x9b\x86\xca\x79\x99\xf7\xe6\x55\ +\x1c\x7f\x38\xd4\xb9\xa9\xf7\x75\x87\xba\x71\xf6\x3d\x37\xff\xde\ +\xdc\xa9\xf8\x87\x53\x9d\x7b\x97\xf2\x4a\x6b\x68\xde\xb8\x3d\x34\ +\x5d\x93\x76\x7d\xea\xc4\xed\xc6\xad\x5b\xc4\xdf\x5f\xd3\x4f\x28\ +\xc0\x1d\xc4\x28\xa5\x8e\xff\xff\xad\xe9\x00\xf7\x47\x55\xbf\xa0\ +\xaa\xbf\xda\xff\xde\xba\x03\x36\xc9\x59\x85\xfd\xd6\x3d\x30\xf9\ +\xdd\xf1\x72\x42\x81\x77\xd2\x03\x9b\xce\x47\xbc\x5c\x52\x5f\x5e\ +\x8f\x17\x76\xe3\x78\x71\xce\x4b\xcf\x37\x8e\x17\xf7\xda\xf5\xe5\ +\xbd\xc4\x0b\xfe\x88\x97\x4b\x9a\xfc\xd7\xfb\xb1\x56\x62\xbc\x4d\ +\xc0\xf0\xae\xbf\x9d\x68\xf2\x6f\xdd\x90\xe1\x6b\x3f\x64\x79\x2f\ +\x0d\x19\x3b\x19\x30\x67\xbd\x5a\xaa\x5e\x77\x7f\xfd\x17\xa7\x84\ +\x21\xa6\x8f\x47\x6c\x44\x06\x6e\xbd\x48\x3c\x75\xbe\xea\x79\x99\ +\xca\x71\xeb\x85\xf6\x75\x5f\xb2\xdd\x0c\x09\xea\xa0\xdd\x37\xf9\ +\x6f\x46\xa2\x75\xf3\x73\xaf\x58\xf8\x48\x7d\x90\xf0\x76\xa7\x30\ +\x29\xbf\x77\x2c\x38\xbe\x02\x0a\xad\xc7\x84\xf7\x0a\x43\xf5\x91\ +\xca\x55\x7c\xc2\xbc\x7f\xaf\xa8\xbe\x7a\x72\xae\x03\x87\x79\xff\ +\xe9\xb3\x76\x0f\x0f\xb1\xdd\x47\x29\x1d\x5c\xec\x93\xe7\x27\x71\ +\x21\xf7\x0e\xc9\xfe\xb3\x0d\xb8\x1b\xa6\xea\x93\x3a\xda\xc6\xc4\ +\x3b\x71\x7a\x1a\x90\xfb\x2f\x2c\x76\xd5\x6d\xb0\x47\xe6\x20\xaa\ +\xcb\xed\x1b\x21\xb9\xfb\xc0\x81\x49\xf5\xd7\x96\x57\xf4\x92\xfb\ +\x07\x85\x21\x7a\x35\x0f\xf9\x06\x8a\x6f\xf3\xff\xa2\x57\x04\xc5\ +\xbb\x18\x96\xa1\x35\x1b\x3f\x0c\xd5\x7f\x89\x8e\x1f\xfe\x0b\x5f\ +\x2f\x09\x26\ +\x00\x00\x0b\xed\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x6c\x6f\x61\ +\x64\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ +\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\ +\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\ +\x6d\x3d\x22\x31\x2e\x39\x37\x39\x35\x31\x30\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ +\x33\x36\x2e\x39\x36\x33\x33\x31\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x38\x2e\ +\x39\x35\x30\x31\x32\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ +\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\ +\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\ +\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\ +\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ +\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ +\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ +\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ +\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ +\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ +\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ +\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ +\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ +\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ +\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ +\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ +\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\ +\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\ +\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\ +\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\ +\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ +\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ +\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\ +\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\ +\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\ +\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\ +\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\ +\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\ +\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\ +\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\ +\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ +\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\ +\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\ +\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\ +\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\ +\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ +\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\ +\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\ +\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x32\x32\x32\ +\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\ +\x33\x33\x34\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\ +\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\ +\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x38\x2c\x39\x2e\x36\ +\x36\x36\x36\x36\x36\x37\x20\x43\x20\x33\x2e\x38\x31\x34\x30\x31\ +\x30\x37\x2c\x31\x34\x2e\x38\x37\x36\x37\x39\x35\x20\x34\x2e\x34\ +\x33\x32\x38\x39\x30\x37\x2c\x32\x32\x2e\x36\x34\x34\x37\x39\x34\ +\x20\x39\x2e\x34\x2c\x32\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x31\ +\x34\x2e\x33\x36\x37\x31\x30\x39\x2c\x33\x31\x2e\x34\x38\x38\x35\ +\x34\x20\x32\x31\x2e\x39\x34\x37\x33\x34\x32\x2c\x33\x30\x2e\x38\ +\x31\x30\x31\x32\x38\x20\x32\x36\x2e\x31\x33\x33\x33\x33\x31\x2c\ +\x32\x35\x2e\x36\x20\x63\x20\x34\x2e\x31\x38\x35\x39\x39\x2c\x2d\ +\x35\x2e\x32\x31\x30\x31\x32\x38\x20\x33\x2e\x35\x36\x37\x31\x31\ +\x2c\x2d\x31\x32\x2e\x39\x37\x38\x31\x32\x37\x20\x2d\x31\x2e\x34\ +\x2c\x2d\x31\x37\x2e\x34\x20\x6c\x20\x33\x2c\x2d\x32\x2e\x38\x36\ +\x36\x36\x36\x36\x37\x20\x48\x20\x31\x37\x2e\x30\x36\x36\x36\x36\ +\x35\x20\x56\x20\x36\x2e\x34\x20\x6c\x20\x33\x2e\x32\x2c\x38\x2e\ +\x35\x33\x33\x33\x33\x33\x20\x32\x2e\x36\x36\x36\x36\x36\x36\x2c\ +\x2d\x33\x2e\x37\x20\x63\x20\x32\x2e\x33\x37\x39\x33\x30\x32\x2c\ +\x33\x2e\x32\x37\x37\x37\x32\x39\x20\x33\x2e\x31\x37\x31\x30\x35\ +\x38\x2c\x38\x2e\x39\x35\x30\x32\x36\x36\x20\x30\x2e\x35\x33\x33\ +\x33\x33\x34\x2c\x31\x32\x2e\x32\x33\x33\x33\x33\x34\x20\x2d\x33\ +\x2e\x30\x34\x31\x38\x35\x39\x2c\x33\x2e\x37\x38\x36\x30\x37\x34\ +\x20\x2d\x38\x2e\x32\x32\x30\x37\x31\x35\x2c\x34\x2e\x32\x31\x39\ +\x37\x32\x20\x2d\x31\x31\x2e\x37\x39\x39\x39\x39\x38\x2c\x31\x2e\ +\x30\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x35\x37\x39\x32\x38\x33\ +\x35\x2c\x2d\x33\x2e\x31\x38\x36\x33\x38\x37\x20\x2d\x34\x2e\x30\ +\x34\x31\x38\x35\x38\x35\x2c\x2d\x38\x2e\x39\x31\x33\x39\x32\x35\ +\x20\x2d\x31\x2c\x2d\x31\x32\x2e\x37\x20\x43\x20\x31\x31\x2e\x32\ +\x2c\x31\x32\x2e\x33\x20\x31\x31\x2e\x32\x2c\x36\x2e\x39\x36\x36\ +\x36\x36\x36\x37\x20\x38\x2c\x39\x2e\x36\x36\x36\x36\x36\x36\x37\ +\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ +\x61\x74\x68\x32\x39\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ +\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x73\x73\x63\ +\x63\x63\x63\x63\x63\x73\x73\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\x08\ +\x00\ +\x00\x1e\xb4\x78\x9c\xdd\x59\x5b\x6f\xdb\x36\x14\x7e\xef\xaf\x10\ +\x14\x0c\x68\xb1\x88\xa2\x44\xdd\x63\xbb\x2f\x45\x81\x01\x7b\xda\ +\x3a\xec\xb1\x90\x25\xda\xd1\x2a\x89\x1e\x45\xc7\x56\x7f\xfd\x0e\ +\xa9\xbb\x2d\x63\x0d\x6a\xb7\x69\x65\x04\x89\xce\x85\x3c\xe7\x3b\ +\x17\x1e\x33\x8b\xb7\xc7\x22\xd7\x9e\x28\xaf\x32\x56\x2e\x75\x0b\ +\x61\x5d\xa3\x65\xc2\xd2\xac\xdc\x2e\xf5\xbf\x3e\xbc\x37\x02\x5d\ +\xab\x44\x5c\xa6\x71\xce\x4a\xba\xd4\x4b\xa6\xbf\x5d\xbd\x5a\x54\ +\x4f\xdb\x57\x9a\xa6\x81\x72\x59\x45\x69\xb2\xd4\x1f\x85\xd8\x45\ +\xa6\xb9\xdb\xf3\x1c\x31\xbe\x35\xd3\xc4\xa4\x39\x2d\x68\x29\x2a\ +\xd3\x42\x96\xa9\x0f\xe2\xc9\x20\x9e\x70\x1a\x8b\xec\x89\x26\xac\ +\x28\x58\x59\x29\xcd\xb2\xba\x1b\x09\xf3\x74\xd3\x4b\x1f\x0e\x07\ +\x74\x20\x4a\xc8\x0a\xc3\xd0\xc4\xb6\x69\xdb\x06\x48\x18\x55\x5d\ +\x8a\xf8\x68\x4c\x55\xc1\xc6\x39\x55\x1b\x63\x6c\x02\x6f\x90\xfc\ +\x32\xa9\xa8\x02\x54\x76\xf0\xd3\x8b\x77\x04\x54\xb1\x3d\x4f\xe8\ +\x06\xf4\x28\x2a\xa9\x30\xdf\x7d\x78\xd7\x33\x0d\x8c\x52\x91\x8e\ +\x96\xc9\xca\x4f\x55\x12\xef\xe8\x64\xd7\x8e\xd8\x20\x10\x17\xb4\ +\xda\xc5\x09\xad\xcc\x8e\xae\xf4\x0f\x59\x2a\x1e\x97\x3a\x71\x90\ +\x45\xe0\x71\x15\xf1\x91\x66\xdb\x47\x71\x4a\xcd\xd2\xa5\x0e\xd6\ +\xdb\x61\xd0\xbc\x8f\x22\x6c\x35\x02\xed\xc2\xd1\x38\xf6\xc8\xd6\ +\x5e\xd3\xc0\x4b\x02\x1f\x07\x7e\x78\xaf\xd9\xd8\xb6\x0c\x6c\x19\ +\x96\xfb\x46\x29\x75\x3e\x45\x29\x4b\xa4\x91\xb0\x07\x2d\xb2\x78\ +\x2f\x58\x01\x61\x4c\x92\x3c\xae\xaa\x6c\x93\x25\xf0\xc2\xca\x5d\ +\xbe\xdf\x66\xe5\x47\xc6\x53\xca\x3f\xae\xeb\x8f\x69\x2c\x28\xea\ +\x10\xed\xb7\xa7\xc7\x1d\xe3\xc2\x38\xa6\x3b\xc0\xd5\xf3\x67\x99\ +\x75\xc7\x5c\x01\x77\x91\xd2\x4d\x25\xa5\x1a\x27\xe5\x1b\x78\xe9\ +\xeb\x9a\xa9\xb8\xbd\x89\xd2\xbe\xf4\x29\xa3\x87\x41\x76\x1d\x57\ +\x0d\x90\x9a\xb6\x8b\xb7\x90\x74\x39\xe3\x4b\xfd\x6e\xa3\x9e\x96\ +\xb1\x56\xf6\x76\x2c\x4f\x3d\x13\x16\x83\xc0\x64\xa2\x6e\x6a\xa5\ +\x5d\xbb\xb3\x57\xae\xda\xf3\xf1\x3c\xbf\x7a\x8c\x53\x76\x58\xea\ +\xf6\x29\xf3\x33\x63\xc5\x52\xf7\x51\x68\x05\xd8\xb1\xfc\x53\x76\ +\x72\x04\x1d\x82\x88\x1d\x3a\xc4\x3b\x63\xd6\x52\xd3\x77\x88\x45\ +\xec\x73\xe6\x9e\x73\xa8\x43\x23\x8f\x6b\x0a\x4e\xa9\x5f\x56\x2b\ +\x54\x3d\xb2\xc3\x96\x4b\x70\x04\xdf\xd3\x53\x4d\xc9\x31\xd6\x6b\ +\x76\x9c\x67\x43\x16\xec\x65\x85\x1b\xfb\x32\x13\x50\x45\xbb\xe3\ +\x78\xd5\x7d\x96\xd2\x6a\x5e\xf1\x90\x95\x80\x81\xd1\xe6\xb3\x45\ +\xbc\x33\x9b\x5b\x89\x2e\xb9\x7d\x7c\x49\x02\x4c\x3b\x83\xb9\x65\ +\xd5\x97\x59\x45\x7c\xcc\x8a\xec\x33\x05\xbf\xad\x53\x91\xaa\x8c\ +\x77\xc6\x36\x67\xeb\x38\xff\x1f\xb7\x39\x13\x2a\xd3\xe5\x3e\x2b\ +\x25\xb4\x98\x40\xd7\xe8\x69\x9a\xa8\x65\xb5\x1f\x6b\x49\xd3\x3b\ +\xa2\xc4\x5c\x12\x88\xef\xb9\x3d\x91\xf1\x0c\x6a\x66\xe4\x53\x47\ +\xaa\xc7\x24\xd9\x1b\xa0\x3f\x1f\x55\x0e\xaa\x0c\xf5\x4f\x79\xf5\ +\x98\xd7\x96\x86\x79\x5e\x1b\x8a\x5e\x50\x11\x43\x71\xc6\x43\xa1\ +\x74\x14\x3b\x0c\x7b\xcf\xa0\xcd\x46\x7f\xbc\x7b\xbf\x6a\x37\x5a\ +\x24\x49\xf4\x37\xe3\x9f\xba\x7d\x35\x4d\x0a\xc4\x6b\xb6\x87\x70\ +\xe9\xab\x9e\xbc\x48\x93\x08\x1a\x23\xf4\x87\x55\x56\x40\xfa\xcb\ +\x9e\xfa\x2b\x34\xc2\x85\x39\x30\x26\xc2\x12\xac\x61\xd1\x66\x59\ +\x4e\x9b\x0e\x3b\x7b\xcc\xa4\x49\x91\x49\x25\xf3\x4f\x91\xe5\xf9\ +\x6f\x72\x93\xd6\xe3\xd1\xa2\x99\xc8\xe9\x40\x5c\x98\xad\xf5\xad\ +\x6f\xe6\xc8\xb9\x85\xd9\x79\xaf\xde\xb6\x03\x2a\x93\xc2\xe9\x03\ +\x9d\xc7\x6b\x0a\x89\xf2\xbb\x64\x6a\x67\xdc\x2d\x67\xfb\x5d\xc1\ +\x52\xda\xaa\xf7\x68\xd2\x44\xf4\x21\x13\x75\x0e\xfc\x0d\x58\x1f\ +\xdd\xf9\x41\xb8\x8e\xed\x07\xf9\x62\xb4\xad\x24\xb2\x9a\x57\xbe\ +\xcf\xa1\x25\x3e\xd1\x92\xa5\xe9\x43\x25\x38\xfb\x44\xa3\x3b\xea\ +\xc9\x4f\xfb\xda\x54\x54\x64\x23\xa7\x23\xe4\x59\x49\xc1\x90\xa8\ +\xfa\x77\x1f\x73\x3a\xa6\xfe\xc3\xb2\x32\x02\xe4\x28\xef\xa8\xea\ +\x25\x87\xba\x10\x51\xaf\x9f\xc6\xd0\xaf\x38\x8f\xeb\xa8\x84\xe3\ +\x7f\x4c\x65\x9b\x4d\x45\x45\x84\x3b\x5a\x6f\xec\x24\xc3\xa5\x9f\ +\x04\x5b\x43\xee\x76\x67\x98\xdd\x53\xfa\x03\x6c\x20\xcd\x66\xf6\ +\x90\xd2\xfe\x40\xe4\x40\xf5\x10\x0e\x5d\x9b\x04\x76\x1f\xf6\x85\ +\xa0\xc7\x1e\x5e\x48\xb6\x48\x9d\xa6\xd0\xa0\x20\x91\x28\x7f\xa2\ +\xfa\x29\xf4\x0c\xaa\x59\xfd\x0d\x6e\x42\x4a\xe6\x0f\x8a\x72\x50\ +\x96\x4d\x48\x15\x34\x8d\xc8\xf2\x10\x8c\x07\xf6\xee\xf8\x20\x81\ +\x6c\x9b\x54\x84\x7f\x69\x44\x36\x71\x91\xe5\x75\x54\xc5\x65\x65\ +\xc0\x6e\xd9\xe6\x21\xa7\x02\x90\x35\xda\xd2\x8c\x30\x28\x1e\xe0\ +\x2c\x99\x10\x9a\xe8\xc3\xd0\x81\x5d\xef\x34\xfa\x6d\xac\xc7\x11\ +\x68\x02\x6d\x21\xe2\x62\xc7\x79\x7e\x00\xcf\x83\x05\x90\x07\xc8\ +\xc3\x5e\x18\x04\x13\xc4\x43\x80\xdc\x81\x23\x67\x12\x55\x09\x2f\ +\xf4\x86\xa1\x6f\x09\x0e\xde\xca\x6a\x86\x89\x20\x89\x73\xfa\xda\ +\x42\xb6\xe3\xba\x21\x76\xef\x31\x0a\xb0\x1d\x10\x1b\xfb\x6f\xf4\ +\xd5\x42\x80\xcf\xe5\x50\xde\x7d\x47\xe2\x4c\xc6\x41\xc2\xa9\x0f\ +\x5c\xb5\x95\x54\x80\xbd\xfc\x11\x7d\xce\xd6\x0b\xd6\x9e\x84\x58\ +\x46\x0f\x0e\x51\xc7\xf7\xc3\x93\xe8\x81\xc1\xee\xa5\xf8\x35\xb1\ +\xd9\x84\xf2\xf3\x2d\x63\xb3\xb2\x16\xa6\xf2\x7f\x05\xbf\x01\xf2\ +\x36\xb9\xb7\x93\x23\x24\xb4\xfd\xb9\x30\x40\x5f\xe5\xd9\xf1\xb5\ +\x75\x8f\xe1\x03\xb6\xa8\xc7\x81\xbf\x0d\x0b\xde\x7c\x78\xc2\x37\ +\x67\x65\xd0\xe7\x20\xc6\x7d\x0b\x9f\xb4\xaa\x59\xd1\x67\x40\x82\ +\x3d\xff\x1a\xc9\x3a\xf4\x96\xc0\x1d\xc7\xba\x6d\x2e\x1e\x72\x94\ +\x61\x63\x85\xae\xcb\xcc\xf1\x64\xbb\x71\x50\xa8\x20\x9a\x26\x94\ +\x0d\x43\x95\x02\x6e\x74\xa2\xbc\x78\x40\x8c\xeb\x40\x62\xb7\x59\ +\xe3\xfc\x0c\x90\x78\xd7\x81\xa4\xf7\xfd\x27\x80\xc4\xbf\x2a\x24\ +\xee\x09\x24\x6d\xf2\xd8\x3f\x14\x24\xee\x4d\x0b\xa7\x27\xff\x48\ +\x90\x90\x2b\x61\x32\x9f\x26\x5d\xdb\xbd\x11\x26\x18\xf9\xae\xe3\ +\x04\xe4\x06\xfd\xc4\x3e\x87\x85\x20\x79\x2b\x15\x86\xe4\xcb\x61\ +\x21\xb8\xf3\x7f\x02\x4b\x80\x5c\x95\x2a\xc1\x30\xd1\x9a\xdb\x4b\ +\xa7\xbf\x11\x3e\xe3\xfc\xef\x26\x68\x02\x73\x00\x46\xc4\x82\xc7\ +\xbd\x30\x07\xc8\x4b\x91\x2f\x9c\x03\x1a\xd1\xef\x9d\xaa\xd6\x55\ +\x32\xf5\x4a\x93\xc0\xcb\x80\x84\x18\x33\x79\xfa\xfd\x66\x81\x97\ +\x01\x8a\x77\xe5\xa3\xef\xa7\x00\xc5\x37\xf0\x2d\x1b\xfd\x73\xe7\ +\x81\x97\x01\x8a\x3b\xea\xad\x2f\x60\x22\x78\x19\xa0\x10\xf7\x5a\ +\x5f\x30\xae\x33\x13\x3c\x13\x95\x5b\xce\x04\x73\x5f\x33\xbe\xcd\ +\x54\x70\xe3\x0b\x2f\x07\xd9\x8e\xf3\x22\x2e\xbc\xac\xc0\x27\xe1\ +\x95\x2e\xbc\xe4\x25\x15\x91\x77\x87\xe3\x1b\x2f\x42\x10\x76\x82\ +\xc0\x1f\xae\x96\xc6\x37\x5e\xc6\xec\x65\x4b\x77\xe7\x05\x6b\x59\ +\xa1\x0f\x33\x17\x0a\x2d\x82\x7d\xdf\x73\xbf\xee\xce\x6b\xf2\x85\ +\x64\xd6\xe0\x0b\x26\xcf\x5d\x7b\x61\xe4\x39\xe4\x34\x86\x37\xb8\ +\xf6\xfa\xea\x08\xad\xec\xf3\x6b\x2f\x95\xe9\x0b\xf9\xcf\x83\xd5\ +\xab\xff\x00\x41\xba\xbf\x82\ +\x00\x00\x06\xf1\ +\x00\ +\x00\x2b\x10\x78\x9c\xe5\x5a\x6d\x6f\xdb\x36\x10\xfe\xde\x5f\x61\ +\x38\x18\x90\x60\xa1\x24\x52\x92\xf5\x12\x3b\xfd\xb0\xa2\xc0\x80\ +\x01\x1b\xd6\x16\xfb\x38\xd0\x12\x6d\x6b\x91\x45\x41\xa2\x63\xbb\ +\xbf\x7e\x47\x49\xd4\xab\x93\xd6\xab\x9d\x3a\x9d\x8c\x22\xe2\xdd\ +\xf1\xe5\x9e\x3b\x3e\x3a\x4a\x9d\xbe\xdd\xad\xe3\xd1\x23\xcb\xf2\ +\x88\x27\xb3\x31\xd6\x8c\xf1\x88\x25\x01\x0f\xa3\x64\x39\x1b\x7f\ +\xfa\xf8\x1e\xb9\xe3\x51\x2e\x68\x12\xd2\x98\x27\x6c\x36\x4e\xf8\ +\xf8\xed\xfd\x9b\x69\xfe\xb8\x7c\x33\x1a\x8d\xa0\x73\x92\xfb\x61\ +\x30\x1b\xaf\x84\x48\x7d\x5d\x4f\x37\x59\xac\xf1\x6c\xa9\x87\x81\ +\xce\x62\xb6\x66\x89\xc8\x75\xac\x61\x7d\xdc\x98\x07\x8d\x79\x90\ +\x31\x2a\xa2\x47\x16\xf0\xf5\x9a\x27\x79\xd1\x33\xc9\xaf\x5a\xc6\ +\x59\xb8\xa8\xad\xb7\xdb\xad\xb6\x35\x0b\x23\xec\x79\x9e\x6e\x10\ +\x9d\x10\x04\x16\x28\xdf\x27\x82\xee\x50\xb7\x2b\xac\xf1\x50\x57\ +\x62\x18\x86\x0e\xba\xc6\xf2\xeb\xac\xfc\x5d\x1c\x25\x0f\x4f\x2e\ +\xa6\xd0\xb6\x67\x07\x0c\x53\xf8\x57\x77\x50\x02\x2d\xe7\x9b\x2c\ +\x60\x0b\xe8\xc9\xb4\x84\x09\xfd\xdd\xc7\x77\xb5\x12\x19\x5a\x28\ +\xc2\xd6\x30\x30\x68\x1e\xd0\x94\x75\xe6\x55\xc2\x12\x2f\xba\x66\ +\x79\x4a\x03\x96\xeb\x4a\x5e\xf4\xdf\x46\xa1\x58\xcd\xc6\xa6\xa5\ +\x61\x13\x2e\xbb\x10\xae\x58\xb4\x5c\x89\xbe\x34\x0a\x67\x63\xf0\ +\x95\x78\x6e\xd9\x6e\xe5\x03\x2e\x0d\xaa\x81\xfd\x76\xa6\x68\x64\ +\x74\xcd\xdc\x49\xe0\x3a\x86\xeb\x78\xb7\x23\x62\x10\x8c\x0c\x8c\ +\xb0\x7d\x53\x74\x52\x3e\xf9\x21\x0f\xe4\x22\x61\x0e\xb6\x8e\xe8\ +\x46\xf0\x35\x04\x3d\x08\x62\x9a\xe7\xd1\x22\x0a\xa0\xc1\x93\x34\ +\xde\x2c\xa3\xe4\xef\x39\x15\xc1\x4a\x53\xb8\xd7\xd3\xb2\x5d\xca\ +\x33\x81\x76\x61\x0a\x78\x4e\x9c\x83\xca\xbd\x52\xde\x83\x76\x1a\ +\xb2\x45\x2e\xad\x4a\xe7\x64\x0b\xbc\x2b\x75\xa0\x0d\xe2\x28\xfd\ +\x83\x8a\x55\x69\x31\x1a\xa9\xf6\xa7\x24\x12\x90\x0e\x9b\x9c\x65\ +\x1f\x24\xa4\xbf\x27\x9f\xf2\x12\x4d\x35\x92\xb2\xc4\xd8\xb2\xab\ +\xd1\x60\x3c\xe8\xa0\x8c\x20\x70\xb3\xb1\x31\x6e\x9a\xfb\x6e\xb3\ +\xc8\x13\x7f\x95\x31\xc8\xeb\xab\x25\x0c\x83\x5b\x4a\x39\x03\x8c\ +\x05\x52\xa7\x25\xad\x22\x89\x0d\xe3\xa7\x96\x54\x85\xb2\x10\x8f\ +\xf4\xca\x33\x5d\x2d\xf0\x74\x9e\xba\xb0\xc9\x26\xf0\x23\xa7\xf0\ +\xd7\xc5\x2e\x72\x31\x82\x21\xdd\x03\x7e\xbb\xc4\x42\xb6\x81\x20\ +\x87\x2e\xce\xfd\x93\x3a\xff\x8c\xeb\x17\xe6\xf8\xe9\xdc\x7e\xd2\ +\xe7\x0b\xf3\x18\x99\xa7\x0c\xf5\xd3\x91\xf6\x4e\xe1\xf7\x54\x97\ +\xd4\x56\xdc\xd5\x74\x2b\xb9\x36\x7c\x8c\xd8\xb6\xe1\xbf\x39\xad\ +\x5d\x4e\xe9\x12\x1e\xb7\x31\xcf\x60\x99\x8b\xe2\xaa\x14\x73\x9e\ +\x85\x2c\x53\xaa\x49\x71\x75\x54\x1c\xd0\x8b\xc4\xbe\xac\x12\xaa\ +\xb1\x15\x07\xcb\x51\x6b\xbd\x71\x58\x9f\xaf\x68\xc8\xb7\xb3\x31\ +\xe9\x2b\x3f\x73\xbe\x9e\x8d\x1d\xcd\xc3\xae\x61\x61\xb7\xaf\x0e\ +\x00\x78\x78\x2e\x62\x93\x98\xb6\xed\x9a\x03\xb5\x5c\x11\x01\xb5\ +\x63\x91\x61\xdf\x4d\x96\x41\x0d\x82\x62\xba\x67\xe0\x56\xf1\x47\ +\x65\x62\xbe\xe2\xdb\x65\x26\xe1\x11\xd9\x86\xf5\x7b\x4a\x0d\x9a\ +\xcf\xf9\xee\xb0\x1a\x9e\x69\x1b\x59\xdd\xa0\x4d\x99\x5e\xe9\xae\ +\x3d\xea\x26\x0a\x59\x7e\xb8\xe3\x36\x4a\x00\x05\xa4\x22\x6e\xd6\ +\x20\xf7\x2d\x54\xf4\x1d\xe3\x29\x8b\x56\x42\xf6\x55\xfb\xa7\x55\ +\x6b\xba\x8b\xd6\xd1\x67\x06\x7e\xe3\xbe\x49\x9e\xd0\x14\x2d\x63\ +\x3e\xa7\xf1\x17\xdc\xce\xb8\x28\x9e\xdb\x72\x9e\x2a\x31\x3b\xd0\ +\xa9\x2c\x16\x7b\x59\xbb\xec\xf6\x52\xd6\xd9\x74\x52\x60\x3a\x13\ +\xbb\x16\xf2\x2c\x82\x0a\xa0\xb3\xc9\x4a\x51\x67\xa3\xc9\x4a\x07\ +\x6a\xd3\x5d\x91\x85\x45\x8e\x3a\x7d\xdd\xbe\xad\x2b\xb7\xcd\x54\ +\x1f\xee\x8e\x42\xbe\x66\x82\x86\x54\xd0\x66\xab\x28\x09\xf1\xbc\ +\xda\x33\x28\x31\xfd\x3f\xdf\xbd\xaf\x69\x21\x08\xfc\xbf\x78\xf6\ +\xd0\xec\x54\x69\x40\xe7\x7c\x03\xe1\xaa\xc9\x43\x16\x21\x81\x0f\ +\x65\x1e\x54\x3b\xf7\xd1\x1a\x36\x80\xac\x27\x7f\x86\xb2\x0e\x36\ +\x6d\xad\xe8\x18\x4b\xb0\x9a\x41\xcb\x61\x33\x56\xd6\x8b\x07\x4b\ +\xec\x30\x58\x47\xb2\x93\xfe\x41\x44\x71\xfc\xab\x9c\xa4\x26\x8a\ +\x7a\xd0\x48\xc4\xac\x11\x02\x7f\x94\xab\x57\x74\xd2\x72\x6e\xaa\ +\x2b\xef\x8b\xd6\xb2\x41\xa5\xb3\x71\xea\x40\xc7\x74\xce\x20\x51\ +\x7e\x93\xca\xd1\x40\xbb\xcc\xf8\x26\x5d\xf3\x90\x55\xdd\x6b\x34\ +\x59\x20\xea\x90\x89\x7d\x0c\xfa\x05\xac\xde\xbf\x32\x8b\xeb\x2e\ +\x17\x19\x7f\x60\xe5\x0e\xf1\x89\x66\x98\x93\x4a\xe4\x57\x84\xa5\ +\x2c\x2a\xc2\xf1\xb1\x12\x00\x18\x2c\x8b\x21\xbb\x85\x6f\x29\x59\ +\x48\x81\x77\xb2\x8c\xee\xfd\x04\x0e\x30\x77\x72\xa6\xa6\x63\x27\ +\x23\xe5\xba\xbc\x56\x3a\xa9\x02\x1a\x6b\x9e\xbc\x9a\x7a\xa5\x2e\ +\xa2\x61\x71\xf2\xb2\x6a\xcd\xc1\xb4\xdc\x1f\x12\x66\x20\x35\x35\ +\xd2\xd0\xfa\x01\x54\x0a\x2e\xf6\xaf\x8a\x39\x8c\xbb\x30\xca\x53\ +\xc0\x11\x4e\x04\xf0\xa4\x61\x77\x1c\x4a\xf1\x45\xcc\xb7\xfe\x63\ +\x94\x47\xf3\x98\xdd\x15\x7f\xa3\x58\xfa\xa5\x44\x25\xac\x15\x68\ +\x5d\xcf\xcb\x66\xb6\x89\x99\xc4\xe5\x33\xb0\x7b\x0d\x72\x35\x5f\ +\x27\x0c\x75\x53\xce\x0d\xd1\xf5\xe7\x1b\x21\xda\xb2\x7f\x78\x94\ +\xf8\x05\xfe\x47\x04\xa3\x25\xe5\x8b\x45\xce\x04\x84\xdb\x35\x89\ +\x6b\x60\xdb\x1d\x06\x79\x4d\xb3\x07\x96\x95\x3d\x59\x42\xc1\x41\ +\x34\xa7\xc1\x83\x4c\xb3\x24\xf4\x69\x00\xcc\xb4\x89\xa9\x60\x83\ +\xa0\x5a\xc6\xc4\x1a\x44\xd5\xd1\x64\xb2\x11\x6b\x18\x55\x57\xb3\ +\x81\x98\x4c\xd2\x8e\x2a\xc2\xb8\x4a\x83\x76\x58\x4d\x4f\xb3\x86\ +\x61\x9d\x68\x13\xc7\x84\xa7\xbc\xdd\x04\x77\xd9\x61\x3e\x28\xef\ +\xcd\xba\x87\x7c\x9a\xa3\x94\xca\x35\xc1\xc6\xbe\xbe\x6a\x1f\x30\ +\x6e\x6a\x2b\x91\xd1\x24\x97\x94\x01\x04\x45\x45\x16\xed\xae\x0d\ +\xcd\xf2\x4c\xdb\x98\x98\xd6\xad\x21\x7f\x4d\x13\xc3\x02\x26\xd0\ +\x72\xe5\x1d\x36\x5d\xdb\x24\x37\x4d\x49\xb3\x6c\x08\xa6\xbf\x8f\ +\x7f\x81\xa9\x7b\xf5\x4a\x79\x40\x69\x11\x4a\xab\xbb\xb2\x70\x89\ +\x01\x55\x93\x87\xda\xd5\xd0\x33\x7e\xd5\xc7\x89\x9b\x8e\x7d\x87\ +\x09\x0c\xc3\x34\x5d\xa3\x9f\xb2\x35\x0b\x84\xf2\xd7\xe3\x89\xe3\ +\xd3\x6e\xc8\x02\x3d\xa4\x8b\x5b\x99\x51\xd7\x48\xe6\x84\xbc\x6e\ +\x91\x53\x86\xdc\x36\x6f\x5a\xb0\xf4\x81\xf9\x22\xb6\x2d\xf4\x0e\ +\x1e\x88\xbe\x37\x22\xf7\x9d\xa5\x74\xc8\xe9\x12\x96\xd7\x5f\x8b\ +\xda\xe9\x8e\x8d\x91\x85\x08\xb2\x06\x16\xd5\xb6\xaf\xe2\xd8\x39\ +\x5e\x97\x97\xda\xfe\x2a\xd2\xfd\x68\x14\x34\x40\x6c\x6d\x32\x90\ +\x4b\x7e\x77\x2a\x82\xef\x3c\x7d\x5f\x1d\x74\x04\x39\x12\xbe\x33\ +\x82\x27\x9f\x2c\xc3\xf1\xf7\x15\xb2\xaf\x1c\x3c\x38\xd3\x21\x13\ +\x0d\x13\xe4\x34\xf0\xa9\x1c\x1b\x2a\x0f\xc3\x37\xd5\x97\x2d\xde\ +\xee\x34\x9e\x26\xf1\xa3\x28\xfc\x19\x02\xb7\x2c\xc7\x25\xf8\x82\ +\x08\xdc\xd6\xca\xea\x12\xdf\x22\x4b\x23\xc5\x5e\x3d\x39\x83\x3f\ +\xc7\xdf\x2f\x0c\xc8\xb1\xfb\xe8\x3b\xc6\x4b\x01\xd9\xe2\xef\x57\ +\xc4\xde\x17\x04\x5c\xc1\xde\xaf\x88\xbb\x2f\x0a\xba\x82\xbb\x5f\ +\x2f\x73\x1f\xc1\xdb\xcf\xb0\x36\xa5\xad\x93\x5f\x3f\x04\xc7\xb0\ +\x2d\x29\xbf\x2e\x61\xfb\x16\x55\x47\x5f\xdb\x3e\x29\xdb\x3e\x47\ +\xb5\x5f\xe9\xc5\xb1\xe9\xfa\xec\xb0\x65\x7e\x4a\x5f\x3d\xc3\x3a\ +\x92\xef\x5e\x11\xdb\x9d\x0b\x03\xa0\xae\x57\x44\x5c\xe7\x43\xc1\ +\xe8\x55\x60\xa7\xc3\xe1\x25\xaa\xc7\x63\x58\x08\x99\xff\x95\x87\ +\x5e\xa4\x5c\x3c\x3b\x81\x0d\x8a\x9c\x17\x05\xe0\x0c\x19\x7f\xc6\ +\x7a\xf0\x07\x63\xc8\xb3\x16\x80\xf6\x8f\xc5\xa3\x67\xae\xf8\x8c\ +\x0b\x67\xdb\xfa\xb6\xb9\x49\x5b\x9f\xb8\x7b\xaf\x42\x5a\xdf\x46\ +\x64\x33\x70\xfa\x6f\xf1\x71\xba\x3b\xfe\x3d\xfe\x10\x4f\xf9\x95\ +\x6c\xa4\x4e\xd1\xee\xed\x44\xb3\x8a\x2f\x06\x64\x14\x8c\x88\x59\ +\xbd\x11\x27\xb7\xc6\xd3\x8d\xce\x1b\x7a\xe9\x90\xe7\xe0\xe6\x65\ +\xf9\x8f\xea\x21\x72\x2e\xd9\xc7\xea\xbd\xf6\xc4\xfb\x36\x1f\xed\ +\x4b\xf6\x11\x63\xcd\x29\x36\x6d\xcb\x47\xb7\xed\xd6\xa0\x71\xd0\ +\x47\xf3\x7f\xe0\xa3\x73\xe1\x91\x24\x9a\xfb\x6d\x0e\xda\x68\x52\ +\xff\xe7\x00\xe0\xd6\xa9\xfc\x38\x7f\xff\xe6\x5f\x67\x47\x77\x71\ +\ +\x00\x00\x09\xf8\ +\x00\ +\x00\xa0\xff\x78\x9c\xed\x5d\x5d\x8f\xa3\x38\x16\x7d\xef\x5f\xc1\ +\xa6\x5f\xa6\x35\xc5\x87\xbf\x30\xce\xa4\x6a\xa4\xdd\xd6\x48\x23\ +\xed\xd3\xce\xac\xf6\xb1\x45\x80\xa4\x50\x27\x10\x01\xa9\x24\xf3\ +\xeb\xc7\x26\x21\x21\xa9\xd8\xd3\xbb\x31\xab\xca\xad\x8e\xba\x55\ +\x85\x6d\xc0\x1c\xdf\x6b\x1f\xdf\x5c\x4e\x4d\x7e\xde\x2e\x17\xce\ +\x4b\x56\xd5\x79\x59\x3c\x8e\x90\x17\x8c\x9c\xac\x48\xca\x34\x2f\ +\xe6\x8f\xa3\x7f\xff\xfe\x8b\x1b\x8d\x9c\xba\x89\x8b\x34\x5e\x94\ +\x45\xf6\x38\x2a\xca\xd1\xcf\x4f\x1f\x26\x7f\x73\x5d\xe7\x1f\x55\ +\x16\x37\x59\xea\x6c\xf2\xe6\xd9\xf9\xb5\xf8\x5a\x27\xf1\x2a\x73\ +\x7e\x78\x6e\x9a\xd5\xd8\xf7\x37\x9b\x8d\x97\x1f\x0a\xbd\xb2\x9a\ +\xfb\x9f\x1c\xd7\x7d\xfa\xf0\x61\x52\xbf\xcc\x3f\x38\x8e\x23\xef\ +\x5b\xd4\xe3\x34\x79\x1c\x1d\x4e\x58\xad\xab\x45\xdb\x30\x4d\xfc\ +\x6c\x91\x2d\xb3\xa2\xa9\x7d\xe4\x21\x7f\x74\x6a\x9e\x9c\x9a\x27\ +\xea\xee\xf9\x4b\x96\x94\xcb\x65\x59\xd4\xed\x99\x45\xfd\xb1\xd7\ +\xb8\x4a\x67\xc7\xd6\xaa\x37\x1b\xd2\x36\x42\x42\x08\x3f\xc0\x3e\ +\xc6\xae\x6c\xe1\xd6\xbb\xa2\x89\xb7\xee\xf9\xa9\xb2\x8f\xd7\x4e\ +\xc5\x41\x10\xf8\xb2\xee\xd4\xf2\xdb\x5a\x8d\x6b\x09\xe8\x4a\xfe\ +\x3f\x36\xef\x0a\xbc\xba\x5c\x57\x49\x36\x93\xe7\x65\x5e\x91\x35\ +\xfe\xe7\xdf\x3f\x1f\x2b\xdd\xc0\x4b\x9b\xb4\x77\x99\x0e\xcf\xb3\ +\xbb\x9e\x81\x5c\xc4\xcb\xac\x5e\xc5\x49\x56\xfb\x5d\x79\x7b\xfe\ +\x26\x4f\x9b\xe7\xc7\x11\xa1\x1e\x22\xf2\xc3\xda\xc2\xe7\x2c\x9f\ +\x3f\x37\x97\xa5\x79\xfa\x38\x92\xbd\xc7\x22\xda\x1f\xf7\x8c\x03\ +\xed\x1b\x1c\x2e\x3c\x3e\xd6\x04\x9e\xc0\x1e\x72\x2a\xc4\x08\xdf\ +\xb7\xe9\x1e\x61\x9c\x96\x89\xea\x93\xbc\x64\xb6\xcc\xe3\x75\x53\ +\x2e\xe5\xa8\x25\xc9\x22\xae\xeb\x7c\x96\x27\xf2\xa0\x2c\x56\x8b\ +\xf5\x3c\x2f\xbe\x4c\xa5\x95\x7d\x91\xc3\x39\xcd\x8b\xb6\xf8\x4b\ +\x53\x96\x0b\xaf\x03\xf2\x78\xd7\x6c\xbb\x2a\xab\xc6\xdd\xa6\x2b\ +\x09\x67\xc8\xaf\x56\xee\xfa\x95\x2f\x79\xb6\xf9\x7b\xb9\x95\xdd\ +\x74\x02\x87\x60\xf9\x6f\xf4\x24\xcb\x27\x69\x36\xab\x55\xfd\xfe\ +\x91\xd5\x91\x7c\x66\x3e\x72\xfc\xb6\xf6\xf8\x04\xaa\xfb\xa9\xba\ +\xc6\xa9\xed\x34\xae\xf7\xb0\x3a\xce\x2a\x9e\x4b\x13\x5c\x94\xd5\ +\xe3\xe8\xe3\xac\xfd\x1c\x2a\xa6\x65\x95\x66\x55\x57\x15\xb6\x9f\ +\xb3\xaa\x52\x0e\x53\xde\xec\xf6\x4e\x77\xb8\x76\xf7\x18\xea\xaa\ +\xc7\xfa\xe0\x7a\x7d\xfd\x1c\xa7\xe5\xe6\x71\x84\x2f\x2b\xff\x28\ +\xcb\xa5\x1c\x54\x4f\x30\x11\xe0\x40\x5c\x56\x27\x12\x09\x17\x05\ +\xd4\x13\x04\x0b\xf6\xaa\x76\xd7\xda\x83\x3c\x33\x7a\x75\xe1\x64\ +\x5d\x55\xd2\x2b\xdd\x45\xbc\xcb\xe4\x43\xb5\x3f\xd0\xa1\x51\xfd\ +\x5c\x6e\xe6\x95\x02\xa7\xa9\xd6\xd9\xe5\x99\xaa\xc6\x9d\x4e\xd5\ +\x20\x5c\xab\x96\x46\xb2\x56\xfe\xee\xae\x8b\xbc\x91\x3e\xb5\xda\ +\xf6\xaf\xba\xce\xd3\xac\xbe\x7e\x62\x5d\xc4\x2b\x77\xbe\x28\xa7\ +\xf1\xe2\x7a\x83\x4d\x5e\x48\x90\xdc\x83\xf9\x23\x72\x1c\x83\xcb\ +\x16\x9d\x2f\xf0\x20\xd2\xb4\x50\x06\xa4\xa9\xda\xe9\xab\x96\xf1\ +\x36\x5f\xe6\x7f\x64\x12\x18\xd4\x9a\x9d\x34\xad\x33\x58\xf6\xa7\ +\x39\x4e\xb3\x53\x7e\xbd\xdd\xa9\xb2\x51\x57\xa8\xf0\x54\x05\x58\ +\x08\x7e\x2c\x2c\xab\x5c\xba\x4b\xaf\x3b\x5d\xd1\xae\x5f\xa4\x66\ +\x01\x39\x89\x6f\xd5\x7d\x2f\xca\x94\xcd\x75\x66\xee\xbf\xb6\xf3\ +\xb6\x7c\x99\x35\x71\x1a\x37\xf1\xc9\xe8\xbb\x12\xd9\x97\xa0\x7b\ +\x12\x39\x81\x8e\xff\xf5\xf9\x97\xa7\xc3\x0d\x26\x49\x32\xfe\x4f\ +\x59\x7d\xed\xee\xe7\x38\xaa\x41\x3c\x2d\xd7\x12\xd9\xd1\xd3\xb1\ +\x78\x92\x26\x63\x39\xe5\xc9\xa9\xe0\x29\x5f\x4a\x53\x56\xb3\xe5\ +\x8f\x72\x8a\x9b\xf8\xa7\x8a\xb3\xc6\x0a\x9c\xd3\x45\xf7\x97\xad\ +\xb2\xfd\xdc\x79\x75\x01\x49\x93\x65\xae\x4e\xf2\x7f\x6b\xf2\xc5\ +\xe2\x57\x75\x93\xc3\x13\xf7\x2e\x9a\x37\x8b\xec\x54\x38\xf1\x0f\ +\xbd\x3f\x3c\x9b\xdf\x7b\xb8\x89\xdf\x3d\x7d\x7b\x34\x3f\xa1\x72\ +\xe6\x04\xc7\x81\x5d\xc4\xd3\x4c\x5a\xe4\x3f\x55\xa5\xf3\xaa\x76\ +\x5e\x95\xeb\xd5\xb2\x4c\xb3\xc3\xe9\x1d\x9a\xf3\xb3\x61\x47\x04\ +\x45\xc7\x91\x6b\xaa\xb8\xa8\x15\x32\x72\x1c\xe2\xa6\xca\xb7\x3f\ +\x20\x8f\x0a\x2c\xdd\x94\x3e\x04\x1e\x62\x54\x4d\x5d\xd1\x83\x5c\ +\x31\x42\x26\x30\x67\x44\xc8\xe2\x90\x87\x01\x93\xc3\xf5\xe0\x0a\ +\xe6\xd1\x30\x24\x88\x3f\xb8\xc4\x8b\x08\x13\x22\xa2\x9f\x8e\x03\ +\x32\xa9\xb2\xa4\xe9\x8d\x59\x3b\x27\x91\xfd\x67\xd4\x2b\x3f\x33\ +\x39\xc7\x91\xcd\x5c\x8c\x7a\x05\xb2\x9e\xb1\xde\x71\xe7\x53\xb4\ +\x57\x76\xf0\xc4\x7e\x91\x7a\x5a\xd5\x03\x16\x11\xd1\x2b\xae\x9b\ +\xdd\x42\x22\x34\x93\xe3\x37\xfe\x18\x04\x49\x32\x9b\xfd\xa4\x0e\ +\xdc\xc3\xc4\x38\x46\xfb\xc3\x6a\xbd\x90\xf3\xfe\x4b\x56\x94\x69\ +\xfa\x53\xdd\x54\xe5\xd7\x6c\x7c\x98\x8a\x0f\x87\x7b\xf7\x1f\x07\ +\xdd\xa1\x34\x8d\xac\x5a\x48\xb7\x6c\xc6\xb4\x2b\x4b\x63\x39\x9f\ +\x56\x55\xbc\x1b\x17\x92\xe7\x74\xa5\xc7\x5b\xf5\x8c\xc7\x26\x5a\ +\xe2\x36\xb4\x5c\xa4\xc7\x2b\x8e\x53\x0a\x0d\xaf\x90\xdc\x8a\x97\ +\x1b\xe9\x11\x0b\xc3\x28\x00\x87\x18\xbf\x19\xb1\x40\x8f\x18\xa5\ +\x8c\x41\x43\x8c\xa3\x5b\x11\x23\x2e\xd6\x5a\xd9\x6c\x86\x63\x1c\ +\x83\xc3\xec\xc6\x59\x5f\x5a\x19\x77\xb5\x73\x3f\x50\xcc\x6e\x9e\ +\xfb\xdd\xc8\x65\x2e\x7f\x5f\xa8\x45\xb7\xaf\x00\x81\x4b\x5c\x02\ +\x1c\x35\x76\x8e\xda\xed\x3c\xc3\xa5\x3a\xc4\x80\x30\x8d\x0b\xc4\ +\x6c\x30\x0d\x13\x3b\x03\xc1\x35\x2e\x31\xb3\xc0\x35\xf4\xf3\x19\ +\x10\xb6\x71\x81\x99\x0d\xb6\x11\xba\xa1\x7e\x3a\x13\x02\x20\x68\ +\x36\xe8\x06\xd6\xbb\x27\x50\xd4\xec\x10\x0e\xe1\x62\xd8\xb8\x21\ +\xe2\x05\xea\x63\x39\xb2\x61\xda\x79\x42\x88\x6d\xe8\x60\xb3\x60\ +\x75\x06\xe4\x20\x70\x0f\x0d\x72\x56\x28\x88\x21\xa0\x06\x81\x82\ +\xe8\xa0\xb3\xc1\x44\xb4\x8b\x2a\x0c\x26\xa2\x81\xce\x4a\xf8\x43\ +\x6f\x76\x51\x7b\x4f\xa8\xd8\xd9\xe0\x25\x86\xcd\x29\x6c\xf0\xec\ +\xd0\x13\xc3\xae\x0b\x34\x7c\x96\x02\x23\xdc\x15\xda\x9d\x3e\x10\ +\xfc\xf8\x39\x70\x37\xf3\xba\xc0\x14\x1b\x01\xc1\xec\x2e\x11\xb3\ +\x10\x4d\xd2\x6f\x22\x80\x70\xba\x0b\xcc\xec\xc4\x93\x5c\xa6\x47\ +\x0d\x04\x9d\xbb\x44\xcd\x4a\x44\xc9\x44\x82\x41\x30\xb9\x0b\xd4\ +\xec\xc4\x94\xb0\x3e\x14\x97\x52\x88\x0b\x81\xa5\xa8\x12\xd7\x6f\ +\xf4\x81\xe2\x66\x2b\xae\x64\x58\x48\x61\x22\x67\x89\xb3\x61\xd3\ +\xc2\x00\x03\x39\x36\x4c\x48\x2e\x20\xfa\xec\x06\xb5\x9e\x82\x05\ +\xee\x76\x97\x0d\xf5\xdb\x54\xc8\xc8\x59\xe1\x71\x5c\x1f\x5b\x02\ +\x8d\x9d\x0d\x36\x67\xd8\xdf\x43\xc6\xce\x4a\x58\xce\xf0\xdd\x2a\ +\x21\xf7\xbf\x7b\xd0\x20\x67\x83\xd6\x19\xf6\x5d\x94\xc6\x77\x9f\ +\x2f\xa2\x41\xce\x0e\xb1\xd3\xae\x13\x38\xe6\xb3\xfb\x8f\x8e\x5c\ +\xc7\xce\x56\x38\x4e\x1f\x0b\xe6\x71\x9c\x66\xf7\x0e\x9e\x18\x88\ +\xd7\x49\x97\xd5\x12\x3b\xb5\xe5\xbf\xff\x65\x42\x83\x9c\x8d\xd0\ +\x9c\x21\x9f\x04\x32\x76\xb6\x42\x74\x72\xc6\xd3\x06\x37\x41\xe3\ +\x67\x27\x58\xa7\x8d\x01\x40\xc6\xce\x4e\xc8\xce\xc0\x52\x20\xf0\ +\x3b\x0d\x74\x76\xc2\x76\xc6\x6f\xfb\xef\x9f\xe1\x69\xb0\xb3\x15\ +\xba\x03\xce\xf1\xae\xa3\x67\x2d\x7c\xa7\xa5\x2a\x20\x48\x1e\xf6\ +\x44\xfb\x21\xe7\xe8\x59\x49\x0c\x33\xbd\x9e\x34\x4d\x52\xc2\xee\ +\xdd\xf4\x34\xe0\xd9\xc9\x0d\x53\x81\x28\x6d\x34\x05\x34\x7c\x56\ +\xf2\xc3\x4c\x2b\x2e\x64\xf4\xec\xa4\x88\xc1\x26\x2b\x3a\xe8\xec\ +\x64\x88\x19\x12\x4e\x00\x90\x15\x1d\x76\xb6\x12\xc4\xb4\x96\x07\ +\x83\xac\xa0\x3d\x59\x09\xa2\x73\xf8\x6c\xe4\x39\x99\xbe\x68\x8c\ +\xa2\x38\xbe\xff\xed\x99\x0e\x3c\x2b\x29\x4f\xa6\xdd\x2d\x68\xf8\ +\x6c\x85\x56\x4c\xef\x87\xc1\x06\xd0\x52\x22\x94\x5c\x3b\xc2\xf7\ +\xe9\xc1\xb6\x92\xa2\x0c\x6a\x08\x00\x68\x8b\x16\x3d\x5b\xb9\x51\ +\xc6\xd7\x3b\xef\x9e\xb9\x68\xe1\xb3\x97\x22\xa5\xb5\x3f\xd0\xe4\ +\xc5\x62\xa6\x94\xfe\xf5\x80\xb7\x12\x6c\x99\xf8\x73\xad\x20\x54\ +\x8f\x40\x5c\x93\x84\x22\x02\x73\x11\x0a\xa5\x03\x85\xc3\x88\x50\ +\x46\x78\xab\x09\x85\x58\x10\x46\x4a\xfd\x09\x79\x88\x33\x4e\xb1\ +\xfc\x35\x0a\x3d\xca\x31\x8a\xa2\x07\x12\x79\xb2\x9e\x84\xfc\x4d\ +\x4a\x42\xe9\x83\x8b\x30\xd2\xeb\xed\x8b\x42\x99\x10\x83\x90\x5c\ +\x3f\x84\x2c\x94\x09\x33\x08\xa9\xf5\x43\x08\x43\x99\x5e\x69\x86\ +\x90\x58\x3f\x8c\x34\x94\x49\xad\x01\x84\xf8\xcc\x20\xe2\x50\x7a\ +\xe2\x03\x14\x35\x4b\xf2\x50\xfa\x88\x03\x4c\xdc\x6c\x09\x44\xe9\ +\xe7\x36\x20\xb8\x0d\x20\x11\x65\x5a\x0f\x40\xf0\x8e\x41\x44\xa2\ +\xc0\x4b\x52\x0e\x22\x13\xe5\x8a\xef\x4a\x51\xff\x8b\x52\x94\x49\ +\x30\x10\x82\x7a\xcf\x50\x5a\x51\xef\x4e\x63\xcb\x9a\x5a\x94\x89\ +\x81\x40\x40\x6e\x30\xbd\x28\xe8\x81\x8f\x21\x15\xa3\x4c\x71\x7a\ +\x08\x54\x64\x50\xcd\x28\xe8\xb1\x90\x41\x55\xa3\xa0\xeb\x65\x0f\ +\xab\x1b\xf5\x5d\x39\xea\x26\xe5\x28\xbd\xac\x0a\x6c\xf8\xac\x69\ +\x47\x19\xf2\x5b\x20\x03\x68\x51\x3d\xca\x90\xe2\x02\x03\xc1\x01\ +\xf4\xa3\x4c\x6b\x06\x08\xa6\x37\x88\x82\x94\x29\x85\x14\x04\xc7\ +\x1b\x48\x43\x0a\xbc\x28\xe8\x40\x2a\x52\xe6\xb4\x5b\x00\xcc\x6e\ +\x28\x1d\x29\x7d\xec\x04\x86\x3a\xcd\x70\x4a\x52\x7a\x57\x05\x8a\ +\x9c\x45\x2d\x29\x3d\x17\x86\x89\x9d\x4d\x35\x29\xe8\xd8\x0d\xa8\ +\x27\xa5\x5f\x25\x20\xeb\xd3\xd8\x51\x94\xd2\x7f\x39\x01\x19\x3b\ +\x5b\x9a\x52\xef\x14\x3d\x4b\xaa\x52\xfa\xdd\x04\x64\xf4\xec\xe8\ +\x4a\x99\x98\x31\x84\xac\xf8\x21\x95\xa5\xcc\x49\x74\xf7\x9f\x12\ +\x3f\xac\xb6\x94\x3e\x9d\x1b\x46\x3e\xfc\xc0\xea\x52\x86\x78\xf1\ +\x5b\xc9\x86\x7f\xb3\xfa\x52\x7a\xc7\x85\xac\x54\x63\x4b\x61\x4a\ +\xbf\xb3\x85\x8c\x9e\x4d\x8d\x29\xfd\xb7\xb4\xa0\x11\xb4\xa4\x32\ +\xf5\x3e\x35\xce\x2c\xe9\x4c\x99\x38\x0b\x04\xbe\x37\xac\xd2\x94\ +\x39\x43\xe0\xfe\x19\xdf\xd0\x5a\x53\x7a\xd2\x02\x83\xf3\x0d\xad\ +\x36\x75\x07\xaf\x40\xbe\x65\xbd\xa9\xef\x8a\x53\x37\x2a\x4e\xbd\ +\x4f\xd5\x24\x7b\x9a\x53\x7a\xff\x85\x8c\x9f\x25\xd5\x29\xd3\x1f\ +\xe5\x06\x40\x5d\x06\xd6\x9d\x02\x4e\x5d\x06\x57\x9e\xd2\x13\x67\ +\x18\xd4\x65\x60\xed\xa9\xef\xea\x53\x37\xaa\x4f\x19\xa4\x46\x21\ +\x03\x68\x53\x7f\x4a\x1f\x38\x80\x0d\xa1\x4d\x05\xaa\x77\x2a\x83\ +\x66\x4d\x83\xca\xa4\x56\x0d\x80\xc4\x0c\xaf\x42\x65\xfa\xf3\xa3\ +\x00\x78\xcc\xff\x43\x87\xea\x9d\xca\x68\xda\x54\xa2\xd2\xb3\xc1\ +\x37\x13\x88\x39\x69\x51\xf5\x91\xbc\xf0\x18\xc6\x6e\x4d\xb6\x46\ +\x1e\xa6\x08\xe3\x80\xa3\x5b\x3a\xfd\xe1\x02\x6f\xdc\x67\xf2\x87\ +\x71\x41\xd8\xc3\x21\xc5\xe4\x34\x83\x76\x83\x88\x02\x2f\xa0\x28\ +\x3a\x55\xa8\x55\x8f\x79\x81\x88\x18\x3d\xf9\x8d\x34\x0d\x86\xbc\ +\x28\xe0\xac\xe7\x4c\xca\x7e\x90\x47\x43\xc4\x71\xd8\x2b\x6d\xad\ +\x8d\x21\x41\x68\x70\xea\xc7\x15\xd9\xae\x87\x40\x89\x74\x45\x21\ +\x25\x21\x8d\xf8\x43\xe0\xb1\x00\x47\x21\x43\xf2\xd7\x87\xe0\xd3\ +\xe9\xb1\x8a\xaf\x75\x12\xaf\x24\xa2\xdb\x55\x59\x35\xee\x36\x5d\ +\xe5\x67\x0b\xf3\x65\x83\x5d\xd7\xe0\x38\x9a\xfd\x41\xd4\x77\x04\ +\x51\xc1\x99\xa0\xaa\x23\x5c\x50\x41\xa3\xf3\x7e\xec\x9f\x2b\x44\ +\x88\x22\xfa\x57\x18\xc8\xa6\x24\xf2\xb0\xda\x53\xa1\x3e\xb0\x12\ +\xc3\x10\x0b\x84\xf0\xb5\x61\x08\x99\x1c\x88\x6f\x18\xb9\x6e\x9c\ +\x09\xef\x81\xf0\xea\x45\x80\x5b\xe9\x04\xf2\x10\x0b\x31\x65\x94\ +\x5b\x71\x28\xad\x1f\xcd\x66\xb7\x67\x56\xca\x49\x4b\x70\x12\x0a\ +\x4a\x6c\xfa\x91\xc4\x57\xfc\x17\x7e\xa4\x66\x58\x1e\xd2\xb3\xf1\ +\xa6\xd2\x34\x22\x16\xf6\xfc\x40\x6d\xb7\xb9\xc7\x30\xe2\xec\xdb\ +\x1c\x89\x23\x46\x04\x16\x7f\xed\x48\x3c\x64\x4c\xdd\x5f\xda\xaf\ +\x74\x29\x42\xa5\x35\xef\x0d\x78\x3f\x06\xed\x94\x36\xf1\xeb\x17\ +\xf9\xe3\x4f\x98\x39\xa9\x7a\ +\x00\x00\x05\xd4\ +\x00\ +\x00\x1e\x9f\x78\x9c\xe5\x59\x5b\x6f\xdb\x36\x14\x7e\xef\xaf\x10\ +\x14\x0c\x68\xb1\x4a\xa2\x44\xeb\x1a\xdb\x7d\x29\x0a\x0c\xd8\xd3\ +\xd6\x61\x8f\x01\x2d\xd1\x0e\x57\x49\xf4\x28\x3a\xb6\xfb\x6b\xf6\ +\x5b\xf6\xcb\x76\x48\xdd\x6d\x79\x6b\x06\x27\x4b\x3b\x19\x81\xc3\ +\x73\x21\xcf\xf9\xce\x8d\x4a\xe6\xef\x0e\x45\x6e\x3c\x50\x51\x31\ +\x5e\x2e\x4c\xd7\x46\xa6\x41\xcb\x94\x67\xac\xdc\x2c\xcc\x5f\x3e\ +\x7e\xb0\x22\xd3\xa8\x24\x29\x33\x92\xf3\x92\x2e\xcc\x92\x9b\xef\ +\x96\xaf\xe6\xd5\xc3\xe6\x95\x61\x18\xa0\x5c\x56\x49\x96\x2e\xcc\ +\x7b\x29\xb7\x89\xe3\x6c\x77\x22\xb7\xb9\xd8\x38\x59\xea\xd0\x9c\ +\x16\xb4\x94\x95\xe3\xda\xae\x63\xf6\xe2\x69\x2f\x9e\x0a\x4a\x24\ +\x7b\xa0\x29\x2f\x0a\x5e\x56\x5a\xb3\xac\x6e\x06\xc2\x22\x5b\x77\ +\xd2\xfb\xfd\xde\xde\x63\x2d\xe4\xc6\x71\xec\x20\xcf\xf1\x3c\x0b\ +\x24\xac\xea\x58\x4a\x72\xb0\xc6\xaa\x60\xe3\x94\xaa\x87\x10\x72\ +\x80\xd7\x4b\x7e\x99\x54\x52\x01\x2a\x5b\xf8\xe9\xc4\x5b\x82\x5d\ +\xf1\x9d\x48\xe9\x1a\xf4\xa8\x5d\x52\xe9\xbc\xff\xf8\xbe\x63\x5a\ +\xc8\xce\x64\x36\xd8\x86\x95\x9f\xaa\x94\x6c\xe9\xe8\xd4\x96\x58\ +\x23\x40\x0a\x5a\x6d\x49\x4a\x2b\xa7\xa5\x6b\xfd\x3d\xcb\xe4\xfd\ +\xc2\xc4\x33\xdb\xc5\xf0\xf8\x9a\x78\x4f\xd9\xe6\x5e\x9e\x52\x59\ +\xb6\x30\xc1\x7a\x2f\x8e\xea\xf5\x20\xc2\x6e\x2d\xd0\x6c\x9c\x0c\ +\x63\x6f\x7b\xc6\x6b\x1a\x05\x69\x14\xa2\x28\x8c\xdf\x1a\x1e\xf2\ +\x5c\x0b\xb9\x96\xeb\xbf\xd1\x4a\xad\x4f\x49\xc6\x53\x65\x24\x9c\ +\x41\x0b\x46\x76\x92\x17\x10\xc6\x34\xcd\x49\x55\xb1\x35\x4b\x61\ +\xc1\xcb\x6d\xbe\xdb\xb0\xf2\x8e\x8b\x8c\x8a\xbb\xd5\xf1\x4e\x29\ +\xd8\x2d\xa2\xdd\xf1\xf4\xb0\xe5\x42\x5a\x87\x6c\x0b\xb8\x06\xe1\ +\x24\xf3\xd8\x32\x97\xc0\x9d\x67\x74\x5d\x29\xa9\xda\x49\xb5\x02\ +\x2f\x43\xd3\x70\x34\xb7\x33\x51\x1d\x97\x3d\x30\xba\xef\x65\x57\ +\xa4\xaa\x81\x34\x8c\x2d\xd9\x40\xd2\xe5\x5c\x2c\xcc\x9b\xb5\x7e\ +\x1a\xc6\x4a\xdb\xdb\xb2\x02\xfd\x8c\x58\x1c\x02\xc3\xe4\xb1\xae\ +\x95\x66\xef\xd6\x5e\xb5\x6b\xc7\x47\xd3\xfc\xea\x9e\x64\x7c\xbf\ +\x30\xbd\x53\xe6\x67\xce\x8b\x85\x19\xda\xb1\x1b\xa1\x99\x1b\x9e\ +\xb2\xd3\x03\xe8\xb8\x76\xe4\x21\x10\x38\x63\x1e\x95\x66\x38\xc3\ +\x2e\xf6\x82\x33\xe6\x4e\x08\xa8\x43\x2b\x27\x47\x0a\x4e\xe9\x2f\ +\xb7\x11\xaa\xee\xf9\x7e\x23\x14\x38\x52\xec\xe8\xa9\xa6\xe2\x58\ +\xab\x15\x3f\x4c\xb3\x21\x0b\x76\xaa\xc2\xad\x5d\xc9\x24\x54\xd1\ +\xf6\x30\xdc\x75\xc7\x32\x5a\x4d\x2b\xee\x59\x09\x18\x58\x4d\x3e\ +\xbb\x38\x38\xb3\xb9\x91\x68\x93\x3b\x44\x97\x24\xc0\xb4\x33\x98\ +\x1b\xd6\xf1\x32\xab\x20\x07\x56\xb0\xcf\x14\xfc\x76\x4f\x45\xaa\ +\x92\x6c\xad\x4d\xce\x57\x24\xff\x07\xb7\x05\x97\x3a\xd3\xd5\x39\ +\x4b\x2d\x34\x1f\x41\x57\xeb\x19\x86\x3c\xaa\x6a\x3f\x1c\x15\xcd\ +\x6c\x89\x0a\x73\x45\xc0\x61\xe0\x77\x44\x2e\x18\xd4\xcc\xc0\xa7\ +\x96\x74\x1c\x92\x54\x6f\x80\xfe\x7c\xd0\x39\xa8\x33\x34\x3c\xe5\ +\x1d\x87\xbc\xa6\x34\x9c\xf3\xda\xd0\xf4\x82\x4a\x92\x11\x49\xfa\ +\x42\x69\x29\x5e\x1c\x77\x9e\x41\x9b\x4d\x7e\x7a\xff\x61\xd9\x1c\ +\x34\x4f\xd3\xe4\x57\x2e\x3e\xb5\xe7\x1a\x86\x12\x20\x2b\xbe\x83\ +\x70\x99\xcb\x8e\x3c\xcf\xd2\x04\x1a\x23\xf4\x87\x25\x2b\x20\xfd\ +\x55\x4f\xfd\x1e\x1a\xe1\xdc\xe9\x19\x23\x61\x05\x56\xbf\x69\xbd\ +\xad\xa0\x75\x87\x9d\x1c\x33\x59\x5a\x30\xa5\xe4\xfc\x2c\x59\x9e\ +\xff\xa0\x0e\x69\x3c\x1e\x6c\xca\x64\x4e\x7b\xe2\xdc\x69\xac\x6f\ +\x7c\x73\x06\xce\xcd\x9d\xd6\x7b\xbd\xda\xf4\xa8\x8c\x0a\xa7\x0b\ +\x74\x4e\x56\x14\x12\xe5\x47\xc5\x34\xce\xb8\x1b\xc1\x77\xdb\x82\ +\x67\xb4\x51\xef\xd0\xa4\xa9\xec\x42\x26\x8f\x39\xf0\xd7\x60\x7d\ +\x72\x13\x46\xf1\x8a\x78\xb7\x6a\x61\x35\xad\x24\x71\xeb\xa5\xd8\ +\xe5\xd0\x12\x1f\x68\xc9\xb3\xec\xb6\x92\x82\x7f\xa2\xc9\x0d\x0d\ +\xd4\xa7\x59\xd6\x15\x95\x78\xf6\xac\x25\xe4\xac\xa4\x60\x48\x52\ +\xfd\xbe\x23\x82\x0e\xa9\xbf\x71\x56\x26\x80\x1c\x15\x2d\x55\x2f\ +\x72\xa8\x0b\x99\x74\xfa\x19\x81\x7e\x25\x04\x39\x26\x25\x8c\xff\ +\x21\x95\xaf\xd7\x15\x95\x09\x6a\x69\x9d\xb1\xa3\x0c\x57\x7e\x62\ +\xe4\xf6\xb9\xdb\xce\x30\xaf\xa3\x74\x03\xac\x27\x4d\x66\x76\x9f\ +\xd2\x61\x4f\x14\x40\x0d\x6c\x14\xfb\x1e\x8e\xbc\x2e\xec\x73\x49\ +\x0f\x1d\xbc\x90\x6c\x89\x9e\xa6\xd0\xa0\x20\x91\xa8\x78\xa0\xe6\ +\x29\xf4\x1c\xaa\x59\xff\x0e\x6e\x42\x4a\xe6\xb7\x9a\xb2\xd7\x96\ +\x8d\x48\x15\x34\x8d\xc4\xf5\xec\x68\x7b\xb8\x55\x28\x36\x1d\x2a\ +\x41\xdf\xd5\xfc\x35\x29\x58\x7e\x4c\x2a\x52\x56\x16\x1c\xc5\xd6\ +\xb7\x39\x95\x00\xab\xd5\xd4\x65\x82\x40\x71\x0f\x83\x64\x44\xa8\ +\x43\x0f\x37\x0e\xe4\x07\xa7\xa1\x6f\x02\x3d\x84\xbf\x8e\xb2\x02\ +\x23\x7c\x7c\xec\xce\xe3\xa4\xd0\xf6\x6d\x1c\x47\x5e\x10\x8d\xd0\ +\xc6\xb6\x07\xbd\xd9\x1f\x47\x54\x41\x0b\x7d\xc1\x37\x97\x73\x09\ +\x3e\x94\x7d\xad\x76\xed\x45\x70\x05\xaa\x82\xc7\xec\xb9\x5a\x57\ +\x29\x80\x72\x38\xa0\x4f\x9e\x7e\xe1\xfc\x93\x80\xe9\x58\x44\xb6\ +\xef\x23\xf7\x24\x1c\xae\xed\xf9\x97\x02\x52\x83\xbd\x8e\xd5\xe7\ +\xf9\xc0\x5e\x92\xb9\xa3\xdd\x5f\xc2\x37\x40\xf8\x3f\x4b\xd4\x61\ +\x21\xab\x8b\x8c\x1d\x63\x84\x87\x85\x0c\xf1\xc6\xc8\xf6\x11\xc6\ +\xee\x64\xbe\xc5\xff\x3a\xdf\x30\x42\xee\x38\xdf\xce\x4f\xbf\x70\ +\xfe\x33\xe5\xdb\x09\x4e\xcb\x55\x97\x2a\x8f\xf2\xf8\xb2\x67\x3e\ +\xb6\x83\x18\xc5\x38\xbc\x80\x0f\x7e\x0a\x8f\xff\x2e\x4b\x4e\x3d\ +\xfe\xf3\x8f\xc9\xea\xd8\x8c\x2e\x4b\xb1\xd7\xdb\x2f\x05\x1c\xa7\ +\xae\x0f\x70\x59\x21\x52\xb0\xc3\x6b\xf7\x2d\x82\x8f\x6b\x63\xfd\ +\xcc\xe0\x77\xcb\x85\x55\x08\x4f\xfc\xe6\xac\x8e\x3a\x0b\x11\xea\ +\x2e\x2b\xa3\xa1\x3c\x29\xfa\xfc\xbd\xb9\x9f\xa2\x91\x3f\x8c\x52\ +\x33\x46\x03\x7b\xa6\x0d\x1b\x2a\xb4\xf3\x74\x8a\xa7\x9a\xed\x0c\ +\x72\x44\x3d\xe3\x14\xf1\xe0\xf5\x41\x03\x37\xb8\x3b\xbd\x78\x40\ +\xac\xeb\x40\xe2\x35\x59\x33\xfb\x16\x20\x09\xae\x03\x49\xe7\xfb\ +\x37\x00\x49\x78\x55\x48\xfc\x13\x48\x9a\xe4\xf1\xbe\x2a\x48\xfc\ +\x27\x2d\x9c\x8e\xfc\x35\x41\x82\xaf\x84\xc9\x74\x9a\xb4\x6d\xf7\ +\x89\x30\x41\x76\xe8\xcf\x66\x11\x7e\x82\x7e\xe2\x9d\xc3\x82\x6d\ +\xf5\xf7\xd7\x38\xc6\x5f\x0e\x0b\x5c\xae\xe2\x89\x54\x81\xbb\x85\ +\x4e\x95\xa8\x7f\x77\x73\x36\x97\xa6\xbf\x15\x3f\x62\xfe\xb7\xef\ +\x8a\x18\xee\x01\xc8\x86\x5b\x9d\xab\xfe\x8a\xf9\x25\xd0\xaf\xd7\ +\x2f\x21\x1d\xdd\xab\x64\xe3\x95\xa6\xfd\xcb\x80\x04\x5b\x13\xb9\ +\xf8\xdf\xcd\xfb\x97\x01\x4a\x70\xe5\xf1\xf6\x4d\x80\x12\x5a\xe8\ +\x29\x9b\xf9\x63\x67\xfe\xcb\x00\xc5\x1f\xf4\xcf\x17\x30\xf5\x5f\ +\x06\x28\xd8\xbf\xd6\x4b\xc4\x75\xe6\xfe\x23\x51\x79\xca\xb9\x3f\ +\xf5\x2a\xf1\x0c\x93\x5f\x7f\xcd\xd5\xff\x09\x96\xaf\xfe\x02\x5d\ +\xc7\xad\xfd\ +\x00\x00\x16\x48\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x70\x72\x6f\x6a\x65\ +\x63\x74\x5f\x72\x61\x73\x74\x65\x72\x5f\x62\x61\x6e\x64\x73\x2e\ +\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ +\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\ +\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\ +\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\ +\x32\x20\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\ +\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\ +\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x6c\x69\x6e\x6b\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\ +\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\ +\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\ +\x32\x37\x32\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\x3d\ +\x22\x31\x31\x2e\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x78\x32\x3d\x22\x33\x2e\x31\x38\x31\x38\x31\x38\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\ +\x36\x33\x36\x33\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\ +\x72\x61\x64\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\ +\x65\x72\x53\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\ +\x2e\x33\x39\x31\x32\x33\x39\x35\x35\x2c\x30\x2c\x30\x2c\x30\x2e\ +\x33\x37\x30\x34\x39\x39\x31\x32\x2c\x38\x2e\x35\x38\x36\x36\x32\ +\x34\x36\x2c\x37\x2e\x30\x34\x34\x31\x31\x32\x31\x29\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\ +\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\ +\x36\x30\x32\x33\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\ +\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\ +\x30\x66\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\ +\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ +\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ +\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\ +\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\ +\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x39\x35\x39\x30\x32\x30\x39\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x78\x3d\x22\x2d\x38\x33\x2e\x39\x38\x35\x39\x33\x34\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ +\x22\x33\x31\x2e\x30\x39\x38\x32\x39\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ +\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ +\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ +\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\ +\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\ +\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\ +\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ +\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\ +\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\ +\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x34\x35\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\ +\x22\x6d\x61\x74\x72\x69\x78\x28\x33\x2e\x38\x31\x37\x34\x31\x34\ +\x33\x2c\x30\x2c\x30\x2c\x34\x2e\x32\x36\x34\x37\x34\x30\x32\x2c\ +\x2d\x39\x2e\x36\x38\x32\x32\x32\x34\x33\x2c\x2d\x32\x33\x2e\x30\ +\x33\x32\x32\x36\x38\x29\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x35\x39\x38\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\ +\x72\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x29\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\ +\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x38\x30\x37\ +\x32\x38\x31\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x63\x78\x3d\x22\x36\x2e\x36\x33\x30\x34\x32\x37\x34\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x39\x2e\x32\x36\ +\x37\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x78\x3d\x22\x33\x2e\x39\x31\x32\x33\x39\x35\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x37\x30\x34\ +\x39\x39\x31\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x30\x2e\x31\x30\x39\x30\x31\x35\x36\x38\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x34\x36\x37\x34\x31\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\ +\x39\x2e\x32\x36\x37\x31\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x34\x36\x37\x31\x34\x38\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x33\ +\x2e\x35\x34\x33\x39\x30\x34\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\ +\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x30\x2e\x31\x36\x32\x35\x31\x30\x39\x39\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\ +\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x36\x2e\x36\ +\x33\x30\x34\x32\x37\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x63\x79\x3d\x22\x39\x2e\x32\x36\x37\x31\x30\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x33\x2e\x32\x36\ +\x30\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x33\x2e\x35\x34\x33\x39\x30\x34\x38\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x30\x2e\x31\x31\x32\x36\x37\x32\x33\x32\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\ +\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\ +\x30\x30\x36\x30\x31\x31\x34\x35\x2c\x30\x2e\x39\x39\x39\x39\x38\ +\x31\x39\x33\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x39\x2e\x32\x36\ +\x37\x32\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\ +\x79\x3d\x22\x2d\x36\x2e\x36\x35\x36\x32\x35\x34\x33\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x34\x34\ +\x39\x38\x32\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x79\x3d\x22\x33\x2e\x38\x33\x30\x38\x35\x38\x39\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x33\x37\x37\x31\x63\x38\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\ +\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x35\ +\x39\x34\x36\x39\x36\x37\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ +\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x36\x2e\ +\x39\x38\x32\x39\x35\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x2e\x38\x31\x32\x38\x37\x33\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x33\x31\x2e\ +\x34\x38\x38\x36\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\ +\x3d\x22\x35\x33\x2e\x33\x30\x31\x39\x37\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x33\x30\x36\x38\x39\x37\ +\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x31\x2e\ +\x31\x39\x34\x35\x35\x38\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\ +\x78\x28\x2d\x30\x2e\x32\x37\x38\x30\x37\x30\x32\x2c\x2d\x30\x2e\ +\x39\x36\x30\x35\x36\x30\x37\x36\x2c\x30\x2e\x36\x30\x36\x31\x35\ +\x31\x39\x37\x2c\x30\x2e\x37\x39\x35\x33\x34\x38\x38\x35\x2c\x30\ +\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\ +\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\ +\x33\x36\x30\x36\x32\x37\x32\x36\x2c\x2d\x30\x2e\x39\x33\x32\x37\ +\x31\x30\x30\x32\x2c\x30\x2e\x37\x36\x38\x36\x36\x30\x37\x34\x2c\ +\x30\x2e\x36\x33\x39\x36\x35\x36\x36\x38\x2c\x30\x2c\x30\x29\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x30\x39\ +\x36\x36\x33\x32\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\ +\x3d\x22\x31\x2e\x39\x37\x30\x34\x38\x33\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x79\x3d\x22\x32\x33\x2e\x38\x35\x35\x31\x31\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x32\x2e\x34\ +\x36\x34\x39\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x38\x2e\x32\x39\x33\x37\x34\x33\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x30\x2e\x35\x32\x38\x36\x30\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x32\x31\x34\x34\x37\x38\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x38\x36\x37\x30\x37\x39\ +\x36\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ +\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x31\x31\x32\x62\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\ +\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x30\ +\x33\x34\x34\x37\x30\x36\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\ +\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\ +\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\ +\x2e\x37\x32\x36\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x2e\x38\x35\x39\x38\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x31\x39\x2e\x34\ +\x36\x32\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x37\x2e\x30\x33\x31\x36\x36\x35\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x37\x39\ +\x38\x36\x34\x39\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\ +\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\ +\x2d\x30\x2e\x33\x38\x33\x35\x32\x31\x35\x36\x2c\x2d\x30\x2e\x39\ +\x32\x33\x35\x33\x31\x39\x32\x2c\x30\x2e\x38\x33\x34\x30\x31\x39\ +\x39\x31\x2c\x30\x2e\x35\x35\x31\x37\x33\x34\x33\x35\x2c\x30\x2c\ +\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\ +\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x2d\x30\x2e\x33\x38\x33\ +\x35\x32\x31\x35\x36\x2c\x2d\x30\x2e\x39\x32\x33\x35\x33\x31\x39\ +\x32\x2c\x30\x2e\x38\x35\x32\x37\x30\x37\x33\x31\x2c\x30\x2e\x35\ +\x32\x32\x33\x38\x38\x39\x37\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x38\x39\x35\x33\x36\ +\x32\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\ +\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x79\x3d\x22\x2d\x36\x2e\x31\x36\x31\x34\x39\x38\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x33\x31\x2e\x35\x35\ +\x31\x33\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x31\x2e\x31\x32\x37\x32\x34\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\ +\x2e\x37\x32\x36\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x63\x63\x63\x63\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x30\x2e\x39\x37\x38\x37\x37\x39\x34\x39\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ +\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0e\x53\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x62\x61\x6e\x64\x73\x65\x74\x5f\x74\x6f\x6f\x6c\x2e\x73\x76\ +\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\ +\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x33\x32\x20\ +\x33\x32\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x35\x39\x38\x39\x30\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x33\x2e\x31\x30\x36\x32\x34\x36\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\ +\x32\x2e\x32\x35\x38\x37\x38\x33\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\ +\x2d\x72\x6f\x74\x61\x74\x69\x6f\x6e\x3d\x22\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\ +\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\ +\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x67\x72\x69\x64\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\ +\x78\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\ +\x63\x69\x6e\x67\x79\x3d\x22\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\ +\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\ +\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x23\x33\x37\x37\x31\x63\x38\x3b\x66\x69\x6c\x6c\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\ +\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\ +\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x37\x31\x36\x32\ +\x31\x37\x38\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\ +\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\x35\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x33\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x38\x2e\x34\x32\ +\x33\x33\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x34\x2e\x39\x35\x35\x38\x39\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x35\x32\x2e\x30\x34\x36\ +\x30\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x34\ +\x34\x2e\x32\x34\x39\x31\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x34\x39\x35\ +\x36\x39\x38\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\ +\x2c\x30\x2c\x2d\x30\x2e\x38\x37\x31\x38\x32\x31\x37\x33\x2c\x30\ +\x2e\x34\x38\x39\x38\x32\x33\x33\x2c\x30\x2c\x30\x29\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\ +\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x38\x32\ +\x34\x33\x35\x32\x37\x31\x2c\x30\x2e\x35\x36\x36\x30\x37\x36\x35\ +\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x32\x2e\x36\x35\x39\x39\x38\x30\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\x38\x39\x34\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x32\x38\x2e\ +\x34\x30\x32\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\ +\x22\x33\x37\x2e\x30\x32\x39\x30\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x35\x2e\x38\x31\x37\ +\x31\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x38\x2e\x34\x32\x33\x33\x38\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x32\x31\x34\x34\x37\x38\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x39\x39\x36\ +\x38\x33\x35\x38\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x32\x2e\ +\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x32\x34\x35\ +\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\ +\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\ +\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\ +\x2e\x39\x34\x34\x38\x30\x31\x37\x35\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x37\x36\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x38\x2e\x34\x32\x33\x33\x38\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x2e\x37\x39\ +\x32\x33\x35\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x32\x35\x2e\x34\x30\x33\x30\x32\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x31\x35\x2e\x31\x38\x30\x37\x39\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\ +\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\ +\x22\x32\x2e\x38\x34\x37\x34\x39\x39\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\ +\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\x30\x2e\x37\x37\x36\x34\ +\x37\x36\x37\x35\x2c\x30\x2e\x36\x33\x30\x31\x34\x35\x39\x2c\x30\ +\x2c\x30\x29\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x31\x2c\x30\x2c\x2d\ +\x30\x2e\x37\x35\x32\x39\x36\x30\x32\x38\x2c\x30\x2e\x36\x35\x38\ +\x30\x36\x35\x39\x36\x2c\x30\x2c\x30\x29\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x39\x34\x38\x37\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x33\x38\x31\ +\x38\x39\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\ +\x34\x2e\x36\x34\x31\x33\x38\x37\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x3d\x22\x31\x36\x2e\x39\x36\x33\x35\x32\x34\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\ +\x37\x2e\x33\x31\x36\x38\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x38\x2e\x34\x32\x33\x33\x38\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x33\x37\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x63\x63\x63\x63\ +\x63\x63\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\ +\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x30\x2e\x39\x32\x34\x35\x34\x31\x37\x37\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x32\x2e\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\ +\x3e\x0a\ +\x00\x00\x06\xa9\ +\x00\ +\x00\x52\x92\x78\x9c\xe5\x9c\x5b\x8f\xa3\x36\x14\xc7\xdf\xe7\x53\ +\x50\xe6\xa5\x55\x65\x30\x97\x84\xcb\x26\xd9\x87\xae\x56\x5a\xa9\ +\x4f\xed\x56\x7d\xac\x1c\xec\x64\xd0\x02\x8e\x80\x4c\x92\xfd\xf4\ +\xb5\x09\x90\x00\xde\xaa\x92\x1d\xc9\x0a\x48\xa3\x15\xe7\x1c\x1b\ +\xf3\xc3\x97\x3f\x07\x6f\x56\x1f\xcf\x79\x66\xbc\x93\xb2\x4a\x69\ +\xb1\x36\x1d\x0b\x9a\x06\x29\x12\x8a\xd3\x62\xbf\x36\xff\xfa\xfa\ +\x19\x84\xa6\x51\xd5\xa8\xc0\x28\xa3\x05\x59\x9b\x05\x35\x3f\x6e\ +\x5e\x56\x3f\x01\x60\xfc\x56\x12\x54\x13\x6c\x9c\xd2\xfa\xcd\xf8\ +\x52\x7c\xab\x12\x74\x20\xc6\xcf\x6f\x75\x7d\x88\x6d\xfb\x74\x3a\ +\x59\x69\x6b\xb4\x68\xb9\xb7\x7f\x31\x00\xd8\xbc\xbc\xac\xaa\xf7\ +\xfd\x8b\x61\x18\xec\xba\x45\x15\xe3\x64\x6d\xb6\x05\x0e\xc7\x32\ +\x6b\x02\x71\x62\x93\x8c\xe4\xa4\xa8\x2b\xdb\xb1\x1c\xdb\xbc\x85\ +\x27\xb7\xf0\x84\x5f\x3d\x7d\x27\x09\xcd\x73\x5a\x54\x4d\xc9\xa2\ +\x7a\xbd\x0b\x2e\xf1\xae\x8f\xe6\xad\x39\x79\x4d\x90\x13\x45\x91\ +\x0d\x5d\xdb\x75\x01\x8b\x00\xd5\xa5\xa8\xd1\x19\x0c\x8b\xb2\x36\ +\x8a\x8a\xba\x10\x42\x9b\xf9\x6e\x91\xff\x2f\x2a\xae\x18\xd0\x03\ +\xfb\xeb\xc3\x3b\x83\x55\xd1\x63\x99\x90\x1d\x2b\x47\xac\x82\xd4\ +\xf6\xa7\xaf\x9f\x7a\x27\x80\x16\xae\xf1\x5d\x35\x1d\xcf\xc1\x55\ +\x07\x90\x0b\x94\x93\xea\x80\x12\x52\xd9\x9d\xbd\x29\x7f\x4a\x71\ +\xfd\xb6\x36\x3d\xdf\x72\x3c\x76\x2c\x1a\xe3\x1b\x49\xf7\x6f\xf5\ +\xd8\x9a\xe2\xb5\xc9\x5a\xef\x46\xe1\xf5\xfc\xae\x73\x38\xd7\x80\ +\xb6\xe2\xb8\xf7\x40\x2b\x72\x2d\xc7\x28\x9d\x85\x17\x5c\x63\xba\ +\x5b\x88\x31\x4d\x78\x9b\x58\x95\x24\x4f\xd1\xb1\xa6\x39\x7b\x6a\ +\x49\x92\xa1\xaa\x4a\x77\x69\xc2\x4e\x68\x71\xc8\x8e\xfb\xb4\xf8\ +\x67\x68\xb4\x3a\x82\xfd\xe5\xc8\xf9\x40\xcb\x1a\x9c\xf1\x81\x71\ +\x5c\x06\x42\xe7\xa5\x73\x6e\x98\x77\x85\xc9\xae\xe2\x51\xd7\x9b\ +\xe2\x67\xec\xae\x02\xd3\xb0\x1b\x6f\xdf\x46\xde\x40\xfc\x9e\x92\ +\xd3\x2d\x76\x8b\xaa\x2b\x38\xc3\x38\xa0\x3d\xeb\x64\x19\x2d\xd7\ +\xe6\xeb\xae\x39\x5a\xc7\x96\x96\x98\x94\x9d\x6b\xd9\x1c\x03\x17\ +\x65\x0f\x22\xad\x2f\xd7\x61\xd5\xd6\xdd\xb5\x97\xd7\xda\xfb\xa1\ +\xd8\x5f\xbd\x21\x4c\x4f\x6b\xd3\x1d\x3b\xbf\x53\x9a\xaf\xcd\xc0\ +\x8a\x9c\x10\xfa\x4e\x30\x76\x27\xe7\xb5\x09\x3c\xcf\x72\x3d\x18\ +\x2c\xbc\x89\x97\x37\xc8\xb7\xbc\x20\xf4\xdc\x49\xcd\xc9\xb1\x2c\ +\xd9\xc0\x03\x19\xba\x10\x76\x57\xcd\x3f\x4e\x1b\x54\xbd\xd1\xd3\ +\xbe\xe4\x74\xea\xf2\x48\xc6\x25\xb9\x07\x6c\xb7\xf4\x2c\x76\xb3\ +\x7e\x70\xe4\x43\x1a\x1c\x8b\xb4\x66\xc3\xe6\x70\xbe\xaf\xf5\x98\ +\x62\x52\x89\x0b\x56\x05\x3a\x80\x7d\x46\xb7\x28\x13\x07\x9c\xd2\ +\x82\x51\x02\x6d\x0f\x77\xbc\xfe\x21\x8c\x23\xba\xee\x1e\xc0\xf0\ +\x07\x11\xac\xed\x93\x07\xd1\xba\x2e\x3f\x76\xe5\xe8\x9c\xe6\xe9\ +\x77\xc2\xc0\x38\x4d\xbf\x63\x7d\x6b\x80\xe5\x5a\xcc\x30\xea\x0b\ +\x1f\xba\xe7\x0b\xb7\x99\x9d\x91\xf3\xe4\x06\x37\x8a\x82\xde\x48\ +\xcb\x94\x8d\x88\xbb\xe6\x74\xa6\xcb\xbd\x89\x0f\x74\x36\x4f\x9f\ +\x9b\x0e\xd6\x74\xbf\x60\xec\xbb\xdc\xfb\xda\x7e\x6f\x4f\x3b\x7e\ +\x63\xcf\x49\x8d\x30\xaa\xd1\x6d\x14\x74\x16\xd6\x36\xd8\xdd\x19\ +\x9b\x33\xe3\x3f\x3e\x7d\xde\xb4\x17\x5a\x25\x49\xfc\x37\x2d\xbf\ +\x75\xd7\x35\x0c\x1e\x80\xb6\xf4\xc8\x48\x9b\x9b\xde\xbc\xc2\x49\ +\xcc\x66\x39\x36\xfa\x37\x69\xce\xfa\x36\x9f\x20\x7f\x65\xb3\xda\ +\xca\xbe\x39\x06\xc1\x1c\xd6\xad\xd2\x6b\xb5\x25\xb9\x4e\x97\xc2\ +\x35\x03\x27\x79\xca\x0b\xd9\x7f\xd6\x69\x96\x7d\xe1\x17\x69\xef\ +\xf8\xae\xd2\xb4\xce\xc8\xcd\xb8\xb2\xdb\xd6\xb7\xf7\x66\xdf\xdd\ +\xdc\xca\xee\xee\xbe\x39\xdb\xdf\xa8\x0c\x06\x45\xff\xa0\x33\xb4\ +\x25\xac\x87\xfe\xce\x9d\xc6\xc4\xbb\x2f\xe9\xf1\x90\x53\x4c\xda\ +\xe2\x3d\x4d\x92\xd4\xfd\x23\xab\x2f\x19\xf3\xef\x58\xeb\xe3\x57\ +\x08\x93\x64\xb7\xfb\xc0\x4f\x40\x3b\x4f\xc4\xce\xf5\xb4\x3c\x66\ +\x6c\xbe\x7b\x27\x05\xc5\xf8\x43\x55\x97\xf4\x1b\x89\xdb\x99\xa9\ +\x3d\xbd\x0e\x86\x18\x76\xa7\x0c\x0c\x29\x33\xd6\x49\xeb\xd8\xef\ +\x6c\x18\xb1\xe9\xa5\x2c\xd1\x25\x2e\xd8\xc2\xde\x59\xfb\x4b\x0d\ +\xfa\x27\x6f\xe5\x22\xf4\xa2\xde\xd8\x0e\x36\xdf\x72\x9b\xae\x75\ +\x73\x74\x63\x6c\xea\x19\x74\xe6\x8b\x28\xa2\x1c\x84\x94\x4d\xd7\ +\xf5\x5d\x7e\x78\xfd\x83\xfc\x2f\x60\x08\x61\x5f\x33\x60\xc0\x91\ +\x44\x36\x35\x3e\x04\xdd\x72\x19\x42\xed\xd0\x81\x50\x12\x5e\x68\ +\x2d\xb8\xac\xf1\xc2\xc7\xc2\xf3\xfd\xc5\x42\x3f\x78\x50\x12\x9e\ +\xe3\x5a\x0f\xe5\xb6\xdb\xb9\xc8\x45\xda\x71\xf3\x64\xb1\x05\xd7\ +\xe5\x76\x8e\xec\x40\x20\x09\xcf\x75\xac\x66\xc0\xfa\x73\x84\x17\ +\x82\x85\x2c\xbe\x85\xb5\x9c\x23\x39\x08\x64\x47\xad\x1b\x59\xe1\ +\x50\x3f\xcf\x47\xa1\x00\x5f\x12\x9e\x50\xa3\x40\x65\xd0\x34\xd5\ +\x26\xd2\xd2\x4e\xa8\x4e\xd4\x61\xd3\x54\x95\x48\xaf\x11\x63\x5d\ +\xa2\x8a\xd8\x6e\x17\x45\x1a\x12\xf3\xc0\x52\x16\x98\x48\x91\x3c\ +\x39\x35\x10\x00\x57\x12\x9b\x50\x8b\x3c\x3b\x36\xa6\x41\x80\xec\ +\x5b\xfe\x58\x85\xa8\x9b\xd2\x34\xcc\x88\x48\xbf\xa3\x0e\x72\x22\ +\x83\xb9\xed\x39\xc5\x46\x28\x0b\x4c\xa8\x36\x94\x82\xd3\x55\x70\ +\xc8\x0e\x4c\xa1\xe0\x50\x4a\x4e\x57\xcd\x21\xbd\x84\x8e\x34\x87\ +\x42\x68\x21\xe4\x87\x76\xd0\x3c\xe9\xf5\x53\x28\x3b\x9e\x1f\x1c\ +\x53\x1e\xd2\x2f\xa3\x22\xe5\x31\x03\x72\x5c\x7c\xc8\xae\x0e\x63\ +\xf1\x31\x03\x6c\x10\x78\xf2\x89\x37\x51\xfe\x43\xe9\xd2\xa0\xa3\ +\x76\x83\xd2\xa9\x8f\x81\x7a\x9b\xae\xaf\xcf\x29\xe1\x7c\xe9\xb5\ +\x41\xa8\xe1\xd4\xe3\xd3\x55\xc8\x39\xd2\x99\x5e\xa1\x94\x53\x0f\ +\x50\x57\x3d\x17\x48\x6b\xe1\xb1\xa2\x53\xcd\x0e\xfb\x5a\x2e\x16\ +\x1e\x58\x3e\x46\xd8\xcd\x84\x1f\xcf\x2b\x3d\xe6\x2b\xd7\x5c\x00\ +\x36\x19\x26\xe9\x8f\xd3\x63\x99\x37\x17\x7a\x5c\xeb\xb9\xd2\x5f\ +\x1e\x84\x6a\x4f\x35\x42\xbe\xf8\xea\x87\x10\xca\xbe\x9c\x0d\x14\ +\xdf\x74\x24\x3f\x23\x33\x47\x3a\x7f\x22\xd4\x7b\x73\x81\x17\x4a\ +\x2f\x18\x42\xb5\x37\x17\x7c\x50\x3a\x27\x30\xd6\x7a\xaa\xc9\x41\ +\xc8\x1e\x8d\x7e\xe4\xd8\x4a\x21\xfd\xad\x55\x24\xf5\xd4\xe3\xf3\ +\x7d\xa4\xe1\xae\x92\x40\x7e\x3f\x8e\x48\xe8\xa9\xc6\xe7\xa2\x60\ +\xa7\x5f\x6a\xe5\x2a\xf4\xa4\x33\xa1\x23\x99\xa7\x9a\x5d\x18\x20\ +\x84\x89\x7e\xec\x9a\x94\xde\x43\xf6\x34\xa9\x26\xc8\x33\x04\xfa\ +\xad\x1a\xf2\xbb\x4c\x86\x9f\x65\x27\xd3\xe0\x33\x42\xe3\x89\xbd\ +\x87\x08\xbd\xb9\xe0\x6b\x12\x7b\x0f\xc9\xec\xcd\x85\x20\xcf\xec\ +\xc9\xa6\xe4\x27\xdf\x6a\x15\xb3\xd3\x56\xed\x2d\xa5\xf5\x8a\xf8\ +\x93\xad\x72\x7e\xba\xca\x3d\x57\x7a\xfa\x13\x7f\xb9\x55\x0c\x50\ +\x67\xc1\x17\x29\x97\x7c\xaa\xe9\xe9\x2c\xf9\x5c\xf9\xbc\xa8\xf0\ +\x3b\xae\x62\x84\xdb\x04\x7b\x0b\x1d\x3b\xa0\xfc\x9e\x6c\x71\xa2\ +\x6a\x02\xf5\x49\xf9\xb1\xe1\xfb\x98\x54\xd5\x4c\x00\x42\xb6\x06\ +\xab\xde\x6a\xa6\x9a\x9d\xb6\xf2\xc5\x7d\x8c\x7c\x51\xcf\x4f\x57\ +\xf9\xe2\x49\x4b\x67\x71\xbe\x4a\x31\x40\x9d\xe5\x8b\xfa\xff\x82\ +\xa7\x9a\x5e\x18\x22\xa4\xdf\x9b\x1b\x04\xbe\xf4\xd2\x3b\xfc\xb0\ +\x76\x8f\xf1\x19\x89\x35\xbb\xa8\xa4\x57\x5b\xb1\x5c\x79\x7e\x76\ +\x4d\xa6\x45\x5a\x2c\x8b\xb5\xca\xf3\xd3\x6b\xf6\x4f\x49\xbf\xa8\ +\x4d\x84\x8a\x3a\x70\xda\x6a\x94\xa5\x82\x57\x34\xb1\x4a\x51\x09\ +\x4f\x57\x81\xc2\xe6\xbb\xc7\xec\x9d\x52\x48\x4f\x67\x75\xc2\xd7\ +\x59\xd5\x1b\xa7\x54\x4e\x77\x5a\x67\x56\x9c\xc7\xec\x9a\x52\xc7\ +\xef\xee\x9e\xf8\x20\x6e\xf6\x9f\x0d\xd8\xb8\x96\x13\x2c\xa0\xe3\ +\x86\x9e\x4a\x48\x6e\x14\x4d\xf6\xd2\x7a\xee\x84\xc8\x9d\x49\xf8\ +\x73\x63\x17\x91\x91\xf3\x58\xb0\xf1\x0a\xbd\xfb\xdf\x50\x60\xa1\ +\x9e\x15\x42\x3f\x0c\xc2\x45\xff\x93\x64\xfb\xcd\xcb\x8a\xff\x24\ +\xd8\xe6\xe5\x5f\xd1\x32\xdf\x60\ +\x00\x00\x06\x60\ +\x00\ +\x00\x4e\xb7\x78\x9c\xe5\x5c\x5b\x8f\xa3\x36\x14\x7e\x9f\x5f\x41\ +\x99\x97\x5d\xb5\x36\xd7\x24\xc0\x26\xd9\x87\x8e\x56\x5a\xa9\x4f\ +\xed\x56\x7d\x5c\x11\x70\x12\x34\x80\x11\x90\x49\xb2\xbf\xbe\xc7\ +\xe6\x92\x90\x30\x52\x2b\x1b\x89\x2c\x8c\x46\x33\xf8\x1c\x83\xfd\ +\xf9\x3b\xf6\xb9\x64\x66\xf9\xf9\x94\xc4\xca\x1b\xc9\x8b\x88\xa6\ +\x2b\xd5\xc0\xba\xaa\x90\x34\xa0\x61\x94\xee\x56\xea\xdf\xdf\xbe\ +\x20\x47\x55\x8a\xd2\x4f\x43\x3f\xa6\x29\x59\xa9\x29\x55\x3f\xaf\ +\x9f\x96\xbf\x20\xa4\xfc\x9e\x13\xbf\x24\xa1\x72\x8c\xca\xbd\xf2\ +\x35\x7d\x2d\x02\x3f\x23\xca\x87\x7d\x59\x66\x9e\xa6\x1d\x8f\x47\ +\x1c\xd5\x8d\x98\xe6\x3b\xed\xa3\x82\xd0\xfa\xe9\x69\x59\xbc\xed\ +\x9e\x14\x45\x81\xf7\xa6\x85\x17\x06\x2b\xb5\xee\x90\x1d\xf2\x98\ +\x2b\x86\x81\x46\x62\x92\x90\xb4\x2c\x34\x03\x1b\x9a\x7a\x51\x0f\ +\x2e\xea\x01\x7b\x7b\xf4\x46\x02\x9a\x24\x34\x2d\x78\xcf\xb4\x78\ +\xbe\x52\xce\xc3\x6d\xab\xcd\x46\x73\xb4\xb8\x92\xe1\xba\xae\xa6\ +\x9b\x9a\x69\x22\xd0\x40\xc5\x39\x2d\xfd\x13\xea\x76\x85\x31\xf6\ +\x75\x35\x75\x5d\xd7\x40\x76\xd1\xfc\x6f\x5a\x5e\x01\x80\x66\xf0\ +\xdd\xaa\x37\x0d\xb8\xa0\x87\x3c\x20\x5b\xe8\x47\x70\x4a\x4a\xed\ +\xe5\xdb\x4b\x2b\x44\x3a\x0e\xcb\xf0\xea\x31\x0d\x9e\x9d\xb7\x76\ +\x40\x4e\xfd\x84\x14\x99\x1f\x90\x42\x6b\xda\x79\xff\x63\x14\x96\ +\xfb\x95\x6a\xd9\xd8\xb0\xe0\x9a\xf1\xc6\x3d\x89\x76\xfb\xf2\xb6\ +\x35\x0a\x57\x2a\x8c\xde\x74\x9d\xea\xfe\x8a\x1c\x46\xa5\x50\x3f\ +\xd8\x6b\x25\x3a\x76\x4d\x6c\x2b\x1f\x66\xa1\x3f\x77\xdc\xc0\x32\ +\xac\xdf\x14\x53\x37\x5c\xa4\x1b\xc8\xb0\x3f\xf2\x5e\xcd\xa4\xbc\ +\x90\x06\x6c\x94\xf0\x12\x92\x44\xfe\xa1\xa4\x09\xac\x63\x10\xc4\ +\x7e\x51\x44\xdb\x28\x80\x1b\x9a\x66\xf1\x61\x17\xa5\xdf\x53\x36\ +\xc0\x0d\xcd\xbf\x67\xd1\x89\xc4\x05\x6e\x40\x6d\x47\x40\x4e\x19\ +\xcd\x4b\x74\x0a\x33\x80\x76\xbe\xe8\x15\x9e\x1b\xe1\x1a\xa4\xcb\ +\x90\x6c\x0b\xa6\x55\xcd\x93\xdd\xc1\x44\x17\xaa\xa2\x71\x69\x3b\ +\x48\x36\xc2\xf0\x2d\x22\xc7\x8b\xee\xc6\x2f\x2a\x2c\x15\x25\xf3\ +\x77\xc0\xbb\x98\xe6\x2b\xf5\x79\xcb\xaf\x5a\x00\x63\x0d\x49\xde\ +\x88\xe6\xfc\xea\x88\x28\xac\x4d\x54\x9e\x2b\x4b\xab\x9f\xdd\x8c\ +\x97\x3d\xb5\x95\xeb\xfd\xf2\x62\xef\x87\xf4\xb8\x52\xcd\x5b\xe1\ +\x0f\x4a\x93\x95\x3a\xc3\x33\xd7\x71\x75\xe3\x56\x1a\x9c\x56\x2a\ +\x2c\xb2\x6e\x3a\xa6\xeb\xde\x09\xd9\x70\x0c\xec\xd8\xf6\xdc\xb5\ +\xef\x84\x87\x3c\x07\x4b\x44\xb1\x7f\x26\x30\x27\xfe\xa3\x79\x7c\ +\xb1\xa7\xc7\x5d\xce\xb0\x29\xf3\x03\xb9\xed\xc9\x24\x68\xb3\xa1\ +\xa7\x7e\x31\xd0\xe0\xc0\x6c\x1c\x1d\xd2\xa8\x04\x3b\xca\x4e\xd7\ +\x4f\x3d\x44\x21\x29\xfa\x3b\x16\xa9\x9f\xa1\x5d\x4c\x37\x7e\xdc\ +\xaf\x70\x8c\x52\xc0\x08\xd5\x94\x37\xac\x76\x09\x6e\x35\x1a\xfe\ +\x2f\xf4\xc5\x3b\x1a\x30\xf6\xbb\x65\xa8\x45\xe7\xf7\x45\x89\x7f\ +\x8a\x92\xe8\x07\x01\x60\x0c\xce\x3a\x60\x56\x07\x96\xaa\x9b\xa2\ +\x94\x67\x66\xcb\xa7\x33\x6b\x53\x9b\x46\x86\x27\x6b\x80\x95\x5a\ +\xb4\x8d\x34\x8f\xc0\x20\xae\x86\xd3\x34\x9d\xaf\x9b\x98\xe5\xc3\ +\xc6\x7d\xe2\xf4\xe2\xe4\x5b\xdc\xca\xce\xd7\xb2\x9a\xf5\xda\x3d\ +\xed\x79\x7b\x42\x4a\x3f\xf4\x4b\xff\x62\x03\x4d\x0b\x8c\x4d\x6f\ +\x66\x06\x9b\xa8\xf7\xe7\xcb\x97\x75\xfd\xa2\x65\x10\x78\xff\xd0\ +\xfc\xb5\x79\xaf\xa2\x30\x05\x7f\x43\x0f\x80\xb4\xba\x6e\x9b\x97\ +\x61\xe0\xc1\xb6\x07\xc6\xbf\x8e\x12\x60\x36\xdb\x31\x7f\x85\x6d\ +\x6e\xa9\x5d\x04\x1d\x65\x06\xd6\xe5\xa1\xd5\x63\x73\x52\xed\x9f\ +\xbd\x87\x48\x18\x24\x11\xeb\xa4\xfd\x55\x46\x71\xfc\x95\xbd\xa4\ +\x9e\xf1\xd5\x43\xa3\x32\x26\x6b\xfe\xce\xea\xd7\x66\x16\x5a\x3d\ +\x8d\x7a\x92\xda\xd5\x2c\x97\x5a\x03\x03\xbf\xdb\x5d\xe0\xe9\x58\ +\x47\xbb\xe2\xb1\xbf\x21\x40\xd5\x3f\x98\x50\xb9\x93\xee\x72\x7a\ +\xc8\x12\x1a\x92\xba\x7b\x0b\x2b\x09\xca\x76\xed\xca\x73\x0c\xf2\ +\x2d\x4c\xc3\x7b\x76\x74\xf6\xf5\x89\xdd\xa0\x7a\xbb\xf0\x8c\xea\ +\x36\x3f\xc4\xb0\xed\xbd\x91\x94\x86\xe1\xa7\xa2\xcc\xe9\x2b\xf1\ +\x9e\x75\x7e\xd5\xb7\x95\x55\x78\x3a\xb6\x2d\xd7\x66\x24\x68\xda\ +\x01\x2a\x92\xc7\x40\xdb\xd2\xb3\x9b\xb6\xd0\x87\xed\x26\xcf\xfd\ +\xb3\x97\xc2\xd9\xdf\xb4\xb6\xef\xec\x30\x96\x0d\x77\xe6\x58\x2e\ +\x32\xc0\x63\x68\x04\xb5\x09\xce\xb0\x65\x5d\xce\x17\x76\x35\x96\ +\x67\x63\x97\x4b\xec\x56\xc2\xb8\xab\xe3\x1b\xee\x02\x69\x2d\xec\ +\x74\xb6\x53\x58\xff\x8e\x35\xe4\x9c\xd8\x73\x9b\x5d\xf3\x76\x99\ +\xdf\x47\x71\x63\xb1\xaf\x31\xa3\x88\x8c\x21\x70\x44\xf7\x3b\x83\ +\x18\x90\xd5\x90\x46\x0d\xa4\x3b\x04\x90\x86\x85\x17\x5d\xcd\x9f\ +\x1e\x47\x03\xcd\x86\x40\xd2\xc1\x0e\x9f\x8b\x39\x1d\x24\x17\x43\ +\xe0\x68\x5a\x58\xd6\xee\xf8\x00\x10\x02\x19\x07\x61\xa3\xe1\xe0\ +\xa9\x1d\x34\xee\x30\x7c\xb4\x2c\x6c\xcb\x3c\x69\xc6\xef\xf8\x30\ +\x52\x22\x7d\x10\xdb\x76\xf0\x8c\xab\x4e\x82\x95\x82\x08\xea\x1d\ +\x16\x4a\x76\x1c\xc7\xce\x42\x41\xec\xee\xd5\xa7\xe8\x7c\xdb\x43\ +\xa0\x28\xdd\xf5\x1e\x39\x8c\xa2\x71\x60\xc7\x8c\x65\xbb\xdb\x63\ +\x37\x63\xe4\x88\xc2\xd7\xcb\x41\xd9\x30\x8e\x9c\x82\xba\xb0\x25\ +\x77\x48\x28\x3b\x52\x19\x3d\x09\x6d\x64\x0e\xc1\x42\xd9\x38\x8e\ +\x9d\x85\x96\x4c\x12\x4a\x0c\xf3\x46\xcf\xbf\xf9\x10\xec\x93\x08\ +\xe0\xd8\x89\x27\x1c\xd8\x75\xcf\x60\xc9\xa1\xf1\xe8\xe9\x67\x0f\ +\x43\xc0\xe9\xa5\x18\xc4\x93\xd9\xfd\x71\x89\xe4\x0c\xc3\xc8\x81\ +\x04\x6f\x46\x18\xc7\xee\x51\x22\x39\xab\xf0\x00\x06\x6d\x0a\x6f\ +\x89\xfd\x67\xca\xa4\xf2\x33\x15\x13\xe5\xfa\xd6\x53\xb4\x65\x61\ +\xef\xba\x83\xa0\xf4\xfc\xc2\xe8\xcd\xd9\x41\xb6\x28\x07\xcd\xf9\ +\xed\x59\xcc\xf3\x5d\x0b\x6b\x42\xd6\x5c\x65\xae\x45\xf7\xc5\x5e\ +\x24\x81\x93\x93\x09\x96\x59\x21\x45\x34\xf9\xdf\x0b\xa2\x31\xa1\ +\x88\xaf\xaa\xa1\x88\x56\xf6\x7a\x61\x74\x6e\xeb\x2a\x3f\x3d\x94\ +\x0b\xe1\x03\xa6\x17\x48\x73\x92\x85\xbd\x19\xd2\x45\xa3\xc1\x7e\ +\xeb\x9e\x96\xeb\x58\x17\x9c\x87\x61\x26\x38\x91\x5c\x73\x42\x67\ +\x0e\x2f\x39\x0b\xbb\xe2\xfd\x76\xee\xe0\x89\x94\x5b\x84\x3f\xff\ +\x30\xa8\xfb\x38\x72\xf0\xc4\xc3\x18\xd3\xc0\x37\x8d\x53\x74\xc2\ +\x6d\x64\x8a\xd6\xfc\x7a\x81\x94\xe8\x83\xd7\x98\x8c\x15\x43\x07\ +\x89\x56\x5a\x8c\xa1\x1c\xef\x6a\x14\xa3\x45\x8e\xe7\x68\x45\xc1\ +\xeb\x65\xdf\x74\x30\xe4\x29\x1d\x5b\xf8\xd3\xef\x43\xc6\x2c\x23\ +\x47\xb0\x4a\xd0\x0e\xb2\x09\x4e\x0b\x48\xdd\x92\xec\xd2\xc8\x0e\ +\xf9\x46\x8e\x9f\x81\xe6\xe2\x39\x88\x3e\x1a\xca\xc6\x71\xe4\x07\ +\xb2\x0e\x81\x9e\xdc\x0d\x51\x76\xb4\x3c\x7a\x22\xda\x40\x45\x4b\ +\xb4\xea\xd7\x7f\x32\x4f\x2e\xf1\xc0\xa2\x65\x57\x38\x45\xdb\x1b\ +\xac\x4c\x2b\xf1\x50\x55\xaf\x1c\xb9\xde\xf6\x74\xd2\x0d\x75\x21\ +\x5a\xb8\x98\xdf\x7f\xc4\xc8\x83\x71\xe4\x16\x5d\x57\xa1\xc5\xff\ +\x2a\x6d\xd0\x1c\xe2\x43\x80\x68\x22\x57\x34\xb9\x6d\x0c\x55\xf8\ +\x1b\x39\x80\x55\x19\x5a\x38\x07\x76\xc5\xb7\x29\x26\xbf\x78\x05\ +\x5a\xf8\xe3\x76\x5d\x10\xa7\xc5\x41\x66\xca\xa2\xbe\x76\x17\x3f\ +\x89\xa9\x9b\x07\xc0\x8f\xd7\x9d\x85\x8f\xe4\x2e\x82\x92\xb3\x0e\ +\x0f\x80\xe2\x42\xc2\x27\xec\xba\x18\xca\x0e\x99\x1f\x00\xc4\xba\ +\xda\x2c\xf9\x4c\x99\x5e\xbc\x57\x15\x9a\x85\xf3\xda\x37\x47\xf3\ +\xb4\xfc\xc3\xab\x1a\xb3\x70\x95\xf9\xc6\xb0\xff\x5f\xa0\xb2\xd4\ +\x76\xeb\xa7\x25\xfb\x37\x41\xeb\xa7\x7f\x01\x0e\x6d\x5f\xf1\ +\x00\x00\x0a\x77\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\ +\x68\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\ +\x33\x35\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\ +\x38\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x30\x2e\x32\x20\ +\x28\x65\x38\x36\x63\x38\x37\x30\x38\x37\x39\x2c\x20\x32\x30\x32\ +\x31\x2d\x30\x31\x2d\x31\x35\x29\x22\x0a\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\ +\x65\x6d\x69\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\ +\x73\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\ +\x5f\x70\x6f\x73\x74\x5f\x70\x72\x6f\x63\x65\x73\x73\x2e\x73\x76\ +\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\ +\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\x0a\x20\x20\ +\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ +\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ +\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\ +\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ +\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ +\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ +\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\ +\x2e\x39\x35\x39\x30\x32\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x38\x2e\x34\x30\ +\x33\x33\x38\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x37\x2e\x31\x36\x35\x36\x38\ +\x33\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\ +\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ +\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\ +\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x37\x30\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\ +\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x72\x6f\x74\x61\x74\ +\x69\x6f\x6e\x3d\x22\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ +\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ +\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\ +\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ +\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ +\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ +\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ +\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ +\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ +\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ +\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ +\x0a\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\ +\x3a\x23\x34\x39\x36\x34\x36\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x31\x2e\x32\x39\x32\x39\x39\x35\x33\x33\x3b\ +\x73\x74\x72\x6f\x6b\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\ +\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\ +\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\ +\x78\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x63\x79\ +\x3d\x22\x31\x37\x2e\x30\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x34\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x72\x79\x3d\x22\x32\x31\x2e\x33\x33\x33\x33\x33\x34\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\ +\x6c\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ +\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x65\x36\x65\x36\x65\x36\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x30\x2e\x39\x33\x30\x39\x38\x39\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x73\ +\x71\x75\x61\x72\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x32\x2e\x39\x34\x39\x31\x37\ +\x35\x2c\x31\x34\x2e\x31\x33\x34\x33\x38\x20\x68\x20\x31\x30\x2e\ +\x31\x36\x30\x34\x34\x20\x56\x20\x38\x2e\x38\x30\x32\x37\x39\x35\ +\x20\x6c\x20\x38\x2e\x38\x39\x30\x33\x38\x36\x2c\x38\x2e\x35\x33\ +\x30\x35\x33\x39\x20\x2d\x38\x2e\x38\x39\x30\x33\x38\x36\x2c\x38\ +\x2e\x35\x33\x30\x35\x33\x39\x20\x76\x20\x2d\x35\x2e\x33\x33\x31\ +\x35\x38\x36\x20\x68\x20\x2d\x31\x30\x2e\x31\x36\x30\x34\x34\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\ +\x63\x74\x33\x38\x31\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x63\x63\ +\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0d\x25\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x6f\x69\x5f\x72\ +\x65\x64\x6f\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\ +\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x33\x2e\x36\x33\x30\x32\x37\x32\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\ +\x38\x2e\x39\x37\x31\x31\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\ +\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\ +\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\ +\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\ +\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\ +\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\ +\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\ +\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\ +\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ +\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ +\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ +\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ +\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ +\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ +\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ +\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\ +\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x23\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\ +\x23\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\ +\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\x38\x33\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\ +\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\ +\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\x39\x39\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\x33\x33\x30\ +\x33\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\ +\x33\x2e\x38\x30\x34\x38\x37\x38\x35\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\ +\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\ +\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\ +\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ +\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\ +\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\x64\x69\x75\ +\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x6e\x6f\ +\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\ +\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\ +\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\x69\x6e\x64\ +\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\ +\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\ +\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\x65\x78\x74\ +\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\x69\x6e\x65\ +\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\x73\x70\x61\ +\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\x6f\x72\x64\ +\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3a\x6e\ +\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\x6f\x64\x65\ +\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\ +\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\x2d\x73\x68\ +\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\x74\x65\x78\ +\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\x74\x3b\x64\ +\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\ +\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\ +\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\ +\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x66\ +\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\ +\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\x33\x33\x34\ +\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\ +\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\ +\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x4d\x20\x38\x2c\x39\x2e\x36\x36\x36\x36\ +\x36\x36\x37\x20\x43\x20\x33\x2e\x38\x31\x34\x30\x31\x30\x37\x2c\ +\x31\x34\x2e\x38\x37\x36\x37\x39\x35\x20\x34\x2e\x34\x33\x32\x38\ +\x39\x30\x37\x2c\x32\x32\x2e\x36\x34\x34\x37\x39\x34\x20\x39\x2e\ +\x34\x2c\x32\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x31\x34\x2e\x33\ +\x36\x37\x31\x30\x39\x2c\x33\x31\x2e\x34\x38\x38\x35\x34\x20\x32\ +\x31\x2e\x39\x34\x37\x33\x34\x34\x2c\x33\x30\x2e\x38\x31\x30\x31\ +\x32\x38\x20\x32\x36\x2e\x31\x33\x33\x33\x33\x33\x2c\x32\x35\x2e\ +\x36\x20\x63\x20\x34\x2e\x31\x38\x35\x39\x39\x2c\x2d\x35\x2e\x32\ +\x31\x30\x31\x32\x38\x20\x33\x2e\x35\x36\x37\x31\x31\x2c\x2d\x31\ +\x32\x2e\x39\x37\x38\x31\x32\x37\x20\x2d\x31\x2e\x34\x2c\x2d\x31\ +\x37\x2e\x34\x20\x6c\x20\x33\x2c\x2d\x32\x2e\x38\x36\x36\x36\x36\ +\x36\x37\x20\x48\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x56\ +\x20\x36\x2e\x34\x20\x6c\x20\x33\x2e\x32\x2c\x38\x2e\x35\x33\x33\ +\x33\x33\x33\x20\x32\x2e\x36\x36\x36\x36\x36\x36\x2c\x2d\x33\x2e\ +\x37\x20\x63\x20\x32\x2e\x33\x37\x39\x33\x30\x32\x2c\x33\x2e\x32\ +\x37\x37\x37\x32\x39\x20\x33\x2e\x31\x37\x31\x30\x35\x38\x2c\x38\ +\x2e\x39\x35\x30\x32\x36\x36\x20\x30\x2e\x35\x33\x33\x33\x33\x34\ +\x2c\x31\x32\x2e\x32\x33\x33\x33\x33\x34\x20\x2d\x33\x2e\x30\x34\ +\x31\x38\x35\x38\x2c\x33\x2e\x37\x38\x36\x30\x37\x34\x20\x2d\x38\ +\x2e\x32\x32\x30\x37\x31\x37\x2c\x34\x2e\x32\x31\x39\x37\x32\x20\ +\x2d\x31\x31\x2e\x38\x2c\x31\x2e\x30\x33\x33\x33\x33\x33\x20\x2d\ +\x33\x2e\x35\x37\x39\x32\x38\x33\x35\x2c\x2d\x33\x2e\x31\x38\x36\ +\x33\x38\x37\x20\x2d\x34\x2e\x30\x34\x31\x38\x35\x38\x35\x2c\x2d\ +\x38\x2e\x39\x31\x33\x39\x32\x35\x20\x2d\x31\x2c\x2d\x31\x32\x2e\ +\x37\x20\x43\x20\x31\x31\x2e\x32\x2c\x31\x32\x2e\x33\x20\x31\x31\ +\x2e\x32\x2c\x36\x2e\x39\x36\x36\x36\x36\x36\x37\x20\x38\x2c\x39\ +\x2e\x36\x36\x36\x36\x36\x36\x37\x20\x5a\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ +\x74\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\ +\x65\x73\x3d\x22\x63\x73\x73\x63\x63\x63\x63\x63\x63\x73\x73\x63\ +\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x08\x75\ +\x00\ +\x00\x59\x6c\x78\x9c\xe5\x5c\xdb\x8e\xe3\x36\x12\x7d\xef\xaf\xd0\ +\x6a\xb0\x48\x06\x3b\xa4\x48\x51\xf7\xb6\x1d\x60\x77\x10\x24\x40\ +\xf6\x65\x93\xc5\x3e\x06\x6a\x89\xed\xd6\x8e\x2c\x19\x92\xdc\xb6\ +\xe7\x6b\xf6\x5b\xf2\x65\x29\x52\x17\x4b\xb6\xbc\x99\x8c\xe4\xa4\ +\x7b\xa8\x46\x63\x46\x55\x45\x91\x3c\x75\xaa\x78\x11\x5b\x8b\x6f\ +\x0e\x9b\x54\x7b\xe6\x45\x99\xe4\xd9\x52\xa7\x98\xe8\x1a\xcf\xa2\ +\x3c\x4e\xb2\xf5\x52\xff\xf7\x4f\xdf\x22\x4f\xd7\xca\x2a\xcc\xe2\ +\x30\xcd\x33\xbe\xd4\xb3\x5c\xff\x66\x75\xb7\xf8\x0b\x42\xda\x3f\ +\x0a\x1e\x56\x3c\xd6\xf6\x49\xf5\xa4\x7d\x9f\x7d\x28\xa3\x70\xcb\ +\xb5\xaf\x9f\xaa\x6a\x1b\x18\xc6\x7e\xbf\xc7\x49\x23\xc4\x79\xb1\ +\x36\xde\x6a\x08\xad\xee\xee\x16\xe5\xf3\xfa\x4e\xd3\x34\xa8\x37\ +\x2b\x83\x38\x5a\xea\x4d\x81\xed\xae\x48\xa5\x61\x1c\x19\x3c\xe5\ +\x1b\x9e\x55\xa5\x41\x31\x35\xf4\x93\x79\x74\x32\x8f\x44\xed\xc9\ +\x33\x8f\xf2\xcd\x26\xcf\x4a\x59\x32\x2b\xdf\xf4\x8c\x8b\xf8\xb1\ +\xb3\x16\xad\xd9\x33\x69\x44\x7d\xdf\x37\x88\x69\x98\x26\x02\x0b\ +\x54\x1e\xb3\x2a\x3c\xa0\x61\x51\x68\xe3\x58\x51\x93\x10\x62\x80\ +\xee\x64\xf9\x69\x56\x41\x09\x80\x6e\xe1\xb7\x33\x6f\x05\xb8\xcc\ +\x77\x45\xc4\x1f\xa1\x1c\xc7\x19\xaf\x8c\xf7\x3f\xbd\xef\x94\x88\ +\xe0\xb8\x8a\x7b\x8f\x69\xf1\x1c\xd4\x3a\x00\x39\x0b\x37\xbc\xdc\ +\x86\x11\x2f\x8d\x56\x2e\xcb\xef\x93\xb8\x7a\x5a\xea\xcc\xc2\x94\ +\xc1\x65\x4b\xe1\x13\x4f\xd6\x4f\xd5\xb9\x34\x89\x97\x3a\xb4\xde\ +\xf4\xbd\xfa\xbe\x47\x0e\x5a\x1b\x34\x0f\x0e\x3a\x0d\xc1\xbe\x89\ +\xa9\x56\x50\x9b\xb9\xb5\x4d\xdb\x85\x20\xce\x23\xd1\x26\x78\x24\ +\xdf\x24\xe1\xae\xca\x37\xe0\xb5\x28\x4a\xc3\xb2\x4c\x1e\x93\x08\ +\x6e\xf2\x6c\x9b\xee\xd6\x49\xf6\x73\x54\xe4\x65\xf9\xf3\x50\x85\ +\x5b\x1c\xbb\x4a\xf9\x61\x9b\x17\x15\x3a\xc4\x5b\x40\xd3\x71\x47\ +\x95\xc7\x56\xb9\x02\xed\x22\xe6\x8f\xa5\xb0\xaa\xbb\x26\xee\xa0\ +\x6f\xae\xae\x19\x52\xdb\xb5\x54\x34\x33\x7e\x4e\xf8\xfe\x64\xfb\ +\x10\x96\x35\x7c\x9a\xb6\x0d\xd7\x40\xb5\x34\x2f\x96\xfa\x9b\x47\ +\x79\x35\x8a\x87\xbc\x88\x79\xd1\xaa\x1c\x79\x0d\x54\x39\xb8\x23\ +\xa9\x8e\x75\x70\x35\xcf\x6e\xdb\x2b\x9e\xda\xe9\xc9\xb8\xbe\x7c\ +\x0a\xe3\x7c\xbf\xd4\xcd\x73\xe5\xc7\x3c\xdf\x2c\x75\x1b\xdb\xbe\ +\xe7\x13\x7a\xae\x8d\x0e\x4b\x1d\xd9\x26\x76\x2c\xe6\x78\x17\x65\ +\x23\xa8\x0f\x51\x8a\x99\xe7\x38\xd6\x85\x72\x57\x14\x10\x7d\x28\ +\x0d\x8f\x1c\x3a\x25\xff\x69\x9f\x5f\x3e\xe5\xfb\x75\x21\xc0\xa9\ +\x8a\x1d\x3f\x2f\x29\x34\xe8\xe1\x21\x3f\x8c\xab\x81\x0c\x3b\x11\ +\xd7\x68\x97\x25\x15\xc4\xce\xf6\xd0\x7f\xea\x2e\x89\x79\x39\x5e\ +\xb0\xcc\xc2\x2d\x5a\xa7\xf9\x43\x98\x8e\x1b\xec\x93\x0c\x40\x42\ +\x0d\xcd\x29\xeb\x7c\x70\x6e\xd1\x72\xde\x25\xde\x15\x0b\x68\xfb\ +\x85\x1f\x1a\xd5\xf1\xba\x6a\x13\x1e\x92\x4d\xf2\x91\x03\x30\x54\ +\xd2\x0e\xa8\x35\x80\xa5\x2e\xa6\x69\xd5\x51\xc4\xef\xe1\x28\x64\ +\x7a\x2b\x14\x78\x0a\x81\xe9\xfb\x6e\x27\xcc\x8b\x04\xc2\xa2\xd7\ +\x9c\x56\x74\xec\x8b\x44\xb4\x43\xb2\x3e\x48\x7e\x49\xf6\xb9\xe7\ +\xba\x63\x5f\xd7\xd0\xde\xb8\xe4\xbd\x94\x6f\x78\x15\xc6\x61\x15\ +\x9e\x82\xa0\x95\x40\xdb\x48\xdb\x33\x48\x9c\xc1\xbf\xde\x7f\xbb\ +\x6a\x2a\x5a\x44\x51\xf0\x9f\xbc\xf8\xd0\xd6\xab\x69\xc2\x20\x7c\ +\xc8\x77\x80\xb4\xbe\xea\xc4\x8b\x38\x0a\x20\xd5\x41\x0a\x58\x25\ +\x1b\xa0\xb6\xc8\x92\x7f\x83\xd4\xb6\x30\x4e\x8a\x81\xb1\x00\xeb\ +\xf4\xd0\xfa\xb1\x05\xaf\x73\xe6\xe8\xc0\x11\x47\x9b\x44\x14\x32\ +\x7e\xac\x92\x34\xfd\x5e\x54\xd2\xf4\xb8\xf7\xd0\xa4\x4a\xf9\x49\ +\xb8\x30\x9a\xd6\x37\x7d\x33\x7a\x9d\x5b\x18\x6d\xef\xe5\xdd\xfa\ +\x84\xca\x20\x28\x3a\x47\xa7\xe1\x03\x07\x86\xfe\x20\x94\xda\x85\ +\x76\x5d\xe4\xbb\xed\x26\x8f\x79\x53\xbc\x43\x93\x47\x55\xe7\xb2\ +\xea\x98\x82\xfe\x11\x5a\x1f\xbc\x09\x89\x19\x99\xd1\xbd\xb8\x41\ +\x4d\x9a\x08\x68\x7d\x5b\xec\x52\x48\x77\xcf\x3c\xcb\xe3\xf8\xbe\ +\xac\x8a\xfc\x03\x0f\x9a\xc4\xd4\xdc\xd6\xc1\x10\x10\x6c\x31\xdf\ +\x12\xbe\x6f\xe5\x80\x10\x2f\x52\x60\x6b\x15\x58\xad\x2c\x0e\x21\ +\xcd\x14\x45\x78\x0c\x32\x18\xe6\x5b\x69\x57\xe7\x80\xa8\xa2\xb9\ +\xb6\xc7\x7c\x44\x91\x87\x4e\xaa\x26\xf6\x6c\xcc\xd8\x69\x30\x11\ +\x57\x1b\x72\x16\xf6\xa5\xc6\xea\x34\x82\xb4\x04\x9f\x91\x56\x66\ +\xa6\x0b\x2a\x17\x83\x38\x28\x24\xa5\x1d\x4b\x5c\x4e\xe7\xe0\x57\ +\x0d\xa4\x7f\x0b\x20\x29\xc3\xee\xd0\xf2\x8b\xc7\x91\x22\xfb\x16\ +\x48\x7a\xd8\x23\xe2\x32\x67\x42\x92\x10\x0f\x7e\x5e\x34\x92\xee\ +\x2d\x70\x34\x19\x76\xd4\x81\x10\xc8\x78\x13\x36\x52\x0f\x0f\x66\ +\x9a\x0a\x40\xe9\xdf\x86\x8f\x8c\x61\x4b\x9d\x91\x66\x22\x82\x64\ +\x80\x1c\xf6\x66\xe5\xe0\xcb\x46\x0e\x38\x68\x4d\x44\xef\xd2\x5c\ +\xc1\xa9\x8e\x37\x27\x05\x15\x9b\xde\x90\xc9\x14\x1c\xa0\xa7\xd8\ +\x94\x86\xb0\x39\xc1\x53\x67\x1e\x43\x26\x0f\xbc\xc3\x98\x55\x6e\ +\xea\x32\x7d\x91\x3c\x3a\x72\xcc\x3d\x73\x79\xe1\x40\x42\xf2\x9b\ +\x8c\xe3\x30\x82\x3d\x6c\x4b\x13\x85\xf0\x9b\x77\x00\x51\x6b\xee\ +\xdc\x20\x68\xce\x89\xa0\x6a\xb3\x3f\xb1\x90\xb3\xa6\x72\xd0\x74\ +\xce\x47\x10\xb9\x1a\x71\xd9\x9c\xd1\xfc\x0a\x80\xa4\x93\x07\xe6\ +\x51\x24\x81\x93\x73\xcd\x08\x5f\x05\x88\xf6\xe4\x0d\xc3\x51\x18\ +\xbd\xf3\xcd\x86\x2f\x7a\x74\x69\x76\x68\x26\x67\xc7\xf1\xd8\x66\ +\xf5\x43\x94\xa1\xa5\x85\xcc\xa9\xeb\x64\x93\xe2\x33\xa1\x52\xa1\ +\xed\xa1\xa9\xab\x3d\x3a\xa0\x20\x9d\x6f\xb9\xf7\xc2\x91\x93\xb3\ +\x1c\x6b\x2a\xfd\xa8\xc2\xb9\x90\xb0\xe9\x5b\xd5\x03\xf8\x4c\xb5\ +\x56\x7a\x14\x39\xd3\x87\xe4\xb1\xf4\xa7\x18\x8e\x04\xc6\xe3\x79\ +\xe3\x98\xaa\xb5\x64\x16\x03\xb1\x83\xd8\xd4\x5d\x87\x51\x2e\x2a\ +\x07\xa5\xd8\x06\x43\x3e\xb9\x05\x96\x73\xcf\x0f\x5f\x38\x96\xcd\ +\x4e\xce\xf4\x73\x0e\x2a\x4f\xb2\x9b\xcd\x1c\xe4\x3b\xb3\xa2\xa8\ +\xce\x0c\xbb\xde\xca\x99\xbc\xe0\xeb\xf1\x4d\xd9\x5d\x1c\x34\x95\ +\x83\x43\x10\xd5\xe2\xa0\x08\xe5\xa9\xb3\x9c\x21\x7e\xea\xac\xf5\ +\xba\x0d\xb0\xc9\x6f\x56\x86\x08\xaa\xb5\xde\x93\x67\xe5\x60\x28\ +\x99\xba\xe8\x1b\x62\xa8\xd8\x62\xa5\x3d\x2d\x87\x88\x33\xf3\x98\ +\x32\xdf\x4c\x7b\x08\xdb\xab\x80\x54\xee\xc9\x4e\xde\x0b\x43\xcc\ +\x3d\x9f\x1c\xfe\xee\x19\x63\x2b\xad\x8a\x30\x2b\xc5\x59\xff\xa5\ +\x5e\x46\x61\xca\xbf\x46\xf4\x1d\x7d\xfb\xc5\x10\x58\x4e\x2c\xa7\ +\xbe\xe1\x3a\xcb\x04\x1e\x56\xe4\x80\x13\x9d\xbe\x5f\x31\x7a\xc6\ +\x73\xe6\x93\x8a\xaf\x85\x89\xb7\xc0\x72\xee\x53\x13\x2f\x9d\x91\ +\x13\x31\x1c\x3f\xb9\xa3\xda\xc9\x59\x6f\x6a\x58\x8f\xc2\xa8\xd8\ +\xe9\x4f\xf9\x5a\xf0\x16\x38\x2a\x76\x0e\x94\x4e\x5e\x6e\x8f\xa2\ +\xa8\xce\x81\x50\xb9\x2d\x7e\x93\x80\x56\xed\x68\xa8\x35\xc3\xaa\ +\x71\x9c\x8c\x8a\x8d\xd2\xf5\x3e\xd0\x44\x24\x47\xcf\x9e\xcc\xb8\ +\x19\xf4\xe2\xe9\xd8\xad\xc0\x6f\x02\xa4\x72\x2f\xbc\xda\xe5\xe0\ +\x2d\xd0\x54\x67\x4d\x38\xef\x51\x0a\xe5\x5e\x30\x4c\x3e\x90\x37\ +\xfa\xc2\x55\x35\x14\xbd\xe9\xe7\xc9\xc6\x4f\x01\x28\xf4\xaa\x41\ +\x4c\x76\x6e\x72\xaa\x51\xad\xb7\x0d\xf5\x8b\x6b\x6f\xde\xe3\x8d\ +\x33\x0e\x27\x2f\x1c\xbe\x66\xd2\x3d\x79\x63\x67\xfc\x80\x99\x42\ +\x30\x7a\xb7\x3a\xed\x3d\xf7\x8b\xaf\x06\x99\x01\x92\xe4\xff\x20\ +\x49\x2c\xb1\x19\x32\x44\xd2\xc2\x1e\xf1\x6d\xdf\xf7\xbc\x11\x24\ +\x61\x34\x94\xfb\x27\xc4\xfe\x5c\x48\x4d\xdf\xbf\xfc\xd3\x7c\x82\ +\x99\x4b\x98\xe3\x5f\x42\xe9\x61\xd7\x22\x2e\xf3\xfa\x50\x12\xec\ +\x99\xbe\xc3\x88\x3d\x5c\x51\x63\xe6\x9b\xb6\x6f\xd9\x03\x2c\x3d\ +\x90\x12\xe6\xdb\xe6\x00\x53\x1b\xbb\xbe\xcd\xfc\xde\x47\x02\xba\ +\x0f\x17\x75\xef\x6c\x50\xc4\x33\xe8\xb7\xf8\x46\x16\x72\xb0\x4b\ +\x1d\x62\x79\xee\x27\xd8\x1f\xa5\xbd\xe5\x7b\xae\xe3\xd8\x27\x9f\ +\x6d\xc3\xea\x69\xcc\x67\x3d\xd4\x44\x24\x5c\xfa\x83\x02\xb3\x1d\ +\x66\x41\x87\xb7\x87\x56\x93\x26\x19\x87\xda\x83\x87\x5d\x55\xf5\ +\x65\xff\xcd\x93\x2c\x90\xee\xba\xee\x08\xf0\xc3\x3f\x35\x44\xb1\ +\x2b\x2f\xf3\x1d\x2c\x56\xe4\x17\xf1\x98\xf6\x9d\x66\x99\xe7\xe3\ +\x8b\x70\x9b\x68\x3a\x03\xdb\xcb\xce\x47\x79\x06\x0d\xa9\xf2\x02\ +\x45\xbb\xe2\x39\xac\x76\x05\x17\xf4\xed\x3a\x5d\xf1\x43\x47\xd4\ +\xc3\x26\x0d\xe4\xe7\xfa\xe0\x81\x05\x2f\x79\xf1\xcc\xf5\x73\x40\ +\xf2\xac\x42\xf2\xff\x00\x4b\xb1\x09\xd3\x7b\x29\xd9\x4b\x32\x04\ +\x0f\x79\x1a\xd7\x82\x32\xf9\xc8\x03\x6a\x36\x7b\x79\xd4\x07\x60\ +\x44\xef\x9b\x0f\x9e\x05\xe4\xaf\xb5\xd9\x63\xb8\x49\xd2\x63\x50\ +\x82\x83\x10\xd4\x97\x3c\xde\xa3\xb6\xe5\xa8\x7e\xce\x96\x47\xdd\ +\xe7\xf7\x82\xaf\x7e\x04\x43\xed\xef\x50\xcb\x57\xf7\x29\xaf\x84\ +\x2f\x9b\x8f\x8a\x05\x04\x6a\xd8\xe7\x45\x3c\x10\xb4\xc9\x4b\xba\ +\xec\x2c\x79\x35\x0e\xed\x87\x44\x9b\xa7\xcc\x1a\x6d\xeb\xd3\xf3\ +\xd4\x20\x8d\x40\x04\x7a\xb6\x3f\xdc\x01\xf1\x21\x2a\x2d\x9f\x0d\ +\x83\x4d\x60\xcf\x3c\xea\x8b\x83\x5f\x9d\xe2\xe2\x8d\x24\xc5\x84\ +\x51\xcb\xa4\xe6\x3b\x82\x7d\x07\x82\xc2\x21\xf4\xad\xbe\x5a\x54\ +\xd0\xd3\xac\x2d\xd5\xfb\xc6\x61\x91\x0b\x47\x09\xb4\xf5\x93\x56\ +\x56\x27\x0a\x30\xcf\xa4\xa8\x7f\x24\x7c\xbc\xcd\x57\x5a\x3d\xe4\ +\xc1\x55\xaf\xfb\xa6\x4b\x2d\xfb\xcc\xe7\x14\x9b\xf6\x64\xaf\xff\ +\xb6\x47\xa7\x78\x71\x65\x2e\x0c\x89\xd2\xef\x44\xf7\x2a\x82\x96\ +\x8d\x3d\x87\x79\x8e\x32\x08\x8e\x32\x0e\x92\xec\xea\x97\xff\x75\ +\xd0\x1a\x82\xf7\xb7\x48\x3f\x7d\xd1\x67\x27\xa0\x9b\xe5\x95\xee\ +\x8f\x6b\xcd\x7e\xb6\xa0\x30\xb0\x5a\xd4\xa5\xde\x60\xa0\xb4\xb1\ +\x45\x4c\xdb\x76\xae\xa6\x8b\x3f\x3e\x61\x20\x3a\x24\xfc\x65\xc3\ +\xaf\x34\xfd\x4f\x67\xfc\x35\x2f\xac\xe8\x67\x47\xfb\x95\xce\x33\ +\x8a\x6d\x87\xf6\x27\x21\x67\xcc\xfd\xdc\xbe\xfe\x16\x91\xce\xc2\ +\x0d\x39\xe3\x01\xb7\x30\xd6\xab\xbb\x85\xf8\xce\xe5\xea\xee\x57\ +\xee\x92\xd2\xac\ +\x00\x00\x0b\xb1\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\ +\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x39\x38\x35\x22\x0a\x20\ +\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\ +\x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ +\x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x65\x6e\x74\x65\x72\ +\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\ +\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\ +\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\x61\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ +\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ +\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ +\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ +\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\ +\x3d\x22\x37\x2e\x39\x31\x38\x30\x34\x31\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\ +\x36\x36\x2e\x32\x37\x39\x39\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x32\x35\x2e\ +\x39\x38\x32\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ +\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\ +\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ +\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\x65\ +\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ +\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\ +\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\x33\ +\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\ +\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\ +\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\x36\ +\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\ +\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\x20\ +\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ +\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ +\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ +\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ +\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ +\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ +\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\ +\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\ +\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x32\ +\x66\x32\x66\x32\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x32\x65\x32\ +\x65\x32\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x33\x2e\x37\x31\x37\x38\x39\x30\x30\x32\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\ +\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\ +\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2c\ +\x33\x2e\x37\x30\x31\x39\x36\x30\x37\x20\x48\x20\x33\x32\x20\x56\ +\x20\x33\x31\x2e\x35\x38\x38\x36\x37\x32\x20\x48\x20\x30\x20\x5a\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x30\x32\x38\x2d\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ +\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\ +\x72\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\ +\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\ +\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\ +\x6c\x69\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\ +\x6c\x3a\x23\x63\x37\x65\x39\x61\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\ +\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\ +\x6c\x65\x3a\x6e\x6f\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x31\x35\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ +\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x32\ +\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\x61\x72\x6b\x65\ +\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\ +\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\ +\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x72\x65\x63\x74\x33\x38\x35\x31\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x2e\x39\x31\ +\x35\x30\x33\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\ +\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\x22\x37\x2e\ +\x38\x38\x34\x39\x36\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x72\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x79\ +\x3d\x22\x39\x2e\x33\x37\x31\x30\x32\x30\x33\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x37\x36\x30\x32\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\ +\x35\x36\x31\x30\x34\x35\x36\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\ +\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x31\x2e\x30\x36\ +\x36\x36\x36\x37\x2c\x32\x35\x2e\x36\x36\x32\x37\x34\x36\x20\x32\ +\x36\x2e\x34\x2c\x31\x38\x2e\x36\x39\x31\x30\x36\x38\x20\x32\x31\ +\x2e\x30\x36\x36\x36\x36\x37\x2c\x31\x31\x2e\x37\x31\x39\x33\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x32\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x07\x98\ \x00\ -\x00\x23\x8c\x78\x9c\xdd\x99\xdd\x73\xe3\xb6\x11\xc0\xdf\xfd\x57\ -\xa0\xbc\x97\x76\x2a\x92\x00\xbf\x49\x4b\xca\x43\x6e\x32\xc9\x4c\ -\xfa\xd2\x26\xe9\xe3\x0d\x45\x42\x12\x6a\x92\x50\x41\xc8\x92\xee\ -\xaf\xcf\x82\x1f\x20\x29\xd1\x53\x5f\x6d\x5f\x7c\xe1\x8c\xc7\xc4\ -\xee\x02\x04\x7e\xd8\x5d\x00\xc2\xf2\xbb\x73\x59\xa0\x47\x2a\x6a\ -\xc6\xab\x95\x41\x2c\x6c\x20\x5a\x65\x3c\x67\xd5\x6e\x65\xfc\xfa\ -\xcb\x0f\x66\x64\xa0\x5a\xa6\x55\x9e\x16\xbc\xa2\x2b\xa3\xe2\xc6\ -\x77\xeb\xbb\xe5\x5f\x4c\x13\x7d\x2f\x68\x2a\x69\x8e\x4e\x4c\xee\ -\xd1\x4f\xd5\x43\x9d\xa5\x07\x8a\xfe\xba\x97\xf2\x90\xd8\xf6\xe9\ -\x74\xb2\x58\x27\xb4\xb8\xd8\xd9\x7f\x43\xa6\xb9\xbe\xbb\x5b\xd6\ -\x8f\xbb\x3b\x84\x10\x7c\xb7\xaa\x93\x3c\x5b\x19\x5d\x85\xc3\x51\ -\x14\x8d\x61\x9e\xd9\xb4\xa0\x25\xad\x64\x6d\x13\x8b\xd8\xc6\x60\ -\x9e\x0d\xe6\x99\xfa\x3a\x7b\xa4\x19\x2f\x4b\x5e\xd5\x4d\xcd\xaa\ -\xfe\x30\x32\x16\xf9\x56\x5b\xab\xde\x9c\xdc\xc6\x88\xc4\x71\x6c\ -\x63\xc7\x76\x1c\x13\x2c\xcc\xfa\x52\xc9\xf4\x6c\x4e\xab\x42\x1f\ -\xe7\xaa\x3a\x18\x63\x1b\x74\x83\xe5\xf3\xac\x92\x1a\x80\x1e\xe0\ -\x4f\x9b\xf7\x02\xab\xe6\x47\x91\xd1\x2d\xd4\xa3\x56\x45\xa5\xfd\ -\xf1\x97\x8f\x5a\x69\x62\x2b\x97\xf9\xa8\x99\x9e\xe7\xe4\xab\x13\ -\xc8\x55\x5a\xd2\xfa\x90\x66\xb4\xb6\x7b\x79\x53\xff\xc4\x72\xb9\ -\x5f\x19\xae\x67\x11\x17\x1e\xbf\x11\xee\x29\xdb\xed\xe5\xb5\x94\ -\xe5\x2b\x03\x7a\xef\xc4\x51\x5b\x1e\x39\x07\x69\x0d\xba\x86\x13\ -\xad\xc1\x56\xec\x58\x04\x09\xe2\xbb\x61\x6b\xd3\x0f\x21\xc9\x79\ -\xa6\xfa\x04\x4d\xd2\x92\xa5\x47\xc9\x4b\x98\xb5\x2c\x2b\xd2\xba\ -\x66\x5b\x96\x41\x81\x57\x87\xe2\xb8\x63\xd5\xa7\x9a\xed\xaa\x4f\ -\x34\x67\xf2\x93\x48\x2b\xc0\xd1\x23\xd4\xdf\xa3\xe7\x03\x17\xd2\ -\x3c\xe7\x07\x00\x19\x84\xb3\xca\x4b\xaf\x5c\x83\x76\x99\xd3\x6d\ -\xad\xac\xda\x51\xa9\x12\x0c\x2b\x34\x90\xdd\x68\x75\x27\x55\x0f\ -\xf3\x47\x46\x4f\x83\xed\x26\xad\x5b\x72\x08\x1d\xd2\x1d\x78\x59\ -\xc1\xc5\xca\xf8\xb0\x6d\x9e\x4e\xb1\xe1\x22\xa7\xa2\x57\x05\xcd\ -\x33\x51\x71\x98\x09\x26\x2f\x6d\x5c\x75\x6d\xf7\xfd\x55\xad\x6a\ -\x3d\x9e\xd7\xd7\xfb\x34\xe7\xa7\x95\xe1\x5c\x2b\x3f\x73\x5e\x42\ -\xab\x30\x23\x71\x18\xe1\x1b\x75\x76\x5e\x19\xa6\xe3\x5a\x71\x48\ -\x9c\xd8\xbf\xd1\xc2\x07\x23\xa8\xe9\x04\x0e\x89\x6e\x94\x47\x21\ -\x20\xf2\xcc\x22\xbd\x50\x18\x55\xf3\x8f\x74\x46\xf5\x9e\x9f\x76\ -\x42\xd1\x91\xe2\x48\xaf\x6b\x2a\x8d\xb9\xd9\xf0\xf3\xbc\x1a\x1c\ -\xe1\xa8\x62\xda\x3c\x56\x4c\x42\xdc\x1c\xce\xe3\x56\x8f\x2c\xa7\ -\xf5\x7c\xc5\x13\xab\x00\x82\xd9\x79\x30\x71\x35\xe3\x6b\x8b\xde\ -\x9d\x43\x7c\x33\xaa\xce\x02\xba\x76\xc3\xb9\x53\x5d\x9e\x56\x95\ -\xe9\x99\x95\xec\x33\x85\x71\x93\x6b\x93\xba\x4a\x0f\xe6\xae\xe0\ -\x9b\xb4\xe8\x7a\xbf\x6e\x2c\x96\x13\x2c\x6d\x25\x84\xe4\x45\xc5\ -\xee\xf9\xa2\x64\x46\x2f\x54\x3c\x95\xc0\x0d\x03\x5f\x0b\xb9\x60\ -\x10\x12\xa3\xfe\xf6\xa2\xcb\x58\xa4\x22\x1d\x12\xf5\xb9\x71\xb0\ -\xc6\xfd\xc2\x6b\xdd\x65\xac\xeb\xfc\xde\xbe\x75\xfc\x46\x5e\x52\ -\x99\xe6\xa9\x4c\x87\x28\xe8\x25\x4e\x1c\xe3\x7e\x64\x90\x34\x93\ -\x7f\x7e\xfc\x61\xdd\x7d\x68\x99\x65\xc9\xbf\xb9\x78\xe8\xbf\x8b\ -\x90\x32\x48\x37\xfc\x08\x53\x61\xac\xb5\x78\x99\x67\x09\xa4\x39\ -\x08\xff\x35\x2b\xc1\xb7\x55\x86\xfc\x3b\xa4\xb5\xa5\x3d\x28\x26\ -\xc6\x0a\xd6\xd0\x68\xdb\xac\xa0\x6d\xbe\x9c\x5d\x34\xf2\xac\x64\ -\xaa\x92\xfd\x2f\xc9\x8a\xe2\x27\xf5\x91\x6e\xc4\xa3\x46\x99\x2c\ -\xe8\x20\x5c\xda\x5d\xef\xbb\xb1\xd9\xa3\xc1\x2d\xed\x7e\xf4\x4d\ -\x69\x37\x50\x99\x04\x85\x9e\xe8\x22\xdd\x50\x70\x82\x9f\x95\x12\ -\xdd\x68\x77\x82\x1f\x0f\x25\xcf\x69\x57\x5d\xd3\xa4\x99\xd4\x53\ -\x26\x2f\x05\xe8\xb7\xd0\xfb\xa4\xcb\x34\xf7\xaa\x60\x76\x79\x22\ -\x21\x6d\x51\x1c\x0b\xc8\x77\x8f\xb4\xe2\x79\x7e\x5f\x4b\xc1\x1f\ -\x68\xf2\x01\x63\x2f\xc2\xb8\x2b\xb6\xd1\x92\xe8\x62\xc1\x2a\x0a\ -\xdd\x48\xea\xff\x1e\x53\x41\xc7\xd2\xff\x70\x56\x25\xc0\x8d\x8a\ -\x5e\xda\x14\x0a\xf0\x78\x99\x78\xbd\x2c\x4f\x21\x15\x09\x91\x5e\ -\x92\x0a\x76\x01\x63\x29\xdf\x6e\x6b\x2a\x87\x2f\xf5\x5d\xc5\x96\ -\xdb\x3d\x13\x47\x57\xc3\x75\xe3\x98\x68\xe1\xec\xc2\xa4\x9e\xf9\ -\xc5\x49\x3d\x93\xa8\x00\xff\x8e\x2d\x2f\x74\x63\xec\x06\xd4\x24\ -\x81\x56\x88\x89\x99\x00\x3b\xd7\x72\x61\x81\x0a\xe2\x48\x7b\xc5\ -\xf2\x90\xca\xfd\x1c\xfd\xd1\x28\x15\x59\xf5\x4c\xc9\x3a\x6d\xa7\ -\x5c\xcf\xbb\x46\xbc\x39\x4a\xf9\x5a\x80\xf5\xbc\xeb\x71\x00\xc2\ -\x7f\x20\xbc\xc0\xe8\x37\xd4\x83\x99\x02\x56\x23\x82\x68\x1d\x38\ -\x0c\x99\x9d\x57\xd0\x43\xc9\x85\x09\x39\xfe\x31\x95\x47\x41\x27\ -\xb9\x44\xe7\x04\x70\x52\x15\x46\x90\x8e\xb3\xec\x5b\x47\xa5\x21\ -\x2d\xf4\x1b\xfa\x11\xe1\x39\x64\xd1\xfb\x41\x46\x2c\x98\x41\xec\ -\xf8\xd1\xe1\xfc\xe5\xcc\x9e\x20\xa1\x57\x81\x85\x13\x59\x11\xfa\ -\x1e\xb9\x96\xd3\xbe\xde\xbc\xdc\xd0\x71\xc3\xd0\x31\xf1\xb3\xf9\ -\xbc\x8a\xcf\x90\xd0\xf7\x88\xef\xbf\x1a\x81\x12\xf9\x7d\x4a\x5a\ -\xb8\xbe\xe5\xa0\x0c\xe2\xc8\xf4\x2c\xa7\x81\xf2\xd4\xfb\x2d\x8a\ -\xc8\x7b\x3b\x10\x01\x81\x8c\x7f\xe5\x09\xdd\xac\x39\xaf\x08\x62\ -\xe4\x0a\xa4\x63\xd2\xcc\x3d\xfc\xa1\x9f\x51\x6c\x05\x0b\x27\xb0\ -\x5a\x0b\x44\xa0\x10\x5a\x61\x6b\xb4\xd7\x0c\xc1\x4e\xdb\x74\xce\ -\xe3\x8c\x0c\x3d\x6c\xf9\x2d\xea\x59\x7f\xf2\x30\x09\xbf\x22\x44\ -\xdf\xf2\xbc\xc6\xc9\x82\xaf\x91\x81\x66\x56\xbe\xf7\x43\xdd\x8c\ -\xdf\x8c\x7b\x44\x6f\xd3\xd8\xab\x3b\xef\x38\x8f\x11\xd7\x8a\x5a\ -\x5c\x5d\xb4\x2a\x99\x03\x50\x08\xee\x19\x69\x85\x22\xaa\x40\x17\ -\x9a\xe5\x02\x88\xf7\x05\x6f\xd1\x2f\x52\x28\xb4\xbc\xa6\xc6\x42\ -\x67\x83\xa8\x85\xea\xa9\xfa\x33\x4c\xdd\xb7\xf3\xe4\x5b\xa2\x90\ -\xb7\x9a\x5e\xc5\xee\x1f\xe7\xc9\xef\x71\x0a\x4c\xf7\x8b\x17\x6f\ -\x6d\x27\x45\x5a\xd5\xea\x00\x62\x66\x70\x3c\xa5\xc2\x6c\x8e\x53\ -\x33\x1b\xa8\x1b\x43\xd8\x53\x9a\xd7\x87\xab\xe7\xce\xee\x76\x3b\ -\xb7\xec\xbf\x69\xbc\x38\x5e\x97\x1e\x34\x61\x90\x39\x96\x37\x9a\ -\x2c\x07\xf7\xc8\x49\xd8\xd6\x83\xf9\x0c\x90\xb2\x5a\x68\xab\x51\ -\x0e\xea\x26\x46\x65\x32\xb7\xb7\x0f\xa0\xc5\x1f\x91\x37\x41\xa8\ -\xa7\x2a\x7c\xab\xfc\x33\xc7\xd3\x6f\x9d\x33\x08\xe3\x3f\x32\x5a\ -\xf0\xc2\xf1\xc1\xcf\x01\xcb\xc2\x71\x5b\xf0\x61\x9b\xee\xf5\x32\ -\x00\x91\xa1\x79\x23\x2d\x5e\x10\xd2\x67\x76\xd5\x42\x13\x2d\x90\ -\xef\xf5\xe4\xc1\xc2\xd0\xf3\x9f\x25\xfd\x05\x41\xf1\x4e\x77\x6c\ -\x83\x63\xbe\x70\xc7\x66\x3e\x7f\x73\xff\x4e\x51\x0c\x5e\xf1\x52\ -\x14\x6f\xb7\x03\xf8\x5a\x28\x82\xd7\xf2\x8a\x6f\xfe\x48\x03\xe9\ -\xe0\xa5\x0c\xbe\xfd\x24\x11\xbc\x98\xc1\xf3\x7f\x2d\x79\x8f\x67\ -\xfb\xc9\xd1\x42\xaf\x30\x19\xea\x37\x54\xee\x02\x3f\xf5\xfe\xc4\ -\x49\xdf\x74\xfe\x34\x40\x48\xd4\x6f\x2b\x5f\x04\x84\x7c\xd3\x40\ -\x26\x5b\x76\x47\xff\xfa\xd3\xbc\xde\xbc\x3c\x85\xe0\x6b\x26\x8a\ -\xb7\xf5\x89\x61\x07\xf5\x22\x9f\xf0\xfe\x34\x40\xf4\x60\x5f\x06\ -\xe4\xff\xd8\x59\x3c\x79\xfd\x41\x02\x37\x4b\xe9\xf4\xfa\x03\x5b\ -\xbe\xe7\xe3\x38\xc2\xde\xff\x5a\x65\x42\x1f\x13\x27\xd2\x87\xe4\ -\x97\xfc\x8c\xdc\xdf\x5a\x38\x71\x3c\x8c\xaf\xbf\xb5\x18\xf2\xa4\ -\xbe\xae\x18\x44\xb3\xd7\x72\x97\x39\xa1\xba\xab\x50\xe7\x60\xec\ -\x06\xc3\x37\xda\x2b\x0b\x18\x6c\x14\x46\xfe\x40\x2c\x63\x22\x2b\ -\xe8\x15\xb3\xe6\x0e\x5a\xd3\xc8\x59\x7d\x28\x60\x60\xac\x52\xfe\ -\x70\xcf\x1f\xa9\xd8\x16\xfc\x94\x3c\xb2\x9a\x6d\x0a\x7a\xdf\xfc\ -\x67\x85\x1a\x67\x2f\x1a\x10\xc7\x51\xdc\x3c\xf7\xed\x3c\x60\xac\ -\x4e\x56\x4f\xce\xc3\x70\x1f\x05\x14\x3f\x53\xc1\x27\x33\xe3\x85\ -\xd3\x99\xf1\x2c\x12\x04\x2e\x34\xfe\xa6\x3f\xc4\x8d\xae\xa5\x20\ -\x9d\xb9\x4e\x84\x89\x1f\xdd\x4c\xf0\x7d\x99\x8a\x07\x2a\xda\x9a\ -\xb4\x4a\x81\x82\xb9\x49\xb3\x07\x75\x51\x57\xe5\x49\x9a\x65\xc7\ -\xf2\x58\xa4\x92\xce\x6d\x19\x86\xd0\x57\x57\xed\xfd\xd9\x6d\x48\ -\x9d\xea\x8a\xfd\x56\x2a\x56\x86\xbe\x0c\xd1\x77\xb1\xbb\xf5\xdd\ -\x52\xdd\x85\xae\xef\x7e\x07\x68\x96\x4a\xd0\ -\x00\x00\x0b\xed\ +\x00\x2c\xab\x78\x9c\xed\x5a\x5b\x6f\xdb\xd8\x11\x7e\xf7\xaf\x50\ +\xe5\x97\x04\x0d\xc9\x73\xbf\x28\x92\x17\x48\x83\x5d\x2c\xd0\xa7\ +\xed\x16\x7d\x0c\x68\xf2\x48\x66\x43\xf1\x08\x24\x65\x49\xfb\xeb\ +\x3b\x87\x14\xaf\xa2\x36\x29\x52\xc0\xae\x12\x39\x86\xc3\x99\x39\ +\x97\xf9\x66\xce\x37\xc3\x63\x2f\x7f\x3a\x6e\xd3\xd9\xb3\xc9\x8b\ +\xc4\x66\xab\x39\xf6\xd1\x7c\x66\xb2\xc8\xc6\x49\xb6\x59\xcd\xff\ +\xf9\xfb\xcf\x9e\x9a\xcf\x8a\x32\xcc\xe2\x30\xb5\x99\x59\xcd\x33\ +\x3b\xff\xe9\xe1\x6e\xf9\x17\xcf\x9b\xfd\x2d\x37\x61\x69\xe2\xd9\ +\x21\x29\x9f\x66\xbf\x66\x9f\x8b\x28\xdc\x99\xd9\x9b\xa7\xb2\xdc\ +\x2d\x82\xe0\x70\x38\xf8\xc9\x59\xe8\xdb\x7c\x13\xbc\x9d\x79\xde\ +\xc3\xdd\xdd\xb2\x78\xde\xdc\xcd\x66\x33\x58\x37\x2b\x16\x71\xb4\ +\x9a\x9f\x07\xec\xf6\x79\x5a\x19\xc6\x51\x60\x52\xb3\x35\x59\x59\ +\x04\xd8\xc7\xc1\xbc\x33\x8f\x3a\xf3\xc8\xad\x9e\x3c\x9b\xc8\x6e\ +\xb7\x36\x2b\xaa\x91\x59\x71\xdf\x33\xce\xe3\x75\x6b\xed\x76\x73\ +\xa0\x95\x11\xd6\x5a\x07\x88\x04\x84\x78\x60\xe1\x15\xa7\xac\x0c\ +\x8f\xde\x70\x28\xec\x71\x6a\x28\x41\x08\x05\xa0\xeb\x2c\xbf\xce\ +\x6a\x51\x00\xa0\x3b\xf8\x6e\xcd\x1b\x81\x5f\xd8\x7d\x1e\x99\x35\ +\x8c\x33\x7e\x66\xca\xe0\xe3\xef\x1f\x5b\xa5\x87\xfc\xb8\x8c\x7b\ +\xd3\x34\x78\x0e\x56\x1d\x80\x9c\x85\x5b\x53\xec\xc2\xc8\x14\x41\ +\x23\xaf\xc6\x1f\x92\xb8\x7c\x5a\xcd\x29\xf3\x31\x85\x0f\xaf\x84\ +\x4f\x26\xd9\x3c\x95\x63\x69\x12\xaf\xe6\xb0\x7b\xa2\x55\xfd\xdc\ +\x4b\x0e\x5c\x1b\x9c\x27\x5e\xb4\x1a\xe4\x6b\xe2\xe3\x59\x8e\x39\ +\x95\xb5\x4d\xe3\xc2\x22\xb6\x91\xdb\x13\x4c\x69\xb6\x49\xb8\x2f\ +\xed\x16\xa2\x16\x45\x69\x58\x14\xc9\x3a\x89\xe0\xc1\x66\xbb\x74\ +\xbf\x49\xb2\x4f\x51\x6a\xf7\xf1\xa7\x6d\x58\x7c\x86\xe4\xfb\x54\ +\x5a\x9b\xfa\x0d\x8a\xed\x92\xe6\xb8\xb3\x79\xe9\x1d\xe3\x1d\x60\ +\x29\xe4\xa4\xf2\xd4\x57\x3e\x27\xe6\xf0\xc1\x1e\x61\x8f\x33\x34\ +\xa3\x04\xfe\xcd\x1f\x40\xbe\x8c\xcd\xba\x70\xfa\xda\x5f\xf7\x04\ +\x0e\xcb\x4a\x07\xda\x75\x92\x96\x26\xaf\xf5\xbd\x05\x22\x9b\xa6\ +\x26\x02\xc4\xc2\xf4\x10\x9e\x8a\x79\x63\x50\x94\xa7\x14\x5c\x04\ +\xb5\xcd\xbd\x24\x83\xa1\x3b\x9b\x56\xae\x79\xf5\x4c\x90\x01\xbf\ +\xfd\xf2\xa1\xb5\x77\x4b\xd6\x0a\x8c\x34\x6b\xc5\xb0\x4b\x08\x39\ +\x26\x9a\x71\x85\x48\x2b\x3e\xc7\x0e\xfb\x84\x2b\x8d\x45\x2b\x3f\ +\x55\xe6\x84\x4a\x46\x99\xa4\xad\xb8\x89\x2a\xf6\x99\x64\x4a\x68\ +\x7e\x76\xca\xb9\x65\x7e\x09\xf7\x00\x7c\x98\x7d\x48\xf7\xad\x7b\ +\x5f\xe1\xa0\x73\x31\xfe\x68\x9e\x93\xca\x29\x17\x70\x8a\x05\xc6\ +\x42\xa8\x9e\x49\xe5\xd5\x60\x05\xf0\x4e\xcc\x67\xc1\x19\xd4\xa0\ +\x76\xf9\x05\x20\x56\x63\x88\xa9\x66\x58\xf0\x09\x84\xa5\x52\x94\ +\x8e\x11\xd6\x48\x0a\xca\xc5\x04\xc2\x5c\x61\x4e\x20\xe5\x5f\x0e\ +\x61\x8c\xd0\xcb\x23\x8c\x7b\xd9\x7a\x46\x98\x29\xce\xd5\x99\x0c\ +\x86\x10\x6b\x89\xb1\x64\x63\x8c\x41\xa4\xdc\x01\x9c\xc8\x62\xca\ +\xb4\xd4\xf2\x45\x31\x66\xaf\x01\x63\x31\xc2\x98\x50\x42\x05\x65\ +\x13\x18\x33\xc1\x24\xe9\x79\x55\x63\x4c\x99\xa0\x84\xf7\x42\xd5\ +\x61\x2c\x34\x11\x2f\xc9\x13\x18\xa9\x57\x80\x30\x46\x37\x4c\xc5\ +\x18\x93\xd7\x00\xf1\x45\xb5\xbb\x21\x2a\xc6\xaf\xa0\xd8\x61\x7c\ +\x51\xec\x6e\x8a\x8a\xc9\x6b\x28\x77\x64\x5c\xee\x6e\x89\x8a\xc9\ +\x6b\x28\x76\x64\x5c\xec\xce\x54\x3c\x95\xc5\xff\x7f\x54\x4c\x5e\ +\x43\xb5\xa3\x17\xd5\xee\x86\xa8\x98\xbe\x86\x62\x47\x2f\x8a\xdd\ +\x4d\x51\x31\x7d\x0d\xe5\x8e\x8e\xcb\xdd\x2d\x51\x31\x9b\x2e\x76\ +\xcb\xc0\xdd\x57\x54\xff\x6b\xef\x59\xdc\x25\x4b\xec\x2e\x3b\xee\ +\xda\xd9\x1e\xc3\xc2\x9c\x17\xd8\x85\x1b\x53\xc1\xbb\x9a\xdf\xaf\ +\xab\xcf\x59\xf1\x68\xf3\xd8\xe4\x8d\x4a\x54\x9f\x81\xca\xee\xc2\ +\x28\x29\x4f\xf5\xd5\xe0\xdd\xd0\x5f\x37\x6b\xab\x47\xd3\xfa\xe2\ +\x29\x8c\xed\x61\x35\x27\x63\xe5\x1f\xd6\x6e\x57\x73\xea\x6b\xae\ +\x11\x41\x7a\xac\x8e\x5c\x34\x31\xc3\xbe\xe2\x8a\xb3\x0b\x2d\x2c\ +\xa8\x7d\x02\xac\xc4\x15\xbd\x50\xee\xf3\xdc\x64\xa5\x97\x86\x27\ +\x03\x5e\x55\x3f\x9a\x74\x28\x9e\xec\x61\x93\x3b\x74\xca\x7c\x6f\ +\xc6\x23\x9d\xc6\x7b\x7c\x74\xd7\x45\x53\xea\xd8\x46\x7b\x77\x2d\ +\xe9\xed\xb3\xa4\x2c\x56\xf3\xdd\xb1\x3f\xeb\x3e\x89\x4d\x31\x3d\ +\xb0\xc8\xc2\x9d\xb7\x49\xed\x63\x98\x4e\x1b\x1c\x92\x0c\x50\xf2\ +\x9a\x54\xa5\x6d\x10\xc6\x16\x4d\x72\x4a\xa4\xae\x58\xb8\xab\xae\ +\x2b\xaa\xd3\x75\xd5\x36\x3c\x26\xdb\xe4\x0f\x03\xc0\xe0\x0b\x54\ +\x9c\x67\x7d\x58\xce\x19\x39\x80\xad\x49\xe4\xf2\xe4\xae\x27\x8f\ +\x27\x27\x1b\x1c\x58\x27\x20\x5a\x77\x5c\x66\xf3\x64\x93\x64\xbd\ +\xed\x36\xa2\x53\x5f\xe4\x2e\x33\x93\x6c\x73\xec\xf6\xd5\xca\x5c\ +\x52\x9e\xcf\xc7\x32\xb8\x3c\x08\x95\x7c\x6b\xca\x30\x0e\xcb\xb0\ +\x3b\x15\x8d\x04\xf6\x82\x1a\x4f\xf2\x78\xbd\xf8\xed\xe3\xcf\xed\ +\x49\x8f\xa2\xc5\xbf\x6c\xfe\xb9\x3b\x9c\xce\x20\x7c\xb4\x7b\x40\ +\xbe\xe5\x03\x77\x89\x18\x2d\xd6\x36\xdf\x86\xe5\x43\xb2\x85\x5c\ +\x77\x97\xbe\x7f\x3d\x6e\x53\x38\x9f\xad\x62\x60\xec\xc0\xe9\x26\ +\xad\xa7\xcd\x4d\x7d\x05\x3c\x79\x0f\x1e\x47\xdb\xc4\x0d\x0a\xfe\ +\x51\x26\x69\xfa\xab\x5b\xa4\x65\x84\x76\xd2\xa4\x4c\x4d\x27\x5c\ +\x06\xe7\xdd\x37\xbc\xd1\x73\x6e\x19\x34\xde\x57\x4f\x9b\x0e\x95\ +\xc1\x21\x69\x03\x9b\x86\x8f\x06\x32\xf6\xef\x4e\x39\xbb\xcc\x8b\ +\xdc\xee\x77\x5b\x1b\x9b\xf3\xf0\x16\x4d\xe0\xc0\x11\xb5\x03\x77\ +\xa5\x8b\x7b\x84\x38\x8f\xd9\x7b\xf7\xe0\x9d\x79\x63\x81\xeb\xc7\ +\x7c\x9f\x9a\x85\x79\x36\x99\x8d\xe3\xf7\x45\x99\xdb\xcf\xc6\xd9\ +\xbb\xcf\xf9\xb1\x3e\x1c\x0b\xec\x63\x2d\xa4\x26\x84\x35\x72\x40\ +\xc8\xe4\x29\x64\x6f\xb9\x68\x65\x71\x08\xbc\x93\xe7\xe1\x69\x91\ +\xd9\xcc\x34\xd2\x76\xcd\x41\x62\xba\xed\x42\x32\x74\xfd\x4d\x73\ +\x0a\xa5\x0f\x0c\xdc\x27\xe9\xb6\x32\x30\x9f\x30\xcd\x45\x37\x0f\ +\xa4\x27\xa7\x3e\x34\x3d\xbc\xd7\x3f\x41\x7e\x32\xe1\x73\x44\x69\ +\xaf\x82\xe7\xc7\xaa\x14\x21\xa5\x04\xea\x66\xce\x4f\x75\x67\x0a\ +\x45\x5d\x75\xd2\x32\x0f\xb3\xc2\xe5\x11\x64\x6d\x58\xe6\xc9\xf1\ +\x0d\x7e\x87\xde\x41\xcd\x52\x1c\x21\x2a\x24\x7d\x87\x60\x4d\x21\ +\x09\x65\x04\x14\xe8\x6d\xe7\xd7\x9f\xdd\x97\x4f\x19\xb4\x77\xe6\ +\x6d\xbd\xe9\x47\xf1\xea\x46\xa0\x03\xc1\xee\x1b\x36\x22\x10\xb4\ +\xdc\x40\xe4\xc3\x8d\xd4\x8e\x71\x21\x61\x93\xfa\x0b\x20\x80\x29\ +\x21\xbe\x46\x40\x7f\xb4\x8f\x2c\x25\xd0\xe3\x33\xa6\x26\x4a\x34\ +\x87\x6c\x60\x54\xaa\x2f\xc7\xae\x89\x34\x95\x3d\x14\x46\xd9\x19\ +\x86\x90\x6d\xdf\x9a\x9d\x58\x2a\x0e\x30\x7c\x4b\x76\x4e\xc6\x60\ +\xb0\xd7\xf5\xba\x5a\xfb\x1b\xf7\x8a\xa0\x7f\x57\x4c\x93\xff\xe5\ +\x49\x02\x7c\xf5\x7f\x71\x92\x04\x84\x16\x4a\xf8\xe0\x24\x41\x54\ +\x89\x26\x8c\x0d\x4e\x12\xf6\x25\x95\x84\xf5\x42\xfd\x67\x27\x49\ +\x48\xc6\xc9\x97\xcf\x11\x58\xc1\x9b\x26\x93\x2e\x7d\x05\x74\x7b\ +\xf4\x7c\x8c\xda\x00\x98\x34\x4d\x76\x85\x19\xc5\x60\x88\xf8\xe2\ +\xde\x08\xf7\xd5\x82\x5d\x37\x58\x43\xb0\x11\x74\x9f\x4a\x32\xad\ +\x55\x23\x4f\x93\xcc\xc0\x09\x5c\x00\x89\x66\x71\x5f\xf8\x6f\x9b\ +\x64\x8b\x2a\x14\x13\x71\x21\x3e\xff\xca\xc8\xbc\xaf\xfb\xc5\x05\ +\x54\x93\x37\xf7\x5d\xb7\xfc\x76\x10\xb1\x5d\x58\x3e\x29\xd5\x01\ +\xed\xba\x2e\x0c\xa0\x62\xe8\xb9\xba\x98\xb8\x6e\x8b\x40\xbb\x85\ +\x14\x62\x64\x84\xbf\x6b\x9e\x89\x1e\xc1\x8f\x34\xa7\x04\x5e\xb1\ +\x6f\x17\x47\x36\x89\xa3\x47\x87\x48\x42\x22\x0b\x2d\x19\x1d\x22\ +\x29\x7d\x4d\x31\x51\x6c\x80\x24\x6c\x88\x53\xe7\xdb\x08\x4a\xc9\ +\x18\x96\xf0\xf2\x7d\xbb\x50\xa2\x69\x28\xc5\x10\x4a\x09\x2f\xc3\ +\x54\x69\x31\x4e\x4a\x0c\x9d\x70\x0f\xe0\x1a\x4a\x09\x04\x8c\xc9\ +\x08\x49\x8a\xe0\x4d\x8f\xdd\x2e\x90\x44\x4c\x03\x29\x07\x40\x12\ +\x68\x19\xb0\x80\xf6\x65\x9c\x93\x88\x72\x4d\xc5\x08\x48\x4d\x11\ +\xc1\x42\x8c\x90\xe4\x5a\x0a\x81\xc8\x0d\x43\x49\xa6\xa1\xbc\x20\ +\x4a\x2d\x15\xe2\x6c\x00\x25\xd6\x3e\x92\x8a\xaa\x71\xa1\xfa\x3e\ +\x89\x12\x4f\x17\x1c\x8f\x5e\x52\xa5\x82\xa2\xcf\xf9\x10\x4b\xe9\ +\x2b\x84\xc5\xf8\x78\x7f\xa7\x4c\x89\xaf\x14\x1d\x31\xce\x4b\xe9\ +\x4b\x78\x93\x40\xfa\x22\x2f\x19\xc4\x43\xff\xe0\x4a\xf7\x9b\xde\ +\x2b\x5c\x39\x2a\x3b\x04\x8e\xa8\xe4\x52\x90\x21\x94\x02\xde\x52\ +\x04\x51\x64\x92\x2d\xe9\xf7\xc6\x96\xe8\x4a\xe1\x21\xc3\xac\x24\ +\x3e\x72\x77\xb3\x6a\x00\xa5\xf0\xa9\xc0\x1c\xe1\xf1\x0b\xf2\xf7\ +\xc9\x96\xe8\x4a\xdd\xa1\x9e\xbe\x60\x4b\xa0\xbb\x61\xe1\xe1\x3e\ +\x74\x42\xd0\x6c\xf2\x1f\x6c\x59\xff\xd1\xd7\x35\xb6\xc4\x63\xb6\ +\x54\xf0\xba\xa3\xc9\x38\x2f\x09\x83\xe3\x2c\x7f\xb0\xa5\xfb\x13\ +\xc5\x6b\x6c\x49\xc6\x6c\x89\x01\x1f\x36\x2c\xe2\xcc\x87\xa2\x43\ +\x35\x1f\x17\x9e\xaf\x61\xcb\x65\xb0\x79\xb8\x5b\xba\x7b\xd5\x87\ +\xbb\xff\x00\x92\xa3\x93\xf5\ +\x00\x00\x0a\xea\ \x3c\ \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ @@ -23254,351 +15603,1032 @@ \x37\x31\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ \x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\ \x6f\x6d\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\ -\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x65\x6c\x6f\x61\ -\x64\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\ -\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x22\ -\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ -\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\x20\x2f\x3e\x0a\ -\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ -\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x62\ -\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ -\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ -\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ -\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ -\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x2e\x30\ -\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ -\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\ -\x6d\x3d\x22\x31\x2e\x39\x37\x39\x35\x31\x30\x34\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ -\x33\x36\x2e\x39\x36\x33\x33\x31\x36\x22\x0a\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x38\x2e\ -\x39\x35\x30\x31\x32\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ -\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ -\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\ -\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\ +\x74\x69\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x72\x6f\x69\x5f\x73\ +\x69\x6e\x67\x6c\x65\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\ +\x70\x69\x3d\x22\x36\x37\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\ +\x22\x36\x37\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x31\x2e\x31\x39\x37\x38\x30\x32\ \x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ -\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\ -\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\ -\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\x69\x64\ -\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ -\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ -\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\x22\x0a\x20\x20\x20\x20\ -\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ -\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\x30\x38\x22\x0a\x20\x20\ -\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ -\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\ -\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ -\x65\x64\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ -\x63\x61\x70\x65\x3a\x73\x6e\x61\x70\x2d\x67\x6c\x6f\x62\x61\x6c\ -\x3d\x22\x74\x72\x75\x65\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6e\ -\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\x67\x72\x69\x64\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x67\x72\x69\x64\ -\x33\x37\x36\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\ -\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ -\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\x3d\x22\x31\x2e\x30\ -\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ -\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\ -\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x73\x6f\x64\x69\x70\ -\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x3e\x0a\x20\ -\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ -\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\x39\x39\x30\ -\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ -\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ -\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ -\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ -\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ -\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ -\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ -\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ -\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ -\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ -\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ -\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ -\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ -\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ -\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\ -\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x63\x78\x3d\x22\x2d\x31\x34\x2e\x39\x31\x38\x38\x38\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x32\x31\x2e\x39\x38\x36\x31\x39\x38\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\ +\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\ +\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\ +\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x73\x6e\x61\ +\x70\x2d\x67\x6c\x6f\x62\x61\x6c\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\x36\x36\ \x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ -\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\ -\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ -\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x37\ +\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\x20\x20\ +\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\x78\x79\ +\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x67\x72\x69\x64\x32\x39\x39\x37\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x78\ +\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\x31\x2e\ +\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ +\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x32\x39\x39\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\ +\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\ +\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\ +\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x65\x39\x61\x62\x31\x36\x3b\x66\x69\x6c\x6c\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\ +\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x31\x38\x64\x36\x66\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x31\x37\x35\x30\x31\x32\ +\x38\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\ +\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\ +\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x32\x39\ +\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\ +\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x35\x2e\ +\x33\x33\x30\x33\x36\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x33\x2e\x38\x30\x34\x38\x37\x38\x35\x22\x20\x2f\x3e\ \x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ -\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\ -\x30\x30\x30\x30\x30\x30\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\ -\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\ -\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\ -\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ -\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\ -\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x6d\x65\ -\x64\x69\x75\x6d\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\ -\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ -\x69\x6c\x79\x3a\x53\x61\x6e\x73\x3b\x2d\x69\x6e\x6b\x73\x63\x61\ -\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\ -\x61\x74\x69\x6f\x6e\x3a\x53\x61\x6e\x73\x3b\x74\x65\x78\x74\x2d\ -\x69\x6e\x64\x65\x6e\x74\x3a\x30\x3b\x74\x65\x78\x74\x2d\x61\x6c\ -\x69\x67\x6e\x3a\x73\x74\x61\x72\x74\x3b\x74\x65\x78\x74\x2d\x64\ -\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x3a\x6e\x6f\x6e\x65\x3b\x74\ -\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\x6f\x6e\x2d\x6c\ -\x69\x6e\x65\x3a\x6e\x6f\x6e\x65\x3b\x6c\x65\x74\x74\x65\x72\x2d\ -\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x77\ -\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x6e\x6f\x72\x6d\ -\x61\x6c\x3b\x74\x65\x78\x74\x2d\x74\x72\x61\x6e\x73\x66\x6f\x72\ -\x6d\x3a\x6e\x6f\x6e\x65\x3b\x77\x72\x69\x74\x69\x6e\x67\x2d\x6d\ -\x6f\x64\x65\x3a\x6c\x72\x2d\x74\x62\x3b\x64\x69\x72\x65\x63\x74\ -\x69\x6f\x6e\x3a\x6c\x74\x72\x3b\x62\x61\x73\x65\x6c\x69\x6e\x65\ -\x2d\x73\x68\x69\x66\x74\x3a\x62\x61\x73\x65\x6c\x69\x6e\x65\x3b\ -\x74\x65\x78\x74\x2d\x61\x6e\x63\x68\x6f\x72\x3a\x73\x74\x61\x72\ -\x74\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\ -\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\ -\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\ -\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x32\x32\x32\ -\x62\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\ -\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\ -\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x34\x31\x33\x33\ -\x33\x33\x34\x32\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\ -\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\ -\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\ -\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x38\x2c\x39\x2e\x36\ -\x36\x36\x36\x36\x36\x37\x20\x43\x20\x33\x2e\x38\x31\x34\x30\x31\ -\x30\x37\x2c\x31\x34\x2e\x38\x37\x36\x37\x39\x35\x20\x34\x2e\x34\ -\x33\x32\x38\x39\x30\x37\x2c\x32\x32\x2e\x36\x34\x34\x37\x39\x34\ -\x20\x39\x2e\x34\x2c\x32\x37\x2e\x30\x36\x36\x36\x36\x37\x20\x31\ -\x34\x2e\x33\x36\x37\x31\x30\x39\x2c\x33\x31\x2e\x34\x38\x38\x35\ -\x34\x20\x32\x31\x2e\x39\x34\x37\x33\x34\x32\x2c\x33\x30\x2e\x38\ -\x31\x30\x31\x32\x38\x20\x32\x36\x2e\x31\x33\x33\x33\x33\x31\x2c\ -\x32\x35\x2e\x36\x20\x63\x20\x34\x2e\x31\x38\x35\x39\x39\x2c\x2d\ -\x35\x2e\x32\x31\x30\x31\x32\x38\x20\x33\x2e\x35\x36\x37\x31\x31\ -\x2c\x2d\x31\x32\x2e\x39\x37\x38\x31\x32\x37\x20\x2d\x31\x2e\x34\ -\x2c\x2d\x31\x37\x2e\x34\x20\x6c\x20\x33\x2c\x2d\x32\x2e\x38\x36\ -\x36\x36\x36\x36\x37\x20\x48\x20\x31\x37\x2e\x30\x36\x36\x36\x36\ -\x35\x20\x56\x20\x36\x2e\x34\x20\x6c\x20\x33\x2e\x32\x2c\x38\x2e\ -\x35\x33\x33\x33\x33\x33\x20\x32\x2e\x36\x36\x36\x36\x36\x36\x2c\ -\x2d\x33\x2e\x37\x20\x63\x20\x32\x2e\x33\x37\x39\x33\x30\x32\x2c\ -\x33\x2e\x32\x37\x37\x37\x32\x39\x20\x33\x2e\x31\x37\x31\x30\x35\ -\x38\x2c\x38\x2e\x39\x35\x30\x32\x36\x36\x20\x30\x2e\x35\x33\x33\ -\x33\x33\x34\x2c\x31\x32\x2e\x32\x33\x33\x33\x33\x34\x20\x2d\x33\ -\x2e\x30\x34\x31\x38\x35\x39\x2c\x33\x2e\x37\x38\x36\x30\x37\x34\ -\x20\x2d\x38\x2e\x32\x32\x30\x37\x31\x35\x2c\x34\x2e\x32\x31\x39\ -\x37\x32\x20\x2d\x31\x31\x2e\x37\x39\x39\x39\x39\x38\x2c\x31\x2e\ -\x30\x33\x33\x33\x33\x33\x20\x2d\x33\x2e\x35\x37\x39\x32\x38\x33\ -\x35\x2c\x2d\x33\x2e\x31\x38\x36\x33\x38\x37\x20\x2d\x34\x2e\x30\ -\x34\x31\x38\x35\x38\x35\x2c\x2d\x38\x2e\x39\x31\x33\x39\x32\x35\ -\x20\x2d\x31\x2c\x2d\x31\x32\x2e\x37\x20\x43\x20\x31\x31\x2e\x32\ -\x2c\x31\x32\x2e\x33\x20\x31\x31\x2e\x32\x2c\x36\x2e\x39\x36\x36\ -\x36\x36\x36\x37\x20\x38\x2c\x39\x2e\x36\x36\x36\x36\x36\x36\x37\ -\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ -\x61\x74\x68\x32\x39\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ -\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ -\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ -\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ -\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x73\x73\x63\ -\x63\x63\x63\x63\x63\x73\x73\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x05\xe1\ +\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x39\ +\x39\x39\x39\x39\x39\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\ +\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x33\x2e\x32\x34\x30\x30\x35\x36\x30\x34\x70\x78\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ +\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ +\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x64\x3d\x22\x6d\x20\x31\x37\x2e\x30\x36\x36\x36\x36\x37\ +\x2c\x37\x2e\x34\x36\x36\x36\x36\x36\x37\x20\x63\x20\x30\x2c\x31\ +\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\x32\ +\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x31\x39\x2e\x32\x30\x30\x30\ +\x30\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x37\x36\x39\x2d\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\ +\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\ +\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x69\x6c\x6c\x3a\x23\x38\x30\x38\x30\x38\x30\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x77\x69\x64\x74\x68\x3a\x33\x2e\x35\x38\x39\x30\x39\x35\ +\x31\x32\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\ +\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x34\ +\x36\x36\x36\x36\x36\x37\x2c\x31\x36\x2e\x36\x30\x32\x32\x38\x39\ +\x20\x63\x20\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\ +\x31\x39\x2e\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x20\x31\x39\x2e\ +\x32\x30\x30\x30\x30\x30\x33\x2c\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x34\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\ +\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x18\xa1\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\ +\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\ +\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\ +\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\x6d\ +\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x33\x34\x2e\x31\ +\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x33\x34\x2e\x31\x33\x33\x33\x33\x35\x22\x0a\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x76\x67\x35\x33\x32\x30\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x31\x20\x72\x31\x35\x33\x37\x31\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x73\x65\x6d\x69\x61\x75\x74\x6f\x6d\ +\x61\x74\x69\x63\x63\x6c\x61\x73\x73\x69\x66\x69\x63\x61\x74\x69\ +\x6f\x6e\x70\x6c\x75\x67\x69\x6e\x5f\x64\x6f\x77\x6e\x6c\x6f\x61\ +\x64\x5f\x69\x6d\x61\x67\x65\x5f\x70\x72\x65\x76\x69\x65\x77\x2e\ +\x73\x76\x67\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x36\x37\ +\x2e\x35\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x36\x37\x2e\ +\x35\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x35\x33\x32\x32\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ +\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\ +\x61\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x36\x30\ +\x32\x33\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\ +\x66\x66\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\ +\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x35\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\ +\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\x66\x66\x66\ +\x66\x3b\x73\x74\x6f\x70\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\ +\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x66\x66\x73\ +\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x73\x74\x6f\x70\x36\x30\x32\x37\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\x20\x20\x3c\x6c\x69\x6e\x65\ +\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6c\x6c\x65\ +\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\x73\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x73\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\ +\x6f\x72\x3a\x23\x30\x30\x30\x30\x38\x30\x3b\x73\x74\x6f\x70\x2d\ +\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\ +\x70\x35\x39\x37\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x73\x74\x6f\x70\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x73\x74\x6f\x70\x2d\x63\x6f\x6c\x6f\x72\ +\x3a\x23\x30\x30\x30\x30\x38\x30\x3b\x73\x74\x6f\x70\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x30\x3b\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x6f\x66\x66\x73\x65\x74\x3d\x22\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x74\x6f\x70\x35\ +\x39\x37\x35\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x6c\x69\ +\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\x74\x3e\x0a\x20\x20\ +\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\x6e\ +\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\x79\ +\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\x3a\ +\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x35\x39\x37\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\ +\x69\x65\x6e\x74\x35\x39\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x78\x31\x3d\x22\x31\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x79\x31\x3d\x22\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x32\x3d\x22\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x32\x3d\ +\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\ +\x69\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\ +\x70\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\ +\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x35\x33\ +\x37\x37\x34\x31\x30\x35\x2c\x30\x2c\x30\x2c\x30\x2e\x35\x33\x37\ +\x37\x34\x31\x30\x35\x2c\x31\x36\x2e\x33\x39\x36\x37\x30\x34\x2c\ +\x31\x37\x2e\x32\x37\x36\x33\x30\x38\x29\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ +\x6e\x74\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x6f\x6c\x6c\x65\x63\x74\x3d\x22\x61\x6c\x77\x61\ +\x79\x73\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x6c\x69\x6e\x6b\ +\x3a\x68\x72\x65\x66\x3d\x22\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\ +\x61\x64\x69\x65\x6e\x74\x36\x30\x32\x33\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\ +\x64\x69\x65\x6e\x74\x36\x30\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x78\x31\x3d\x22\x2d\x37\x2e\x37\x32\x37\x32\x37\x32\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x31\x3d\x22\x31\x31\x2e\ +\x34\x35\x34\x35\x34\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x78\ +\x32\x3d\x22\x33\x2e\x31\x38\x31\x38\x31\x38\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x79\x32\x3d\x22\x32\x2e\x33\x36\x33\x36\x33\ +\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x67\x72\x61\x64\x69\ +\x65\x6e\x74\x55\x6e\x69\x74\x73\x3d\x22\x75\x73\x65\x72\x53\x70\ +\x61\x63\x65\x4f\x6e\x55\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x67\x72\x61\x64\x69\x65\x6e\x74\x54\x72\x61\x6e\x73\x66\x6f\ +\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x33\x32\x32\ +\x36\x34\x34\x36\x33\x2c\x30\x2c\x30\x2c\x30\x2e\x33\x30\x39\x32\ +\x30\x31\x31\x2c\x33\x31\x2e\x34\x35\x33\x34\x35\x33\x2c\x32\x39\ +\x2e\x34\x35\x32\x37\x38\x33\x29\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x2f\x64\x65\x66\x73\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\ +\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x37\x2e\x39\x31\x38\x30\ +\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x78\x3d\x22\x2d\x34\x32\x2e\x33\x31\x30\x35\x36\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x79\x3d\x22\x31\x39\x2e\x38\x33\x35\x36\x37\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\ +\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\ +\x65\x72\x33\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ +\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x69\x64\x2d\x62\x62\x6f\ +\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2d\ +\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\x20\x20\x20\x20\ +\x73\x68\x6f\x77\x67\x75\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x75\x69\x64\x65\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x33\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x37\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\ +\x69\x64\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x3d\x22\ +\x78\x79\x67\x72\x69\x64\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x67\x72\x69\x64\x35\x33\x34\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x6f\x72\x69\x67\x69\x6e\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\ +\x67\x78\x3d\x22\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x70\x61\x63\x69\x6e\x67\x79\x3d\x22\ +\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x35\x33\x32\x35\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ +\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\ +\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\ +\x6c\x61\x79\x65\x72\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x67\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\ +\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\ +\x62\x65\x6c\x3d\x22\x4c\x69\x76\x65\x6c\x6c\x6f\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x65\x63\x74\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x23\x30\x30\ +\x30\x30\x30\x30\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ +\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\ +\x76\x69\x73\x69\x62\x6c\x65\x3b\x66\x69\x6c\x6c\x3a\x23\x62\x33\ +\x62\x33\x62\x33\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x6e\x6f\ +\x6e\x7a\x65\x72\x6f\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x31\x35\ +\x66\x66\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\ +\x68\x3a\x32\x2e\x32\x34\x30\x30\x30\x30\x30\x31\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\x73\ +\x65\x74\x3a\x32\x2e\x38\x33\x32\x38\x30\x31\x35\x38\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x6d\ +\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x65\x6e\x61\x62\x6c\ +\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ +\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x72\x65\x63\x74\x33\x30\x30\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x34\x34\x2e\x37\ +\x39\x39\x39\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x33\x37\x2e\x33\x33\x33\x33\x33\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x78\x3d\x22\x2d\x36\x2e\x34\x30\ +\x30\x30\x30\x30\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x79\x3d\ +\x22\x2d\x32\x2e\x31\x33\x33\x33\x33\x33\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x72\x79\x3d\x22\x39\x2e\x33\x37\x31\x30\x32\x30\ +\x33\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\ +\x6c\x6c\x3a\x23\x62\x33\x66\x66\x38\x30\x3b\x73\x74\x72\x6f\x6b\ +\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\ +\x2d\x77\x69\x64\x74\x68\x3a\x31\x2e\x31\x33\x37\x37\x37\x37\x36\ +\x39\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\ +\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\ +\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x31\x31\x2e\x33\ +\x37\x37\x37\x37\x38\x2c\x30\x20\x33\x34\x2e\x31\x33\x33\x33\x33\ +\x33\x2c\x31\x31\x2e\x33\x37\x37\x37\x37\x38\x20\x32\x32\x2e\x37\ +\x35\x35\x35\x35\x35\x2c\x33\x34\x2e\x31\x33\x33\x33\x33\x33\x20\ +\x30\x2c\x32\x32\x2e\x37\x35\x35\x35\x35\x35\x20\x5a\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x39\ +\x39\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x67\x33\x30\x30\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\ +\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\ +\x28\x31\x2e\x32\x39\x33\x34\x34\x32\x33\x2c\x30\x2c\x30\x2c\x31\ +\x2e\x32\x37\x38\x31\x32\x39\x36\x2c\x2d\x37\x2e\x35\x32\x35\x37\ +\x36\x32\x35\x2c\x2d\x31\x30\x2e\x33\x37\x36\x37\x35\x31\x29\x22\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x72\x65\x63\x74\x35\x33\x34\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x33\x2e\ +\x33\x30\x33\x33\x31\x34\x2c\x31\x37\x2e\x31\x34\x31\x38\x37\x33\ +\x20\x63\x20\x2d\x30\x2e\x35\x35\x30\x38\x32\x32\x2c\x30\x20\x2d\ +\x30\x2e\x39\x39\x31\x34\x36\x2c\x30\x2e\x34\x34\x30\x36\x33\x38\ +\x20\x2d\x30\x2e\x39\x39\x31\x34\x36\x2c\x30\x2e\x39\x39\x31\x34\ +\x36\x20\x76\x20\x37\x2e\x32\x30\x39\x30\x39\x32\x20\x68\x20\x2d\ +\x33\x2e\x37\x36\x34\x31\x38\x36\x20\x63\x20\x2d\x31\x2e\x30\x37\ +\x35\x34\x38\x33\x2c\x30\x20\x35\x2e\x39\x31\x35\x31\x35\x2c\x38\ +\x2e\x30\x36\x36\x31\x31\x35\x20\x35\x2e\x39\x31\x35\x31\x35\x2c\ +\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x6c\x20\x30\x2e\x35\x33\x37\ +\x37\x34\x31\x2c\x30\x2e\x35\x33\x37\x37\x34\x31\x20\x30\x2e\x35\ +\x33\x37\x37\x34\x32\x2c\x2d\x30\x2e\x35\x33\x37\x37\x34\x31\x20\ +\x63\x20\x30\x2c\x30\x20\x36\x2e\x39\x39\x30\x36\x33\x33\x2c\x2d\ +\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x35\x2e\x39\x31\x35\x31\x35\ +\x32\x2c\x2d\x38\x2e\x30\x36\x36\x31\x31\x35\x20\x68\x20\x2d\x33\ +\x2e\x37\x36\x34\x31\x38\x38\x20\x76\x20\x2d\x37\x2e\x32\x30\x39\ +\x30\x39\x32\x20\x63\x20\x30\x2c\x2d\x30\x2e\x35\x35\x30\x38\x32\ +\x32\x20\x2d\x30\x2e\x34\x34\x30\x36\x33\x38\x2c\x2d\x30\x2e\x39\ +\x39\x31\x34\x36\x20\x2d\x30\x2e\x39\x39\x31\x34\x36\x2c\x2d\x30\ +\x2e\x39\x39\x31\x34\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x75\ +\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\x65\ +\x6e\x74\x35\x39\x37\x37\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\ +\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x31\x2e\x30\x36\x36\x36\x36\x36\x37\x32\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\ +\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x35\x39\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x75\x72\x6c\x28\x23\x6c\x69\x6e\x65\x61\x72\x47\x72\x61\x64\x69\ +\x65\x6e\x74\x36\x30\x32\x39\x29\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\ +\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\ +\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x30\x2e\x33\x31\x35\x38\x35\x31\x33\x36\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\ +\x32\x39\x2e\x38\x34\x30\x32\x32\x39\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x63\x79\x3d\x22\x33\x31\x2e\x33\x30\x37\x39\x38\ +\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\ +\x33\x2e\x32\x32\x36\x34\x34\x36\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x79\x3d\x22\x33\x2e\x30\x39\x32\x30\x31\x31\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\ +\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x36\x30\x34\x33\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x30\x2e\x30\x39\x30\x34\x33\x39\x32\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\ +\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\ +\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x63\x78\x3d\x22\x32\x39\x2e\x37\x30\x35\x37\x39\x35\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x79\x3d\x22\x33\x31\x2e\ +\x33\x30\x37\x39\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x78\x3d\x22\x31\x2e\x32\x30\x39\x39\x31\x37\x34\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x79\x3d\x22\x32\x2e\x39\ +\x35\x37\x35\x37\x35\x38\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x6e\ +\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\ +\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\ +\x30\x2e\x31\x33\x34\x38\x31\x38\x38\x32\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\ +\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\x34\x35\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x32\x39\x2e\x38\x34\ +\x30\x32\x32\x39\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\ +\x79\x3d\x22\x33\x31\x2e\x33\x30\x37\x39\x38\x39\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x32\x2e\x36\x38\x38\ +\x37\x30\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x79\x3d\x22\x32\x2e\x39\x35\x37\x35\x37\x35\x38\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x65\x6c\x6c\x69\x70\x73\x65\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\ +\x66\x69\x6c\x6c\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\ +\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x77\x69\x64\x74\x68\x3a\x30\x2e\x30\x39\x33\x34\x37\x32\x37\x33\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\ +\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x36\x30\ +\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\ +\x2e\x30\x30\x35\x39\x34\x30\x32\x38\x2c\x30\x2e\x39\x39\x39\x39\ +\x38\x32\x33\x36\x2c\x2d\x31\x2c\x30\x2c\x30\x2c\x30\x29\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x78\x3d\x22\x33\x31\x2e\ +\x33\x30\x38\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x63\x79\x3d\x22\x2d\x32\x39\x2e\x37\x32\x31\x34\x38\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x78\x3d\x22\x31\x2e\x32\ +\x30\x39\x39\x35\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x79\x3d\x22\x33\x2e\x31\x35\x39\x32\x30\x35\x34\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\ +\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x36\x36\x66\x66\ +\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\ +\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x30\x3b\x73\ +\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\ +\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\ +\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\ +\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\ +\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\ +\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ +\x20\x32\x31\x2e\x33\x33\x33\x33\x33\x33\x2c\x35\x2e\x38\x36\x36\ +\x36\x36\x36\x37\x20\x2d\x34\x2e\x31\x30\x32\x35\x36\x34\x2c\x34\ +\x2e\x35\x39\x34\x38\x37\x31\x33\x20\x2d\x32\x2e\x32\x39\x37\x34\ +\x33\x36\x2c\x34\x2e\x34\x37\x31\x37\x39\x35\x20\x2d\x31\x2e\x31\ +\x34\x38\x37\x31\x38\x2c\x34\x2e\x34\x33\x30\x37\x36\x39\x20\x76\ +\x20\x36\x2e\x36\x34\x36\x31\x35\x34\x20\x33\x2e\x33\x32\x33\x30\ +\x37\x37\x20\x4c\x20\x30\x2c\x32\x32\x2e\x36\x38\x37\x31\x38\x20\ +\x31\x31\x2e\x34\x38\x37\x31\x38\x2c\x30\x2e\x35\x33\x33\x33\x33\ +\x33\x33\x33\x20\x31\x38\x2e\x31\x33\x33\x33\x33\x33\x2c\x33\x2e\ +\x37\x33\x33\x33\x33\x33\x33\x20\x5a\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x30\x30\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\ +\x73\x3d\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x07\x21\ \x00\ -\x00\x17\x33\x78\x9c\xed\x58\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ -\x14\x0c\x58\xb1\xea\x42\xdd\x2c\x29\xb6\xfb\xb0\xa2\x58\x81\xf5\ -\x65\xeb\xb6\xc7\x82\x96\x68\x9b\x8b\x24\x0a\x14\x15\xdb\xf9\xf5\ -\x3b\xa4\xee\xb6\x53\xa4\x18\x96\x3e\xb4\x02\x02\x45\xe7\x42\x9e\ -\xf3\x9d\xef\x1c\x32\x59\xbe\x39\x16\x39\x7a\xa0\xa2\x66\xbc\x5c\ -\x19\xd8\x72\x0c\x44\xcb\x94\x67\xac\xdc\xad\x8c\x3f\x3f\xbe\x33\ -\x23\x03\xd5\x92\x94\x19\xc9\x79\x49\x57\x46\xc9\x8d\x37\xeb\x9b\ -\xe5\x0f\xa6\x89\x7e\x11\x94\x48\x9a\xa1\x03\x93\x7b\xf4\xbe\xbc\ -\xaf\x53\x52\x51\xf4\xd3\x5e\xca\x2a\xb1\xed\xc3\xe1\x60\xb1\x4e\ -\x68\x71\xb1\xb3\x5f\x21\xd3\x5c\xdf\xdc\x2c\xeb\x87\xdd\x0d\x42\ -\x08\xf6\x2d\xeb\x24\x4b\x57\x46\xe7\x50\x35\x22\xd7\x86\x59\x6a\ -\xd3\x9c\x16\xb4\x94\xb5\x8d\x2d\x6c\x1b\xa3\x79\x3a\x9a\xa7\x6a\ -\x77\xf6\x40\x53\x5e\x14\xbc\xac\xb5\x67\x59\xdf\x4e\x8c\x45\xb6\ -\x1d\xac\x55\x34\x07\x4f\x1b\xe1\x38\x8e\x6d\xc7\xb5\x5d\xd7\x04\ -\x0b\xb3\x3e\x95\x92\x1c\xcd\xb9\x2b\xc4\x78\xcd\xd5\x75\x1c\xc7\ -\x06\xdd\x68\xf9\x3c\xab\xa4\x06\x40\x2b\xf8\x19\xcc\x7b\x81\x55\ -\xf3\x46\xa4\x74\x0b\x7e\xd4\x2a\xa9\xb4\xdf\x7e\x7c\x3b\x28\x4d\ -\xc7\xca\x64\x36\x59\xa6\xc7\x73\xb6\xeb\x0c\xe4\x92\x14\xb4\xae\ -\x48\x4a\x6b\xbb\x97\x6b\xff\x03\xcb\xe4\x7e\x65\x78\xbe\x85\x3d\ -\x78\x02\x2d\xdc\x53\xb6\xdb\xcb\x73\x29\xcb\x56\x06\x44\xef\xc6\ -\x51\xfb\x3d\x21\x07\x6e\x0d\xba\x85\x93\x41\xe3\x58\xb1\x6b\x61\ -\x24\x70\xe0\x2d\x5a\x9b\x3e\x85\x24\xe3\xa9\x8a\x09\x96\xa4\x05\ -\x23\x8d\xe4\x05\x54\x2d\x4d\x73\x52\xd7\x6c\xcb\x52\xf8\xe0\x65\ -\x95\x37\x3b\x56\x7e\x12\xb4\xe2\x42\x7e\x92\x9c\xe7\x56\x0f\xdf\ -\xb0\x17\x3d\x2a\xa5\x79\xcc\x2a\x00\x31\x5c\x5c\x55\x9e\x7a\xe5\ -\x1a\xb4\xcb\x8c\x6e\x6b\x65\xd5\x66\xa4\xbe\x20\xa5\x85\x81\x6c\ -\xad\x1d\x02\x54\xd1\x65\x0f\x8c\x1e\x46\xdb\x0d\xa9\x5b\xd4\x10\ -\xaa\xc8\x0e\x18\x96\x73\xb1\x32\x6e\xb7\xfa\xe9\x14\x1b\x2e\x32\ -\x2a\x7a\x55\xa8\x9f\x99\x8a\x43\x15\x98\x3c\xb5\x3d\xd5\xad\xdd\ -\xc7\xab\x56\x1d\xf4\xce\x75\x7d\xbd\x27\x19\x3f\xac\x0c\xf7\x5c\ -\xf9\xc8\x79\xb1\x32\x02\x2b\x88\xa3\xd8\xc1\xe7\xda\xf4\x08\x3b\ -\x42\xa5\x42\xd7\xc7\xde\x85\x52\x87\x13\xb8\x91\x87\xfd\xe8\x42\ -\xd9\x08\x01\x3d\x67\xe6\xe4\x44\x21\x27\xfd\xea\x97\xaf\xf7\xfc\ -\xb0\x13\x0a\x1b\x29\x1a\x7a\xee\xa9\x34\xe6\x66\xc3\x8f\xd7\xd5\ -\x40\x81\x46\x75\xb3\xd9\x94\x4c\x42\xc7\x54\xc7\xe9\xaa\x0d\xcb\ -\x68\x7d\xdd\xb1\x2e\x49\x65\xee\x72\xbe\x21\xf9\x75\x83\x03\x2b\ -\x01\x23\xb3\x23\x37\xf6\x86\x12\x9c\x5b\xf4\x4c\x5f\x38\x17\x69\ -\x77\x16\x10\xfb\x45\x19\x3a\xd5\xe9\x69\x55\x41\x8e\xac\x60\x8f\ -\x14\x80\xc1\x9a\x75\xc0\xac\x19\x2c\xad\x1b\x42\xf2\xa4\xba\xf6\ -\x78\x52\x32\xa3\x17\x2a\x3c\x95\xc0\x8d\xe3\xc5\x20\xe4\x82\x41\ -\x33\x4c\xc2\xe9\x45\xa7\xa9\x48\xf5\x38\x8c\xe8\xa3\xa6\x97\x26\ -\xdf\xe2\x5c\x77\x9a\xea\x3a\xd6\xdb\x97\xb4\xd7\xf2\x82\x4a\x92\ -\x11\x49\xc6\x1e\xe8\x25\x10\x9b\xd3\x67\x06\xe3\x32\xf9\xfd\xed\ -\xbb\x75\xb7\xd1\x32\x4d\x93\xbf\xb9\xb8\xef\xf7\x45\x48\x19\x90\ -\x0d\x6f\x00\x69\x63\x3d\x88\x97\x59\x9a\xc0\x80\x83\xc6\x5f\xb3\ -\x02\x98\xad\x66\xe3\xcf\x30\xd0\x96\xf6\xa8\x98\x19\x2b\xb0\xc6\ -\x45\xdb\x65\x05\x6d\x27\xe5\xd5\xe3\x22\x4b\x0b\xa6\x9c\xec\x3f\ -\x24\xcb\xf3\xf7\x6a\x93\x2e\xe3\xc9\xa2\x4c\xe6\x74\x14\x2e\xed\ -\x2e\xfa\x2e\x37\x7b\x92\xdc\xd2\xee\xb3\xd7\x5f\xbb\x11\x95\x59\ -\x53\x0c\x85\xce\xc9\x86\x02\x43\x7f\x53\x4a\x74\xa1\xdd\x09\xde\ -\x54\x05\xcf\x68\xe7\x3e\xa0\x49\x53\x39\x94\x4c\x9e\x72\xd0\xeb\ -\x71\x92\xdc\x3a\xfa\xb9\xcb\x58\x5d\x81\x07\x4c\xfd\x9c\x95\xf4\ -\x8e\xc3\xb8\xdd\xe6\xfc\x90\x3c\xb0\x9a\x6d\x72\x7a\xa7\xdf\x2c\ -\x87\xcc\x07\xd1\x16\xd2\x4f\x6e\xb7\xd1\x36\x4e\x1d\xfd\x61\x76\ -\x63\x26\xc1\xed\xa7\x68\x72\x9a\x94\xbc\x7c\x84\x01\x75\x57\x4b\ -\xc1\xef\x69\xd2\x0d\xb6\xee\xb3\xed\xa6\xc4\x6d\x8f\x04\xcf\xf7\ -\x7b\xb9\x0a\x02\x12\x4a\x36\x8d\x94\x53\xd9\x3f\x9c\x95\x09\xe0\ -\x4f\x45\x2f\xd5\x1f\x39\x34\x86\x4c\x06\xef\x8c\xc0\x40\x13\x02\ -\xd2\x81\xdd\xe9\x54\xca\xb7\xdb\x9a\xca\xc4\xe9\x65\x63\xc4\x05\ -\x11\xf7\x54\xb4\x0e\xb4\x24\x90\xa0\xb9\x21\xe9\xbd\x02\xb4\xcc\ -\x12\x92\xc2\x58\x69\x72\xb8\x82\xcc\x1a\x4a\xc1\xea\xc1\x80\x1b\ -\x84\xfd\xd1\x17\x58\xea\x60\x76\x46\xc5\x70\xfc\x5d\x68\xa0\xad\ -\x4c\x6c\x79\xae\x1b\x86\xb1\x3f\x48\xf5\xac\x6e\x51\x89\xdd\x41\ -\x2a\xc0\xd8\xb7\x22\x2f\x8c\x70\xe8\x8d\x52\x30\xf6\xac\x28\x76\ -\xe3\xc0\x0f\x07\x2e\x2e\x2b\x22\xf7\x67\x35\xd7\x25\x9b\x60\x32\ -\x94\x7f\x56\x8e\xd0\xf2\xda\x4e\x8e\xff\xcf\x72\x0c\xd0\x0f\x79\ -\xa8\x49\x80\xe0\x1e\xe2\x06\xe1\x6b\xdc\xc2\xe4\x2c\xd0\x1e\x79\ -\x91\xe5\xa3\xbf\xd4\x2b\xd0\x2c\x01\x91\xa9\x65\x8f\xb3\x62\xa8\ -\x7c\xbd\x08\x8f\xb3\x69\x3c\x6d\x78\x09\xf1\x4b\x2e\x4c\x38\x77\ -\x1e\x88\x6c\x04\x55\xf3\xed\xbf\x23\x85\x2d\x3f\xf4\x17\xe1\x22\ -\xc2\x2f\x8e\xd4\x07\x84\x3d\x4b\x91\x26\x5c\xbc\x0e\x3b\x60\x30\ -\xa0\x14\xb8\x56\x1c\xbb\x41\xec\x5d\xc3\x26\xfe\x36\xb0\x01\x16\ -\x75\x1d\x35\xc5\x66\x8f\x7c\xcf\x0a\x87\xbb\xc8\x14\x18\xd7\xfb\ -\x36\x80\xf9\x80\x9c\xd7\xae\xda\x1f\x9e\x08\xfd\x8a\x7c\x17\x60\ -\x52\xf8\x5c\xc3\x24\xf8\x72\x4c\x24\x3d\x0e\xc7\x0c\x1c\xba\x89\ -\xfe\xeb\x00\x16\x84\x03\x95\x8a\x87\x71\x76\xf6\x78\x71\xb8\xa8\ -\xe9\xdf\x21\x74\x38\x9a\xf3\x3b\x2d\x39\xe8\x59\x39\x13\xd5\x70\ -\xef\x49\xb0\x6b\x45\x1a\x4f\x1c\x57\xc7\x3b\x05\x50\x77\xd7\x4a\ -\x9c\x1f\x5b\xb3\x2d\x29\x58\x7e\x4a\x6a\x52\xd6\x26\xec\xc8\xb6\ -\x77\x39\x95\x80\x98\xd9\x5d\x53\x12\x07\x1c\x0f\x70\x65\x9e\x09\ -\xda\x83\xac\x2b\xd5\xd9\x41\xd6\x15\x72\x8a\x6c\x5f\xc5\xee\xba\ -\xe3\x4e\x27\x39\x0e\x2d\x98\xc2\x8b\xc5\x6c\x90\xbb\x91\xe5\xc0\ -\x64\x0e\xf1\x0c\x65\x85\x15\x9c\x1d\x23\xf4\x52\x40\xd8\xea\x8a\ -\x02\x7f\xbf\xa4\x24\xa7\x3f\x39\x6a\xa6\x47\x6e\x14\x78\x30\x0e\ -\x31\xcc\x43\x2f\x88\x5f\x19\xeb\xa5\x84\xe0\xcb\xf1\xce\x32\x5c\ -\xb3\x04\x57\xa0\x2a\x5c\x8c\x51\xab\xb7\x52\x0e\xb0\x57\x30\x91\ -\x5f\x0d\xf6\x89\x70\xcf\x0a\xa6\x6a\x11\x59\x51\x14\x85\x4e\x80\ -\xdd\xb3\x52\xc0\xe0\x0e\x9e\x2a\xc6\x53\x00\xae\xb1\xeb\x2d\x6d\ -\x1d\xe5\x1a\xde\x00\xcc\x77\x3e\x7d\x86\x4f\xd8\xb7\x16\x2e\x5e\ -\x04\xde\x55\x3e\x99\xc1\x4b\x32\xca\x8c\x9f\xc5\xa9\xcb\x90\xbf\ -\x73\xea\x6b\x71\xca\xb7\x7c\xdf\xf7\x9c\x2f\xa1\x94\xf3\xa2\x94\ -\x0a\xe7\x94\xba\x88\xf7\xab\x31\xea\x3b\x9f\x9e\xcb\xa7\xcf\x1f\ -\x79\xa6\xf3\xc2\x43\x2a\x34\xfd\xe7\x70\xea\x6b\x9c\x7c\x97\x9c\ -\x5a\xda\xbb\xf5\xcd\x52\xfd\xe3\x62\x7d\xf3\x2f\x01\x81\xea\x10\ +\x00\x20\x55\x78\x9c\xed\x59\x5b\x8f\xe3\xb6\x0e\x7e\xdf\x5f\x61\ +\x64\x5f\x76\x71\x22\x59\x17\xeb\xe6\x4d\xa6\x28\xb0\x28\x70\x80\ +\xf6\xe5\x9c\x16\x7d\x76\x6c\x25\xe3\x8e\x63\x07\xb6\x33\x49\xf6\ +\xd7\x97\x72\xe2\x4b\x12\x67\x76\xf6\x9c\xb4\x0b\x14\xe3\x60\x90\ +\x11\x49\x49\x24\xc5\x8f\xa4\x9c\xd9\x0f\xfb\x75\xe6\x3d\xdb\xb2\ +\x4a\x8b\x7c\x3e\xa1\x98\x4c\x3c\x9b\xc7\x45\x92\xe6\xab\xf9\xe4\ +\xb7\x5f\x7f\x42\x7a\xe2\x55\x75\x94\x27\x51\x56\xe4\x76\x3e\xc9\ +\x8b\xc9\x0f\x0f\xef\x66\xd5\xf3\xea\x9d\xe7\x79\x30\x39\xaf\xc2\ +\x24\x9e\x4f\x1e\xeb\x7a\x13\xfa\xfe\x66\x5b\x66\xb8\x28\x57\x7e\ +\x12\xfb\x36\xb3\x6b\x9b\xd7\x95\x4f\x31\xf5\x27\xbd\x78\xdc\x8b\ +\xc7\xa5\x8d\xea\xf4\xd9\xc6\xc5\x7a\x5d\xe4\x55\x33\x33\xaf\xde\ +\x0f\x84\xcb\x64\xd9\x49\xef\x76\x3b\xbc\xe3\x8d\x10\x35\xc6\xf8\ +\x84\xf9\x8c\x21\x90\x40\xd5\x21\xaf\xa3\x3d\x3a\x9f\x0a\x3a\x8e\ +\x4d\x65\x84\x10\x1f\x78\xbd\xe4\xeb\xa4\xc2\x0a\xbc\xb2\x81\xbf\ +\x4e\xbc\x25\xe0\xaa\xd8\x96\xb1\x5d\xc2\x3c\x8b\x73\x5b\xfb\x9f\ +\x7f\xfd\xdc\x31\x11\xc1\x49\x9d\x0c\x96\x49\xf3\xa7\x2a\x8e\x36\ +\xf6\x6c\xd7\x96\x78\xf4\x40\xb4\xb6\xd5\x26\x8a\x6d\xe5\xb7\xf4\ +\x66\xfe\x2e\x4d\xea\xc7\xf9\x84\x07\x98\x72\x78\x44\x43\x7c\xb4\ +\xe9\xea\xb1\xbe\xa4\xa6\xc9\x7c\x02\xda\x33\xa3\x8f\xe3\xc1\x09\ +\xd3\xa3\xc0\x69\xe1\x70\x78\xf6\x98\x79\x1f\xac\x96\xb1\x56\x44\ +\x2b\x33\xf5\x18\x61\x14\x11\x8a\xa8\xf8\xd8\x4c\x6a\x6d\x0a\x93\ +\x22\x76\x4a\x82\x09\x36\xdb\xe0\xd6\x4d\xdd\x9a\x76\xbf\x29\xca\ +\x1a\xed\x93\x0d\x38\x4b\xaa\x51\xe6\xa1\x65\x3e\x00\x77\x96\xd8\ +\x65\xe5\xa4\x8e\x9a\xbb\x11\xa8\xae\x26\x9e\xdf\x70\xbb\x7d\xdd\ +\xa6\xc9\x73\x6a\x77\xbd\xec\x22\xaa\x8e\xde\xf1\xbc\x4d\xb4\x82\ +\x48\xca\x8a\x72\x3e\x79\xbf\x6c\x9e\x13\x63\x51\x94\x89\x2d\x5b\ +\x96\x6c\x9e\x33\x56\x01\xde\x4e\xeb\xc3\x11\x00\xa7\xb5\x5b\x7d\ +\xdd\xaa\x1d\x9f\x8c\xf3\xab\xc7\x28\x29\x76\xf3\x09\xbb\x64\x7e\ +\x29\x8a\x35\x9c\x0d\x36\xc2\x10\x46\xf4\x25\x3b\xde\xbb\x2d\x19\ +\x35\x8c\x28\x7e\xc5\x84\xfd\x38\xc1\x46\xc1\x29\x88\x2b\xe6\xb6\ +\x2c\x01\x5c\x28\x8b\x0e\x16\x8c\x6a\xbe\xe8\x49\xa8\x7a\x2c\x76\ +\xab\xd2\x39\xa7\x2e\xb7\xf6\x72\xa6\xe3\xa0\xc5\xa2\xd8\x8f\xb3\ +\xe1\x68\xb7\x0e\xb6\x68\x9b\xa7\x35\x40\x63\xb3\x1f\xae\xba\x4d\ +\x13\x5b\x8d\x4f\xdc\xa5\x39\xf8\x00\x9d\x82\x94\xf2\xce\xc5\x97\ +\x12\x6d\xc4\x2a\x72\x4b\x02\x54\xbb\x72\xf3\x89\x75\xb8\xcd\x5a\ +\x47\xfb\x74\x9d\x7e\xb1\x60\x37\xbd\x14\xa9\xf2\x68\x83\x56\x59\ +\xb1\x88\xb2\xaf\x98\x5d\x16\x35\xa4\x24\x07\x08\xd2\x84\x26\x84\ +\xdf\x99\xeb\x8e\xf3\x3c\xaf\x3e\x38\x08\xef\x0f\x8e\x36\x69\x89\ +\xce\xe7\x8e\xc0\x95\x14\x1d\xb1\x28\xd3\x55\x9a\x0f\x6c\x6a\x49\ +\x87\x21\xc9\x01\x1e\x92\x6e\x13\x10\xa4\x89\x50\x75\xc9\x3b\x0c\ +\x79\x27\x68\xf8\xd7\xd8\x68\xe8\x6b\x5b\x47\x49\x54\x47\x3d\x50\ +\x5a\x0a\x33\xa6\xb3\x0c\x72\x67\xf8\x9f\xcf\x3f\x3d\x9c\x36\x9a\ +\xc5\x71\xf8\x7b\x51\x3e\xb5\xfb\x7a\x9e\x13\x88\x16\xc5\x16\x8e\ +\x6b\xf2\xd0\x91\x67\x49\x1c\x42\xb6\x5b\x47\xf5\x43\xba\x86\xf0\ +\x77\x89\xf2\x5f\x90\xdd\x66\x7e\xcf\x38\x13\x76\xce\xea\x17\x3d\ +\x2e\x5b\xda\x63\xda\x1c\xad\x1d\x49\xbc\x4e\xdd\x24\xff\xbf\x75\ +\x9a\x65\xff\x76\x9b\x9c\x2c\x1e\x2c\x9a\xd6\x99\xed\x89\x33\xff\ +\xa4\xfd\xc9\x36\x7f\x60\xdc\xcc\x6f\xad\x6f\x46\xab\xde\x2b\x67\ +\xc0\xe9\x0e\x3a\x8b\x16\x16\x02\xe5\x67\xc7\xf4\xae\xb8\xab\xb2\ +\xd8\x6e\xd6\x45\x62\x4f\xd3\x5b\x6f\xc6\x69\x19\x67\x9d\x9d\x55\ +\x7d\xc8\x40\xa2\xc9\x3a\xe1\x7b\xd2\x3c\x9f\x92\xb4\xda\xc0\x1c\ +\x28\x02\x59\x9a\xdb\x4f\x05\x64\xdf\x65\x56\xec\xc2\xe7\xb4\x4a\ +\x17\x99\xfd\xd4\x7c\xa7\x19\xd8\xde\x91\x96\xe0\x80\xf0\xfd\x52\ +\xba\x4f\x33\x40\xa7\x6c\x14\xd2\xe3\xb0\xdc\x66\x36\xcc\x8b\xfc\ +\x0b\xe4\xb1\x4f\x55\x5d\x16\x4f\xd6\xed\x27\x63\x93\x9c\x86\x47\ +\x50\x86\xa4\x1d\xba\xbd\xc1\x92\x70\xb1\xad\xeb\x21\xed\x8f\x22\ +\xcd\x43\x70\xbc\x2d\x5b\x6a\x33\xc8\x00\x56\x75\xc8\xb1\x68\xa9\ +\x49\x04\x09\xaf\x2c\xc1\x0e\xd8\xd6\x0e\xa9\xc5\x72\x59\xd9\x3a\ +\x64\x58\x73\xa6\x09\x15\xba\x65\xf6\x3a\xaf\xa3\xf2\xc9\x96\xc7\ +\x99\x36\x8f\xc0\x44\xb4\x88\xe2\x27\xe7\xd4\x3c\x09\xa3\x18\x70\ +\xb8\xcd\xa2\xda\x9e\x81\x6a\x13\xd5\x8f\x9c\x09\xd3\x11\x9b\xcc\ +\xa9\x8e\x68\xd0\x3d\xd5\x41\x44\x76\xc3\xb2\x19\xb5\x21\xd2\x1e\ +\xfb\x09\xa6\x9c\x50\x3a\xb9\x38\xac\xd6\x7b\x81\x91\x81\x5c\x5c\ +\xe9\xde\x41\x60\xe6\xf4\xe9\x03\xba\x8b\x8c\xba\x8c\xf2\xca\x01\ +\x00\xc5\x90\x4b\x6c\xe9\xd2\x15\xc3\x92\x69\x63\x82\xc9\x6b\xe4\ +\xc1\x2a\x44\xb1\x52\x46\x0d\x8d\x1d\x54\xde\x62\x63\xf3\xb3\x0c\ +\x76\xc6\xb5\x79\xe2\x6a\x94\xa6\x42\x09\x23\xf4\x98\x08\x34\x73\ +\x65\x3d\x4c\x3c\x90\xca\x5a\x2d\xe6\x93\x26\xfb\xd9\x0f\x32\x80\ +\x35\x20\x85\xd3\x8f\x03\x31\x58\xfa\x17\x8f\x0b\x2c\xa4\xa6\x53\ +\xa4\x71\xa0\xb8\x66\x54\x7a\x3f\x7a\x94\x63\xdd\x64\xa5\x69\xfb\ +\x9f\xf6\x08\x7c\xa8\xc7\xa1\xba\x91\x20\x50\xc1\x94\x82\x1b\x02\ +\xc1\xb4\x1a\x53\xaa\x74\xe7\xd6\x4e\x1d\x15\xd8\xf7\x02\xa3\x2b\ +\xb8\x93\xef\x75\x1a\x95\x80\x25\x18\xf8\x96\xd0\x80\xf3\xe1\x61\ +\xb4\xe1\x05\xf8\x44\x0c\x0d\xcf\xe9\xae\x10\x1e\x40\xe5\x32\xc0\ +\x8e\xf0\x14\xd8\x04\x4a\x13\xa3\xfe\x2f\x98\x06\xdf\x00\x52\xa3\ +\x25\xe1\x81\x56\x77\x00\xe9\xc0\xd1\xc7\xca\x18\x95\xf1\x20\x63\ +\x5f\x00\xe6\x6f\x0e\x67\x04\xb1\x8c\x59\xc0\x88\xb8\x8a\x67\x88\ +\x19\x41\x8c\x51\x54\x4e\x0d\xa6\x14\x52\x96\xa0\xa3\x11\xad\x4e\ +\x11\x8d\x28\x24\x37\xc5\x85\xd1\x53\x6a\x20\xb8\xb5\x20\xe2\x6b\ +\x21\x3d\x1e\xf3\xaf\x09\xe9\x4e\xa7\x5b\x11\x8d\x18\xc3\xd0\x6d\ +\x48\xae\x6f\x87\x34\x45\xfa\x2d\xa8\xff\xfa\xa0\x7e\xb1\x0a\xc0\ +\x35\x90\x19\xa2\x14\xe5\xea\xd5\x85\x80\x41\x21\x80\x64\xa5\xbe\ +\x63\x21\x00\x74\xd0\x00\xd4\x36\xd7\x85\x00\xb4\x83\x8a\xac\xa4\ +\x43\x88\x04\x00\xf1\x17\x61\xc3\x34\xe6\x52\x1b\x31\x65\x1c\x2b\ +\x23\x82\xf1\x2c\x7f\x17\xcc\xb4\xfa\xdc\x82\x0c\xd5\xb0\x80\x30\ +\xf4\x85\x1a\x80\xe8\x1b\x60\xfe\x81\x55\x40\x31\x4c\x04\xdc\xb4\ +\xaf\xab\x80\xc0\x1c\xb2\xa8\x66\x6a\x8a\x68\x80\xb9\x11\x42\x9b\ +\x17\x1b\x1b\x64\x5c\x27\xc1\x89\xd6\x53\x14\x00\xb4\x15\xe3\x7a\ +\xb4\xed\xb8\x53\x6b\xd3\x69\x75\xb3\x10\x34\xd5\x28\xe0\xe2\xc5\ +\x3a\xf0\xd6\xde\x7c\xff\x4a\xc0\xb0\xd0\x8c\x9f\x77\xc2\x5f\xbb\ +\x11\x10\x68\x6c\x15\xff\x8e\x85\x00\x09\x8e\x03\x6a\x02\xca\xae\ +\xc0\x43\x61\x79\xb8\x87\x29\xe5\x72\xbb\x04\x09\xfd\x72\x07\x25\ +\x71\x10\x70\xc0\xa1\x98\x72\xa8\x05\xdc\x48\x3e\xda\xdd\xdc\xa7\ +\x18\x74\x2a\xdd\xc4\x0d\x87\x9c\x60\x8c\x21\xec\xc5\x7a\x80\xd8\ +\x1b\x70\xfe\x71\x15\x01\xe2\x02\x0b\xa6\xa8\xba\x88\xe9\xb5\x47\ +\x21\x48\x95\xa0\x84\x4f\x91\x6b\x58\x02\x09\x3d\xb8\x17\xbd\x54\ +\x0f\x20\x3f\x4b\x2e\x19\xb4\x43\x04\x13\xa3\xf9\x78\xcb\x7e\xa7\ +\x6a\xd0\xe9\x74\xf3\xa2\x8b\x25\xd1\x50\x0c\xcc\x57\xaa\x01\x32\ +\x6f\x61\x7d\xf7\xb0\x9e\xf9\xab\xd3\x3f\x36\xcb\xd2\x4d\xf5\x17\ +\xbd\x12\x24\x84\xf1\x20\x7e\xfd\x2b\x41\x2b\xdc\xe7\xfc\x10\x28\ +\xf4\x3d\x42\x51\x16\xf0\xbf\xe9\x14\xc8\x1d\x9c\xdf\x06\x32\xdc\ +\xc1\x19\xea\xdb\xfc\xa6\xb7\x97\x58\x9b\x20\x60\x03\x6a\xf3\x4a\ +\x10\x43\xbf\xcf\x06\xef\xe4\x1d\xcc\x14\x0e\x1c\xca\x44\x2f\xeb\ +\xd0\x29\xf1\xf1\xf7\x21\xd1\x1f\xe7\xf8\x29\x5e\x47\xf9\x98\x83\ +\xe1\xda\x47\x18\xa1\x5a\xe9\x6f\x77\x5b\xff\xde\xf1\xd2\x72\x09\ +\x8d\x1e\x92\x97\x96\x0b\xcd\xf9\xe0\x9d\xe6\x6d\xcb\xe1\xea\x66\ +\xdc\x23\x2e\x2c\x77\x2d\x30\xa5\xb7\x2d\x1f\x6c\x2f\xd0\xe0\xe7\ +\x89\x6f\x73\x88\x7b\xf1\x2a\xa8\xa6\xf7\x70\xc8\xf0\xcc\x5f\x63\ +\xb9\xc4\xcc\x3d\x34\xf8\x46\xcb\x07\xb5\x63\x1d\xd5\x65\xba\xff\ +\x00\x59\x9e\x48\xae\x84\x56\x53\x82\x9d\x33\x95\x91\xee\xf6\x30\ +\x25\xee\xf3\x71\xec\xc8\x14\x12\xff\xab\xcf\x98\xfb\x41\x56\xb0\ +\x3b\xba\x0c\x9c\x23\x07\x3d\xcf\xf1\x92\x21\xb1\x73\x64\x20\x2f\ +\xa2\x05\x6a\x89\x1a\xdc\x3c\x9c\xcb\x14\x86\x50\x23\x42\xd2\xee\ +\x87\x28\xc8\x79\x33\xf7\x43\xd0\xc3\xbb\x3f\x01\x98\x7a\x70\xee\ +\ +\x00\x00\x10\x81\ +\x00\ +\x01\x72\x36\x78\x9c\xed\x9d\x4b\x93\xe3\xb6\x11\x80\xef\xfb\x2b\ +\x14\xed\xc5\xae\x2c\x21\x3c\xf8\x82\x76\x66\x7d\xb0\x2b\x15\x57\ +\x25\x97\xc4\x49\x8e\x2e\x8e\xc4\xd1\x28\x2b\x89\x13\x8a\x9a\x87\ +\x7f\x7d\x00\xbe\x44\x52\xe4\xec\x7a\x85\x26\x66\xe4\xd6\xd8\xb5\ +\x12\x41\x89\x24\x3e\x74\xa3\xbb\xd1\x00\xae\x7e\x78\xda\x6e\x26\ +\x0f\x71\xba\x5f\x27\xbb\xeb\x29\x23\x74\x3a\x89\x77\x8b\x64\xb9\ +\xde\xad\xae\xa7\xff\xfa\xe5\x2f\x4e\x38\x9d\xec\xb3\x68\xb7\x8c\ +\x36\xc9\x2e\xbe\x9e\xee\x92\xe9\x0f\x9f\xde\x5d\xfd\xc9\x71\x26\ +\x3f\xa6\x71\x94\xc5\xcb\xc9\xe3\x3a\xbb\x9b\xfc\xbc\xfb\xbc\x5f\ +\x44\xf7\xf1\xe4\xbb\xbb\x2c\xbb\x9f\xcf\x66\x8f\x8f\x8f\x64\x5d\ +\x1e\x24\x49\xba\x9a\x7d\x3f\x71\x9c\x4f\xef\xde\x5d\xed\x1f\x56\ +\xef\x26\x93\x89\xba\xee\x6e\x3f\x5f\x2e\xae\xa7\xe5\x17\xee\x0f\ +\xe9\x26\x3f\x71\xb9\x98\xc5\x9b\x78\x1b\xef\xb2\xfd\x8c\x11\x36\ +\x9b\x1e\x4f\x5f\x1c\x4f\x5f\xe8\xab\xaf\x1f\xe2\x45\xb2\xdd\x26\ +\xbb\x7d\xfe\xcd\xdd\xfe\x7d\xe3\xe4\x74\x79\x5b\x9f\xad\xef\xe6\ +\x51\xe4\x27\x31\x29\xe5\x8c\xf2\x19\xe7\x8e\x3a\xc3\xd9\x3f\xef\ +\xb2\xe8\xc9\x69\x7f\x55\xdd\x63\xdf\x57\x39\xa5\x74\xa6\xca\x8e\ +\x67\x7e\xdd\x59\xf3\xbd\xaa\xd0\x7b\xf5\x7f\x7d\x7a\x75\x80\xec\ +\x93\x43\xba\x88\x6f\xd5\xf7\x62\xb2\x8b\xb3\xd9\x4f\xbf\xfc\x54\ +\x17\x3a\x94\x2c\xb3\x65\xe3\x67\xaa\xfa\x6c\x5d\xb5\x55\xc9\xbb\ +\x68\x1b\xef\xef\xa3\x45\xbc\x9f\x55\xc7\xf3\xef\x3f\xae\x97\xd9\ +\xdd\xf5\x54\xb8\x84\x09\xf5\xf2\xf2\x83\x77\xf1\x7a\x75\x97\x75\ +\x8f\xae\x97\xd7\x53\x75\xf7\x5c\x86\xc5\xe7\x46\xe3\x60\xc5\x09\ +\xe5\x0f\xcf\xeb\x12\x4a\x24\x27\x6c\x92\x32\x4f\x04\xc5\x39\xd5\ +\x23\xcc\x97\xc9\x42\xdf\x93\xfa\xc9\x78\xbb\x8e\x0e\x59\xb2\x55\ +\xd4\x16\x8b\x4d\xb4\xdf\xaf\x6f\xd7\x0b\xf5\x21\xd9\xdd\x6f\x0e\ +\xab\xf5\xee\x57\xf5\xa3\x59\x16\xa7\xbf\x66\x49\xb2\x21\x55\xfd\ +\xd5\x17\x8b\x9f\xee\x93\x34\x73\x9e\x96\xf7\xaa\x16\xfd\xa0\xb7\ +\xf0\xb9\x2a\xfc\xa4\x4a\xaf\x96\xf1\xed\x5e\x9f\x55\x3c\x92\xfe\ +\xa4\x9e\x29\x98\x4e\x66\x79\x69\x7d\x87\xfa\xf6\x96\x0f\xeb\xf8\ +\xf1\x78\xee\x4d\xb4\x2f\xaa\x6d\x32\xb9\x8f\x56\xaa\x89\x6d\x92\ +\xf4\x7a\xfa\xfe\x36\x7f\x95\x05\x37\x49\xba\x8c\xd3\xaa\xc8\xcf\ +\x5f\xad\xa2\x44\x61\x58\x67\xcf\x85\x50\x95\xbf\x5d\xdd\xaf\xfe\ +\xd5\xba\x9c\xf6\x97\xef\xef\xa2\x65\xf2\x78\x3d\xe5\xdd\xc2\xdf\ +\x92\x64\xab\xa0\x11\xe9\x49\xca\xa9\xec\x16\x2f\x9e\xae\xa7\x8e\ +\x2b\x09\x0b\x28\x2b\x11\x36\x4b\xd5\x05\x43\x97\x78\x4c\x06\x9e\ +\x38\x29\x3c\xa4\xa9\x12\x3b\x67\x13\x3d\xc7\xea\xa9\xf2\x7f\x58\ +\x79\xd2\xfe\x2e\x79\x5c\xa5\xba\x76\xb2\xf4\x10\x77\xbf\xa9\x4b\ +\x9c\x9b\x9b\xe4\xa9\xbf\x58\xb5\x82\x83\x16\x68\xe7\xb0\x5b\x67\ +\x4a\x68\xee\x9f\x9a\xbf\x7a\x58\x2f\xe3\x7d\xff\x17\x1f\xd7\x3b\ +\x55\x09\x4e\xd9\x7c\x99\xa8\xeb\xb8\x7b\x46\xd5\x96\x03\x1a\x0e\ +\x9c\xa1\x6e\xed\xa4\x9e\xcb\xa2\xe7\xe1\xa2\x6d\xf4\xb4\xde\xae\ +\x7f\x8b\xd5\x73\xb3\xee\x29\xfb\x5d\x74\xef\xac\x36\xc9\x4d\xb4\ +\x29\xef\xfe\x53\x7e\xc6\x55\xab\x5a\x8a\x2f\x4d\x26\xd9\xb3\x16\ +\xdc\xa7\x67\x7d\x6c\x5a\x1d\xd4\xf5\xa9\x0f\x88\xc0\xf7\xea\x83\ +\x49\xba\x56\xf2\xd0\xb8\xdf\xea\xd0\x73\xf3\x90\x16\x73\xa5\xa5\ +\x9f\xf2\x06\x96\x37\xbf\xa0\x5b\xf6\xdc\x2c\x2b\xdb\xfd\xec\xb4\ +\xe1\xe7\xc7\xb7\x71\x16\x2d\xa3\x2c\x3a\x4a\x41\x75\x84\x4b\x49\ +\xab\x27\x53\x1a\x73\xfe\x8f\x9f\xfe\xf2\xa9\xbc\xd0\xd5\x62\x31\ +\xff\x4f\x92\x7e\xae\xae\x3b\x99\xe8\x13\xa2\x9b\xe4\xa0\x50\x4c\ +\x3f\xd5\x87\xaf\x96\x8b\xb9\xd2\x71\x4a\xf6\x3f\xad\xb7\xaa\x6d\ +\x6b\xf5\xf8\x67\xa5\xd3\xae\x66\xc7\x82\xd6\xc9\xba\xb2\x8e\x3f\ +\x5a\xfc\x6c\x1a\x17\xca\xb2\xb7\xc7\x58\x2e\xb6\x6b\xfd\xa5\xd9\ +\x3f\xb3\xf5\x66\xf3\xb3\xbe\x48\xf9\xc4\x8d\x1f\x5d\x67\x9b\xf8\ +\x78\xf0\x6a\x56\xde\x7d\xf9\x6c\xb3\xc6\xc3\x5d\xcd\xaa\xa7\xcf\ +\x3f\xad\x8e\xb5\xd2\x12\x8a\x1a\xf4\x26\xba\x89\x55\x23\xf8\x9b\ +\x2e\x9c\x9c\x94\xae\xd2\xe4\x70\xbf\x4d\x96\x71\xf9\xf5\xba\x36\ +\xe3\x45\x56\x23\xcb\x9e\x37\xaa\xfc\x56\xdd\xfd\xfc\xfd\x2d\xd5\ +\x7f\x1f\xf5\x07\xa7\xd4\x13\x73\x56\x7c\x4c\x0f\x1b\xa5\xef\x1e\ +\xe2\x5d\xb2\x5c\x7e\xdc\x67\x69\xf2\x39\x9e\xbf\xa7\xd4\x0d\x29\ +\x2d\x3f\x16\xd2\x32\xaf\x3f\x6e\xd6\xbb\x58\xdd\xc6\x7c\xff\xbf\ +\x43\x94\xc6\xcd\xa3\xff\x4d\xd6\xbb\xb9\xaa\xb7\x38\xad\x8e\xe6\ +\x1f\x36\xaa\xc5\x67\x73\xb7\x3a\xb6\x8c\x94\x2a\x4a\xd3\xe8\x79\ +\xbe\x53\x26\x40\xf3\x68\x72\x7b\xbb\x8f\xb3\xe3\x95\xaa\x5b\xa5\ +\x44\x94\xaf\x56\x43\xd7\x8f\x2b\xa4\x64\xf5\xc1\xde\x5e\x49\xbf\ +\xfa\x7b\x26\xfd\x6a\x49\x85\x6a\xdf\x92\xb8\x81\x90\x54\xf8\xb1\ +\xc3\xfc\xba\x20\x6d\x9d\x96\x3e\x6b\x75\x29\x54\xef\xe4\xcb\xb0\ +\x6e\x15\x57\xf7\x51\x76\xd7\x57\xfb\x8d\xa7\xd4\x35\x4b\x6f\x39\ +\x6f\xd7\x2c\x2f\x6e\x4a\xb8\x6e\xb7\x8a\x6f\x0e\x59\x66\xaa\x82\ +\x6b\xee\xf5\x73\xa8\x2a\xfc\xfb\x84\x7e\xa0\x93\x7f\x4f\xaa\x8a\ +\x69\x57\xb0\x7e\x22\x25\xad\xc7\x7a\x38\x6a\xf6\x64\xa7\xee\x30\ +\x4b\x52\x47\xe9\xf8\x87\x28\x3b\xa4\x71\x4b\x97\xd4\x3a\x41\x35\ +\x52\x2d\x46\x4a\x1d\x2f\x16\x6f\xbd\xaa\xea\x4a\xfa\x50\xbf\x9b\ +\xfc\x75\x42\xfb\xaa\x2c\x7c\x3d\x55\xc6\x88\x22\x48\xb9\x17\xde\ +\x3f\xfd\xfe\x3a\x1b\xa8\x89\xba\x17\xf8\xc0\x43\x12\x4e\x7e\x9c\ +\x08\xc2\x8b\xb7\x27\x6f\x4e\x6a\x47\x04\x01\x77\xe8\x57\xd7\x8f\ +\x91\x36\xc3\x02\xcf\x65\x9e\x67\xac\x06\xb6\x13\xaf\x52\x49\x1f\ +\x84\x47\xf8\x64\xa1\xe4\xc8\x71\x09\xcf\x2b\x65\xe8\xfd\x69\x55\ +\x84\xee\x9b\xaf\x08\x46\x49\xd9\x14\xce\xac\x08\xe7\xeb\x65\xe6\ +\x8b\x55\xf1\x7e\xc1\x97\xf4\xd6\xef\x76\x78\xa3\x57\x0e\x67\xc4\ +\x4c\x2b\x71\xe4\x5b\x6f\x27\xdc\x37\xd5\x4e\xde\xbc\xc8\x08\x7e\ +\x76\x1d\x88\xb7\x5e\x07\xcc\x3f\xbb\x0e\xbe\xde\x2c\xf9\xb2\xbe\ +\xd0\x8e\x78\x6d\xf0\x8e\xd5\x8f\x6e\x9b\xfd\xa8\x20\x6e\xf1\xdc\ +\x8b\x49\x65\xe4\x08\x65\x9a\x0d\xbc\x1f\xe8\x55\x1d\x7e\x49\x75\ +\xc2\xc2\xca\xca\x3a\xab\x4e\xd8\x88\xb2\x02\x6b\x6c\x31\x5e\x1b\ +\x5b\xf9\xdb\x93\x37\x43\x55\x30\xa6\xba\x80\x6d\x13\x41\x21\x26\ +\xe7\xca\x89\x7b\x31\x15\x52\x3f\xec\x79\x15\xf2\x0d\xf6\xc5\xaa\ +\x15\x74\x72\x79\x78\x6c\x7e\x2d\x3d\xe2\x7a\xfa\xaf\x63\x8b\xd5\ +\xa7\x66\x69\xb4\xdb\xeb\x90\x8d\x0e\x79\xa9\xb7\x9b\x28\x8b\xbf\ +\x73\x24\x91\x61\xa0\xfe\xdc\x0f\x9e\x20\x21\x0d\x5c\x1a\x7e\x5f\ +\xc7\x7f\x8e\x57\xae\xae\x4d\xe5\x11\xe8\x57\x5d\xbd\x11\xc8\x69\ +\x06\x4d\x1a\xdf\xce\x23\xb1\x39\x50\xf5\xfa\xb8\x5c\xef\xef\x37\ +\xca\x4b\x5c\xef\x34\xa6\x8f\xc9\x43\x9c\xde\x6e\x92\xc7\xf9\xc3\ +\x7a\xbf\xbe\xd9\xc4\x1f\xf3\x7f\xd7\x1b\xfd\xe3\xd5\xa1\x17\x2e\ +\xdf\x88\xbc\xa8\xd6\xf3\x5b\x9c\x26\xc7\x06\x14\xd0\xc0\xbb\xfd\ +\x42\xe4\xc5\xa4\xaf\xfb\x52\xdc\x85\x7d\xdc\x46\xe9\xe7\x38\x2d\ +\xbe\x10\xef\x22\xf5\x5c\xce\x4d\xb4\xf8\xac\x03\x50\xbb\xe5\x3c\ +\x5a\x2c\x0e\xdb\x83\x26\x36\x6d\xd6\x60\x1d\x9b\x09\x29\x77\xb8\ +\x68\x95\x55\x91\x57\xc2\x5b\x87\xab\x00\x0d\x25\x92\xa9\x96\xe4\ +\x05\xed\xe2\xa7\xeb\xa9\xea\x20\x03\xce\xd4\x5f\xab\xe0\xf9\x7a\ +\xea\x70\x49\x02\xa1\x4a\xc2\x76\x80\x0e\xb9\x82\x72\x75\x1b\x2a\ +\xe3\x3c\xb0\x3e\x61\x08\xf6\xf5\x80\xe5\x62\x88\x6c\x77\x54\xa0\ +\xc9\xb7\xbf\x54\xe1\x15\xca\x05\xd6\x78\xd9\x09\x5e\x55\xe2\xe6\ +\x9a\x1d\xf1\x8e\x2b\xb7\x0d\xcf\xc9\x00\x5f\xe5\xb8\xe8\x3a\x75\ +\x91\xef\xab\xe0\xeb\x3b\xa2\x11\x21\x31\xc0\xd7\x27\x7e\x5e\xa7\ +\xa7\x7c\x39\x71\x15\xde\xc0\x43\xbe\x23\xf2\x95\xc2\x09\x8d\xca\ +\x2f\xea\xe7\x57\xc5\xd7\x75\x84\x70\x38\x2a\xe8\x8b\x05\xcc\x95\ +\x82\xf6\x42\x93\x80\x39\x11\xb9\xb3\x7c\x0a\x58\x10\x4f\x13\x66\ +\x08\x78\x54\x09\xf6\x1d\xe6\x78\x26\x09\xbb\xc4\xd3\x3a\xba\x47\ +\x84\x91\xb0\x25\x17\xc9\x61\xe3\xe8\x68\x8f\xf8\xda\xc8\xe2\x08\ +\x78\x6c\x27\xc9\xac\x9b\xe4\x11\x4f\x2b\x69\xf9\x46\x09\x17\xd7\ +\xbb\x1c\xc2\xd2\xc9\x5d\x25\x93\x84\x83\x22\x40\x89\x66\xd6\xab\ +\x00\xec\x3a\xa1\x23\x99\xea\x88\x8d\x3a\xc3\xc3\x52\x8c\x90\xad\ +\x48\x31\x53\xff\x07\x26\x09\x0f\x87\x3b\xde\x84\xa9\x75\x69\x7a\ +\x5a\x8b\xb1\xef\x78\x66\x3d\xe2\x90\x68\x77\x09\xfd\xa5\xd7\x83\ +\x58\xe6\x7f\xae\x41\xc8\x5c\x12\x36\xe0\x15\xbf\x09\x55\x7d\x69\ +\x82\x9c\xc7\xa5\xcd\x9a\xd4\x83\x62\xec\x13\x6d\x50\x8b\xd7\x0d\ +\xf8\xf2\xc4\x58\x38\x81\x13\x78\x66\x23\x1f\x18\x9d\x7e\x55\x90\ +\x8b\xc8\x87\x49\x3d\xfd\xd6\x4d\xea\x4b\xd3\xd3\x45\xe8\xc3\xec\ +\x10\xd3\xdb\xf6\x8c\x2f\x8d\x70\xd1\x13\x9b\x0c\x5f\xba\x7a\xc2\ +\x76\xbf\x96\xc6\x31\x62\x6b\x32\xec\x99\x8c\x7c\x70\x3a\xe4\x17\ +\x2b\x43\x9b\x23\x62\x3b\x91\x0f\x66\x32\x80\xc9\xd9\x60\x86\x65\ +\x40\x18\xfa\xc5\x76\xf4\xb4\xc9\xc0\x07\x17\x24\xd4\xb5\xea\x9f\ +\xea\x69\x4a\x84\x26\x8c\x80\x47\x4f\xf5\x30\x9a\x6d\x89\x6a\xfa\ +\xb5\x21\xce\x73\x01\x8c\x5a\x5b\xc3\x7a\xfa\x6d\xd8\xd3\x97\xc6\ +\x58\xea\x84\x1e\x27\x34\xab\xa9\x87\xe5\x18\xfb\x62\x6b\x71\x0f\ +\xb3\xaa\x3a\x1c\x9a\xf7\x80\x4e\x93\xc5\x9c\x0f\xa3\xe3\xc5\x4a\ +\x58\xe9\x40\x5e\x0f\x32\xb6\x97\xf5\xe1\x98\x4c\xbf\xe4\xee\x50\ +\xf0\x03\x4d\x2e\xbb\x89\x1f\x66\xad\x2e\x9e\x8f\x36\xf5\x8c\x27\ +\x22\x66\x8b\xa9\x1f\x46\x53\xb8\x5e\xf0\x8f\xd1\xb2\xb6\x99\xfc\ +\x61\xb6\x53\xf6\x8a\xc9\xe5\x6f\x75\xc4\xe9\xd2\x28\x97\x99\x01\ +\x66\x67\x9d\x52\xc2\x07\xd2\xb8\x5c\xe2\x6b\xc6\x01\x32\x1e\x7b\ +\xd2\x8b\x34\x6b\x77\x61\xb8\xfa\x75\x21\x2e\x52\x03\xcc\x76\xc8\ +\x68\x74\xbd\x2a\xc6\x55\x72\x80\xd1\x3c\x2e\x74\xa0\x5e\x17\xe4\ +\x32\x3f\xc0\xac\xb2\x1e\x0e\x76\x9d\x8e\x3c\x5d\xcd\x56\xd5\x12\ +\xca\xd5\x9b\xee\x5a\x43\xec\xd8\xb1\xf7\x2e\x20\xa4\xba\x80\xa0\ +\x5c\x78\x91\x12\x99\xbf\x6b\xac\x1f\xd4\x6e\x40\x65\x97\xc1\x03\ +\x9f\x35\x4d\x10\xbd\xec\x39\x57\xf6\xa0\x7e\x35\x9b\xe6\x8b\x2b\ +\x9a\xf4\xae\x82\xd2\xf6\x5b\x1a\x05\x66\x1b\x2e\x8b\xd8\x8d\x1b\ +\x5d\x7e\xc3\x6d\x34\x94\xaf\x05\x49\xcd\xf1\x73\x5b\x72\x81\x04\ +\xcd\x13\xac\x56\x42\xec\xc8\xa2\xff\x82\x2c\xf6\xe9\x9d\x17\x14\ +\x56\x0b\xa8\x40\x9c\x36\x70\x96\x6b\x7b\xfa\xd2\x30\x4e\x65\x80\ +\xf6\xac\x05\x87\x44\xcd\x11\x65\xca\x2a\xeb\x0a\xa2\x26\x5a\x2d\ +\x89\xed\x19\x26\xda\x9e\xe0\x85\x40\x47\x03\x2a\x5a\xbd\xa0\x19\ +\xe1\x0c\x1d\xdf\x43\x9a\xa0\x0a\xd7\x23\xfe\x48\x92\xc9\x5b\x39\ +\x0f\xc8\x72\x0c\x96\x10\x42\xe9\xa3\x86\x05\xe6\x58\xee\x03\xe0\ +\x8e\x64\x04\xe9\x94\x24\x1f\x91\xda\x40\x5a\xef\x50\x03\xd0\x75\ +\xca\xd6\x38\x18\x42\x85\x88\x1e\x04\x63\xca\x29\x17\x48\xd4\x0e\ +\x51\x38\x31\x45\x21\xb5\x13\x51\xe8\x8b\xf1\x9d\xd7\x87\x72\x34\ +\x8b\xec\xc4\x86\x40\xfb\x50\x86\x4e\x8b\x1d\xcb\x08\x2a\x80\xeb\ +\x3b\x02\x35\xae\x0d\xa2\xa6\x35\xae\x5e\x41\x02\x83\x43\x63\x07\ +\x14\xfa\xb0\x98\xe9\x3f\x99\x23\x11\x27\x2c\xce\x90\x04\x52\xbf\ +\x60\x05\x53\x67\x04\xe0\xb8\x35\x2c\x49\x4e\xa4\xe4\x9e\xe4\x1d\ +\xe9\x74\x49\xe8\xea\xbf\xfe\xd0\xad\xa0\x22\x50\xff\xf5\x21\x2d\ +\xd2\x58\xbc\x61\x5d\x2b\x5b\xfb\x82\x21\x54\x98\x7e\xd3\x0f\xd5\ +\xab\x6b\xdf\x52\x92\x33\x0d\x06\x4c\xa1\x6f\xa7\x2a\xf3\xe9\xa6\ +\x68\x0d\xc1\x52\x75\x09\x97\x3e\x97\x5d\xaa\x8c\x48\xa1\xfe\x5c\ +\xd3\x50\x73\xed\xdb\x9a\xcb\x82\x50\xc7\x19\x69\x11\x39\x50\x01\ +\x20\xa4\xd8\x9f\x8e\xcf\x13\x4c\xeb\xea\xb0\x82\xa7\xae\x88\x8a\ +\x17\xdc\xda\xe5\xc5\xd4\x8d\x71\x14\x6f\x31\xb1\x9f\x3b\x98\x4f\ +\x64\x25\x0a\x58\x6f\xf5\x6a\xda\x31\x45\xe5\x6b\x89\x28\x54\x1e\ +\x4a\xbe\x90\x0e\x86\x1a\xc6\xee\x50\xa1\x02\xba\x7a\xb2\x18\x7a\ +\xa6\x63\xd3\x84\x4b\xc8\xf5\x3b\x93\x49\x90\xe7\x68\x63\x2e\x70\ +\x39\xb9\xf9\x9a\x47\x28\xa5\x56\xa8\xc2\x24\xe6\x4a\x4c\x5d\xb0\ +\x95\x8d\x02\x96\xa0\x2b\x3a\xbb\x2a\x20\xd3\xd1\x98\x42\x08\x69\ +\xbe\xac\x2f\xe2\xb4\xe1\xbb\xc0\x0d\x93\xea\x08\x2f\xa6\xa4\x58\ +\xe9\x48\xa1\x42\x0c\xdd\x35\xc6\x10\xe9\x68\x48\xa1\xe4\xb4\xd8\ +\xde\x04\xe5\x74\x64\xb7\xd4\x7c\x8e\x51\xb1\xa4\x14\x46\x00\xa1\ +\xd3\x19\xba\x82\x19\x12\x2f\x17\xd8\x10\x80\x68\xb1\x7d\x18\x32\ +\xbd\x94\x64\x23\x8a\x2c\xed\xa4\x1b\x41\x8f\x91\xaa\x2e\x14\xed\ +\x22\xe8\xec\x14\x3f\xf4\x02\xf6\x15\xb3\x23\xbe\x7d\x05\x14\x9c\ +\x5b\x08\x6d\xdb\xd2\x2e\x97\xc2\xb6\xed\x0b\x29\x7c\xeb\x42\x44\ +\x4e\x80\xd3\x5b\x60\x31\xfa\xc4\xd3\x64\x4e\x33\xae\x0d\x62\xe4\ +\xa8\x50\xc1\xbb\x4a\xad\x4f\x5d\x01\xa6\x50\xf3\xd9\xda\x68\xf0\ +\x40\x1b\xaf\x22\x47\x03\x46\x91\x0b\x8c\x0e\xc0\x47\x07\x74\x35\ +\x72\x38\x86\x9d\x65\x88\x11\xe2\x9b\x9f\x62\x5f\x85\x07\xd0\x64\ +\xbd\xb0\x79\xf6\x02\x7d\xc9\x4b\x83\x5a\x64\x95\xb8\x38\xd7\xc1\ +\x0a\x56\x88\x50\xbb\xd6\xbc\x1e\xea\x5e\x3b\xeb\xf7\x41\x45\xdc\ +\x05\x0a\xa8\x1d\xa0\x50\x09\xb7\x7a\xcd\x54\x4c\xfd\x02\x66\xea\ +\x96\xeb\x90\x8f\x94\x82\xd0\xdd\x1b\xc9\x32\xd2\xe2\x7a\x7f\x0c\ +\xa4\x70\xd3\x1c\xf4\xea\xa9\xaf\x29\x01\xec\x22\xa9\x06\x05\x87\ +\x70\x24\xe5\x9b\x47\xff\xd0\x93\xb1\x03\x15\x36\xea\x40\x31\xf7\ +\xd6\x8e\xa1\x04\xe7\xa0\x72\x4c\x02\xb3\x05\x15\x54\x56\x99\x8e\ +\xfd\x22\x57\x1b\x3a\x18\xca\x4d\xd5\xeb\xc2\x61\xbf\x6a\x87\x29\ +\x64\xd8\x17\xd7\x59\x80\x86\x1a\x92\x40\xe7\x86\x79\x27\x16\xb0\ +\x0c\x59\xc8\x82\x7e\x57\xf5\xec\xb5\xa8\x50\xff\x82\xcb\xaa\xcb\ +\xd5\xeb\x44\x54\x7d\x05\x35\xa4\x10\xcb\xdc\xe8\x4d\xb8\x91\xaa\ +\x15\x6b\x49\x16\x63\xe5\xd4\xb8\x09\x2c\x30\xd3\xda\x56\x60\x09\ +\x8a\x69\xb1\x7e\xc6\x6b\x8a\xea\x53\x7a\xcb\xf9\xa5\x51\x1d\xb0\ +\x95\xe0\x22\xc0\xc5\x1c\x7d\x34\x97\xec\x70\x85\x0c\x03\xe7\x73\ +\xf5\xb1\x6b\xbd\x94\x7d\xd1\xca\x49\xc0\xaf\x49\x03\xff\x91\x80\ +\x82\x4a\x2a\x53\x56\x70\x67\x5b\x74\x44\x3b\x9a\x12\x86\x32\x99\ +\xf2\x19\xde\x28\xaf\x76\x02\x11\x50\x2e\x6b\x63\x92\x1a\x6e\xfd\ +\x02\x8c\xd6\x27\x7a\x9b\x6e\x7a\xba\x48\x6b\xe1\xf9\xf4\x46\x0e\ +\xbf\x7d\xc2\x9a\x83\xfb\x3c\xc3\xcb\xaa\x27\xa9\xdb\x0a\x0e\x7e\ +\x29\x12\x7c\xd6\x7c\x19\x94\x50\x63\x40\xaf\x66\xab\xf2\xcd\xea\ +\x5d\xa3\xc2\x57\x2e\x6b\x60\xcb\xd2\x68\xb7\xbf\x4d\xd2\xed\xf5\ +\x34\x7f\xab\x7f\xe1\x3b\xc7\x0d\x49\xd1\x51\x7e\x70\x05\x09\xf3\ +\x89\x52\xdf\x4f\x5f\x68\x26\xc2\x25\x1a\x38\xed\x4c\x22\xf7\xca\ +\x9f\xe9\x1b\x03\xfa\xe6\x56\x02\x37\x4e\xeb\x2e\x7c\x7f\xc9\xfe\ +\x38\x0d\xa4\x1f\x25\x57\xfd\xa9\xe2\xcd\xc1\x51\x42\x5a\xcf\x88\ +\x52\xa3\xf4\x09\xd3\x60\x3a\x8e\x91\x27\x49\xa8\x51\xf6\xf9\x45\ +\x67\xf4\xc5\x70\x61\x0b\x84\xa9\x61\x2a\x77\xd6\xe3\x22\xe8\xaa\ +\x58\x59\x78\xb9\xc6\x63\x17\x28\x9b\x36\x70\xfa\xec\x74\x9d\x3a\ +\x53\x63\x01\x08\x14\x14\xa8\x62\x90\x1b\x4a\x1d\xa0\xb4\x48\x30\ +\x35\x1f\x5b\x44\x7d\x6b\x85\x27\x2f\xf3\x9a\x00\x82\x8a\x70\x29\ +\xe0\x48\x54\x13\x15\x84\x33\xe5\xcc\x86\xe3\xa8\x5c\x09\xba\xef\ +\x25\x12\x7d\x81\xa8\x20\x9e\x5e\xd1\x0c\x68\x4d\x3a\x64\x6a\xc3\ +\x30\x82\x64\xca\x00\x43\xfe\x08\x75\x58\x50\xa1\x9c\x17\x1f\x23\ +\x0b\xe0\xeb\xee\x48\x25\xa4\x27\x91\x05\xbf\x08\x0b\x83\x4c\x91\ +\x03\x4c\x78\x41\xa6\x5a\x46\x29\xa1\x5a\x46\x83\x71\x98\xe6\x89\ +\xa4\x48\xd4\x06\xd1\xb0\x9c\x72\x03\xe1\xc2\x60\x78\x1e\x3c\x3c\ +\xcf\xb4\xe6\xed\x86\xe7\x81\x7a\xd2\x2a\x2b\x0d\xa9\xda\xa0\x0a\ +\x18\x0d\x74\x02\xc0\x91\x56\x64\x3a\x7e\xc0\xbe\x64\x8a\x11\x07\ +\xe8\x2e\x95\x7b\x3e\x0d\xdd\x93\x2e\x55\xe6\x59\x48\x86\x53\x97\ +\x24\xe4\x86\x23\x08\x74\x18\xa8\xd2\xbc\xa1\x46\xd3\x6f\x23\x9d\ +\x93\x8b\x26\x20\x67\xc4\x21\xd2\x62\x41\x51\xea\x32\xde\xdd\xeb\ +\xe9\xe5\x91\x98\xf3\x66\xc4\xc1\x2d\x08\x81\x44\x5f\x20\x2a\x14\ +\x36\x49\xfb\x57\x0e\x38\x37\x5f\x14\xc3\xbc\xd0\x16\x6f\xe8\x0b\ +\x57\xb2\x71\x84\x94\xe3\x60\x8c\x2d\xa2\x50\x42\xaa\xe7\x21\x63\ +\x00\x09\x7a\x49\x51\xdf\x0d\xfd\xe0\x74\xc4\x14\xc4\x38\x2a\xa6\ +\x36\x62\xe6\x91\x1d\xa8\x2e\x09\x7c\xe1\x0f\xac\xed\x71\x5e\x6f\ +\xaa\x23\x48\x28\xaa\xd0\xd1\x06\x37\xa0\xa1\x1c\x49\x54\xf3\x2d\ +\x88\x51\x50\xad\x20\x05\x13\x54\x09\xba\x62\x21\x32\x7d\x21\xdc\ +\x00\xa9\x7c\x19\x1a\x4a\x96\xfa\x54\xa8\xb0\xa0\x8f\xde\x8c\xa5\ +\x90\x83\x17\x10\x57\x39\x33\x60\xfb\x28\x22\x54\x1b\x62\xea\x13\ +\xaa\x94\xef\xc0\x80\xf8\xd9\xfe\x0c\xda\x49\xe0\x1b\xf2\x09\xd7\ +\x95\x81\x18\x47\xf9\xd6\x43\xe2\x18\xc7\xb7\xc2\x15\x70\x68\x46\ +\x0f\xa0\x62\xe0\x17\x7c\x5e\x85\xe7\xc9\x20\x1c\x49\x07\x1f\xf7\ +\x11\x47\xcf\xe6\x92\x46\xc6\xab\x74\x07\x1c\x7a\xbb\xa8\x74\x7c\ +\x89\x8e\xcd\x65\xcd\x99\xd1\xae\x2a\x26\x0f\x5e\xd6\x54\xe2\xaa\ +\x47\x45\xfb\xf7\x92\x54\x6f\xdd\xa3\xa2\x01\x7c\x49\x06\xb0\x4e\ +\x21\x44\x49\xb5\x83\x14\xce\xf6\x85\xdd\x5c\x0a\xa1\xbe\x10\x56\ +\x82\x89\x00\xe7\x59\x84\x68\x29\xd9\x89\x28\x01\x25\x9d\x95\x89\ +\x84\xd8\xa1\x02\x6b\x5f\x97\x30\x3f\x60\xf2\x77\xad\xbc\x72\x76\ +\xe6\x19\x52\xb5\x33\xc5\x18\x6a\xa6\x45\x99\x7b\x86\x2a\xd8\x0a\ +\x56\xb8\xa0\x7e\x99\x7d\x86\xe2\x0a\xbe\xd6\x60\x10\xb8\x7e\x77\ +\x11\x76\x28\x71\x2d\xf2\xcf\xd0\xaf\xb1\x02\x15\x4e\x58\xf3\x0c\ +\x34\xa4\x6a\xc5\x5b\x05\x55\xc1\x79\x0e\x1a\x66\xa1\xd9\x5a\x95\ +\x05\x24\xb2\x94\x67\xa1\xe1\xf8\xdb\x45\xa5\x2c\x35\x92\x5b\x70\ +\x20\xee\xa2\x72\x46\xeb\xf4\x16\xf4\x70\x2e\x2a\xbe\x7f\x4c\x84\ +\xc0\x05\xb2\xc0\x47\xce\x85\x5e\x18\xbf\xb3\xb9\x09\xc0\x72\xea\ +\x5a\xff\x62\x74\x1f\x7a\x70\xb5\x6f\xd3\x30\x90\x1d\x2b\x18\x7a\ +\x34\x56\x60\xfa\xd5\x98\xb7\x39\x98\xc5\x4a\x84\x68\xf3\xc2\x5a\ +\x46\x2e\x51\x95\x2d\xbd\xee\xc8\x9b\x3f\xbc\x6e\xdd\x39\x7b\x48\ +\x21\x4c\x50\x98\x65\xf7\x78\xba\xac\xa4\x79\x98\x28\x99\xf0\x03\ +\xa8\x5c\x09\x26\xef\x26\xf9\x06\xc3\xa9\x66\x67\x48\x26\xe4\x66\ +\x60\x88\xb3\x70\x55\xfc\x3c\x62\x34\x02\x4e\x1c\x06\x87\x8f\xfe\ +\xd1\xbc\xdb\x1c\xc5\x3d\xc1\x50\xae\x15\x98\x40\x8a\x16\x3d\x14\ +\x4b\x1d\x27\xc4\x56\x6c\xb8\x66\xa4\x25\x93\x16\x26\x76\x80\xfe\ +\x89\x0d\x98\x60\xb1\x03\x8a\xb3\xc1\xa1\x87\x55\x58\xef\x18\x28\ +\x40\xec\x20\xc0\x31\xb2\x71\x46\xb4\x7b\x72\xb0\x8d\x9b\x41\x3e\ +\xce\x68\xb2\x23\x9b\x00\xaa\x36\x1f\x40\xc1\xe8\x81\x15\x4d\x0b\ +\xb1\x51\x74\xee\xa2\x04\x68\x0a\xd9\xd1\xb6\x10\x11\x04\x86\x9b\ +\x74\x59\xc2\xe9\x73\x90\x61\x14\x3d\x7d\x09\x15\xae\x8d\x2d\x69\ +\x95\x35\x74\x32\xfa\x69\x6e\x42\x30\x45\xa3\xc8\xce\x3e\x31\x80\ +\xbb\x74\xf9\x7a\xb1\x39\x1f\xc5\x15\x58\xff\xd2\xa1\x29\x11\x2f\ +\x80\x3d\x77\x06\x29\x0a\xab\x0d\xa6\xca\x85\x61\x81\x17\x78\xfd\ +\x6b\x32\x9c\x3f\x83\x14\xa9\xc2\x52\xe5\x84\x06\xa1\xa0\xdd\xcc\ +\x3e\x9f\x84\x8c\x33\x0e\x31\x2f\xb8\x4a\xb2\x46\x1b\xd8\x0a\x59\ +\x49\x02\x05\xd6\xfc\x32\xae\x55\x8e\x35\x8e\xc0\x58\xc1\x0a\xd4\ +\xb5\xd6\x13\xf9\x51\x11\x03\x73\x65\x44\x6a\xff\xf3\x34\x21\x25\ +\xd0\x7b\x26\xf6\xcd\x89\x38\x67\x98\x14\xc3\xf7\xc6\x70\x5e\xcd\ +\x56\xfa\x4d\xfe\xcf\xd5\x6c\xff\xa0\xfe\xf9\x3f\xa7\x5f\x0b\x56\ \ -\x00\x00\x05\xe1\ +\x00\x00\x06\xb7\ \x00\ -\x00\x17\x33\x78\x9c\xed\x58\x5b\x6f\xdb\x36\x14\x7e\xcf\xaf\xe0\ -\x14\x0c\x58\xb1\xea\x42\xdd\x2c\x29\xb6\xfb\xb0\xa2\x58\x81\xf5\ -\x65\xeb\xb6\xc7\x82\x96\x68\x9b\x8b\x24\x0a\x14\x15\xdb\xf9\xf5\ -\x3b\xa4\xee\xb6\x53\xa4\x18\x96\x3e\xb4\x02\x02\x45\xe7\x42\x9e\ -\xf3\x9d\xef\x1c\x32\x59\xbe\x39\x16\x39\x7a\xa0\xa2\x66\xbc\x5c\ -\x19\xd8\x72\x0c\x44\xcb\x94\x67\xac\xdc\xad\x8c\x3f\x3f\xbe\x33\ -\x23\x03\xd5\x92\x94\x19\xc9\x79\x49\x57\x46\xc9\x8d\x37\xeb\x9b\ -\xe5\x0f\xa6\x89\x7e\x11\x94\x48\x9a\xa1\x03\x93\x7b\xf4\xbe\xbc\ -\xaf\x53\x52\x51\xf4\xd3\x5e\xca\x2a\xb1\xed\xc3\xe1\x60\xb1\x4e\ -\x68\x71\xb1\xb3\x5f\x21\xd3\x5c\xdf\xdc\x2c\xeb\x87\xdd\x0d\x42\ -\x08\xf6\x2d\xeb\x24\x4b\x57\x46\xe7\x50\x35\x22\xd7\x86\x59\x6a\ -\xd3\x9c\x16\xb4\x94\xb5\x8d\x2d\x6c\x1b\xa3\x79\x3a\x9a\xa7\x6a\ -\x77\xf6\x40\x53\x5e\x14\xbc\xac\xb5\x67\x59\xdf\x4e\x8c\x45\xb6\ -\x1d\xac\x55\x34\x07\x4f\x1b\xe1\x38\x8e\x6d\xc7\xb5\x5d\xd7\x04\ -\x0b\xb3\x3e\x95\x92\x1c\xcd\xb9\x2b\xc4\x78\xcd\xd5\x75\x1c\xc7\ -\x06\xdd\x68\xf9\x3c\xab\xa4\x06\x40\x2b\xf8\x19\xcc\x7b\x81\x55\ -\xf3\x46\xa4\x74\x0b\x7e\xd4\x2a\xa9\xb4\xdf\x7e\x7c\x3b\x28\x4d\ -\xc7\xca\x64\x36\x59\xa6\xc7\x73\xb6\xeb\x0c\xe4\x92\x14\xb4\xae\ -\x48\x4a\x6b\xbb\x97\x6b\xff\x03\xcb\xe4\x7e\x65\x78\xbe\x85\x3d\ -\x78\x02\x2d\xdc\x53\xb6\xdb\xcb\x73\x29\xcb\x56\x06\x44\xef\xc6\ -\x51\xfb\x3d\x21\x07\x6e\x0d\xba\x85\x93\x41\xe3\x58\xb1\x6b\x61\ -\x24\x70\xe0\x2d\x5a\x9b\x3e\x85\x24\xe3\xa9\x8a\x09\x96\xa4\x05\ -\x23\x8d\xe4\x05\x54\x2d\x4d\x73\x52\xd7\x6c\xcb\x52\xf8\xe0\x65\ -\x95\x37\x3b\x56\x7e\x12\xb4\xe2\x42\x7e\x92\x9c\xe7\x56\x0f\xdf\ -\xb0\x17\x3d\x2a\xa5\x79\xcc\x2a\x00\x31\x5c\x5c\x55\x9e\x7a\xe5\ -\x1a\xb4\xcb\x8c\x6e\x6b\x65\xd5\x66\xa4\xbe\x20\xa5\x85\x81\x6c\ -\xad\x1d\x02\x54\xd1\x65\x0f\x8c\x1e\x46\xdb\x0d\xa9\x5b\xd4\x10\ -\xaa\xc8\x0e\x18\x96\x73\xb1\x32\x6e\xb7\xfa\xe9\x14\x1b\x2e\x32\ -\x2a\x7a\x55\xa8\x9f\x99\x8a\x43\x15\x98\x3c\xb5\x3d\xd5\xad\xdd\ -\xc7\xab\x56\x1d\xf4\xce\x75\x7d\xbd\x27\x19\x3f\xac\x0c\xf7\x5c\ -\xf9\xc8\x79\xb1\x32\x02\x2b\x88\xa3\xd8\xc1\xe7\xda\xf4\x08\x3b\ -\x42\xa5\x42\xd7\xc7\xde\x85\x52\x87\x13\xb8\x91\x87\xfd\xe8\x42\ -\xd9\x08\x01\x3d\x67\xe6\xe4\x44\x21\x27\xfd\xea\x97\xaf\xf7\xfc\ -\xb0\x13\x0a\x1b\x29\x1a\x7a\xee\xa9\x34\xe6\x66\xc3\x8f\xd7\xd5\ -\x40\x81\x46\x75\xb3\xd9\x94\x4c\x42\xc7\x54\xc7\xe9\xaa\x0d\xcb\ -\x68\x7d\xdd\xb1\x2e\x49\x65\xee\x72\xbe\x21\xf9\x75\x83\x03\x2b\ -\x01\x23\xb3\x23\x37\xf6\x86\x12\x9c\x5b\xf4\x4c\x5f\x38\x17\x69\ -\x77\x16\x10\xfb\x45\x19\x3a\xd5\xe9\x69\x55\x41\x8e\xac\x60\x8f\ -\x14\x80\xc1\x9a\x75\xc0\xac\x19\x2c\xad\x1b\x42\xf2\xa4\xba\xf6\ -\x78\x52\x32\xa3\x17\x2a\x3c\x95\xc0\x8d\xe3\xc5\x20\xe4\x82\x41\ -\x33\x4c\xc2\xe9\x45\xa7\xa9\x48\xf5\x38\x8c\xe8\xa3\xa6\x97\x26\ -\xdf\xe2\x5c\x77\x9a\xea\x3a\xd6\xdb\x97\xb4\xd7\xf2\x82\x4a\x92\ -\x11\x49\xc6\x1e\xe8\x25\x10\x9b\xd3\x67\x06\xe3\x32\xf9\xfd\xed\ -\xbb\x75\xb7\xd1\x32\x4d\x93\xbf\xb9\xb8\xef\xf7\x45\x48\x19\x90\ -\x0d\x6f\x00\x69\x63\x3d\x88\x97\x59\x9a\xc0\x80\x83\xc6\x5f\xb3\ -\x02\x98\xad\x66\xe3\xcf\x30\xd0\x96\xf6\xa8\x98\x19\x2b\xb0\xc6\ -\x45\xdb\x65\x05\x6d\x27\xe5\xd5\xe3\x22\x4b\x0b\xa6\x9c\xec\x3f\ -\x24\xcb\xf3\xf7\x6a\x93\x2e\xe3\xc9\xa2\x4c\xe6\x74\x14\x2e\xed\ -\x2e\xfa\x2e\x37\x7b\x92\xdc\xd2\xee\xb3\xd7\x5f\xbb\x11\x95\x59\ -\x53\x0c\x85\xce\xc9\x86\x02\x43\x7f\x53\x4a\x74\xa1\xdd\x09\xde\ -\x54\x05\xcf\x68\xe7\x3e\xa0\x49\x53\x39\x94\x4c\x9e\x72\xd0\xeb\ -\x71\x92\xdc\x3a\xfa\xb9\xcb\x58\x5d\x81\x07\x4c\xfd\x9c\x95\xf4\ -\x8e\xc3\xb8\xdd\xe6\xfc\x90\x3c\xb0\x9a\x6d\x72\x7a\xa7\xdf\x2c\ -\x87\xcc\x07\xd1\x16\xd2\x4f\x6e\xb7\xd1\x36\x4e\x1d\xfd\x61\x76\ -\x63\x26\xc1\xed\xa7\x68\x72\x9a\x94\xbc\x7c\x84\x01\x75\x57\x4b\ -\xc1\xef\x69\xd2\x0d\xb6\xee\xb3\xed\xa6\xc4\x6d\x8f\x04\xcf\xf7\ -\x7b\xb9\x0a\x02\x12\x4a\x36\x8d\x94\x53\xd9\x3f\x9c\x95\x09\xe0\ -\x4f\x45\x2f\xd5\x1f\x39\x34\x86\x4c\x06\xef\x8c\xc0\x40\x13\x02\ -\xd2\x81\xdd\xe9\x54\xca\xb7\xdb\x9a\xca\xc4\xe9\x65\x63\xc4\x05\ -\x11\xf7\x54\xb4\x0e\xb4\x24\x90\xa0\xb9\x21\xe9\xbd\x02\xb4\xcc\ -\x12\x92\xc2\x58\x69\x72\xb8\x82\xcc\x1a\x4a\xc1\xea\xc1\x80\x1b\ -\x84\xfd\xd1\x17\x58\xea\x60\x76\x46\xc5\x70\xfc\x5d\x68\xa0\xad\ -\x4c\x6c\x79\xae\x1b\x86\xb1\x3f\x48\xf5\xac\x6e\x51\x89\xdd\x41\ -\x2a\xc0\xd8\xb7\x22\x2f\x8c\x70\xe8\x8d\x52\x30\xf6\xac\x28\x76\ -\xe3\xc0\x0f\x07\x2e\x2e\x2b\x22\xf7\x67\x35\xd7\x25\x9b\x60\x32\ -\x94\x7f\x56\x8e\xd0\xf2\xda\x4e\x8e\xff\xcf\x72\x0c\xd0\x0f\x79\ -\xa8\x49\x80\xe0\x1e\xe2\x06\xe1\x6b\xdc\xc2\xe4\x2c\xd0\x1e\x79\ -\x91\xe5\xa3\xbf\xd4\x2b\xd0\x2c\x01\x91\xa9\x65\x8f\xb3\x62\xa8\ -\x7c\xbd\x08\x8f\xb3\x69\x3c\x6d\x78\x09\xf1\x4b\x2e\x4c\x38\x77\ -\x1e\x88\x6c\x04\x55\xf3\xed\xbf\x23\x85\x2d\x3f\xf4\x17\xe1\x22\ -\xc2\x2f\x8e\xd4\x07\x84\x3d\x4b\x91\x26\x5c\xbc\x0e\x3b\x60\x30\ -\xa0\x14\xb8\x56\x1c\xbb\x41\xec\x5d\xc3\x26\xfe\x36\xb0\x01\x16\ -\x75\x1d\x35\xc5\x66\x8f\x7c\xcf\x0a\x87\xbb\xc8\x14\x18\xd7\xfb\ -\x36\x80\xf9\x80\x9c\xd7\xae\xda\x1f\x9e\x08\xfd\x8a\x7c\x17\x60\ -\x52\xf8\x5c\xc3\x24\xf8\x72\x4c\x24\x3d\x0e\xc7\x0c\x1c\xba\x89\ -\xfe\xeb\x00\x16\x84\x03\x95\x8a\x87\x71\x76\xf6\x78\x71\xb8\xa8\ -\xe9\xdf\x21\x74\x38\x9a\xf3\x3b\x2d\x39\xe8\x59\x39\x13\xd5\x70\ -\xef\x49\xb0\x6b\x45\x1a\x4f\x1c\x57\xc7\x3b\x05\x50\x77\xd7\x4a\ -\x9c\x1f\x5b\xb3\x2d\x29\x58\x7e\x4a\x6a\x52\xd6\x26\xec\xc8\xb6\ -\x77\x39\x95\x80\x98\xd9\x5d\x53\x12\x07\x1c\x0f\x70\x65\x9e\x09\ -\xda\x83\xac\x2b\xd5\xd9\x41\xd6\x15\x72\x8a\x6c\x5f\xc5\xee\xba\ -\xe3\x4e\x27\x39\x0e\x2d\x98\xc2\x8b\xc5\x6c\x90\xbb\x91\xe5\xc0\ -\x64\x0e\xf1\x0c\x65\x85\x15\x9c\x1d\x23\xf4\x52\x40\xd8\xea\x8a\ -\x02\x7f\xbf\xa4\x24\xa7\x3f\x39\x6a\xa6\x47\x6e\x14\x78\x30\x0e\ -\x31\xcc\x43\x2f\x88\x5f\x19\xeb\xa5\x84\xe0\xcb\xf1\xce\x32\x5c\ -\xb3\x04\x57\xa0\x2a\x5c\x8c\x51\xab\xb7\x52\x0e\xb0\x57\x30\x91\ -\x5f\x0d\xf6\x89\x70\xcf\x0a\xa6\x6a\x11\x59\x51\x14\x85\x4e\x80\ -\xdd\xb3\x52\xc0\xe0\x0e\x9e\x2a\xc6\x53\x00\xae\xb1\xeb\x2d\x6d\ -\x1d\xe5\x1a\xde\x00\xcc\x77\x3e\x7d\x86\x4f\xd8\xb7\x16\x2e\x5e\ -\x04\xde\x55\x3e\x99\xc1\x4b\x32\xca\x8c\x9f\xc5\xa9\xcb\x90\xbf\ -\x73\xea\x6b\x71\xca\xb7\x7c\xdf\xf7\x9c\x2f\xa1\x94\xf3\xa2\x94\ -\x0a\xe7\x94\xba\x88\xf7\xab\x31\xea\x3b\x9f\x9e\xcb\xa7\xcf\x1f\ -\x79\xa6\xf3\xc2\x43\x2a\x34\xfd\xe7\x70\xea\x6b\x9c\x7c\x97\x9c\ -\x5a\xda\xbb\xf5\xcd\x52\xfd\xe3\x62\x7d\xf3\x2f\x01\x81\xea\x10\ -\ +\x00\x26\x68\x78\x9c\xed\x59\x49\x8f\xe3\x44\x14\xbe\xf7\xaf\x28\ +\xdc\x17\x10\x71\xb9\x16\x6f\xe5\x4e\x32\x87\x19\x21\x90\xe0\x02\ +\x03\x1c\x47\x8e\x5d\x49\x4c\xdb\xae\x60\x3b\x9d\x84\x5f\xcf\x2b\ +\x6f\x71\x36\xe8\xa1\x33\x91\x90\xe2\x56\xab\xed\xf7\x5e\x6d\xdf\ +\xf7\x36\xbb\xc7\xef\xb6\x59\x8a\x5e\x64\x51\x26\x2a\x9f\x18\x14\ +\x13\x03\xc9\x3c\x52\x71\x92\x2f\x26\xc6\xaf\x1f\xbf\x33\x7d\x03\ +\x95\x55\x98\xc7\x61\xaa\x72\x39\x31\x72\x65\xbc\x9b\x3e\x8c\xbf\ +\x32\x4d\xf4\xbe\x90\x61\x25\x63\xb4\x49\xaa\x25\xfa\x21\x7f\x2e\ +\xa3\x70\x25\xd1\xd7\xcb\xaa\x5a\x05\x96\xb5\xd9\x6c\x70\xd2\x0a\ +\xb1\x2a\x16\xd6\x37\xc8\x34\xa7\x0f\x0f\xe3\xf2\x65\xf1\x80\x10\ +\x82\x75\xf3\x32\x88\xa3\x89\xd1\x0e\x58\xad\x8b\xb4\x36\x8c\x23\ +\x4b\xa6\x32\x93\x79\x55\x5a\x14\x53\xcb\xd8\x9b\x47\x7b\xf3\x48\ +\xaf\x9e\xbc\xc8\x48\x65\x99\xca\xcb\x7a\x64\x5e\x3e\x0e\x8c\x8b\ +\x78\xde\x5b\xeb\xdd\x6c\x78\x6d\x44\x85\x10\x16\x61\x16\x63\x26\ +\x58\x98\xe5\x2e\xaf\xc2\xad\x79\x38\x14\xf6\x78\x6e\x28\x23\x84\ +\x58\xa0\xdb\x5b\xbe\xce\x2a\x28\x01\xd0\x15\xfc\xf6\xe6\x9d\x00\ +\x97\x6a\x5d\x44\x72\x0e\xe3\x24\xce\x65\x65\x7d\xf8\xf8\xa1\x57\ +\x9a\x04\xc7\x55\x3c\x98\xa6\xc3\xf3\x60\xd5\x03\x90\xf3\x30\x93\ +\xe5\x2a\x8c\x64\x69\x75\xf2\x7a\xfc\x26\x89\xab\xe5\xc4\xe0\x36\ +\xa6\x1c\x2e\xa7\x16\x2e\x65\xb2\x58\x56\xc7\xd2\x24\x9e\x18\xb0\ +\x7b\x26\xfc\xe6\x79\xe0\x1c\xb4\x31\x68\x27\x0e\x7a\x0d\xc1\x82\ +\x61\x8a\x0a\xea\x70\xaf\xb1\xe9\x8e\x10\xc4\x2a\xd2\x7b\x82\x29\ +\x65\x96\x84\xeb\x4a\x65\xc0\x5a\x14\xa5\x61\x59\x26\xf3\x24\x82\ +\x07\x95\xaf\xd2\xf5\x22\xc9\x3f\x95\xc9\x22\xff\x54\x29\x95\xe2\ +\x0e\xbc\x7e\x25\xb9\x5d\xa9\xa2\x32\xb7\xf1\x0a\x20\x74\xbd\xb3\ +\xca\x5d\xa7\x9c\x82\x76\x1c\xcb\x79\xa9\xad\x9a\xf3\xe8\x27\x38\ +\x90\x67\x20\xab\xd6\xf6\xdb\xd3\x7b\x8b\x5f\x12\xb9\xd9\xdb\xce\ +\xc2\xb2\xc1\x0c\xa1\x55\xb8\x00\xff\x4a\x55\x31\x31\x1e\xe7\xf5\ +\xd5\x2a\x66\xaa\x88\x65\xd1\xa9\xdc\xfa\x3a\x50\x29\xe0\x20\xa9\ +\x76\x4d\x44\xb5\x73\x77\xfb\xd5\xb3\xf6\x7a\x72\x5e\x5f\x2e\xc3\ +\x58\x6d\x26\x06\x3b\x56\xfe\xa5\x54\x36\x31\x1c\xec\x08\x5f\x10\ +\x7a\xac\x8d\xb6\x13\xc3\x64\x2e\xa6\x94\xfb\xcc\x39\xd1\xc2\x7a\ +\x1c\x36\x24\x84\x2d\xfc\x13\xe5\xba\x28\x20\xe4\xcc\x34\xdc\x49\ +\x38\x54\xfd\xa7\x9b\xbf\x5c\xaa\xcd\xa2\xd0\xe0\x54\xc5\x5a\x1e\ +\x8f\xd4\x1a\x73\x36\x53\xdb\xf3\x6a\xf0\x80\xb5\x0e\x66\x73\x9d\ +\x27\x15\x04\xcc\x6a\x3b\x9c\x75\x9d\xc4\xb2\x3c\x3f\x70\x93\xe4\ +\x80\x81\xd9\xba\x2e\xe5\x3d\xc4\xc7\x16\x9d\x1f\x7b\xe4\xe4\x54\ +\xad\x05\x6c\xed\x04\xe6\x56\xb5\xbb\xac\xca\xc2\x6d\x92\x25\x7f\ +\x49\x38\xf7\x09\xd2\x65\x1e\xae\xcc\x45\xaa\x66\x61\xda\xee\x7e\ +\x5a\x5b\x8c\x0f\x60\x69\x06\x21\x54\xed\x74\xd0\x6e\x77\x5a\x66\ +\x74\x42\x8d\xa7\x16\x70\xcf\x75\x7a\xa1\x2a\x12\x88\x85\xc1\x7e\ +\x3b\xd1\x6e\x28\xd2\x21\x0e\x19\x7a\x5b\xfb\x57\xed\x7d\xde\xb1\ +\x6e\x37\xd4\xb5\x6e\x6f\x9d\xfa\x7d\x2d\xcf\x64\x15\xc6\x61\x15\ +\xee\x83\xa0\x93\x30\x21\x48\x77\x32\xc8\x96\xc1\xcf\x1f\xbe\x9b\ +\xb6\x0b\x8d\xa3\x28\xf8\x5d\x15\xcf\xdd\xba\x08\x69\x83\x70\xa6\ +\xd6\x40\x85\x31\xed\xc5\xe3\x38\x0a\x20\xbf\x41\xdc\x4f\x93\x0c\ +\x5c\x5b\xa7\xc6\x6f\x21\x9f\x8d\xad\xbd\xe2\xc0\x58\x83\xb5\x9f\ +\xb4\x99\xb6\x90\x4d\xa2\x3c\x5b\x2d\xe2\x28\x4b\xf4\x20\xeb\x97\ +\x2a\x49\xd3\x1f\xf4\x22\xed\x89\x07\x93\x26\x55\x2a\xf7\xc2\xb1\ +\xd5\xee\xbe\x3d\x9b\x35\x38\xdc\xd8\xea\x4e\x5f\x3f\x2d\xf6\xa8\ +\x1c\x04\x45\x4f\x74\x1a\xce\x24\x38\xc1\x8f\x5a\x89\x4e\xb4\x8b\ +\x42\xad\x57\x99\x8a\x65\x3b\xbc\x47\x53\x46\x55\x4f\x59\xb5\x4b\ +\x41\x3f\x87\xdd\x07\x8f\x73\xa2\x7f\x9e\xf4\x83\xd9\xa6\x89\x80\ +\x36\x8f\xc5\x3a\x85\x74\xf7\x22\x73\x15\xc7\x4f\x65\x55\xa8\x67\ +\x19\x3c\x12\x62\xfb\x84\xb4\x8f\x4d\xb4\x04\xfd\x63\x9a\xe4\x12\ +\xb6\x11\x94\x7f\xae\xc3\x42\x0e\xa5\x7f\xa8\x24\x0f\x00\x37\x59\ +\x74\xd2\xfa\x21\x05\x8f\xaf\x02\xbb\x93\xc5\x21\x64\xa2\xa2\x08\ +\x77\x41\x0e\xe5\x7f\x28\x55\xf3\x79\x29\xab\xfd\x4a\xdd\x56\x09\ +\xe6\xed\x75\xe0\xe8\xfa\xb8\x5c\x08\xda\x0b\xcf\x56\x24\x7d\x9d\ +\xaf\x4a\xfa\x3a\x88\x0a\xf0\x6f\x81\x6d\x8f\x0b\xc2\x5d\x69\x52\ +\xb7\x57\x14\x07\x66\x85\xce\x79\x98\x43\x65\x72\x21\xe7\x75\x0e\ +\x30\x5e\x85\xd5\xf2\x1c\xfa\x83\x53\x06\x8f\x94\x02\xb6\xd1\x21\ +\xb2\x0e\xf6\x9b\x98\x12\xc7\x10\xcf\xd6\x55\x75\x2d\x80\x7b\xde\ +\xfb\x73\xe8\x98\x44\xac\x41\x84\xf3\x51\x07\x0e\x47\x2e\xb6\x47\ +\x66\xa7\x40\x1c\xeb\xf6\x46\x08\x6f\x20\xab\x2d\x6c\xcc\xea\x6d\ +\x23\xa7\xe1\x07\x44\xed\x1d\x47\xad\xce\xed\xc7\xd8\x47\xb3\x2e\ +\x91\x8f\x9d\x5a\x71\xc0\xa9\x06\xd1\x26\x9e\x30\xb9\x39\x50\xf4\ +\x05\x45\xe5\x00\x4c\xa5\x0a\x13\x4a\xcb\x4b\x58\xad\x0b\xa9\x89\ +\xf9\x3c\x0a\x88\xcf\x63\x2f\x3e\xa4\x00\xf6\x66\x43\x35\x20\xc2\ +\xb9\x39\x05\x3f\x21\x0d\x8a\x70\x39\x25\x74\x04\xa5\xd4\x71\x1c\ +\x0a\x68\x71\x6c\xfb\x1e\x75\xa9\x18\x41\xed\xf5\x19\x75\xb9\x00\ +\x9c\x05\xe5\x9e\x4d\x47\x0c\xdc\xcf\x01\x80\x11\x25\xd8\x73\x5d\ +\x5f\x88\x11\x85\x23\x50\xdb\x23\x0e\xa2\xc0\x23\x15\xcc\x15\x23\ +\x1f\x7b\xc2\x25\x8c\x50\x44\x3d\x0c\x0b\xd8\x9e\x3f\xb2\xb1\x20\ +\x0e\x78\x2e\x47\x7a\x12\x6a\x0b\x67\x44\x30\xf5\x18\xb1\xa9\x80\ +\x55\xd9\xc8\xe4\x98\x5d\xa0\xe4\x0b\x11\x22\x49\x1c\xcd\x8f\x62\ +\xa2\xaf\x33\x6c\xb5\xfd\x7c\x4a\x2e\x00\x0d\x27\x1b\x78\xb9\xc0\ +\xee\x88\x33\x44\x19\xf6\x47\x4c\x34\x31\xe8\x21\x2a\xc0\x88\x39\ +\xd8\x45\xcc\x6e\x1c\x94\x8f\x18\xe9\x3c\x9d\xf9\x60\x4c\xfd\x3e\ +\x34\x1c\x30\xa6\xee\xde\x99\xf9\x59\xe4\xfe\xdf\xb8\x65\x08\x1a\ +\x4a\xdf\x13\xbe\x0b\xbe\xc2\xc0\x91\xc0\x8f\x3c\x0e\xce\xc8\x3c\ +\xc6\x6d\xe2\x3a\x75\x26\x00\x0b\xdb\x81\x6c\xc2\x5c\xdf\xf6\x1c\ +\x5f\xbb\x11\x25\x0e\xb8\xa8\x46\x11\x46\x52\x48\x05\x2e\x66\xd0\ +\x45\xb2\x3a\xa5\x40\xb6\x73\x3d\x2d\xf2\x6d\x5b\x50\x18\x0a\xe4\ +\xb8\xc2\x73\x6d\x3d\x12\x72\x30\x77\x1c\xaf\x5b\x83\xee\x57\x00\ +\xb0\x7d\x4c\x28\xe1\xa4\x4e\x2d\xc2\xa6\x60\x27\x2e\xe4\x10\xff\ +\x2a\xc0\xd7\x2d\xb9\xae\x89\xfa\x7a\x8a\x93\x72\x05\x45\x17\xde\ +\x9b\x34\x84\x4f\x0a\x5e\x58\xe6\xa9\xda\x04\x2f\x49\x99\xcc\x52\ +\xf9\x54\xff\x4d\x52\x8d\x62\x27\x3a\x93\x82\x08\x99\x33\x76\xc8\ +\x5c\x97\x19\x6d\xfb\x4b\xa6\xa0\x7f\x2a\xb3\xf4\x29\x0b\x8b\x67\ +\x59\x34\x03\x64\x1e\xc2\xe6\xcd\x59\x18\x3d\xeb\x7e\x23\x8f\x83\ +\x30\x82\xae\x7b\x9d\xc2\x0b\xfa\x61\x58\x91\x11\x41\xbf\xa1\x3e\ +\xb0\x4e\xb8\x80\x86\xcf\x7d\x35\x13\x3d\xf8\x7d\x5b\x09\x7d\x8e\ +\xee\xc4\xa0\xa3\x8f\xa2\x3b\x51\xff\x9d\xa8\x0c\xf5\xc9\x41\x17\ +\x10\xbb\xc9\x68\xd1\xa0\x03\x20\x97\xee\x4f\x28\xe5\x9e\xc7\x4c\ +\x62\xb2\x7b\x80\xdd\x96\xb7\x7d\xe9\x79\x13\x6f\xf4\xce\xdb\x2d\ +\x12\xe3\x80\x37\x68\x32\xd0\xfb\xba\x01\xa9\x6f\x4f\x6e\x2e\x31\ +\x75\x9d\x9e\xeb\xce\xd4\xab\x23\xcc\x6b\x12\xe3\x5b\x33\xe3\x75\ +\x5e\x5e\xee\xbc\xbd\xbe\xa2\x75\x9c\xbc\x8d\xb7\xeb\xf4\xea\x77\ +\xde\xfe\x25\x33\xf6\xcd\xe2\xe0\x7d\xec\x7b\x74\xca\x0a\xb4\x8e\ +\xaf\x6f\xe2\xef\xad\xe3\x97\x0b\xb4\xee\xc3\x0e\x10\x06\x2f\x65\ +\x10\x63\x64\xf0\xfd\xe7\xc2\xfd\x69\x8c\xf9\x36\xb9\xc7\xd7\x4d\ +\xf2\x22\xc1\x6d\x5e\x7c\x23\x5d\xf7\x77\xe8\xdb\x10\xc6\x28\xbe\ +\x4e\x7c\xdd\x2b\xd8\x8d\x08\x73\xaf\x15\x61\xf7\x94\x78\x13\xc2\ +\x38\x7b\x33\x53\xf7\x97\xb1\xdb\x14\x2f\xf7\xcd\x4c\xbd\xfe\x7b\ +\xe3\x9d\xa9\xab\x7c\xe0\xd0\xff\x18\x69\x3f\x70\xd4\xb7\x27\x37\ +\x17\x5e\xb8\x3e\x93\xa7\xb1\xb5\x98\x3e\x8c\xf5\xbf\xfb\xa7\x0f\ +\x7f\x03\xa5\x38\xeb\x75\ " qt_resource_name = b"\ @@ -23618,124 +16648,44 @@ \x04\x0a\xbe\x87\ \x00\x52\ \x00\x4f\x00\x49\x00\x5f\x00\x70\x00\x6f\x00\x69\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x0f\ -\x08\x15\x58\x47\ -\x00\x4c\ -\x00\x43\x00\x53\x00\x5f\x00\x70\x00\x6f\x00\x69\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x21\ \x03\xbc\xd8\xde\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \ -\x00\x36\ -\x03\xbd\xf7\x87\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x61\x00\x74\x00\x75\x00\x72\ -\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x2e\ -\x07\x8b\xc8\x87\ +\x09\xbb\x8e\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6e\x00\x65\x00\x77\x00\x5f\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2d\ -\x09\x19\xff\xe7\ +\x00\x5f\x00\x70\x00\x63\x00\x61\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x25\ +\x08\xe6\x23\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6f\x00\x73\x00\x6d\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x04\x8b\x22\x27\ +\x08\x31\xe6\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x61\x00\x6e\x00\x64\x00\x6f\x00\x6d\x00\x5f\x00\x66\x00\x6f\x00\x72\x00\x65\x00\x73\x00\x74\x00\x2e\x00\x73\ +\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x2e\x00\x73\ \x00\x76\x00\x67\ -\x00\x3b\ -\x08\x9a\x1a\xc7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x5f\x00\x63\x00\x6f\x00\x6d\x00\x62\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x69\x00\x6f\ -\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x2e\ -\x07\xf0\x2f\xe7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x66\x00\x69\x00\x74\x00\x5f\x00\x70\x00\x6c\x00\x6f\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x34\ -\x0b\x25\x0c\xa7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x30\ -\x0b\x07\xa0\xc7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x6f\x00\x64\x00\x69\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x42\ -\x03\xe4\x77\xa7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x75\x00\x6c\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\ -\x00\x72\x00\x61\x00\x6c\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x74\x00\x61\x00\x6e\x00\x63\x00\x65\x00\x73\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x32\ -\x01\xae\xc7\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x6f\x00\x73\x00\x74\x00\x5f\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x35\ -\x02\x01\x3b\xe7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x70\x00\x6c\x00\x6f\x00\x74\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2f\ -\x0d\x85\xeb\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x67\x00\x6f\x00\x65\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3c\ -\x04\x97\x38\x67\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x4c\x00\x43\x00\x53\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\x00\x6f\x00\x6c\x00\x64\x00\x5f\x00\x52\ -\x00\x4f\x00\x49\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3b\ -\x05\x89\xb6\xe7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x76\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\ -\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3a\ -\x0a\x7e\x58\x47\ +\x08\x42\x8e\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ -\x00\x73\x00\x69\x00\x65\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x34\ -\x00\xc8\xd6\x67\ +\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x31\ +\x07\x3d\x00\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\x00\x6f\x00\x6c\x00\x64\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x6d\x00\x6f\x00\x73\x00\x61\x00\x69\x00\x63\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\ \x00\x35\ \x01\x5a\xa1\xc7\ \x00\x73\ @@ -23743,382 +16693,276 @@ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \x00\x5f\x00\x7a\x00\x6f\x00\x6f\x00\x6d\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\ \x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x36\ -\x07\x83\x81\x87\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\ -\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x31\ -\x0d\x36\x6d\xe7\ +\x0b\x10\xd2\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x74\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x72\x00\x65\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \ -\x00\x3c\ -\x03\xd6\xc9\xc7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x7a\x00\x6f\x00\x6e\x00\x61\x00\x6c\x00\x5f\x00\x73\x00\x74\x00\x61\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\ -\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x37\ -\x06\x63\x81\x07\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x74\x00\x61\x00\x6e\ -\x00\x63\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x32\ -\x03\xcc\xbb\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x70\x00\x6c\x00\x69\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x34\ -\x0b\xd0\x68\xc7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x74\x00\x72\x00\x61\x00\x69\x00\x6e\x00\x69\x00\x6e\x00\x67\x00\x5f\x00\x69\x00\x6e\x00\x70\x00\x75\x00\x74\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x3b\ -\x0a\x87\x1d\x47\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x72\x00\x65\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x70\ -\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x0c\xdd\xa2\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x2d\ -\x08\x78\xe0\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x5f\x00\x75\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3a\ -\x0a\x7a\x16\x07\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x61\x00\x74\x00\x75\x00\x72\x00\x65\ -\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2a\ -\x01\x2c\xbe\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x68\x00\x6f\x00\x6d\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x3b\ \x00\xf7\x85\xe7\ \x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\ -\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x34\ -\x0b\x2d\x6f\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x6e\x00\x74\x00\x69\x00\x6e\x00\x65\x00\x6c\x00\x33\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x35\ -\x0d\x30\x6f\x07\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x5f\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x69\x00\x6e\x00\x67\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3c\ -\x09\x49\x98\x67\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x4c\x00\x43\x00\x53\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\x00\x6f\x00\x6c\x00\x64\x00\x5f\x00\x73\ -\x00\x65\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x0f\ -\x08\x44\x34\x67\ -\x00\x66\ -\x00\x72\x00\x6f\x00\x6d\x00\x47\x00\x49\x00\x53\x00\x74\x00\x6f\x00\x52\x00\x53\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x31\ -\x08\xcd\x14\x07\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x7a\x00\x6f\x00\x6f\x00\x6d\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x52\x00\x4f\x00\x49\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ -\x00\x3a\ -\x0b\xe7\xf2\x67\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x72\x00\x6f\x00\x73\x00\x73\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\ -\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2b\ -\x0b\x55\x18\xa7\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x74\x00\x63\x00\x68\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3a\ -\x0c\x29\x56\xc7\ +\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ +\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ +\x00\x5f\x00\x72\x00\x65\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\ +\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x02\x74\x17\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x76\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\ -\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x31\ -\x0b\x06\xec\x67\ +\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x6d\x00\x75\x00\x6c\x00\x74\x00\x69\x00\x70\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x2e\ +\x00\xfe\x9b\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x6f\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ -\x00\x34\ -\x0b\x2c\xaf\x27\ +\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x64\x00\x69\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2c\ +\x0a\x26\x7c\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x6e\x00\x74\x00\x69\x00\x6e\x00\x65\x00\x6c\x00\x31\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x72\x00\x65\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x0a\x12\x1b\xa7\ +\x08\x3e\x26\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x61\x00\x63\x00\x63\x00\x75\x00\x72\x00\x61\x00\x63\x00\x79\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x5f\x00\x75\x00\x6e\x00\x64\x00\x6f\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x2e\x00\x73\ \x00\x76\x00\x67\ -\x00\x3c\ -\x06\x49\x1a\x87\ +\x00\x2e\ +\x07\x8b\xc8\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ -\x00\x65\x00\x72\x00\x6f\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x32\ -\x0c\xae\xea\xe7\ +\x00\x5f\x00\x6e\x00\x65\x00\x77\x00\x5f\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x34\ +\x0f\xca\xfb\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x2b\ -\x0b\xec\x1f\x07\ +\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x6c\x00\x6f\x00\x67\x00\x69\x00\x6e\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x45\ +\x03\x19\xe7\x47\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x63\x00\x6b\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x32\ -\x0c\xc2\x5d\xe7\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x63\x00\x75\x00\x6d\x00\x75\x00\x6c\x00\x61\x00\x74\ +\x00\x69\x00\x76\x00\x65\x00\x5f\x00\x73\x00\x74\x00\x72\x00\x65\x00\x74\x00\x63\x00\x68\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3d\ +\x0a\x2f\xdc\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x39\ -\x04\xc8\xa7\xe7\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ +\x00\x64\x00\x69\x00\x6c\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3d\ +\x0b\x0c\xe5\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x73\x00\x68\x00\x6f\x00\x77\x00\x5f\x00\x72\x00\x61\ -\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2c\ -\x0a\x73\xf2\x07\ +\x00\x5f\x00\x69\x00\x6d\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\ +\x00\x5f\x00\x6c\x00\x69\x00\x62\x00\x72\x00\x61\x00\x72\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x09\ +\x0f\xa8\x87\xa7\ +\x00\x67\ +\x00\x75\x00\x69\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x33\ +\x0d\x1b\x39\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x32\ -\x0b\x90\x78\x87\ +\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x0f\ +\x08\x44\x34\x67\ +\x00\x66\ +\x00\x72\x00\x6f\x00\x6d\x00\x47\x00\x49\x00\x53\x00\x74\x00\x6f\x00\x52\x00\x53\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x30\ +\x02\x41\xc2\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ +\x00\x5f\x00\x73\x00\x65\x00\x6c\x00\x65\x00\x63\x00\x74\x00\x5f\x00\x61\x00\x6c\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x0d\xca\x79\x07\ +\x02\x83\x9e\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x61\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\x00\x2e\x00\x73\ +\x00\x5f\x00\x73\x00\x65\x00\x74\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ \x00\x76\x00\x67\ \x00\x3c\ -\x0f\xbb\x15\x07\ +\x06\x49\x1a\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x5f\ -\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x29\ -\x00\x30\x94\xe7\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ +\x00\x65\x00\x72\x00\x6f\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x34\ +\x00\xc8\xd6\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x75\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x36\ -\x02\x01\xeb\x67\ +\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\x00\x6f\x00\x6c\x00\x64\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x33\ +\x06\x9a\x7d\x47\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x6f\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\ -\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x38\ -\x08\xd6\x91\xc7\ +\x00\x5f\x00\x7a\x00\x6f\x00\x6f\x00\x6d\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x49\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x35\ +\x0d\x30\x6f\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x75\x00\x6e\x00\x64\x00\x6f\x00\x5f\x00\x6c\x00\x63\x00\x73\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\ -\x00\x6f\x00\x6c\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x30\ -\x02\x41\xc2\x67\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x5f\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x69\x00\x6e\x00\x67\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x31\ +\x08\xcd\x14\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x6c\x00\x65\x00\x63\x00\x74\x00\x5f\x00\x61\x00\x6c\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2c\ -\x0a\x26\x7c\x67\ +\x00\x5f\x00\x7a\x00\x6f\x00\x6f\x00\x6d\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x52\x00\x4f\x00\x49\x00\x2e\x00\x73\x00\x76\x00\x67\ +\ +\x00\x2b\ +\x0b\xec\x1f\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2f\ -\x06\xff\x4b\xe7\ +\x00\x5f\x00\x64\x00\x6f\x00\x63\x00\x6b\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3d\ +\x03\xe9\x26\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x08\x3e\x26\x67\ +\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x5f\ +\x00\x74\x00\x65\x00\x6d\x00\x70\x00\x5f\x00\x52\x00\x4f\x00\x49\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2d\ +\x09\x10\x3d\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x75\x00\x6e\x00\x64\x00\x6f\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x35\ -\x00\x7f\x00\xe7\ +\x00\x5f\x00\x6b\x00\x6d\x00\x6c\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x37\ +\x06\x63\x81\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x65\x00\x72\x00\x67\x00\x65\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3d\ -\x0b\x0c\xe5\xa7\ +\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x74\x00\x61\x00\x6e\ +\x00\x63\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2e\ +\x08\x72\x6e\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x69\x00\x6d\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\ -\x00\x5f\x00\x6c\x00\x69\x00\x62\x00\x72\x00\x61\x00\x72\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3c\ -\x00\x8a\xdd\xc7\ +\x00\x5f\x00\x72\x00\x67\x00\x62\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x29\ +\x0e\x16\x94\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x70\x00\x72\x00\x6f\x00\x6a\x00\x65\x00\x63\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\ -\x00\x72\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x35\ -\x05\x02\xfb\xa7\ +\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x34\ +\x0b\x25\x0c\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6e\x00\x65\x00\x69\x00\x67\x00\x68\x00\x62\x00\x6f\x00\x72\x00\x5f\x00\x70\x00\x69\x00\x78\x00\x65\x00\x6c\x00\x73\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x0c\x3f\xc2\x67\ +\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x42\ +\x03\xe4\x77\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6c\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x61\x00\x74\x00\x38\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x31\ -\x07\x3d\x00\xc7\ +\x00\x5f\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x75\x00\x6c\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\ +\x00\x72\x00\x61\x00\x6c\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x74\x00\x61\x00\x6e\x00\x63\x00\x65\x00\x73\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x35\ +\x00\x7f\x00\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x6f\x00\x73\x00\x61\x00\x69\x00\x63\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ -\x00\x2f\ -\x0d\x9b\xac\xc7\ +\x00\x5f\x00\x6d\x00\x65\x00\x72\x00\x67\x00\x65\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x30\ +\x09\x73\xbf\x47\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2e\ -\x08\x72\x6e\x67\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2d\ +\x09\x19\xff\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x67\x00\x62\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2c\ -\x0a\x72\x64\x07\ +\x00\x5f\x00\x6f\x00\x73\x00\x6d\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x0b\x90\x78\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x69\x00\x6d\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x06\x9a\x7d\x47\ +\x00\x5f\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x31\ +\x0b\x06\xec\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x7a\x00\x6f\x00\x6f\x00\x6d\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x49\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x2b\ -\x0b\x0b\x11\x07\ +\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x6f\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\ +\x00\x29\ +\x00\x30\x94\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2e\ -\x08\x42\x8e\x67\ +\x00\x5f\x00\x72\x00\x75\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x35\ +\x0c\x28\x19\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x30\ -\x09\x3e\x1f\xe7\ +\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x73\x00\x65\x00\x61\x00\x72\x00\x63\x00\x68\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x08\xc0\xeb\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3c\ -\x04\xa6\x91\x27\ +\x00\x5f\x00\x70\x00\x6f\x00\x69\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x2d\ +\x08\x78\xe0\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x5f\ -\x00\x64\x00\x69\x00\x73\x00\x70\x00\x6c\x00\x61\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2f\ -\x03\x9c\x4c\x27\ +\x00\x5f\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x5f\x00\x75\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x39\ +\x0f\xd5\x33\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x08\ -\x0c\x33\x57\x07\ -\x00\x68\ -\x00\x65\x00\x6c\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x72\x00\x65\x00\x73\ +\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x2f\ \x05\x5c\x0b\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \x00\x5f\x00\x63\x00\x6c\x00\x69\x00\x70\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x35\ -\x0c\x28\x19\x87\ +\x00\x3a\ +\x0c\x29\x56\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x73\x00\x65\x00\x61\x00\x72\x00\x63\x00\x68\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x76\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\ +\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x32\ \x07\x2c\x8e\x07\ \x00\x73\ @@ -24126,700 +16970,587 @@ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \x00\x5f\x00\x73\x00\x74\x00\x61\x00\x63\x00\x6b\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\ \x00\x67\ -\x00\x2e\ -\x09\xaf\x8e\x07\ +\x00\x3b\ +\x05\x89\xb6\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x30\ -\x03\xf4\xa6\x67\ +\x00\x5f\x00\x76\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\ +\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x33\ +\x0c\x3f\xc2\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x73\x00\x69\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x36\ -\x05\x2e\xaf\xa7\ +\x00\x5f\x00\x6c\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x61\x00\x74\x00\x38\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x2a\ +\x01\x2c\xbe\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x75\x00\x6e\x00\x64\x00\x6f\x00\x5f\x00\x65\x00\x64\x00\x69\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\ -\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x68\x00\x6f\x00\x6d\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x2b\ -\x04\x0c\xee\x27\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6d\x00\x69\x00\x6e\x00\x75\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x31\ -\x03\x06\x73\x47\ +\x08\x09\x78\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x5f\x00\x74\x00\x65\x00\x6d\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ -\x00\x3d\ -\x0a\x2f\xdc\xc7\ +\x00\x5f\x00\x72\x00\x65\x00\x73\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2f\ +\x03\x9c\x4c\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ -\x00\x64\x00\x69\x00\x6c\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x32\ -\x08\xc0\xeb\xc7\ +\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x33\ +\x0d\xca\x79\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x6f\x00\x69\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ -\x00\x67\ -\x00\x3d\ -\x0b\x0c\x28\xa7\ +\x00\x5f\x00\x73\x00\x65\x00\x61\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x36\ +\x07\x83\x81\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\ -\x00\x5f\x00\x6c\x00\x69\x00\x62\x00\x72\x00\x61\x00\x72\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2a\ -\x08\xda\xb9\x07\ +\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\ +\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2d\ +\x0c\xed\xcc\x47\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x6c\x00\x75\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x39\ -\x0f\xd5\x33\xe7\ +\x00\x5f\x00\x6f\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x42\ +\x00\x32\x99\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x72\x00\x65\x00\x73\ -\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x73\x00\x74\x00\x64\x00\x5f\x00\x64\x00\x65\x00\x76\ +\x00\x5f\x00\x73\x00\x74\x00\x72\x00\x65\x00\x74\x00\x63\x00\x68\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ \x00\x2e\ \x0b\x5f\xf5\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x34\ -\x0a\xed\xd0\x07\ +\x00\x2c\ +\x0a\x72\x64\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x5f\x00\x72\x00\x75\x00\x6c\x00\x65\x00\x73\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x0d\x1b\x39\x27\ +\x00\x5f\x00\x69\x00\x6d\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2e\ +\x07\xf0\x2f\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x25\ -\x08\xe6\x23\x67\ +\x00\x5f\x00\x66\x00\x69\x00\x74\x00\x5f\x00\x70\x00\x6c\x00\x6f\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x34\ +\x0b\xd0\x68\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x33\ -\x08\x31\xe6\x67\ +\x00\x5f\x00\x74\x00\x72\x00\x61\x00\x69\x00\x6e\x00\x69\x00\x6e\x00\x67\x00\x5f\x00\x69\x00\x6e\x00\x70\x00\x75\x00\x74\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x2f\ +\x0d\x9b\xac\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x2e\x00\x73\ -\x00\x76\x00\x67\ -\x00\x2e\ -\x00\xfe\x9b\xa7\ +\x00\x5f\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x33\ +\x0c\xdd\xa2\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x64\x00\x69\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x63\x00\x61\x00\x6c\x00\x63\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ \x00\x3a\ -\x08\x52\x72\x67\ +\x0a\x7e\x58\x47\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x5f\ -\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x38\ -\x05\x98\xb9\x87\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x5f\ +\x00\x73\x00\x69\x00\x65\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x03\xcc\xbb\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x4c\x00\x43\x00\x53\x00\x5f\x00\x74\x00\x68\x00\x72\x00\x65\x00\x73\x00\x68\x00\x6f\x00\x6c\x00\x64\x00\x5f\x00\x74\ -\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x34\ -\x0b\x58\x32\x67\ +\x00\x5f\x00\x73\x00\x70\x00\x6c\x00\x69\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x2d\ +\x01\xf6\x20\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x2d\ -\x09\x10\x3d\xe7\ +\x00\x5f\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3d\ +\x0b\x0c\x28\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6b\x00\x6d\x00\x6c\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x73\x00\x70\x00\x65\x00\x63\x00\x74\x00\x72\x00\x61\x00\x6c\ +\x00\x5f\x00\x6c\x00\x69\x00\x62\x00\x72\x00\x61\x00\x72\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x30\ \x09\xb7\x00\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ \x00\x5f\x00\x6d\x00\x61\x00\x6e\x00\x75\x00\x61\x00\x6c\x00\x5f\x00\x52\x00\x4f\x00\x49\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x09\ -\x0f\xa8\x87\xa7\ -\x00\x67\ -\x00\x75\x00\x69\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x29\ -\x0e\x16\x94\x87\ +\x00\x35\ +\x02\x01\x3b\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x31\ -\x0a\x7c\xc7\x87\ +\x00\x5f\x00\x73\x00\x61\x00\x76\x00\x65\x00\x5f\x00\x70\x00\x6c\x00\x6f\x00\x74\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2c\ +\x0a\x73\xf2\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x77\x00\x65\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ +\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x02\x83\x9e\x27\ +\x0a\x12\x1b\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x74\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x5f\x00\x61\x00\x63\x00\x63\x00\x75\x00\x72\x00\x61\x00\x63\x00\x79\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ \x00\x76\x00\x67\ -\x00\x45\ -\x03\x19\xe7\x47\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x63\x00\x75\x00\x6d\x00\x75\x00\x6c\x00\x61\x00\x74\ -\x00\x69\x00\x76\x00\x65\x00\x5f\x00\x73\x00\x74\x00\x72\x00\x65\x00\x74\x00\x63\x00\x68\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x38\ -\x0c\x5f\xd5\x87\ -\x00\x73\ -\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ -\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x75\x00\x64\x00\x5f\x00\x6d\x00\x61\x00\x73\x00\x6b\x00\x69\x00\x6e\x00\x67\x00\x5f\x00\x74\ -\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2d\ -\x01\xf6\x20\xc7\ +\x00\x2c\ +\x09\x95\x7c\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x72\x00\x65\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x05\xfb\x52\x67\ +\x0d\x6b\x5d\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6f\x00\x72\x00\x64\x00\x65\x00\x72\x00\x5f\x00\x62\x00\x79\x00\x5f\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\x2e\x00\x73\ +\x00\x5f\x00\x6f\x00\x72\x00\x64\x00\x65\x00\x72\x00\x5f\x00\x62\x00\x79\x00\x5f\x00\x64\x00\x61\x00\x74\x00\x65\x00\x2e\x00\x73\ \x00\x76\x00\x67\ -\x00\x34\ -\x0f\xca\xfb\x27\ +\x00\x2b\ +\x0b\x55\x18\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x6c\x00\x6f\x00\x67\x00\x69\x00\x6e\x00\x2e\ -\x00\x73\x00\x76\x00\x67\ -\x00\x31\ -\x03\xc9\x19\x87\ +\x00\x5f\x00\x62\x00\x61\x00\x74\x00\x63\x00\x68\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3b\ +\x08\x9a\x1a\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6b\x00\x6d\x00\x65\x00\x61\x00\x6e\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x5f\x00\x63\x00\x6f\x00\x6d\x00\x62\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x69\x00\x6f\ +\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x33\ -\x02\x86\x46\x27\ +\x05\xfb\x52\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x65\x00\x6e\x00\x74\x00\x69\x00\x6e\x00\x65\x00\x6c\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\ +\x00\x5f\x00\x6f\x00\x72\x00\x64\x00\x65\x00\x72\x00\x5f\x00\x62\x00\x79\x00\x5f\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\x2e\x00\x73\ \x00\x76\x00\x67\ -\x00\x2b\ -\x08\x09\x78\x27\ +\x00\x3c\ +\x00\x8a\xdd\xc7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x73\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x5f\x00\x72\x00\x65\x00\x70\x00\x72\x00\x6f\x00\x6a\x00\x65\x00\x63\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\ +\x00\x72\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x32\ -\x02\x74\x17\x67\ +\x0c\xae\xea\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x6d\x00\x75\x00\x6c\x00\x74\x00\x69\x00\x70\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\ +\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ \x00\x67\ -\x00\x31\ -\x08\x14\xc3\x87\ +\x00\x34\ +\x0b\x58\x32\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x65\x00\x64\x00\x69\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ -\x00\x37\ -\x09\x72\x22\x47\ +\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x35\ +\x05\x02\xfb\xa7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x6c\x00\x61\x00\x6e\x00\x64\x00\x5f\x00\x63\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x5f\x00\x63\x00\x68\x00\x61\x00\x6e\ -\x00\x67\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x42\ -\x00\x32\x99\x07\ +\x00\x5f\x00\x6e\x00\x65\x00\x69\x00\x67\x00\x68\x00\x62\x00\x6f\x00\x72\x00\x5f\x00\x70\x00\x69\x00\x78\x00\x65\x00\x6c\x00\x73\ +\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x01\xae\xc7\x27\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x62\x00\x61\x00\x6e\x00\x64\x00\x73\x00\x65\x00\x74\x00\x5f\x00\x73\x00\x74\x00\x64\x00\x5f\x00\x64\x00\x65\x00\x76\ -\x00\x5f\x00\x73\x00\x74\x00\x72\x00\x65\x00\x74\x00\x63\x00\x68\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ +\x00\x5f\x00\x70\x00\x6f\x00\x73\x00\x74\x00\x5f\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x2e\x00\x73\x00\x76\ \x00\x67\ -\x00\x30\ -\x09\x73\xbf\x47\ +\x00\x2e\ +\x09\xaf\x8e\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3d\ -\x03\xe9\x26\x87\ +\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x72\x00\x65\x00\x64\x00\x6f\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3a\ +\x0b\xe7\xf2\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x72\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x5f\ -\x00\x74\x00\x65\x00\x6d\x00\x70\x00\x5f\x00\x52\x00\x4f\x00\x49\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x3a\ -\x04\xac\x4b\x67\ +\x00\x5f\x00\x63\x00\x72\x00\x6f\x00\x73\x00\x73\x00\x5f\x00\x63\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\ +\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x2b\ +\x0b\x0b\x11\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x65\x00\x64\x00\x69\x00\x74\x00\x5f\x00\x70\x00\x6f\ -\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2e\ -\x09\xbb\x8e\x67\ +\x00\x5f\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x38\ +\x0c\x5f\xd5\x87\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x70\x00\x63\x00\x61\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x35\ -\x03\x84\xa4\x27\ +\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x75\x00\x64\x00\x5f\x00\x6d\x00\x61\x00\x73\x00\x6b\x00\x69\x00\x6e\x00\x67\x00\x5f\x00\x74\ +\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x30\ +\x03\xf4\xa6\x67\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x65\x00\x64\x00\x69\x00\x74\x00\x5f\x00\x72\x00\x61\x00\x6e\x00\x67\x00\x65\ -\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x2c\ -\x09\x95\x7c\x87\ +\x00\x5f\x00\x72\x00\x6f\x00\x69\x00\x5f\x00\x73\x00\x69\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x3c\ +\x0f\xbb\x15\x07\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ -\x00\x31\ -\x0b\x10\xd2\x67\ +\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x5f\x00\x69\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x5f\ +\x00\x70\x00\x72\x00\x65\x00\x76\x00\x69\x00\x65\x00\x77\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x08\ +\x0c\x33\x57\x07\ +\x00\x68\ +\x00\x65\x00\x6c\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x32\ +\x0c\xc2\x5d\xe7\ \x00\x73\ \x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ \x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ -\x00\x5f\x00\x72\x00\x65\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ -\ +\x00\x5f\x00\x73\x00\x63\x00\x61\x00\x74\x00\x74\x00\x65\x00\x72\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x2f\ +\x06\xff\x4b\xe7\ +\x00\x73\ +\x00\x65\x00\x6d\x00\x69\x00\x61\x00\x75\x00\x74\x00\x6f\x00\x6d\x00\x61\x00\x74\x00\x69\x00\x63\x00\x63\x00\x6c\x00\x61\x00\x73\ +\x00\x73\x00\x69\x00\x66\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ +\x00\x5f\x00\x73\x00\x69\x00\x67\x00\x6e\x00\x5f\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ " qt_resource_struct_v1 = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x07\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ \x00\x00\x00\x28\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ -\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x05\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ \x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x08\x09\ -\x00\x00\x00\x80\x00\x02\x00\x00\x00\x01\x00\x00\x00\x08\ -\x00\x00\x00\x28\x00\x02\x00\x00\x00\x7b\x00\x00\x00\x09\ -\x00\x00\x15\xc2\x00\x01\x00\x00\x00\x01\x00\x02\x62\xed\ -\x00\x00\x2e\xe4\x00\x00\x00\x00\x00\x01\x00\x05\x3b\xc5\ -\x00\x00\x18\x96\x00\x01\x00\x00\x00\x01\x00\x02\xb0\xfd\ -\x00\x00\x19\x86\x00\x00\x00\x00\x00\x01\x00\x02\xc0\x10\ -\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xa8\x68\ -\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xae\x6a\ -\x00\x00\x0c\xf4\x00\x01\x00\x00\x00\x01\x00\x01\x44\xe1\ -\x00\x00\x26\x64\x00\x00\x00\x00\x00\x01\x00\x04\x4a\x30\ -\x00\x00\x0c\x9a\x00\x01\x00\x00\x00\x01\x00\x01\x3b\xec\ -\x00\x00\x07\xc4\x00\x01\x00\x00\x00\x01\x00\x00\xb4\x6c\ -\x00\x00\x04\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x74\x66\ -\x00\x00\x2b\x34\x00\x01\x00\x00\x00\x01\x00\x04\xc4\x8c\ -\x00\x00\x05\x0e\x00\x01\x00\x00\x00\x01\x00\x00\x7e\xc3\ -\x00\x00\x16\x1a\x00\x00\x00\x00\x00\x01\x00\x02\x67\x4f\ -\x00\x00\x17\x02\x00\x00\x00\x00\x00\x01\x00\x02\x7f\x55\ -\x00\x00\x2d\x9e\x00\x01\x00\x00\x00\x01\x00\x05\x16\x1f\ -\x00\x00\x29\xc2\x00\x01\x00\x00\x00\x01\x00\x04\x9d\x3b\ -\x00\x00\x2c\xd6\x00\x01\x00\x00\x00\x01\x00\x04\xff\x9d\ -\x00\x00\x21\xc8\x00\x01\x00\x00\x00\x01\x00\x03\xcb\xb2\ -\x00\x00\x2a\x2e\x00\x00\x00\x00\x00\x01\x00\x04\xa6\x88\ -\x00\x00\x31\x30\x00\x01\x00\x00\x00\x01\x00\x05\x92\x49\ -\x00\x00\x1e\x7a\x00\x00\x00\x00\x00\x01\x00\x03\x5b\x08\ -\x00\x00\x00\xc8\x00\x01\x00\x00\x00\x01\x00\x00\x1d\x2f\ -\x00\x00\x2c\x6e\x00\x01\x00\x00\x00\x01\x00\x04\xe9\x9c\ -\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x00\xfa\x14\ -\x00\x00\x09\x0e\x00\x00\x00\x00\x00\x01\x00\x00\xe1\x27\ -\x00\x00\x04\x1a\x00\x01\x00\x00\x00\x01\x00\x00\x6d\xeb\ -\x00\x00\x2f\xd4\x00\x01\x00\x00\x00\x01\x00\x05\x5d\x59\ -\x00\x00\x20\x94\x00\x00\x00\x00\x00\x01\x00\x03\xa0\xf2\ -\x00\x00\x21\x6c\x00\x00\x00\x00\x00\x01\x00\x03\xc1\x98\ -\x00\x00\x01\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x3b\xd6\ -\x00\x00\x05\xe2\x00\x01\x00\x00\x00\x01\x00\x00\x8f\x36\ -\x00\x00\x1d\xfc\x00\x01\x00\x00\x00\x01\x00\x03\x48\x5c\ -\x00\x00\x30\x54\x00\x01\x00\x00\x00\x01\x00\x05\x74\x0d\ -\x00\x00\x13\x98\x00\x01\x00\x00\x00\x01\x00\x02\x14\x5f\ -\x00\x00\x1a\x04\x00\x01\x00\x00\x00\x01\x00\x02\xd6\x5c\ -\x00\x00\x20\xfa\x00\x01\x00\x00\x00\x01\x00\x03\xb6\xbc\ -\x00\x00\x20\xfa\x00\x01\x00\x00\x00\x01\x00\x03\xab\xe0\ -\x00\x00\x1e\xf4\x00\x01\x00\x00\x00\x01\x00\x03\x6c\xee\ -\x00\x00\x06\x60\x00\x01\x00\x00\x00\x01\x00\x00\x9c\x64\ -\x00\x00\x27\x40\x00\x01\x00\x00\x00\x01\x00\x04\x66\xba\ -\x00\x00\x2b\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcb\xcd\ -\x00\x00\x11\xea\x00\x01\x00\x00\x00\x01\x00\x01\xe3\x6a\ -\x00\x00\x09\x8c\x00\x01\x00\x00\x00\x01\x00\x00\xf3\x9f\ -\x00\x00\x1c\x6c\x00\x00\x00\x00\x00\x01\x00\x03\x16\x8b\ -\x00\x00\x17\xc6\x00\x01\x00\x00\x00\x01\x00\x02\x98\x1e\ -\x00\x00\x1f\xc8\x00\x00\x00\x00\x00\x01\x00\x03\x84\xbd\ -\x00\x00\x1a\xe0\x00\x01\x00\x00\x00\x01\x00\x02\xe7\x6a\ -\x00\x00\x08\x34\x00\x00\x00\x00\x00\x01\x00\x00\xbd\x76\ -\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x22\xfb\ -\x00\x00\x02\xe4\x00\x01\x00\x00\x00\x01\x00\x00\x4d\xcc\ -\x00\x00\x2d\x42\x00\x00\x00\x00\x00\x01\x00\x05\x08\x9e\ -\x00\x00\x2e\x08\x00\x01\x00\x00\x00\x01\x00\x05\x1c\xb7\ -\x00\x00\x25\xf8\x00\x00\x00\x00\x00\x01\x00\x04\x38\x02\ -\x00\x00\x18\x2a\x00\x00\x00\x00\x00\x01\x00\x02\x9e\xd9\ -\x00\x00\x1d\x34\x00\x01\x00\x00\x00\x01\x00\x03\x37\x2f\ -\x00\x00\x0e\xcc\x00\x00\x00\x00\x00\x01\x00\x01\x88\x7d\ -\x00\x00\x26\xc6\x00\x01\x00\x00\x00\x01\x00\x04\x53\xcd\ -\x00\x00\x1b\xac\x00\x00\x00\x00\x00\x01\x00\x02\xf9\x44\ -\x00\x00\x0b\xc0\x00\x00\x00\x00\x00\x01\x00\x01\x1e\x03\ -\x00\x00\x02\x68\x00\x01\x00\x00\x00\x01\x00\x00\x43\xd0\ -\x00\x00\x22\xb0\x00\x00\x00\x00\x00\x01\x00\x03\xdb\x9d\ -\x00\x00\x0e\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x9c\xca\ -\x00\x00\x16\x8c\x00\x01\x00\x00\x00\x01\x00\x02\x73\x55\ -\x00\x00\x23\x9a\x00\x00\x00\x00\x00\x01\x00\x03\xef\xb5\ -\x00\x00\x25\xa8\x00\x01\x00\x00\x00\x01\x00\x04\x25\x3c\ -\x00\x00\x28\x24\x00\x01\x00\x00\x00\x01\x00\x04\x76\x44\ -\x00\x00\x01\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x59\ -\x00\x00\x1d\x96\x00\x01\x00\x00\x00\x01\x00\x03\x3d\xe1\ -\x00\x00\x0e\x4e\x00\x01\x00\x00\x00\x01\x00\x01\x7e\xee\ -\x00\x00\x2e\x70\x00\x01\x00\x00\x00\x01\x00\x05\x24\x11\ -\x00\x00\x2f\x6e\x00\x00\x00\x00\x00\x01\x00\x05\x52\x39\ -\x00\x00\x31\xa0\x00\x00\x00\x00\x00\x01\x00\x05\x99\x49\ -\x00\x00\x20\x32\x00\x00\x00\x00\x00\x01\x00\x03\x93\xc9\ -\x00\x00\x28\x84\x00\x01\x00\x00\x00\x01\x00\x04\x7e\xa5\ -\x00\x00\x30\xce\x00\x01\x00\x00\x00\x01\x00\x05\x7d\x10\ -\x00\x00\x11\x7e\x00\x01\x00\x00\x00\x01\x00\x01\xda\xf2\ -\x00\x00\x17\x68\x00\x00\x00\x00\x00\x01\x00\x02\x8d\xf7\ -\x00\x00\x22\x30\x00\x01\x00\x00\x00\x01\x00\x03\xd5\x40\ -\x00\x00\x1c\x0e\x00\x00\x00\x00\x00\x01\x00\x03\x08\xed\ -\x00\x00\x14\x10\x00\x00\x00\x00\x00\x01\x00\x02\x1b\xc1\ -\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x01\x33\x1c\ -\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x01\x2a\x4c\ -\x00\x00\x29\x5a\x00\x01\x00\x00\x00\x01\x00\x04\x96\x3c\ -\x00\x00\x06\xdc\x00\x01\x00\x00\x00\x01\x00\x00\xa2\x31\ -\x00\x00\x0a\xd8\x00\x01\x00\x00\x00\x01\x00\x01\x0f\x47\ -\x00\x00\x24\xce\x00\x01\x00\x00\x00\x01\x00\x04\x17\xe6\ -\x00\x00\x10\xa8\x00\x01\x00\x00\x00\x01\x00\x01\xc8\x06\ -\x00\x00\x03\xb4\x00\x01\x00\x00\x00\x01\x00\x00\x64\x49\ -\x00\x00\x1c\xd8\x00\x00\x00\x00\x00\x01\x00\x03\x2b\x7a\ -\x00\x00\x23\x1a\x00\x01\x00\x00\x00\x01\x00\x03\xe8\x76\ -\x00\x00\x19\x06\x00\x01\x00\x00\x00\x01\x00\x02\xb9\x12\ -\x00\x00\x31\xfe\x00\x01\x00\x00\x00\x01\x00\x05\xab\x1f\ -\x00\x00\x31\xfe\x00\x01\x00\x00\x00\x01\x00\x05\xa5\x3a\ -\x00\x00\x03\x46\x00\x00\x00\x00\x00\x01\x00\x00\x54\xc7\ -\x00\x00\x11\x10\x00\x01\x00\x00\x00\x01\x00\x01\xd0\xb8\ -\x00\x00\x0d\x70\x00\x00\x00\x00\x00\x01\x00\x01\x50\x0c\ -\x00\x00\x0f\xd2\x00\x01\x00\x00\x00\x01\x00\x01\xb6\xc7\ -\x00\x00\x27\xb6\x00\x01\x00\x00\x00\x01\x00\x04\x6f\x97\ -\x00\x00\x24\x6c\x00\x00\x00\x00\x00\x01\x00\x04\x08\x3e\ -\x00\x00\x14\x6e\x00\x01\x00\x00\x00\x01\x00\x02\x29\x80\ -\x00\x00\x0a\x6a\x00\x00\x00\x00\x00\x01\x00\x01\x06\x7f\ -\x00\x00\x0f\x58\x00\x01\x00\x00\x00\x01\x00\x01\xae\x4e\ -\x00\x00\x12\xd2\x00\x00\x00\x00\x00\x01\x00\x01\xf8\x26\ -\x00\x00\x1f\x58\x00\x00\x00\x00\x00\x01\x00\x03\x77\x1c\ -\x00\x00\x10\x2e\x00\x01\x00\x00\x00\x01\x00\x01\xc1\x39\ -\x00\x00\x1e\xde\x00\x01\x00\x00\x00\x01\x00\x03\x65\xb9\ -\x00\x00\x1a\x74\x00\x01\x00\x00\x00\x01\x00\x02\xdc\xc0\ -\x00\x00\x2a\xbe\x00\x01\x00\x00\x00\x01\x00\x04\xbc\xf0\ -\x00\x00\x12\x68\x00\x00\x00\x00\x00\x01\x00\x01\xe9\xc7\ -\x00\x00\x13\x2e\x00\x01\x00\x00\x00\x01\x00\x02\x03\xda\ -\x00\x00\x0b\x54\x00\x01\x00\x00\x00\x01\x00\x01\x18\x3d\ -\x00\x00\x25\x3c\x00\x01\x00\x00\x00\x01\x00\x04\x1f\x52\ -\x00\x00\x0d\xde\x00\x00\x00\x00\x00\x01\x00\x01\x6c\xd8\ -\x00\x00\x08\xa6\x00\x00\x00\x00\x00\x01\x00\x00\xd0\x2c\ -\x00\x00\x05\x7e\x00\x01\x00\x00\x00\x01\x00\x00\x85\x76\ -\x00\x00\x1b\x48\x00\x00\x00\x00\x00\x01\x00\x02\xec\xfe\ -\x00\x00\x14\xd8\x00\x00\x00\x00\x00\x01\x00\x02\x32\x7c\ -\x00\x00\x29\x02\x00\x00\x00\x00\x00\x01\x00\x04\x8a\xdc\ -\x00\x00\x28\xea\x00\x01\x00\x00\x00\x01\x00\x04\x85\xf5\ -\x00\x00\x15\x44\x00\x00\x00\x00\x00\x01\x00\x02\x4a\x48\ -\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x01\x00\x04\xdf\x43\ -\x00\x00\x23\xf4\x00\x00\x00\x00\x00\x01\x00\x03\xfc\x7d\ +\x00\x00\x00\x5c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x07\ +\x00\x00\x00\x28\x00\x02\x00\x00\x00\x5c\x00\x00\x00\x08\ +\x00\x00\x10\xea\x00\x01\x00\x00\x00\x01\x00\x01\xe6\x5e\ +\x00\x00\x17\x7c\x00\x00\x00\x00\x00\x01\x00\x02\xa6\xe1\ +\x00\x00\x0e\xe2\x00\x01\x00\x00\x00\x01\x00\x01\xb3\xee\ +\x00\x00\x1f\xd8\x00\x00\x00\x00\x00\x01\x00\x03\x5a\xad\ +\x00\x00\x09\xce\x00\x01\x00\x00\x00\x01\x00\x01\x12\x43\ +\x00\x00\x09\xce\x00\x01\x00\x00\x00\x01\x00\x01\x0c\x41\ +\x00\x00\x03\x64\x00\x01\x00\x00\x00\x01\x00\x00\x5e\xc7\ +\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\ +\x00\x00\x15\x24\x00\x01\x00\x00\x00\x01\x00\x02\x4f\xa0\ +\x00\x00\x02\x8c\x00\x01\x00\x00\x00\x01\x00\x00\x49\xf3\ +\x00\x00\x21\x9e\x00\x00\x00\x00\x00\x01\x00\x03\x8c\x61\ +\x00\x00\x1b\x4a\x00\x01\x00\x00\x00\x01\x00\x03\x01\xca\ +\x00\x00\x1c\x90\x00\x01\x00\x00\x00\x01\x00\x03\x17\x55\ +\x00\x00\x08\x7e\x00\x00\x00\x00\x00\x01\x00\x00\xee\xcc\ +\x00\x00\x03\xe0\x00\x01\x00\x00\x00\x01\x00\x00\x69\xf2\ +\x00\x00\x08\xe4\x00\x01\x00\x00\x00\x01\x00\x00\xfd\x6e\ +\x00\x00\x06\x46\x00\x00\x00\x00\x00\x01\x00\x00\xab\x47\ +\x00\x00\x15\xda\x00\x00\x00\x00\x00\x01\x00\x02\x65\xb8\ +\x00\x00\x1a\xe0\x00\x00\x00\x00\x00\x01\x00\x02\xf5\x5f\ +\x00\x00\x0e\x58\x00\x01\x00\x00\x00\x01\x00\x01\xad\x73\ +\x00\x00\x0b\xdc\x00\x01\x00\x00\x00\x01\x00\x01\x5c\x7e\ +\x00\x00\x23\xb6\x00\x00\x00\x00\x00\x01\x00\x03\xbf\xcf\ +\x00\x00\x21\x2e\x00\x01\x00\x00\x00\x01\x00\x03\x85\xfd\ +\x00\x00\x12\xf4\x00\x01\x00\x00\x00\x01\x00\x02\x1f\x12\ +\x00\x00\x14\x3c\x00\x01\x00\x00\x00\x01\x00\x02\x3f\x19\ +\x00\x00\x1f\x6c\x00\x01\x00\x00\x00\x01\x00\x03\x54\xd5\ +\x00\x00\x09\x50\x00\x01\x00\x00\x00\x01\x00\x01\x05\xe4\ +\x00\x00\x0c\xbc\x00\x01\x00\x00\x00\x01\x00\x01\x7b\x93\ +\x00\x00\x0a\x3c\x00\x00\x00\x00\x00\x01\x00\x01\x18\x45\ +\x00\x00\x25\x1a\x00\x01\x00\x00\x00\x01\x00\x03\xfb\x0c\ +\x00\x00\x13\xd2\x00\x00\x00\x00\x00\x01\x00\x02\x30\x0d\ +\x00\x00\x02\x24\x00\x01\x00\x00\x00\x01\x00\x00\x44\x5f\ +\x00\x00\x16\xaa\x00\x00\x00\x00\x00\x01\x00\x02\x88\x35\ +\x00\x00\x05\x76\x00\x00\x00\x00\x00\x01\x00\x00\x96\x7a\ +\x00\x00\x18\xc6\x00\x01\x00\x00\x00\x01\x00\x02\xcd\x89\ +\x00\x00\x15\x7e\x00\x00\x00\x00\x00\x01\x00\x02\x58\x95\ +\x00\x00\x01\x56\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x95\ +\x00\x00\x05\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x84\x56\ +\x00\x00\x01\xc2\x00\x01\x00\x00\x00\x01\x00\x00\x3d\xc3\ +\x00\x00\x08\x5a\x00\x00\x00\x00\x00\x01\x00\x00\xda\x7f\ +\x00\x00\x0d\x30\x00\x00\x00\x00\x00\x01\x00\x01\x82\x08\ +\x00\x00\x12\x1c\x00\x00\x00\x00\x00\x01\x00\x02\x07\x16\ +\x00\x00\x1e\xf0\x00\x01\x00\x00\x00\x01\x00\x03\x4a\xd9\ +\x00\x00\x11\xb2\x00\x00\x00\x00\x00\x01\x00\x01\xfa\x3d\ +\x00\x00\x0b\x18\x00\x00\x00\x00\x00\x01\x00\x01\x3f\x46\ +\x00\x00\x01\x06\x00\x01\x00\x00\x00\x01\x00\x00\x1d\x42\ +\x00\x00\x0c\x5c\x00\x01\x00\x00\x00\x01\x00\x01\x73\x32\ +\x00\x00\x0f\xb8\x00\x00\x00\x00\x00\x01\x00\x01\xc6\x33\ +\x00\x00\x0f\x52\x00\x00\x00\x00\x00\x01\x00\x01\xba\xb4\ +\x00\x00\x1d\xca\x00\x00\x00\x00\x00\x01\x00\x03\x31\xe7\ +\x00\x00\x22\x08\x00\x00\x00\x00\x00\x01\x00\x03\x96\xdc\ +\x00\x00\x1c\x2a\x00\x01\x00\x00\x00\x01\x00\x03\x10\x05\ +\x00\x00\x00\xa4\x00\x01\x00\x00\x00\x01\x00\x00\x08\x09\ +\x00\x00\x1d\x5e\x00\x01\x00\x00\x00\x01\x00\x03\x29\x6f\ +\x00\x00\x04\xac\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x27\ +\x00\x00\x06\xd6\x00\x01\x00\x00\x00\x01\x00\x00\xc1\xaf\ +\x00\x00\x18\x68\x00\x00\x00\x00\x00\x01\x00\x02\xc2\x7c\ +\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x01\x00\x03\x1d\x3c\ +\x00\x00\x1a\x66\x00\x01\x00\x00\x00\x01\x00\x02\xef\x28\ +\x00\x00\x10\x82\x00\x01\x00\x00\x00\x01\x00\x01\xdd\xac\ +\x00\x00\x22\xe4\x00\x00\x00\x00\x00\x01\x00\x03\xac\x7e\ +\x00\x00\x1b\xaa\x00\x01\x00\x00\x00\x01\x00\x03\x09\x0b\ +\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xc8\x0c\ +\x00\x00\x02\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x58\xe2\ +\x00\x00\x02\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x52\xfd\ +\x00\x00\x0d\xea\x00\x00\x00\x00\x00\x01\x00\x01\x9d\xee\ +\x00\x00\x1e\x94\x00\x01\x00\x00\x00\x01\x00\x03\x43\xe4\ +\x00\x00\x20\xc0\x00\x01\x00\x00\x00\x01\x00\x03\x7f\x50\ +\x00\x00\x18\x06\x00\x01\x00\x00\x00\x01\x00\x02\xbd\x55\ +\x00\x00\x10\x18\x00\x01\x00\x00\x00\x01\x00\x01\xd4\xb0\ +\x00\x00\x19\x28\x00\x00\x00\x00\x00\x01\x00\x02\xd4\x84\ +\x00\x00\x22\x6a\x00\x01\x00\x00\x00\x01\x00\x03\xa4\x05\ +\x00\x00\x0b\x80\x00\x00\x00\x00\x00\x01\x00\x01\x50\xca\ +\x00\x00\x11\x42\x00\x00\x00\x00\x00\x01\x00\x01\xec\x9c\ +\x00\x00\x13\x58\x00\x01\x00\x00\x00\x01\x00\x02\x29\x40\ +\x00\x00\x24\x9a\x00\x01\x00\x00\x00\x01\x00\x03\xe3\x62\ +\x00\x00\x14\xb8\x00\x01\x00\x00\x00\x01\x00\x02\x44\xe6\ +\x00\x00\x23\x40\x00\x01\x00\x00\x00\x01\x00\x03\xb8\x33\ +\x00\x00\x20\x56\x00\x00\x00\x00\x00\x01\x00\x03\x70\xf9\ +\x00\x00\x24\xb0\x00\x01\x00\x00\x00\x01\x00\x03\xea\x87\ +\x00\x00\x19\xfa\x00\x01\x00\x00\x00\x01\x00\x02\xe9\x77\ +\x00\x00\x17\x1c\x00\x00\x00\x00\x00\x01\x00\x02\x9a\xe4\ +\x00\x00\x07\xee\x00\x01\x00\x00\x00\x01\x00\x00\xd3\xaf\ +\x00\x00\x0a\xa8\x00\x00\x00\x00\x00\x01\x00\x01\x2d\x34\ +\x00\x00\x1e\x28\x00\x01\x00\x00\x00\x01\x00\x03\x3d\xd8\ +\x00\x00\x19\x96\x00\x00\x00\x00\x00\x01\x00\x02\xdd\x4c\ +\x00\x00\x16\x3e\x00\x00\x00\x00\x00\x01\x00\x02\x70\x69\ +\x00\x00\x0d\x92\x00\x00\x00\x00\x00\x01\x00\x01\x91\xb1\ +\x00\x00\x07\xd6\x00\x01\x00\x00\x00\x01\x00\x00\xce\xc8\ +\x00\x00\x24\x1c\x00\x00\x00\x00\x00\x01\x00\x03\xca\xbd\ +\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\xa0\xd8\ +\x00\x00\x12\x7c\x00\x00\x00\x00\x00\x01\x00\x02\x13\x51\ " qt_resource_struct_v2 = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x07\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x28\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x05\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x08\x09\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x00\x80\x00\x02\x00\x00\x00\x01\x00\x00\x00\x08\ +\x00\x00\x01\x8a\xea\x7b\xd3\x86\ +\x00\x00\x00\x5c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x07\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x28\x00\x02\x00\x00\x00\x7b\x00\x00\x00\x09\ +\x00\x00\x00\x28\x00\x02\x00\x00\x00\x5c\x00\x00\x00\x08\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x15\xc2\x00\x01\x00\x00\x00\x01\x00\x02\x62\xed\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2e\xe4\x00\x00\x00\x00\x00\x01\x00\x05\x3b\xc5\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x18\x96\x00\x01\x00\x00\x00\x01\x00\x02\xb0\xfd\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x19\x86\x00\x00\x00\x00\x00\x01\x00\x02\xc0\x10\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xa8\x68\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xae\x6a\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0c\xf4\x00\x01\x00\x00\x00\x01\x00\x01\x44\xe1\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x26\x64\x00\x00\x00\x00\x00\x01\x00\x04\x4a\x30\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0c\x9a\x00\x01\x00\x00\x00\x01\x00\x01\x3b\xec\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x07\xc4\x00\x01\x00\x00\x00\x01\x00\x00\xb4\x6c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x04\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x74\x66\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2b\x34\x00\x01\x00\x00\x00\x01\x00\x04\xc4\x8c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x05\x0e\x00\x01\x00\x00\x00\x01\x00\x00\x7e\xc3\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x16\x1a\x00\x00\x00\x00\x00\x01\x00\x02\x67\x4f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x17\x02\x00\x00\x00\x00\x00\x01\x00\x02\x7f\x55\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2d\x9e\x00\x01\x00\x00\x00\x01\x00\x05\x16\x1f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x29\xc2\x00\x01\x00\x00\x00\x01\x00\x04\x9d\x3b\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2c\xd6\x00\x01\x00\x00\x00\x01\x00\x04\xff\x9d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x21\xc8\x00\x01\x00\x00\x00\x01\x00\x03\xcb\xb2\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2a\x2e\x00\x00\x00\x00\x00\x01\x00\x04\xa6\x88\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x31\x30\x00\x01\x00\x00\x00\x01\x00\x05\x92\x49\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1e\x7a\x00\x00\x00\x00\x00\x01\x00\x03\x5b\x08\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x00\xc8\x00\x01\x00\x00\x00\x01\x00\x00\x1d\x2f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2c\x6e\x00\x01\x00\x00\x00\x01\x00\x04\xe9\x9c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x00\xfa\x14\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x09\x0e\x00\x00\x00\x00\x00\x01\x00\x00\xe1\x27\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x04\x1a\x00\x01\x00\x00\x00\x01\x00\x00\x6d\xeb\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2f\xd4\x00\x01\x00\x00\x00\x01\x00\x05\x5d\x59\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x20\x94\x00\x00\x00\x00\x00\x01\x00\x03\xa0\xf2\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x21\x6c\x00\x00\x00\x00\x00\x01\x00\x03\xc1\x98\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x01\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x3b\xd6\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x05\xe2\x00\x01\x00\x00\x00\x01\x00\x00\x8f\x36\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1d\xfc\x00\x01\x00\x00\x00\x01\x00\x03\x48\x5c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x30\x54\x00\x01\x00\x00\x00\x01\x00\x05\x74\x0d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x13\x98\x00\x01\x00\x00\x00\x01\x00\x02\x14\x5f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1a\x04\x00\x01\x00\x00\x00\x01\x00\x02\xd6\x5c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x20\xfa\x00\x01\x00\x00\x00\x01\x00\x03\xb6\xbc\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x20\xfa\x00\x01\x00\x00\x00\x01\x00\x03\xab\xe0\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1e\xf4\x00\x01\x00\x00\x00\x01\x00\x03\x6c\xee\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x06\x60\x00\x01\x00\x00\x00\x01\x00\x00\x9c\x64\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x27\x40\x00\x01\x00\x00\x00\x01\x00\x04\x66\xba\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2b\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcb\xcd\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x11\xea\x00\x01\x00\x00\x00\x01\x00\x01\xe3\x6a\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x09\x8c\x00\x01\x00\x00\x00\x01\x00\x00\xf3\x9f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1c\x6c\x00\x00\x00\x00\x00\x01\x00\x03\x16\x8b\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x17\xc6\x00\x01\x00\x00\x00\x01\x00\x02\x98\x1e\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1f\xc8\x00\x00\x00\x00\x00\x01\x00\x03\x84\xbd\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1a\xe0\x00\x01\x00\x00\x00\x01\x00\x02\xe7\x6a\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x08\x34\x00\x00\x00\x00\x00\x01\x00\x00\xbd\x76\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x22\xfb\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x02\xe4\x00\x01\x00\x00\x00\x01\x00\x00\x4d\xcc\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2d\x42\x00\x00\x00\x00\x00\x01\x00\x05\x08\x9e\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2e\x08\x00\x01\x00\x00\x00\x01\x00\x05\x1c\xb7\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x25\xf8\x00\x00\x00\x00\x00\x01\x00\x04\x38\x02\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x18\x2a\x00\x00\x00\x00\x00\x01\x00\x02\x9e\xd9\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1d\x34\x00\x01\x00\x00\x00\x01\x00\x03\x37\x2f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0e\xcc\x00\x00\x00\x00\x00\x01\x00\x01\x88\x7d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x26\xc6\x00\x01\x00\x00\x00\x01\x00\x04\x53\xcd\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1b\xac\x00\x00\x00\x00\x00\x01\x00\x02\xf9\x44\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0b\xc0\x00\x00\x00\x00\x00\x01\x00\x01\x1e\x03\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x02\x68\x00\x01\x00\x00\x00\x01\x00\x00\x43\xd0\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x22\xb0\x00\x00\x00\x00\x00\x01\x00\x03\xdb\x9d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0e\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x9c\xca\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x16\x8c\x00\x01\x00\x00\x00\x01\x00\x02\x73\x55\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x23\x9a\x00\x00\x00\x00\x00\x01\x00\x03\xef\xb5\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x25\xa8\x00\x01\x00\x00\x00\x01\x00\x04\x25\x3c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x28\x24\x00\x01\x00\x00\x00\x01\x00\x04\x76\x44\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x01\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x59\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1d\x96\x00\x01\x00\x00\x00\x01\x00\x03\x3d\xe1\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0e\x4e\x00\x01\x00\x00\x00\x01\x00\x01\x7e\xee\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2e\x70\x00\x01\x00\x00\x00\x01\x00\x05\x24\x11\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2f\x6e\x00\x00\x00\x00\x00\x01\x00\x05\x52\x39\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x31\xa0\x00\x00\x00\x00\x00\x01\x00\x05\x99\x49\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x20\x32\x00\x00\x00\x00\x00\x01\x00\x03\x93\xc9\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x28\x84\x00\x01\x00\x00\x00\x01\x00\x04\x7e\xa5\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x30\xce\x00\x01\x00\x00\x00\x01\x00\x05\x7d\x10\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x11\x7e\x00\x01\x00\x00\x00\x01\x00\x01\xda\xf2\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x17\x68\x00\x00\x00\x00\x00\x01\x00\x02\x8d\xf7\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x22\x30\x00\x01\x00\x00\x00\x01\x00\x03\xd5\x40\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1c\x0e\x00\x00\x00\x00\x00\x01\x00\x03\x08\xed\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x14\x10\x00\x00\x00\x00\x00\x01\x00\x02\x1b\xc1\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x01\x33\x1c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x01\x2a\x4c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x29\x5a\x00\x01\x00\x00\x00\x01\x00\x04\x96\x3c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x06\xdc\x00\x01\x00\x00\x00\x01\x00\x00\xa2\x31\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0a\xd8\x00\x01\x00\x00\x00\x01\x00\x01\x0f\x47\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x24\xce\x00\x01\x00\x00\x00\x01\x00\x04\x17\xe6\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x10\xa8\x00\x01\x00\x00\x00\x01\x00\x01\xc8\x06\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x03\xb4\x00\x01\x00\x00\x00\x01\x00\x00\x64\x49\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1c\xd8\x00\x00\x00\x00\x00\x01\x00\x03\x2b\x7a\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x23\x1a\x00\x01\x00\x00\x00\x01\x00\x03\xe8\x76\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x19\x06\x00\x01\x00\x00\x00\x01\x00\x02\xb9\x12\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x31\xfe\x00\x01\x00\x00\x00\x01\x00\x05\xab\x1f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x31\xfe\x00\x01\x00\x00\x00\x01\x00\x05\xa5\x3a\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x03\x46\x00\x00\x00\x00\x00\x01\x00\x00\x54\xc7\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x11\x10\x00\x01\x00\x00\x00\x01\x00\x01\xd0\xb8\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0d\x70\x00\x00\x00\x00\x00\x01\x00\x01\x50\x0c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0f\xd2\x00\x01\x00\x00\x00\x01\x00\x01\xb6\xc7\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x27\xb6\x00\x01\x00\x00\x00\x01\x00\x04\x6f\x97\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x24\x6c\x00\x00\x00\x00\x00\x01\x00\x04\x08\x3e\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x14\x6e\x00\x01\x00\x00\x00\x01\x00\x02\x29\x80\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0a\x6a\x00\x00\x00\x00\x00\x01\x00\x01\x06\x7f\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0f\x58\x00\x01\x00\x00\x00\x01\x00\x01\xae\x4e\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x12\xd2\x00\x00\x00\x00\x00\x01\x00\x01\xf8\x26\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1f\x58\x00\x00\x00\x00\x00\x01\x00\x03\x77\x1c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x10\x2e\x00\x01\x00\x00\x00\x01\x00\x01\xc1\x39\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1e\xde\x00\x01\x00\x00\x00\x01\x00\x03\x65\xb9\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1a\x74\x00\x01\x00\x00\x00\x01\x00\x02\xdc\xc0\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2a\xbe\x00\x01\x00\x00\x00\x01\x00\x04\xbc\xf0\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x12\x68\x00\x00\x00\x00\x00\x01\x00\x01\xe9\xc7\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x13\x2e\x00\x01\x00\x00\x00\x01\x00\x02\x03\xda\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0b\x54\x00\x01\x00\x00\x00\x01\x00\x01\x18\x3d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x25\x3c\x00\x01\x00\x00\x00\x01\x00\x04\x1f\x52\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x0d\xde\x00\x00\x00\x00\x00\x01\x00\x01\x6c\xd8\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x08\xa6\x00\x00\x00\x00\x00\x01\x00\x00\xd0\x2c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x05\x7e\x00\x01\x00\x00\x00\x01\x00\x00\x85\x76\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x1b\x48\x00\x00\x00\x00\x00\x01\x00\x02\xec\xfe\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x14\xd8\x00\x00\x00\x00\x00\x01\x00\x02\x32\x7c\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x29\x02\x00\x00\x00\x00\x00\x01\x00\x04\x8a\xdc\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x28\xea\x00\x01\x00\x00\x00\x01\x00\x04\x85\xf5\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x15\x44\x00\x00\x00\x00\x00\x01\x00\x02\x4a\x48\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x01\x00\x04\xdf\x43\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ -\x00\x00\x23\xf4\x00\x00\x00\x00\x00\x01\x00\x03\xfc\x7d\ -\x00\x00\x01\x86\xcd\x7e\x4d\x20\ +\x00\x00\x10\xea\x00\x01\x00\x00\x00\x01\x00\x01\xe6\x5e\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x17\x7c\x00\x00\x00\x00\x00\x01\x00\x02\xa6\xe1\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0e\xe2\x00\x01\x00\x00\x00\x01\x00\x01\xb3\xee\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1f\xd8\x00\x00\x00\x00\x00\x01\x00\x03\x5a\xad\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x09\xce\x00\x01\x00\x00\x00\x01\x00\x01\x12\x43\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x09\xce\x00\x01\x00\x00\x00\x01\x00\x01\x0c\x41\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x03\x64\x00\x01\x00\x00\x00\x01\x00\x00\x5e\xc7\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x15\x24\x00\x01\x00\x00\x00\x01\x00\x02\x4f\xa0\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x02\x8c\x00\x01\x00\x00\x00\x01\x00\x00\x49\xf3\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x21\x9e\x00\x00\x00\x00\x00\x01\x00\x03\x8c\x61\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1b\x4a\x00\x01\x00\x00\x00\x01\x00\x03\x01\xca\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1c\x90\x00\x01\x00\x00\x00\x01\x00\x03\x17\x55\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x08\x7e\x00\x00\x00\x00\x00\x01\x00\x00\xee\xcc\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x03\xe0\x00\x01\x00\x00\x00\x01\x00\x00\x69\xf2\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x08\xe4\x00\x01\x00\x00\x00\x01\x00\x00\xfd\x6e\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x06\x46\x00\x00\x00\x00\x00\x01\x00\x00\xab\x47\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x15\xda\x00\x00\x00\x00\x00\x01\x00\x02\x65\xb8\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1a\xe0\x00\x00\x00\x00\x00\x01\x00\x02\xf5\x5f\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0e\x58\x00\x01\x00\x00\x00\x01\x00\x01\xad\x73\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0b\xdc\x00\x01\x00\x00\x00\x01\x00\x01\x5c\x7e\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x23\xb6\x00\x00\x00\x00\x00\x01\x00\x03\xbf\xcf\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x21\x2e\x00\x01\x00\x00\x00\x01\x00\x03\x85\xfd\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x12\xf4\x00\x01\x00\x00\x00\x01\x00\x02\x1f\x12\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x14\x3c\x00\x01\x00\x00\x00\x01\x00\x02\x3f\x19\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1f\x6c\x00\x01\x00\x00\x00\x01\x00\x03\x54\xd5\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x09\x50\x00\x01\x00\x00\x00\x01\x00\x01\x05\xe4\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0c\xbc\x00\x01\x00\x00\x00\x01\x00\x01\x7b\x93\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0a\x3c\x00\x00\x00\x00\x00\x01\x00\x01\x18\x45\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x25\x1a\x00\x01\x00\x00\x00\x01\x00\x03\xfb\x0c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x13\xd2\x00\x00\x00\x00\x00\x01\x00\x02\x30\x0d\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x02\x24\x00\x01\x00\x00\x00\x01\x00\x00\x44\x5f\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x16\xaa\x00\x00\x00\x00\x00\x01\x00\x02\x88\x35\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x05\x76\x00\x00\x00\x00\x00\x01\x00\x00\x96\x7a\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x18\xc6\x00\x01\x00\x00\x00\x01\x00\x02\xcd\x89\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x15\x7e\x00\x00\x00\x00\x00\x01\x00\x02\x58\x95\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x01\x56\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x95\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x05\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x84\x56\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x01\xc2\x00\x01\x00\x00\x00\x01\x00\x00\x3d\xc3\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x08\x5a\x00\x00\x00\x00\x00\x01\x00\x00\xda\x7f\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0d\x30\x00\x00\x00\x00\x00\x01\x00\x01\x82\x08\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x12\x1c\x00\x00\x00\x00\x00\x01\x00\x02\x07\x16\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1e\xf0\x00\x01\x00\x00\x00\x01\x00\x03\x4a\xd9\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x11\xb2\x00\x00\x00\x00\x00\x01\x00\x01\xfa\x3d\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0b\x18\x00\x00\x00\x00\x00\x01\x00\x01\x3f\x46\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x01\x06\x00\x01\x00\x00\x00\x01\x00\x00\x1d\x42\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0c\x5c\x00\x01\x00\x00\x00\x01\x00\x01\x73\x32\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0f\xb8\x00\x00\x00\x00\x00\x01\x00\x01\xc6\x33\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0f\x52\x00\x00\x00\x00\x00\x01\x00\x01\xba\xb4\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1d\xca\x00\x00\x00\x00\x00\x01\x00\x03\x31\xe7\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x22\x08\x00\x00\x00\x00\x00\x01\x00\x03\x96\xdc\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1c\x2a\x00\x01\x00\x00\x00\x01\x00\x03\x10\x05\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x00\xa4\x00\x01\x00\x00\x00\x01\x00\x00\x08\x09\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1d\x5e\x00\x01\x00\x00\x00\x01\x00\x03\x29\x6f\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x04\xac\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x27\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x06\xd6\x00\x01\x00\x00\x00\x01\x00\x00\xc1\xaf\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x18\x68\x00\x00\x00\x00\x00\x01\x00\x02\xc2\x7c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x01\x00\x03\x1d\x3c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1a\x66\x00\x01\x00\x00\x00\x01\x00\x02\xef\x28\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x10\x82\x00\x01\x00\x00\x00\x01\x00\x01\xdd\xac\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x22\xe4\x00\x00\x00\x00\x00\x01\x00\x03\xac\x7e\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1b\xaa\x00\x01\x00\x00\x00\x01\x00\x03\x09\x0b\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x07\x56\x00\x01\x00\x00\x00\x01\x00\x00\xc8\x0c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x02\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x58\xe2\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x02\xfc\x00\x01\x00\x00\x00\x01\x00\x00\x52\xfd\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0d\xea\x00\x00\x00\x00\x00\x01\x00\x01\x9d\xee\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1e\x94\x00\x01\x00\x00\x00\x01\x00\x03\x43\xe4\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x20\xc0\x00\x01\x00\x00\x00\x01\x00\x03\x7f\x50\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x18\x06\x00\x01\x00\x00\x00\x01\x00\x02\xbd\x55\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x10\x18\x00\x01\x00\x00\x00\x01\x00\x01\xd4\xb0\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x19\x28\x00\x00\x00\x00\x00\x01\x00\x02\xd4\x84\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x22\x6a\x00\x01\x00\x00\x00\x01\x00\x03\xa4\x05\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0b\x80\x00\x00\x00\x00\x00\x01\x00\x01\x50\xca\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x11\x42\x00\x00\x00\x00\x00\x01\x00\x01\xec\x9c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x13\x58\x00\x01\x00\x00\x00\x01\x00\x02\x29\x40\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x24\x9a\x00\x01\x00\x00\x00\x01\x00\x03\xe3\x62\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x14\xb8\x00\x01\x00\x00\x00\x01\x00\x02\x44\xe6\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x23\x40\x00\x01\x00\x00\x00\x01\x00\x03\xb8\x33\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x20\x56\x00\x00\x00\x00\x00\x01\x00\x03\x70\xf9\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x24\xb0\x00\x01\x00\x00\x00\x01\x00\x03\xea\x87\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x19\xfa\x00\x01\x00\x00\x00\x01\x00\x02\xe9\x77\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x17\x1c\x00\x00\x00\x00\x00\x01\x00\x02\x9a\xe4\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x07\xee\x00\x01\x00\x00\x00\x01\x00\x00\xd3\xaf\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0a\xa8\x00\x00\x00\x00\x00\x01\x00\x01\x2d\x34\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x1e\x28\x00\x01\x00\x00\x00\x01\x00\x03\x3d\xd8\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x19\x96\x00\x00\x00\x00\x00\x01\x00\x02\xdd\x4c\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x16\x3e\x00\x00\x00\x00\x00\x01\x00\x02\x70\x69\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x0d\x92\x00\x00\x00\x00\x00\x01\x00\x01\x91\xb1\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x07\xd6\x00\x01\x00\x00\x00\x01\x00\x00\xce\xc8\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x24\x1c\x00\x00\x00\x00\x00\x01\x00\x03\xca\xbd\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\xa0\xd8\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ +\x00\x00\x12\x7c\x00\x00\x00\x00\x00\x01\x00\x02\x13\x51\ +\x00\x00\x01\x8a\xea\x7b\xa4\x3e\ " qt_version = [int(v) for v in QtCore.qVersion().split('.')] diff --git a/ui/scatterwidget2.py b/ui/scatterwidget2.py old mode 100644 new mode 100755 index 4865625..bc738fe --- a/ui/scatterwidget2.py +++ b/ui/scatterwidget2.py @@ -1,84 +1,81 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' # Import PyQt libraries -from PyQt5 import QtGui, QtWidgets -from PyQt5.QtWidgets import QWidget +from PyQt5.QtWidgets import QWidget, QGridLayout + # Import FigureCanvas try: - import matplotlib -except: - pass -try: - matplotlib.use('Qt5Agg') -except: - pass + import matplotlib + + matplotlib.use('Qt5Agg') +except Exception as error: + str(error) try: - from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigCanvas - # Import Figure - from matplotlib.figure import Figure -except: - FigCanvas = QWidget + from matplotlib.backends.backend_qt5agg import ( + FigureCanvasQTAgg as FigCanvas + ) + # Import Figure + from matplotlib.figure import Figure +except Exception as error: + str(error) + FigCanvas = QWidget + +# noinspection PyMissingConstructor class SigCanvas(FigCanvas): - def __init__(self): - try: - # Figure - self.figure = Figure() - # Add subplot for plot and legend - self.ax = self.figure.add_axes([0.1, 0.15, 0.9, 0.9]) - # Canvas initialization - FigCanvas.__init__(self, self.figure) - except: - return None - # Set empty ticks - self.ax.set_xticks([]) - self.ax.set_yticks([]) - self.ax.set_aspect('equal', 'datalim') + + def __init__(self): + try: + # Figure + self.figure = Figure() + # Add subplot for plot and legend + self.ax = self.figure.add_axes([0.1, 0.15, 0.9, 0.9]) + # Canvas initialization + FigCanvas.__init__(self, self.figure) + # Set empty ticks + self.ax.set_xticks([]) + self.ax.set_yticks([]) + self.ax.set_aspect('equal', 'datalim') + except Exception as err: + str(err) + class ScatterWidget2(QWidget): - def __init__(self, parent = None): - try: - # Widget initialization - QWidget.__init__(self, parent) - # Widget canvas - self.sigCanvas = SigCanvas() - # Create grid layout - self.gridLayout = QtWidgets.QGridLayout() - # Add widget to grid - self.gridLayout.addWidget(self.sigCanvas) - # Set layout - self.setLayout(self.gridLayout) - except: - return None \ No newline at end of file + + # noinspection PyArgumentList + def __init__(self, parent=None): + try: + # Widget initialization + QWidget.__init__(self, parent) + # Widget canvas + self.sigCanvas = SigCanvas() + # Create grid layout + self.gridLayout = QGridLayout() + # Add widget to grid + self.gridLayout.addWidget(self.sigCanvas) + # Set layout + self.setLayout(self.gridLayout) + except Exception as err: + str(err) + return diff --git a/ui/semiautomaticclassificationplugindialog.py b/ui/semiautomaticclassificationplugindialog.py old mode 100644 new mode 100755 index 348d88d..f9db2a6 --- a/ui/semiautomaticclassificationplugindialog.py +++ b/ui/semiautomaticclassificationplugindialog.py @@ -1,259 +1,234 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -from PyQt5 import QtGui -from PyQt5 import QtWidgets -from .ui_semiautomaticclassificationplugin import Ui_SemiAutomaticClassificationPlugin +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . + + +from PyQt5.QtCore import ( + Qt, QFileInfo, QSettings, qVersion, QCoreApplication, QTranslator +) +from PyQt5.QtWidgets import QDialog, QDockWidget +from qgis.core import QgsApplication + +from .ui_semiautomaticclassificationplugin import ( + Ui_SemiAutomaticClassificationPlugin +) from .ui_semiautomaticclassificationplugin_dock_class import Ui_DockClass from .ui_semiautomaticclassificationplugin_scatter_plot import Ui_ScatterPlot -from .ui_semiautomaticclassificationplugin_welcome import Ui_SCP_Welcome -from .ui_semiautomaticclassificationplugin_signature_plot import Ui_SpectralSignaturePlot +from .ui_semiautomaticclassificationplugin_signature_plot import ( + Ui_SpectralSignaturePlot +) +from .ui_semiautomaticclassificationplugin_widget import Ui_SCP_Widget + try: - cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) -except: - pass + cfg = __import__( + str(__name__).split('.')[0] + '.core.config', fromlist=[''] + ) +except Exception as error: + str(error) + # create the dialog -class SemiAutomaticClassificationPluginDialog(QtWidgets.QDialog): - def __init__(self): - QtWidgets.QDialog.__init__(self) - try: - self.setWindowFlags(cfg.QtSCP.Window) - except: - return - # initialize plugin directory - self.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/SemiAutomaticClassificationPlugin" - # locale name - self.lclNm = cfg.QSettingsSCP().value("locale/userLocale")[0:2] - # path to locale - lclPth = "" - if cfg.QFileInfoSCP(self.plgnDir).exists(): - lclPth = self.plgnDir + "/i18n/semiautomaticclassificationplugin_" + self.lclNm + ".qm" - if cfg.QFileInfoSCP(lclPth).exists(): - self.trnsltr = cfg.QtCoreSCP.QTranslator() - self.trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(self.trnsltr) - # Set up the user interface from Designer. - self.ui = Ui_SemiAutomaticClassificationPlugin() - self.ui.setupUi(self) - - def shape_clip_combo(self, shape): - self.ui.shapefile_comboBox.addItem(shape) - - def vector_to_raster_combo(self, vector): - self.ui.vector_name_combo.addItem(vector) - - def vector_edit_raster_combo(self, vector): - self.ui.vector_name_combo_2.addItem(vector) - - def classification_layer_combo(self, layer): - self.ui.classification_name_combo.addItem(layer) - - def classification_layer_combo_2(self, layer): - self.ui.classification_name_combo_2.addItem(layer) - - def classification_layer_combo_3(self, layer): - self.ui.classification_name_combo_3.addItem(layer) - - def classification_layer_combo_5(self, layer): - self.ui.classification_name_combo_5.addItem(layer) - - def classification_report_combo(self, layer): - self.ui.classification_report_name_combo.addItem(layer) - - def classification_to_vector_combo(self, layer): - self.ui.classification_vector_name_combo.addItem(layer) - - def reclassification_combo(self, layer): - self.ui.reclassification_name_combo.addItem(layer) - - def reference_layer_combo(self, shape): - self.ui.reference_name_combo.addItem(shape) - - def reference_layer_combo_2(self, shape): - self.ui.reference_name_combo_2.addItem(shape) - - def reference_layer_combo_3(self, shape): - self.ui.reference_name_combo_3.addItem(shape) - - def classification_reference_layer_combo(self, layer): - self.ui.classification_reference_name_combo.addItem(layer) - - def new_classification_layer_combo(self, layer): - self.ui.new_classification_name_combo.addItem(layer) - - def raster_layer_combo(self, layer): - self.ui.raster_name_combo.addItem(layer) - - def raster_extent_combo(self, layer): - self.ui.raster_extent_combo.addItem(layer) - - def edit_raster_combo(self, layer): - self.ui.edit_raster_name_combo.addItem(layer) - - def sieve_raster_combo(self, layer): - self.ui.sieve_raster_name_combo.addItem(layer) - - def erosion_raster_combo(self, layer): - self.ui.erosion_raster_name_combo.addItem(layer) - - def dilation_raster_combo(self, layer): - self.ui.dilation_raster_name_combo.addItem(layer) - - def cloud_mask_raster_combo(self, layer): - self.ui.classification_name_combo_4.addItem(layer) - - def reference_raster_combo(self, layer): - self.ui.reference_raster_name_combo.addItem(layer) - - def project_raster_combo(self, layer): - self.ui.raster_align_comboBox.addItem(layer) - - def raster_data_type_combo(self, dataType): - self.ui.raster_precision_combo.addItem(dataType) - - def class_field_combo(self, field): - self.ui.class_field_comboBox.addItem(field) - - def class_field_combo_2(self, field): - self.ui.class_field_comboBox_2.addItem(field) - - def class_field_combo_3(self, field): - self.ui.class_field_comboBox_3.addItem(field) - - def class_field_combo_4(self, field): - self.ui.class_field_comboBox_4.addItem(field) - - def reference_field_combo(self, field): - self.ui.field_comboBox.addItem(field) - - def reference_field_combo2(self, field): - self.ui.field_comboBox_2.addItem(field) - - def statistic_name_combo(self, field): - self.ui.statistic_name_combobox.addItem(field) - - def statistic_name_combo2(self, field): - self.ui.statistic_name_combobox_2.addItem(field) - +class SemiAutomaticClassificationPluginDialog(QDialog): + # noinspection PyArgumentList + def __init__(self): + QDialog.__init__(self) + try: + self.setWindowFlags(Qt.Window) + except Exception as err: + str(err) + return + # initialize plugin directory + self.plugin_dir = QFileInfo( + QgsApplication.qgisUserDatabaseFilePath() + ).path() + '/python/plugins/SemiAutomaticClassificationPlugin' + # locale name + self.locale_name = QSettings().value('locale/userLocale')[0:2] + # path to locale + locale_path = '' + if QFileInfo(self.plugin_dir).exists(): + locale_path = ('%s/i18n/semiautomaticclassificationplugin_%s.qm' + % (self.plugin_dir, self.locale_name)) + if QFileInfo(locale_path).exists(): + self.translator = QTranslator() + self.translator.load(locale_path) + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + # Set up the user interface from Designer. + self.ui = Ui_SemiAutomaticClassificationPlugin() + self.ui.setupUi(self) + + def shape_clip_combo(self, shape): + self.ui.shapefile_comboBox.addItem(shape) + + def vector_to_raster_combo(self, vector): + self.ui.vector_name_combo.addItem(vector) + + def classification_layer_combo(self, layer): + self.ui.classification_name_combo.addItem(layer) + + def classification_layer_combo_2(self, layer): + self.ui.classification_name_combo_2.addItem(layer) + + def classification_report_combo(self, layer): + self.ui.classification_report_name_combo.addItem(layer) + + def classification_to_vector_combo(self, layer): + self.ui.classification_vector_name_combo.addItem(layer) + + def reclassification_combo(self, layer): + self.ui.reclassification_name_combo.addItem(layer) + + def reference_layer_combo(self, shape): + self.ui.reference_name_combo.addItem(shape) + + def reference_layer_combo_2(self, shape): + self.ui.reference_name_combo_2.addItem(shape) + + def raster_layer_combo(self, layer): + self.ui.raster_name_combo.addItem(layer) + + def raster_extent_combo(self, layer): + self.ui.raster_extent_combo.addItem(layer) + + def raster_extent_combo_2(self, layer): + self.ui.raster_extent_combo_2.addItem(layer) + + def cloud_mask_raster_combo(self, layer): + self.ui.classification_name_combo_4.addItem(layer) + + def reference_raster_combo(self, layer): + self.ui.reference_raster_name_combo.addItem(layer) + + def project_raster_combo(self, layer): + self.ui.raster_align_comboBox.addItem(layer) + + def class_field_combo(self, field): + self.ui.class_field_comboBox.addItem(field) + + def class_field_combo_2(self, field): + self.ui.class_field_comboBox_2.addItem(field) + + def class_field_combo_3(self, field): + self.ui.class_field_comboBox_3.addItem(field) + + def reference_field_combo(self, field): + self.ui.field_comboBox.addItem(field) + + def statistic_name_combo2(self, field): + self.ui.statistic_name_combobox_2.addItem(field) + + # create the dialog -class DockClassDialog(QtWidgets.QDockWidget): - def __init__(self, parent, iface): - QtWidgets.QDockWidget.__init__(self) - # initialize plugin directory - try: - self.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/SemiAutomaticClassificationPlugin" - except: - return - # locale name - self.lclNm = cfg.QSettingsSCP().value("locale/userLocale")[0:2] - # path to locale - lclPth = "" - if cfg.QFileInfoSCP(self.plgnDir).exists(): - lclPth = self.plgnDir + "/i18n/semiautomaticclassificationplugin_" + self.lclNm + ".qm" - if cfg.QFileInfoSCP(lclPth).exists(): - self.trnsltr = cfg.QtCoreSCP.QTranslator() - self.trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(self.trnsltr) - self.ui = Ui_DockClass() - self.ui.setupUi(self) +class DockClassDialog(QDockWidget): + # noinspection PyArgumentList,PyUnusedLocal + def __init__(self, parent, iface): + QDockWidget.__init__(self) + # initialize plugin directory + try: + self.plugin_dir = QFileInfo( + QgsApplication.qgisUserDatabaseFilePath() + ).path() + '/python/plugins/SemiAutomaticClassificationPlugin' + except Exception as err: + str(err) + return + # locale name + self.locale_name = QSettings().value('locale/userLocale')[0:2] + # path to locale + locale_path = '' + if QFileInfo(self.plugin_dir).exists(): + locale_path = ('%s/i18n/semiautomaticclassificationplugin_%s.qm' + % (self.plugin_dir, self.locale_name)) + if QFileInfo(locale_path).exists(): + self.translator = QTranslator() + self.translator.load(locale_path) + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + self.ui = Ui_DockClass() + self.ui.setupUi(self) + # create the dialog -class ScatterPlotDialog(QtWidgets.QDialog): - def __init__(self): - QtWidgets.QDockWidget.__init__(self) - try: - self.setWindowFlags(cfg.QtSCP.Window) - except: - return - # initialize plugin directory - self.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/SemiAutomaticClassificationPlugin" - # locale name - self.lclNm = cfg.QSettingsSCP().value("locale/userLocale")[0:2] - # path to locale - lclPth = "" - if cfg.QFileInfoSCP(self.plgnDir).exists(): - lclPth = self.plgnDir + "/i18n/semiautomaticclassificationplugin_" + self.lclNm + ".qm" - if cfg.QFileInfoSCP(lclPth).exists(): - self.trnsltr = cfg.QtCoreSCP.QTranslator() - self.trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(self.trnsltr) - self.ui = Ui_ScatterPlot() - self.ui.setupUi(self) - -class SpectralSignatureDialog(QtWidgets.QDialog): - def __init__(self): - QtWidgets.QDockWidget.__init__(self) - self.setWindowFlags(cfg.QtSCP.Window) - # initialize plugin directory - self.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/SemiAutomaticClassificationPlugin" - # locale name - self.lclNm = cfg.QSettingsSCP().value("locale/userLocale")[0:2] - # path to locale - lclPth = "" - if cfg.QFileInfoSCP(self.plgnDir).exists(): - lclPth = self.plgnDir + "/i18n/semiautomaticclassificationplugin_" + self.lclNm + ".qm" - if cfg.QFileInfoSCP(lclPth).exists(): - self.trnsltr = cfg.QtCoreSCP.QTranslator() - self.trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(self.trnsltr) - self.ui = Ui_SpectralSignaturePlot() - self.ui.setupUi(self) - -class WelcomeDialog(QtWidgets.QDialog): - def __init__(self): - QtWidgets.QDockWidget.__init__(self) - try: - self.setWindowFlags(cfg.QtSCP.Window) - except: - return - # initialize plugin directory - self.plgnDir = cfg.QFileInfoSCP(cfg.qgisCoreSCP.QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/SemiAutomaticClassificationPlugin" - # locale name - self.lclNm = cfg.QSettingsSCP().value("locale/userLocale")[0:2] - # path to locale - lclPth = "" - if cfg.QFileInfoSCP(self.plgnDir).exists(): - lclPth = self.plgnDir + "/i18n/semiautomaticclassificationplugin_" + self.lclNm + ".qm" - if cfg.QFileInfoSCP(lclPth).exists(): - self.trnsltr = cfg.QtCoreSCP.QTranslator() - self.trnsltr.load(lclPth) - if cfg.QtCoreSCP.qVersion() > '4.3.3': - cfg.QtCoreSCP.QCoreApplication.installTranslator(self.trnsltr) - self.ui = Ui_SCP_Welcome() - self.ui.setupUi(self) \ No newline at end of file +# noinspection PyMissingConstructor +class ScatterPlotDialog(QDialog): + # noinspection PyArgumentList + def __init__(self): + QDockWidget.__init__(self) + try: + self.setWindowFlags(Qt.Window) + except Exception as err: + str(err) + return + # initialize plugin directory + self.plugin_dir = QFileInfo( + QgsApplication.qgisUserDatabaseFilePath() + ).path() + '/python/plugins/SemiAutomaticClassificationPlugin' + # locale name + self.locale_name = QSettings().value('locale/userLocale')[0:2] + # path to locale + locale_path = '' + if QFileInfo(self.plugin_dir).exists(): + locale_path = ('%s/i18n/semiautomaticclassificationplugin_%s.qm' + % (self.plugin_dir, self.locale_name)) + if QFileInfo(locale_path).exists(): + self.translator = QTranslator() + self.translator.load(locale_path) + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + self.ui = Ui_ScatterPlot() + self.ui.setupUi(self) + + +# noinspection PyMissingConstructor +class SpectralSignatureDialog(QDialog): + # noinspection PyArgumentList + def __init__(self): + QDockWidget.__init__(self) + self.setWindowFlags(Qt.Window) + # initialize plugin directory + self.plugin_dir = QFileInfo( + QgsApplication.qgisUserDatabaseFilePath() + ).path() + '/python/plugins/SemiAutomaticClassificationPlugin' + # locale name + self.locale_name = QSettings().value('locale/userLocale')[0:2] + # path to locale + locale_path = '' + if QFileInfo(self.plugin_dir).exists(): + locale_path = ('%s/i18n/semiautomaticclassificationplugin_%s.qm' + % (self.plugin_dir, self.locale_name)) + if QFileInfo(locale_path).exists(): + self.translator = QTranslator() + self.translator.load(locale_path) + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + self.ui = Ui_SpectralSignaturePlot() + self.ui.setupUi(self) + + +# noinspection PyMissingConstructor +class WidgetDialog(QDialog): + def __init__(self): + QDockWidget.__init__(self) + try: + self.setWindowFlags(Qt.Window) + except Exception as err: + str(err) + self.ui = Ui_SCP_Widget() + self.ui.setupUi(self) diff --git a/ui/sigwidget2.py b/ui/sigwidget2.py old mode 100644 new mode 100755 index 0fdadf6..bfae8cb --- a/ui/sigwidget2.py +++ b/ui/sigwidget2.py @@ -1,83 +1,79 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin +# SemiAutomaticClassificationPlugin +# The Semi-Automatic Classification Plugin for QGIS allows for the supervised +# classification of remote sensing images, providing tools for the download, +# the preprocessing and postprocessing of images. +# begin: 2012-12-29 +# Copyright (C) 2012-2023 by Luca Congedo. +# Author: Luca Congedo +# Email: ing.congedoluca@gmail.com +# +# This file is part of SemiAutomaticClassificationPlugin. +# SemiAutomaticClassificationPlugin is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# SemiAutomaticClassificationPlugin is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with SemiAutomaticClassificationPlugin. +# If not, see . - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' # Import PyQt libraries -from PyQt5 import QtGui, QtWidgets -from PyQt5.QtWidgets import QWidget +from PyQt5.QtWidgets import QWidget, QGridLayout + # Import FigureCanvas try: - import matplotlib -except: - pass -try: - matplotlib.use('Qt5Agg') -except: - pass + import matplotlib + + matplotlib.use('Qt5Agg') +except Exception as error: + str(error) try: - from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigCanvas - # Import Figure - from matplotlib.figure import Figure -except: - FigCanvas = QWidget + from matplotlib.backends.backend_qt5agg import ( + FigureCanvasQTAgg as FigCanvas + ) + # Import Figure + from matplotlib.figure import Figure +except Exception as error: + str(error) + FigCanvas = QWidget + class SigCanvas(FigCanvas): - def __init__(self): - try: - # Figure - self.figure = Figure() - # Add subplot for plot and legend - self.ax = self.figure.add_axes([0.1, 0.15, 0.8, 0.8]) - # Canvas initialization - FigCanvas.__init__(self, self.figure) - except: - return None - # Set empty ticks - self.ax.set_xticks([]) - self.ax.set_yticks([]) + + # noinspection PyMissingConstructor + def __init__(self): + try: + # Figure + self.figure = Figure() + # Add subplot for plot and legend + self.ax = self.figure.add_axes([0.1, 0.15, 0.8, 0.8]) + # Canvas initialization + FigCanvas.__init__(self, self.figure) + # Set empty ticks + self.ax.set_xticks([]) + self.ax.set_yticks([]) + except Exception as err: + str(err) + class SigWidget2(QWidget): - def __init__(self, parent = None): - try: - # Widget initialization - QWidget.__init__(self, parent) - # Widget canvas - self.sigCanvas = SigCanvas() - # Create grid layout - self.gridLayout = QtWidgets.QGridLayout() - # Add widget to grid - self.gridLayout.addWidget(self.sigCanvas) - except: - return None - # Set layout - self.setLayout(self.gridLayout) \ No newline at end of file + + # noinspection PyArgumentList + def __init__(self, parent=None): + try: + # Widget initialization + QWidget.__init__(self, parent) + # Widget canvas + self.sigCanvas = SigCanvas() + # Create grid layout + self.gridLayout = QGridLayout() + # Add widget to grid + self.gridLayout.addWidget(self.sigCanvas) + # Set layout + self.setLayout(self.gridLayout) + except Exception as err: + str(err) diff --git a/ui/ui_semiautomaticclassificationplugin.py b/ui/ui_semiautomaticclassificationplugin.py old mode 100644 new mode 100755 index c01a7f7..47110d2 --- a/ui/ui_semiautomaticclassificationplugin.py +++ b/ui/ui_semiautomaticclassificationplugin.py @@ -2,17 +2,20 @@ # Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin.ui' # -# Created by: PyQt5 UI code generator 5.11.3 +# Created by: PyQt5 UI code generator 5.15.9 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_SemiAutomaticClassificationPlugin(object): def setupUi(self, SemiAutomaticClassificationPlugin): SemiAutomaticClassificationPlugin.setObjectName("SemiAutomaticClassificationPlugin") SemiAutomaticClassificationPlugin.setEnabled(True) - SemiAutomaticClassificationPlugin.resize(951, 529) + SemiAutomaticClassificationPlugin.resize(959, 558) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -29,6 +32,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.splitter = QtWidgets.QSplitter(SemiAutomaticClassificationPlugin) self.splitter.setFrameShape(QtWidgets.QFrame.NoFrame) self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter.setHandleWidth(4) self.splitter.setChildrenCollapsible(False) self.splitter.setObjectName("splitter") self.widget = QtWidgets.QWidget(self.splitter) @@ -37,6 +41,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.widget.setObjectName("widget") self.gridLayout_193 = QtWidgets.QGridLayout(self.widget) self.gridLayout_193.setContentsMargins(1, 1, 1, 1) + self.gridLayout_193.setHorizontalSpacing(2) self.gridLayout_193.setObjectName("gridLayout_193") self.f_filter_lineEdit = QtWidgets.QLineEdit(self.widget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) @@ -78,14 +83,16 @@ def setupUi(self, SemiAutomaticClassificationPlugin): font.setWeight(75) item_0.setFont(0, font) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_0.setIcon(0, icon2) - item_1 = QtWidgets.QTreeWidgetItem(item_0) + item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item_0.setFont(0, font) icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_weight_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon3) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - item_1.setIcon(0, icon1) + icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon3) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon4 = QtGui.QIcon() icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export_spectral_library.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) @@ -96,240 +103,163 @@ def setupUi(self, SemiAutomaticClassificationPlugin): item_1.setIcon(0, icon5) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_multiple.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon6) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_multiple.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon7) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon8) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon9 = QtGui.QIcon() - icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon9) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) item_0.setFont(0, font) + icon9 = QtGui.QIcon() + icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon9) + item_1 = QtWidgets.QTreeWidgetItem(item_0) icon10 = QtGui.QIcon() - icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon10) - item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - item_0.setFont(0, font) + icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_1.setIcon(0, icon10) + item_1 = QtWidgets.QTreeWidgetItem(item_0) icon11 = QtGui.QIcon() - icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon11) + icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_landsat8_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_1.setIcon(0, icon11) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon12 = QtGui.QIcon() - icon12.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_aster_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon12.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cloud_masking_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon12) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon13 = QtGui.QIcon() - icon13.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_goes_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon13.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_mosaic_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon13) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon14 = QtGui.QIcon() - icon14.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_landsat8_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon14.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reproject_raster_bands.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon14) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon15 = QtGui.QIcon() - icon15.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_modis_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon15.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_split_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon15) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon16 = QtGui.QIcon() - icon16.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel1_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon16.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_stack_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon16) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon17 = QtGui.QIcon() - icon17.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon17.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_vector_to_raster_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon17) - item_1 = QtWidgets.QTreeWidgetItem(item_0) + item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item_0.setFont(0, font) icon18 = QtGui.QIcon() - icon18.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel3_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon18) + icon18.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon18) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon19 = QtGui.QIcon() - icon19.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon19.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon19) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon20 = QtGui.QIcon() - icon20.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cloud_masking_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon20.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_combination_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon20) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon21 = QtGui.QIcon() - icon21.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_mosaic_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon21.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon21) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon22 = QtGui.QIcon() - icon22.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon22.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon22) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon23 = QtGui.QIcon() - icon23.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reproject_raster_bands.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon23.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon23) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon24 = QtGui.QIcon() - icon24.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_split_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon24.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon24) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon25 = QtGui.QIcon() - icon25.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_stack_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon25.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon25) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon26 = QtGui.QIcon() - icon26.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_vector_to_raster_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon26) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) item_0.setFont(0, font) + icon26 = QtGui.QIcon() + icon26.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon26) + item_1 = QtWidgets.QTreeWidgetItem(item_0) icon27 = QtGui.QIcon() - icon27.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon27) + icon27.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_1.setIcon(0, icon27) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon28 = QtGui.QIcon() - icon28.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_combination_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon28.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_report_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon28) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon29 = QtGui.QIcon() - icon29.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon29.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon29) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon30 = QtGui.QIcon() - icon30.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_kmeans_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon30.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cross_classification.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon30) item_1 = QtWidgets.QTreeWidgetItem(item_0) icon31 = QtGui.QIcon() - icon31.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon31.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reclassification_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) item_1.setIcon(0, icon31) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon32 = QtGui.QIcon() - icon32.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_random_forest.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon32) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon33 = QtGui.QIcon() - icon33.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_spectral_distance.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon33) - item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - item_0.setFont(0, font) - icon34 = QtGui.QIcon() - icon34.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon34) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon35 = QtGui.QIcon() - icon35.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon35) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon36 = QtGui.QIcon() - icon36.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon36) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon37 = QtGui.QIcon() - icon37.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon37) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon38 = QtGui.QIcon() - icon38.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_report_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon38) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon39 = QtGui.QIcon() - icon39.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon39) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon40 = QtGui.QIcon() - icon40.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon40) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon41 = QtGui.QIcon() - icon41.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_signature_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon41) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon42 = QtGui.QIcon() - icon42.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cross_classification.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon42) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon43 = QtGui.QIcon() - icon43.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_edit_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon43) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon44 = QtGui.QIcon() - icon44.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_land_cover_change.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon44) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon45 = QtGui.QIcon() - icon45.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reclassification_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon45) - item_1 = QtWidgets.QTreeWidgetItem(item_0) - icon46 = QtGui.QIcon() - icon46.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_1.setIcon(0, icon46) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) item_0.setFont(0, font) - icon47 = QtGui.QIcon() - icon47.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon47) + icon32 = QtGui.QIcon() + icon32.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon32) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) item_0.setFont(0, font) - icon48 = QtGui.QIcon() - icon48.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon48) + icon33 = QtGui.QIcon() + icon33.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon33) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) item_0.setFont(0, font) - icon49 = QtGui.QIcon() - icon49.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_settings_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon49) + icon34 = QtGui.QIcon() + icon34.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_settings_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon34) item_1 = QtWidgets.QTreeWidgetItem(item_0) item_1 = QtWidgets.QTreeWidgetItem(item_0) item_1 = QtWidgets.QTreeWidgetItem(item_0) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) - icon50 = QtGui.QIcon() - icon50.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/guide.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon50) - item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) - icon51 = QtGui.QIcon() - icon51.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/help.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon51) + icon35 = QtGui.QIcon() + icon35.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/guide.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon35) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - item_0.setFont(0, font) - icon52 = QtGui.QIcon() - icon52.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - item_0.setIcon(0, icon52) + icon36 = QtGui.QIcon() + icon36.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/help.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon36) item_0 = QtWidgets.QTreeWidgetItem(self.menu_treeWidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - font.setStrikeOut(False) item_0.setFont(0, font) - brush = QtGui.QBrush(QtGui.QColor(92, 184, 92)) - brush.setStyle(QtCore.Qt.SolidPattern) - item_0.setBackground(0, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.NoBrush) - item_0.setForeground(0, brush) - item_0.setIcon(0, icon) + icon37 = QtGui.QIcon() + icon37.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item_0.setIcon(0, icon37) self.gridLayout_193.addWidget(self.menu_treeWidget, 1, 0, 1, 1) self.main_tabWidget = QtWidgets.QTabWidget(self.splitter) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum) @@ -345,8 +275,8 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.main_tabWidget.setObjectName("main_tabWidget") self.tool_tab = QtWidgets.QWidget() self.tool_tab.setObjectName("tool_tab") - self.gridLayout_262 = QtWidgets.QGridLayout(self.tool_tab) - self.gridLayout_262.setObjectName("gridLayout_262") + self.gridLayout_60 = QtWidgets.QGridLayout(self.tool_tab) + self.gridLayout_60.setObjectName("gridLayout_60") self.SCP_tabs = QtWidgets.QTabWidget(self.tool_tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) @@ -359,187 +289,160 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.SCP_tabs.setObjectName("SCP_tabs") self.tab_band_set = QtWidgets.QWidget() self.tab_band_set.setObjectName("tab_band_set") - self.gridLayout_219 = QtWidgets.QGridLayout(self.tab_band_set) - self.gridLayout_219.setObjectName("gridLayout_219") - self.gridLayout_52 = QtWidgets.QGridLayout() - self.gridLayout_52.setObjectName("gridLayout_52") - self.label_59 = QtWidgets.QLabel(self.tab_band_set) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_59.sizePolicy().hasHeightForWidth()) - self.label_59.setSizePolicy(sizePolicy) - self.label_59.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_59.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_59.setWordWrap(False) - self.label_59.setObjectName("label_59") - self.gridLayout_52.addWidget(self.label_59, 0, 0, 1, 1) - self.wavelength_sat_combo = QtWidgets.QComboBox(self.tab_band_set) - self.wavelength_sat_combo.setObjectName("wavelength_sat_combo") - self.gridLayout_52.addWidget(self.wavelength_sat_combo, 0, 1, 1, 1) - self.gridLayout_50 = QtWidgets.QGridLayout() + self.gridLayout_50 = QtWidgets.QGridLayout(self.tab_band_set) + self.gridLayout_50.setContentsMargins(3, 3, 3, 3) self.gridLayout_50.setObjectName("gridLayout_50") - self.label_60 = QtWidgets.QLabel(self.tab_band_set) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_60.sizePolicy().hasHeightForWidth()) - self.label_60.setSizePolicy(sizePolicy) - self.label_60.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_60.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_60.setObjectName("label_60") - self.gridLayout_50.addWidget(self.label_60, 0, 0, 1, 1) - self.unit_combo = QtWidgets.QComboBox(self.tab_band_set) - self.unit_combo.setMinimumSize(QtCore.QSize(100, 0)) - self.unit_combo.setObjectName("unit_combo") - self.gridLayout_50.addWidget(self.unit_combo, 0, 1, 1, 1) - self.export_bandset_toolButton = QtWidgets.QToolButton(self.tab_band_set) - self.export_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") - icon53 = QtGui.QIcon() - icon53.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.export_bandset_toolButton.setIcon(icon53) - self.export_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_bandset_toolButton.setObjectName("export_bandset_toolButton") - self.gridLayout_50.addWidget(self.export_bandset_toolButton, 0, 5, 1, 1) - self.import_bandset_toolButton = QtWidgets.QToolButton(self.tab_band_set) - self.import_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") - icon54 = QtGui.QIcon() - icon54.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.import_bandset_toolButton.setIcon(icon54) - self.import_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_bandset_toolButton.setObjectName("import_bandset_toolButton") - self.gridLayout_50.addWidget(self.import_bandset_toolButton, 0, 4, 1, 1) - self.bandset_dateEdit = QtWidgets.QDateEdit(self.tab_band_set) + self.splitter_3 = QtWidgets.QSplitter(self.tab_band_set) + self.splitter_3.setOrientation(QtCore.Qt.Horizontal) + self.splitter_3.setHandleWidth(0) + self.splitter_3.setChildrenCollapsible(False) + self.splitter_3.setObjectName("splitter_3") + self.widget_bandset_tab = QtWidgets.QWidget(self.splitter_3) + self.widget_bandset_tab.setMinimumSize(QtCore.QSize(60, 0)) + self.widget_bandset_tab.setMaximumSize(QtCore.QSize(500, 16777215)) + self.widget_bandset_tab.setObjectName("widget_bandset_tab") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.widget_bandset_tab) + self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_2.setSpacing(2) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.band_set_filter_lineEdit = QtWidgets.QLineEdit(self.widget_bandset_tab) + self.band_set_filter_lineEdit.setMinimumSize(QtCore.QSize(30, 0)) + self.band_set_filter_lineEdit.setObjectName("band_set_filter_lineEdit") + self.verticalLayout_2.addWidget(self.band_set_filter_lineEdit) + self.bandset_tableWidget = QtWidgets.QTableWidget(self.widget_bandset_tab) + self.bandset_tableWidget.setMinimumSize(QtCore.QSize(150, 0)) + self.bandset_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.bandset_tableWidget.setAlternatingRowColors(True) + self.bandset_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.bandset_tableWidget.setGridStyle(QtCore.Qt.SolidLine) + self.bandset_tableWidget.setObjectName("bandset_tableWidget") + self.bandset_tableWidget.setColumnCount(1) + self.bandset_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.bandset_tableWidget.setHorizontalHeaderItem(0, item) + self.bandset_tableWidget.horizontalHeader().setStretchLastSection(True) + self.verticalLayout_2.addWidget(self.bandset_tableWidget) + self.gridLayout_130 = QtWidgets.QGridLayout() + self.gridLayout_130.setObjectName("gridLayout_130") + self.move_up_toolButton_4 = QtWidgets.QToolButton(self.widget_bandset_tab) + self.move_up_toolButton_4.setStyleSheet("margin: 0px;padding: 0px;") + icon38 = QtGui.QIcon() + icon38.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.move_up_toolButton_4.setIcon(icon38) + self.move_up_toolButton_4.setIconSize(QtCore.QSize(22, 22)) + self.move_up_toolButton_4.setObjectName("move_up_toolButton_4") + self.gridLayout_130.addWidget(self.move_up_toolButton_4, 1, 1, 1, 1) + self.add_band_set_toolButton = QtWidgets.QToolButton(self.widget_bandset_tab) + self.add_band_set_toolButton.setStyleSheet("margin: 0px;padding: 0px") + icon39 = QtGui.QIcon() + icon39.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.add_band_set_toolButton.setIcon(icon39) + self.add_band_set_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.add_band_set_toolButton.setObjectName("add_band_set_toolButton") + self.gridLayout_130.addWidget(self.add_band_set_toolButton, 0, 0, 1, 1) + self.move_down_toolButton_4 = QtWidgets.QToolButton(self.widget_bandset_tab) + self.move_down_toolButton_4.setStyleSheet("margin: 0px;padding: 0px;") + icon40 = QtGui.QIcon() + icon40.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.move_down_toolButton_4.setIcon(icon40) + self.move_down_toolButton_4.setIconSize(QtCore.QSize(22, 22)) + self.move_down_toolButton_4.setObjectName("move_down_toolButton_4") + self.gridLayout_130.addWidget(self.move_down_toolButton_4, 1, 0, 1, 1) + self.remove_bandset_toolButton = QtWidgets.QToolButton(self.widget_bandset_tab) + self.remove_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") + icon41 = QtGui.QIcon() + icon41.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.remove_bandset_toolButton.setIcon(icon41) + self.remove_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.remove_bandset_toolButton.setObjectName("remove_bandset_toolButton") + self.gridLayout_130.addWidget(self.remove_bandset_toolButton, 0, 1, 1, 1) + self.sort_by_date = QtWidgets.QToolButton(self.widget_bandset_tab) + self.sort_by_date.setStyleSheet("margin: 0px;padding: 0px;") + icon42 = QtGui.QIcon() + icon42.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_date.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.sort_by_date.setIcon(icon42) + self.sort_by_date.setIconSize(QtCore.QSize(22, 22)) + self.sort_by_date.setObjectName("sort_by_date") + self.gridLayout_130.addWidget(self.sort_by_date, 0, 2, 1, 1) + self.rgb_toolButton = QtWidgets.QToolButton(self.widget_bandset_tab) + self.rgb_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.rgb_toolButton.setIcon(icon7) + self.rgb_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.rgb_toolButton.setObjectName("rgb_toolButton") + self.gridLayout_130.addWidget(self.rgb_toolButton, 1, 2, 1, 1) + self.verticalLayout_2.addLayout(self.gridLayout_130) + self.frame_2 = QtWidgets.QFrame(self.splitter_3) + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + self.gridLayout_11 = QtWidgets.QGridLayout(self.frame_2) + self.gridLayout_11.setContentsMargins(2, 2, 2, 2) + self.gridLayout_11.setSpacing(2) + self.gridLayout_11.setObjectName("gridLayout_11") + self.gridLayout_42 = QtWidgets.QGridLayout() + self.gridLayout_42.setObjectName("gridLayout_42") + self.gridLayout_65 = QtWidgets.QGridLayout() + self.gridLayout_65.setObjectName("gridLayout_65") + self.label_154 = QtWidgets.QLabel(self.frame_2) + self.label_154.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_154.setFrameShape(QtWidgets.QFrame.Panel) + self.label_154.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_154.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_154.setObjectName("label_154") + self.gridLayout_65.addWidget(self.label_154, 0, 0, 1, 5) + self.gridLayout_127 = QtWidgets.QGridLayout() + self.gridLayout_127.setObjectName("gridLayout_127") + self.bandset_dateEdit = QtWidgets.QDateEdit(self.frame_2) self.bandset_dateEdit.setDateTime(QtCore.QDateTime(QtCore.QDate(2020, 1, 1), QtCore.QTime(0, 0, 0))) self.bandset_dateEdit.setMaximumDate(QtCore.QDate(2045, 12, 31)) self.bandset_dateEdit.setMinimumDate(QtCore.QDate(1972, 1, 1)) self.bandset_dateEdit.setCalendarPopup(True) self.bandset_dateEdit.setDate(QtCore.QDate(2020, 1, 1)) self.bandset_dateEdit.setObjectName("bandset_dateEdit") - self.gridLayout_50.addWidget(self.bandset_dateEdit, 0, 3, 1, 1) - self.label_3 = QtWidgets.QLabel(self.tab_band_set) - self.label_3.setObjectName("label_3") - self.gridLayout_50.addWidget(self.label_3, 0, 2, 1, 1) - self.gridLayout_52.addLayout(self.gridLayout_50, 0, 2, 1, 1) - self.gridLayout_219.addLayout(self.gridLayout_52, 2, 0, 1, 2) - self.splitter_3 = QtWidgets.QSplitter(self.tab_band_set) - self.splitter_3.setOrientation(QtCore.Qt.Vertical) - self.splitter_3.setChildrenCollapsible(False) - self.splitter_3.setObjectName("splitter_3") - self.widget_5 = QtWidgets.QWidget(self.splitter_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.widget_5.sizePolicy().hasHeightForWidth()) - self.widget_5.setSizePolicy(sizePolicy) - self.widget_5.setMinimumSize(QtCore.QSize(0, 50)) - self.widget_5.setObjectName("widget_5") - self.gridLayout_203 = QtWidgets.QGridLayout(self.widget_5) - self.gridLayout_203.setContentsMargins(1, 1, 1, 1) - self.gridLayout_203.setObjectName("gridLayout_203") - self.gridLayout_59 = QtWidgets.QGridLayout() - self.gridLayout_59.setObjectName("gridLayout_59") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_59.addItem(spacerItem, 2, 1, 1, 1) - self.label_52 = QtWidgets.QLabel(self.widget_5) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_52.sizePolicy().hasHeightForWidth()) - self.label_52.setSizePolicy(sizePolicy) - self.label_52.setStyleSheet("background-color : #656565; color : white") - self.label_52.setFrameShape(QtWidgets.QFrame.Panel) - self.label_52.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_52.setObjectName("label_52") - self.gridLayout_59.addWidget(self.label_52, 0, 0, 1, 1) - self.bands_filter_lineEdit = QtWidgets.QLineEdit(self.widget_5) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.bands_filter_lineEdit.sizePolicy().hasHeightForWidth()) - self.bands_filter_lineEdit.setSizePolicy(sizePolicy) - self.bands_filter_lineEdit.setObjectName("bands_filter_lineEdit") - self.gridLayout_59.addWidget(self.bands_filter_lineEdit, 0, 1, 1, 1) - self.gridLayout_69 = QtWidgets.QGridLayout() - self.gridLayout_69.setObjectName("gridLayout_69") - self.bands_tableWidget = QtWidgets.QTableWidget(self.widget_5) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding) + self.gridLayout_127.addWidget(self.bandset_dateEdit, 0, 6, 1, 1) + self.unit_combo = QtWidgets.QComboBox(self.frame_2) + self.unit_combo.setMinimumSize(QtCore.QSize(100, 0)) + self.unit_combo.setObjectName("unit_combo") + self.gridLayout_127.addWidget(self.unit_combo, 0, 4, 1, 1) + self.label_94 = QtWidgets.QLabel(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.bands_tableWidget.sizePolicy().hasHeightForWidth()) - self.bands_tableWidget.setSizePolicy(sizePolicy) - self.bands_tableWidget.setMinimumSize(QtCore.QSize(0, 30)) - self.bands_tableWidget.setFrameShadow(QtWidgets.QFrame.Sunken) - self.bands_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.bands_tableWidget.setTabKeyNavigation(True) - self.bands_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.bands_tableWidget.setObjectName("bands_tableWidget") - self.bands_tableWidget.setColumnCount(1) - self.bands_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.bands_tableWidget.setHorizontalHeaderItem(0, item) - self.bands_tableWidget.horizontalHeader().setVisible(False) - self.bands_tableWidget.horizontalHeader().setStretchLastSection(True) - self.bands_tableWidget.verticalHeader().setVisible(False) - self.gridLayout_69.addWidget(self.bands_tableWidget, 0, 0, 1, 1) - self.gridLayout_60 = QtWidgets.QGridLayout() - self.gridLayout_60.setObjectName("gridLayout_60") - self.toolButton_reload_3 = QtWidgets.QToolButton(self.widget_5) - self.toolButton_reload_3.setStyleSheet("margin: 0px;padding: 0px") - icon55 = QtGui.QIcon() - icon55.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.toolButton_reload_3.setIcon(icon55) - self.toolButton_reload_3.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_3.setObjectName("toolButton_reload_3") - self.gridLayout_60.addWidget(self.toolButton_reload_3, 1, 0, 1, 1) - self.select_all_bands_Button = QtWidgets.QToolButton(self.widget_5) - self.select_all_bands_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon56 = QtGui.QIcon() - icon56.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.select_all_bands_Button.setIcon(icon56) - self.select_all_bands_Button.setIconSize(QtCore.QSize(22, 22)) - self.select_all_bands_Button.setObjectName("select_all_bands_Button") - self.gridLayout_60.addWidget(self.select_all_bands_Button, 2, 0, 1, 1) - self.add_raster_bands_Button = QtWidgets.QToolButton(self.widget_5) - self.add_raster_bands_Button.setStyleSheet("margin: 0px;padding: 0px") - icon57 = QtGui.QIcon() - icon57.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.add_raster_bands_Button.setIcon(icon57) - self.add_raster_bands_Button.setIconSize(QtCore.QSize(22, 22)) - self.add_raster_bands_Button.setObjectName("add_raster_bands_Button") - self.gridLayout_60.addWidget(self.add_raster_bands_Button, 3, 0, 1, 1) - self.gridLayout_69.addLayout(self.gridLayout_60, 0, 1, 1, 1) - self.gridLayout_59.addLayout(self.gridLayout_69, 1, 0, 2, 2) - self.gridLayout_203.addLayout(self.gridLayout_59, 0, 0, 1, 1) - self.widget_6 = QtWidgets.QWidget(self.splitter_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.widget_6.sizePolicy().hasHeightForWidth()) - self.widget_6.setSizePolicy(sizePolicy) - self.widget_6.setMinimumSize(QtCore.QSize(0, 50)) - self.widget_6.setObjectName("widget_6") - self.gridLayout_217 = QtWidgets.QGridLayout(self.widget_6) - self.gridLayout_217.setContentsMargins(1, 1, 1, 1) - self.gridLayout_217.setObjectName("gridLayout_217") - self.gridLayout_11 = QtWidgets.QGridLayout() - self.gridLayout_11.setObjectName("gridLayout_11") - self.gridLayout_42 = QtWidgets.QGridLayout() - self.gridLayout_42.setObjectName("gridLayout_42") - self.label_53 = QtWidgets.QLabel(self.widget_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) + sizePolicy.setHeightForWidth(self.label_94.sizePolicy().hasHeightForWidth()) + self.label_94.setSizePolicy(sizePolicy) + self.label_94.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_94.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_94.setObjectName("label_94") + self.gridLayout_127.addWidget(self.label_94, 0, 3, 1, 1) + self.label_6 = QtWidgets.QLabel(self.frame_2) + self.label_6.setObjectName("label_6") + self.gridLayout_127.addWidget(self.label_6, 0, 5, 1, 1) + self.toolButton_custom_wavelength = QtWidgets.QToolButton(self.frame_2) + self.toolButton_custom_wavelength.setStyleSheet("margin: 0px;padding: 0px;") + icon43 = QtGui.QIcon() + icon43.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.toolButton_custom_wavelength.setIcon(icon43) + self.toolButton_custom_wavelength.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_custom_wavelength.setObjectName("toolButton_custom_wavelength") + self.gridLayout_127.addWidget(self.toolButton_custom_wavelength, 0, 2, 1, 1) + self.wavelength_sat_combo = QtWidgets.QComboBox(self.frame_2) + self.wavelength_sat_combo.setObjectName("wavelength_sat_combo") + self.gridLayout_127.addWidget(self.wavelength_sat_combo, 0, 1, 1, 1) + self.label_150 = QtWidgets.QLabel(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_53.sizePolicy().hasHeightForWidth()) - self.label_53.setSizePolicy(sizePolicy) - self.label_53.setStyleSheet("background-color : #656565; color : white") - self.label_53.setFrameShape(QtWidgets.QFrame.Panel) - self.label_53.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_53.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_53.setObjectName("label_53") - self.gridLayout_42.addWidget(self.label_53, 0, 0, 1, 1) - self.gridLayout_11.addLayout(self.gridLayout_42, 0, 0, 1, 2) - self.Band_set_tabWidget = QtWidgets.QTabWidget(self.widget_6) + sizePolicy.setHeightForWidth(self.label_150.sizePolicy().hasHeightForWidth()) + self.label_150.setSizePolicy(sizePolicy) + self.label_150.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_150.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_150.setWordWrap(False) + self.label_150.setObjectName("label_150") + self.gridLayout_127.addWidget(self.label_150, 0, 0, 1, 1) + self.gridLayout_65.addLayout(self.gridLayout_127, 1, 0, 1, 5) + self.gridLayout_42.addLayout(self.gridLayout_65, 2, 0, 1, 2) + self.Band_set_tabWidget = QtWidgets.QTabWidget(self.frame_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -556,7621 +459,5046 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.Band_set_tabWidget.setTabsClosable(True) self.Band_set_tabWidget.setMovable(True) self.Band_set_tabWidget.setObjectName("Band_set_tabWidget") - self.gridLayout_11.addWidget(self.Band_set_tabWidget, 1, 0, 1, 1) - self.gridLayout_65 = QtWidgets.QGridLayout() - self.gridLayout_65.setObjectName("gridLayout_65") + self.gridLayout_42.addWidget(self.Band_set_tabWidget, 1, 0, 1, 1) + self.gridLayout_59 = QtWidgets.QGridLayout() + self.gridLayout_59.setObjectName("gridLayout_59") + self.virtual_raster_bandset_checkBox = QtWidgets.QCheckBox(self.frame_2) + self.virtual_raster_bandset_checkBox.setObjectName("virtual_raster_bandset_checkBox") + self.gridLayout_59.addWidget(self.virtual_raster_bandset_checkBox, 1, 0, 1, 1) + self.band_calc_checkBox = QtWidgets.QCheckBox(self.frame_2) + self.band_calc_checkBox.setObjectName("band_calc_checkBox") + self.gridLayout_59.addWidget(self.band_calc_checkBox, 1, 3, 1, 1) + self.stack_raster_bandset_checkBox = QtWidgets.QCheckBox(self.frame_2) + self.stack_raster_bandset_checkBox.setObjectName("stack_raster_bandset_checkBox") + self.gridLayout_59.addWidget(self.stack_raster_bandset_checkBox, 1, 1, 1, 1) + self.overview_raster_bandset_checkBox = QtWidgets.QCheckBox(self.frame_2) + self.overview_raster_bandset_checkBox.setObjectName("overview_raster_bandset_checkBox") + self.gridLayout_59.addWidget(self.overview_raster_bandset_checkBox, 1, 2, 1, 1) + self.label_208 = QtWidgets.QLabel(self.frame_2) + self.label_208.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_208.setFrameShape(QtWidgets.QFrame.Panel) + self.label_208.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_208.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_208.setObjectName("label_208") + self.gridLayout_59.addWidget(self.label_208, 0, 0, 1, 7) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_59.addItem(spacerItem, 1, 4, 1, 1) + self.band_set_process_toolButton = QtWidgets.QToolButton(self.frame_2) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.band_set_process_toolButton.setFont(font) + self.band_set_process_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.band_set_process_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon44 = QtGui.QIcon() + icon44.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.band_set_process_toolButton.setIcon(icon44) + self.band_set_process_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.band_set_process_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.band_set_process_toolButton.setObjectName("band_set_process_toolButton") + self.gridLayout_59.addWidget(self.band_set_process_toolButton, 1, 5, 1, 1) + self.gridLayout_42.addLayout(self.gridLayout_59, 3, 0, 1, 2) + self.horizontalLayout_77 = QtWidgets.QHBoxLayout() + self.horizontalLayout_77.setObjectName("horizontalLayout_77") + self.label_59 = QtWidgets.QLabel(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_59.sizePolicy().hasHeightForWidth()) + self.label_59.setSizePolicy(sizePolicy) + self.label_59.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_59.setFrameShape(QtWidgets.QFrame.Panel) + self.label_59.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_59.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_59.setObjectName("label_59") + self.horizontalLayout_77.addWidget(self.label_59) + self.bandset_number_spinBox = QtWidgets.QSpinBox(self.frame_2) + self.bandset_number_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.bandset_number_spinBox.setMinimum(1) + self.bandset_number_spinBox.setMaximum(1) + self.bandset_number_spinBox.setProperty("value", 1) + self.bandset_number_spinBox.setObjectName("bandset_number_spinBox") + self.horizontalLayout_77.addWidget(self.bandset_number_spinBox) + self.label_bandset_date_4 = QtWidgets.QLabel(self.frame_2) + self.label_bandset_date_4.setObjectName("label_bandset_date_4") + self.horizontalLayout_77.addWidget(self.label_bandset_date_4) + self.bandset_date_lineEdit = QtWidgets.QLineEdit(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.bandset_date_lineEdit.sizePolicy().hasHeightForWidth()) + self.bandset_date_lineEdit.setSizePolicy(sizePolicy) + self.bandset_date_lineEdit.setMinimumSize(QtCore.QSize(80, 0)) + self.bandset_date_lineEdit.setMaxLength(10000) + self.bandset_date_lineEdit.setObjectName("bandset_date_lineEdit") + self.horizontalLayout_77.addWidget(self.bandset_date_lineEdit) + self.label_289 = QtWidgets.QLabel(self.frame_2) + self.label_289.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_289.setAlignment(QtCore.Qt.AlignCenter) + self.label_289.setObjectName("label_289") + self.horizontalLayout_77.addWidget(self.label_289) + self.root_dir_lineEdit = QtWidgets.QLineEdit(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.root_dir_lineEdit.sizePolicy().hasHeightForWidth()) + self.root_dir_lineEdit.setSizePolicy(sizePolicy) + self.root_dir_lineEdit.setMinimumSize(QtCore.QSize(200, 0)) + self.root_dir_lineEdit.setMaxLength(10000) + self.root_dir_lineEdit.setObjectName("root_dir_lineEdit") + self.horizontalLayout_77.addWidget(self.root_dir_lineEdit) + self.gridLayout_42.addLayout(self.horizontalLayout_77, 0, 0, 1, 2) self.gridLayout_169 = QtWidgets.QGridLayout() self.gridLayout_169.setObjectName("gridLayout_169") - self.remove_toolButton = QtWidgets.QToolButton(self.widget_6) + self.gridLayout_197 = QtWidgets.QGridLayout() + self.gridLayout_197.setObjectName("gridLayout_197") + self.remove_toolButton = QtWidgets.QToolButton(self.frame_2) self.remove_toolButton.setStyleSheet("margin: 0px;padding: 0px") - icon58 = QtGui.QIcon() - icon58.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.remove_toolButton.setIcon(icon58) + self.remove_toolButton.setIcon(icon41) self.remove_toolButton.setIconSize(QtCore.QSize(22, 22)) self.remove_toolButton.setObjectName("remove_toolButton") - self.gridLayout_169.addWidget(self.remove_toolButton, 0, 0, 1, 1) - self.clear_bandset_toolButton = QtWidgets.QToolButton(self.widget_6) + self.gridLayout_197.addWidget(self.remove_toolButton, 1, 0, 1, 1) + self.clear_bandset_toolButton = QtWidgets.QToolButton(self.frame_2) self.clear_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon59 = QtGui.QIcon() - icon59.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.clear_bandset_toolButton.setIcon(icon59) + icon45 = QtGui.QIcon() + icon45.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.clear_bandset_toolButton.setIcon(icon45) self.clear_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) self.clear_bandset_toolButton.setObjectName("clear_bandset_toolButton") - self.gridLayout_169.addWidget(self.clear_bandset_toolButton, 1, 0, 1, 1) - self.gridLayout_65.addLayout(self.gridLayout_169, 1, 0, 1, 2) - self.gridLayout_127 = QtWidgets.QGridLayout() - self.gridLayout_127.setObjectName("gridLayout_127") - self.sort_by_name_toolButton = QtWidgets.QToolButton(self.widget_6) + self.gridLayout_197.addWidget(self.clear_bandset_toolButton, 2, 0, 1, 1) + self.verticalLayout_11 = QtWidgets.QVBoxLayout() + self.verticalLayout_11.setObjectName("verticalLayout_11") + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_11.addItem(spacerItem1) + self.import_bandset_toolButton = QtWidgets.QToolButton(self.frame_2) + self.import_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") + icon46 = QtGui.QIcon() + icon46.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.import_bandset_toolButton.setIcon(icon46) + self.import_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.import_bandset_toolButton.setObjectName("import_bandset_toolButton") + self.verticalLayout_11.addWidget(self.import_bandset_toolButton) + self.export_bandset_toolButton = QtWidgets.QToolButton(self.frame_2) + self.export_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") + icon47 = QtGui.QIcon() + icon47.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.export_bandset_toolButton.setIcon(icon47) + self.export_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.export_bandset_toolButton.setObjectName("export_bandset_toolButton") + self.verticalLayout_11.addWidget(self.export_bandset_toolButton) + self.gridLayout_197.addLayout(self.verticalLayout_11, 3, 0, 1, 1) + spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_197.addItem(spacerItem2, 0, 0, 1, 1) + self.gridLayout_169.addLayout(self.gridLayout_197, 1, 0, 1, 2) + self.gridLayout_203 = QtWidgets.QGridLayout() + self.gridLayout_203.setObjectName("gridLayout_203") + self.sort_by_name_toolButton = QtWidgets.QToolButton(self.frame_2) self.sort_by_name_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon60 = QtGui.QIcon() - icon60.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.sort_by_name_toolButton.setIcon(icon60) + icon48 = QtGui.QIcon() + icon48.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.sort_by_name_toolButton.setIcon(icon48) self.sort_by_name_toolButton.setIconSize(QtCore.QSize(22, 22)) self.sort_by_name_toolButton.setObjectName("sort_by_name_toolButton") - self.gridLayout_127.addWidget(self.sort_by_name_toolButton, 3, 0, 1, 1) - self.move_up_toolButton = QtWidgets.QToolButton(self.widget_6) - self.move_up_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon61 = QtGui.QIcon() - icon61.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.move_up_toolButton.setIcon(icon61) - self.move_up_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.move_up_toolButton.setObjectName("move_up_toolButton") - self.gridLayout_127.addWidget(self.move_up_toolButton, 1, 0, 1, 1) - self.move_down_toolButton = QtWidgets.QToolButton(self.widget_6) + self.gridLayout_203.addWidget(self.sort_by_name_toolButton, 5, 0, 1, 1) + self.toolButton_input_raster = QtWidgets.QToolButton(self.frame_2) + self.toolButton_input_raster.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_input_raster.setIcon(icon43) + self.toolButton_input_raster.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_input_raster.setObjectName("toolButton_input_raster") + self.gridLayout_203.addWidget(self.toolButton_input_raster, 0, 0, 1, 1) + self.move_down_toolButton = QtWidgets.QToolButton(self.frame_2) self.move_down_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon62 = QtGui.QIcon() - icon62.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.move_down_toolButton.setIcon(icon62) + self.move_down_toolButton.setIcon(icon40) self.move_down_toolButton.setIconSize(QtCore.QSize(22, 22)) self.move_down_toolButton.setObjectName("move_down_toolButton") - self.gridLayout_127.addWidget(self.move_down_toolButton, 2, 0, 1, 1) - self.add_band_set_toolButton = QtWidgets.QToolButton(self.widget_6) - self.add_band_set_toolButton.setStyleSheet("margin: 0px;padding: 0px") - icon63 = QtGui.QIcon() - icon63.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.add_band_set_toolButton.setIcon(icon63) - self.add_band_set_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.add_band_set_toolButton.setObjectName("add_band_set_toolButton") - self.gridLayout_127.addWidget(self.add_band_set_toolButton, 0, 0, 1, 1) - self.gridLayout_65.addLayout(self.gridLayout_127, 0, 0, 1, 2) - self.gridLayout_11.addLayout(self.gridLayout_65, 1, 1, 1, 1) - self.gridLayout_217.addLayout(self.gridLayout_11, 0, 0, 1, 1) - self.gridLayout_219.addWidget(self.splitter_3, 1, 0, 1, 2) - self.gridLayout_53 = QtWidgets.QGridLayout() - self.gridLayout_53.setObjectName("gridLayout_53") - self.virtual_raster_bandset_checkBox = QtWidgets.QCheckBox(self.tab_band_set) - self.virtual_raster_bandset_checkBox.setObjectName("virtual_raster_bandset_checkBox") - self.gridLayout_53.addWidget(self.virtual_raster_bandset_checkBox, 1, 0, 1, 1) - self.band_calc_checkBox = QtWidgets.QCheckBox(self.tab_band_set) - self.band_calc_checkBox.setObjectName("band_calc_checkBox") - self.gridLayout_53.addWidget(self.band_calc_checkBox, 1, 3, 1, 1) - self.stack_raster_bandset_checkBox = QtWidgets.QCheckBox(self.tab_band_set) - self.stack_raster_bandset_checkBox.setObjectName("stack_raster_bandset_checkBox") - self.gridLayout_53.addWidget(self.stack_raster_bandset_checkBox, 1, 1, 1, 1) - self.overview_raster_bandset_checkBox = QtWidgets.QCheckBox(self.tab_band_set) - self.overview_raster_bandset_checkBox.setObjectName("overview_raster_bandset_checkBox") - self.gridLayout_53.addWidget(self.overview_raster_bandset_checkBox, 1, 2, 1, 1) - self.label_94 = QtWidgets.QLabel(self.tab_band_set) - self.label_94.setStyleSheet("background-color : #656565; color : white") - self.label_94.setFrameShape(QtWidgets.QFrame.Panel) - self.label_94.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_94.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_94.setObjectName("label_94") - self.gridLayout_53.addWidget(self.label_94, 0, 0, 1, 7) - spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_53.addItem(spacerItem1, 1, 4, 1, 1) - self.band_set_process_toolButton = QtWidgets.QToolButton(self.tab_band_set) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.band_set_process_toolButton.setFont(font) - self.band_set_process_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.band_set_process_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon64 = QtGui.QIcon() - icon64.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.band_set_process_toolButton.setIcon(icon64) - self.band_set_process_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.band_set_process_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.band_set_process_toolButton.setObjectName("band_set_process_toolButton") - self.gridLayout_53.addWidget(self.band_set_process_toolButton, 1, 5, 1, 1) - self.gridLayout_219.addLayout(self.gridLayout_53, 3, 0, 1, 2) - self.gridLayout_130 = QtWidgets.QGridLayout() - self.gridLayout_130.setObjectName("gridLayout_130") - self.toolButton_reload = QtWidgets.QToolButton(self.tab_band_set) - self.toolButton_reload.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload.setIcon(icon55) - self.toolButton_reload.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload.setObjectName("toolButton_reload") - self.gridLayout_130.addWidget(self.toolButton_reload, 1, 4, 1, 1) - self.label_39 = QtWidgets.QLabel(self.tab_band_set) - self.label_39.setStyleSheet("background-color : #656565; color : white") - self.label_39.setFrameShape(QtWidgets.QFrame.Panel) - self.label_39.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_39.setObjectName("label_39") - self.gridLayout_130.addWidget(self.label_39, 0, 0, 1, 5) - self.toolButton_input_raster = QtWidgets.QToolButton(self.tab_band_set) - self.toolButton_input_raster.setStyleSheet("margin: 0px;padding: 0px;") - icon65 = QtGui.QIcon() - icon65.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.toolButton_input_raster.setIcon(icon65) - self.toolButton_input_raster.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_input_raster.setObjectName("toolButton_input_raster") - self.gridLayout_130.addWidget(self.toolButton_input_raster, 1, 3, 1, 1) - self.image_raster_name_combo = QtWidgets.QComboBox(self.tab_band_set) - self.image_raster_name_combo.setObjectName("image_raster_name_combo") - self.gridLayout_130.addWidget(self.image_raster_name_combo, 1, 0, 1, 3) - self.gridLayout_219.addLayout(self.gridLayout_130, 0, 0, 1, 2) - self.SCP_tabs.addTab(self.tab_band_set, "") - self.tab_basic_tools = QtWidgets.QWidget() - self.tab_basic_tools.setObjectName("tab_basic_tools") - self.gridLayout_216 = QtWidgets.QGridLayout(self.tab_basic_tools) - self.gridLayout_216.setObjectName("gridLayout_216") - self.tabWidget_5 = QtWidgets.QTabWidget(self.tab_basic_tools) - self.tabWidget_5.setStyleSheet("") - self.tabWidget_5.setIconSize(QtCore.QSize(20, 20)) - self.tabWidget_5.setDocumentMode(True) - self.tabWidget_5.setObjectName("tabWidget_5") - self.tab_RGB = QtWidgets.QWidget() - self.tab_RGB.setObjectName("tab_RGB") - self.gridLayout_213 = QtWidgets.QGridLayout(self.tab_RGB) - self.gridLayout_213.setObjectName("gridLayout_213") - self.gridLayout_243 = QtWidgets.QGridLayout() - self.gridLayout_243.setObjectName("gridLayout_243") - self.gridLayout_234 = QtWidgets.QGridLayout() - self.gridLayout_234.setObjectName("gridLayout_234") - self.label_126 = QtWidgets.QLabel(self.tab_RGB) - self.label_126.setStyleSheet("background-color : #656565; color : white") - self.label_126.setFrameShape(QtWidgets.QFrame.Panel) - self.label_126.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_126.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_126.setObjectName("label_126") - self.gridLayout_234.addWidget(self.label_126, 0, 0, 1, 1) - self.gridLayout_243.addLayout(self.gridLayout_234, 0, 0, 1, 2) - self.gridLayout_244 = QtWidgets.QGridLayout() - self.gridLayout_244.setObjectName("gridLayout_244") - spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_244.addItem(spacerItem2, 3, 0, 1, 1) - self.sort_by_name_toolButton_2 = QtWidgets.QToolButton(self.tab_RGB) - self.sort_by_name_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.sort_by_name_toolButton_2.setIcon(icon60) - self.sort_by_name_toolButton_2.setIconSize(QtCore.QSize(22, 22)) - self.sort_by_name_toolButton_2.setObjectName("sort_by_name_toolButton_2") - self.gridLayout_244.addWidget(self.sort_by_name_toolButton_2, 2, 0, 1, 1) - self.move_down_toolButton_3 = QtWidgets.QToolButton(self.tab_RGB) - self.move_down_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") - self.move_down_toolButton_3.setIcon(icon62) - self.move_down_toolButton_3.setIconSize(QtCore.QSize(22, 22)) - self.move_down_toolButton_3.setObjectName("move_down_toolButton_3") - self.gridLayout_244.addWidget(self.move_down_toolButton_3, 1, 0, 1, 1) - self.move_up_toolButton_3 = QtWidgets.QToolButton(self.tab_RGB) - self.move_up_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") - self.move_up_toolButton_3.setIcon(icon61) - self.move_up_toolButton_3.setIconSize(QtCore.QSize(22, 22)) - self.move_up_toolButton_3.setObjectName("move_up_toolButton_3") - self.gridLayout_244.addWidget(self.move_up_toolButton_3, 0, 0, 1, 1) - self.gridLayout_243.addLayout(self.gridLayout_244, 1, 1, 1, 1) - self.gridLayout_245 = QtWidgets.QGridLayout() - self.gridLayout_245.setObjectName("gridLayout_245") - self.add_RGB_pushButton = QtWidgets.QToolButton(self.tab_RGB) - self.add_RGB_pushButton.setStyleSheet("margin: 0px;padding: 0px") - icon66 = QtGui.QIcon() - icon66.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.add_RGB_pushButton.setIcon(icon66) - self.add_RGB_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_RGB_pushButton.setObjectName("add_RGB_pushButton") - self.gridLayout_245.addWidget(self.add_RGB_pushButton, 0, 0, 1, 1) - self.export_RGB_List_toolButton = QtWidgets.QToolButton(self.tab_RGB) - self.export_RGB_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_RGB_List_toolButton.setIcon(icon53) - self.export_RGB_List_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_RGB_List_toolButton.setObjectName("export_RGB_List_toolButton") - self.gridLayout_245.addWidget(self.export_RGB_List_toolButton, 4, 0, 1, 1) - self.import_RGB_List_toolButton = QtWidgets.QToolButton(self.tab_RGB) - self.import_RGB_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_RGB_List_toolButton.setIcon(icon54) - self.import_RGB_List_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_RGB_List_toolButton.setObjectName("import_RGB_List_toolButton") - self.gridLayout_245.addWidget(self.import_RGB_List_toolButton, 5, 0, 1, 1) - self.clear_RGB_list_toolButton = QtWidgets.QToolButton(self.tab_RGB) - self.clear_RGB_list_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.clear_RGB_list_toolButton.setIcon(icon59) - self.clear_RGB_list_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.clear_RGB_list_toolButton.setObjectName("clear_RGB_list_toolButton") - self.gridLayout_245.addWidget(self.clear_RGB_list_toolButton, 2, 0, 1, 1) - self.remove_RGB_toolButton = QtWidgets.QToolButton(self.tab_RGB) - self.remove_RGB_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.remove_RGB_toolButton.setIcon(icon58) - self.remove_RGB_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_RGB_toolButton.setObjectName("remove_RGB_toolButton") - self.gridLayout_245.addWidget(self.remove_RGB_toolButton, 1, 0, 1, 1) + self.gridLayout_203.addWidget(self.move_down_toolButton, 4, 0, 1, 1) + self.add_loaded_bands_pushButton = QtWidgets.QToolButton(self.frame_2) + self.add_loaded_bands_pushButton.setStyleSheet("margin: 0px;padding: 0px") + icon49 = QtGui.QIcon() + icon49.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.add_loaded_bands_pushButton.setIcon(icon49) + self.add_loaded_bands_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_loaded_bands_pushButton.setObjectName("add_loaded_bands_pushButton") + self.gridLayout_203.addWidget(self.add_loaded_bands_pushButton, 1, 0, 1, 1) spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_245.addItem(spacerItem3, 3, 0, 1, 1) - self.gridLayout_243.addLayout(self.gridLayout_245, 2, 1, 1, 1) - self.RGB_tableWidget = QtWidgets.QTableWidget(self.tab_RGB) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_203.addItem(spacerItem3, 2, 0, 1, 1) + self.move_up_toolButton = QtWidgets.QToolButton(self.frame_2) + self.move_up_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.move_up_toolButton.setIcon(icon38) + self.move_up_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.move_up_toolButton.setObjectName("move_up_toolButton") + self.gridLayout_203.addWidget(self.move_up_toolButton, 3, 0, 1, 1) + self.gridLayout_169.addLayout(self.gridLayout_203, 0, 0, 1, 2) + self.gridLayout_42.addLayout(self.gridLayout_169, 1, 1, 1, 1) + self.gridLayout_11.addLayout(self.gridLayout_42, 0, 0, 1, 1) + self.gridLayout_50.addWidget(self.splitter_3, 0, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_band_set, "") + self.tab_download_products = QtWidgets.QWidget() + self.tab_download_products.setObjectName("tab_download_products") + self.gridLayout_68 = QtWidgets.QGridLayout(self.tab_download_products) + self.gridLayout_68.setContentsMargins(3, 3, 3, 3) + self.gridLayout_68.setObjectName("gridLayout_68") + self.gridLayout_113 = QtWidgets.QGridLayout() + self.gridLayout_113.setObjectName("gridLayout_113") + self.tabWidget_3 = QtWidgets.QTabWidget(self.tab_download_products) + self.tabWidget_3.setStyleSheet("QTabBar::tab {\n" +"padding: 10px;\n" +"min-height: 18px;\n" +"}") + self.tabWidget_3.setTabPosition(QtWidgets.QTabWidget.North) + self.tabWidget_3.setObjectName("tabWidget_3") + self.tab_search = QtWidgets.QWidget() + self.tab_search.setObjectName("tab_search") + self.gridLayout_87 = QtWidgets.QGridLayout(self.tab_search) + self.gridLayout_87.setObjectName("gridLayout_87") + self.gridLayout_133 = QtWidgets.QGridLayout() + self.gridLayout_133.setObjectName("gridLayout_133") + self.gridLayout_54 = QtWidgets.QGridLayout() + self.gridLayout_54.setObjectName("gridLayout_54") + self.toolButton_OSM = QtWidgets.QToolButton(self.tab_search) + self.toolButton_OSM.setStyleSheet("margin: 0px;padding: 0px;") + icon50 = QtGui.QIcon() + icon50.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.toolButton_OSM.setIcon(icon50) + self.toolButton_OSM.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_OSM.setObjectName("toolButton_OSM") + self.gridLayout_54.addWidget(self.toolButton_OSM, 0, 0, 1, 1) + self.label_205 = QtWidgets.QLabel(self.tab_search) + self.label_205.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_205.setAlignment(QtCore.Qt.AlignCenter) + self.label_205.setOpenExternalLinks(True) + self.label_205.setObjectName("label_205") + self.gridLayout_54.addWidget(self.label_205, 0, 1, 1, 1) + self.label_206 = QtWidgets.QLabel(self.tab_search) + self.label_206.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_206.setAlignment(QtCore.Qt.AlignCenter) + self.label_206.setOpenExternalLinks(True) + self.label_206.setObjectName("label_206") + self.gridLayout_54.addWidget(self.label_206, 0, 2, 1, 1) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_54.addItem(spacerItem4, 0, 3, 1, 2) + self.gridLayout_133.addLayout(self.gridLayout_54, 3, 0, 1, 2) + self.label_103 = QtWidgets.QLabel(self.tab_search) + self.label_103.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_103.setFrameShape(QtWidgets.QFrame.Panel) + self.label_103.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_103.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_103.setObjectName("label_103") + self.gridLayout_133.addWidget(self.label_103, 0, 0, 1, 2) + self.gridLayout_122 = QtWidgets.QGridLayout() + self.gridLayout_122.setObjectName("gridLayout_122") + self.selectUL_toolButton_3 = QtWidgets.QToolButton(self.tab_search) + self.selectUL_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") + icon51 = QtGui.QIcon() + icon51.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.selectUL_toolButton_3.setIcon(icon51) + self.selectUL_toolButton_3.setIconSize(QtCore.QSize(22, 22)) + self.selectUL_toolButton_3.setObjectName("selectUL_toolButton_3") + self.gridLayout_122.addWidget(self.selectUL_toolButton_3, 0, 7, 1, 1) + self.LX_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) + self.LX_lineEdit_3.setText("") + self.LX_lineEdit_3.setMaxLength(15) + self.LX_lineEdit_3.setObjectName("LX_lineEdit_3") + self.gridLayout_122.addWidget(self.LX_lineEdit_3, 0, 4, 1, 1) + self.UX_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) + self.UX_lineEdit_3.setMaxLength(15) + self.UX_lineEdit_3.setObjectName("UX_lineEdit_3") + self.gridLayout_122.addWidget(self.UX_lineEdit_3, 0, 1, 1, 1) + self.label_105 = QtWidgets.QLabel(self.tab_search) + self.label_105.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_105.setAlignment(QtCore.Qt.AlignCenter) + self.label_105.setObjectName("label_105") + self.gridLayout_122.addWidget(self.label_105, 0, 3, 1, 1) + self.label_107 = QtWidgets.QLabel(self.tab_search) + self.label_107.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_107.setAlignment(QtCore.Qt.AlignCenter) + self.label_107.setObjectName("label_107") + self.gridLayout_122.addWidget(self.label_107, 0, 0, 1, 1) + self.LY_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) + self.LY_lineEdit_3.setMaxLength(15) + self.LY_lineEdit_3.setObjectName("LY_lineEdit_3") + self.gridLayout_122.addWidget(self.LY_lineEdit_3, 0, 5, 1, 1) + self.UY_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) + self.UY_lineEdit_3.setMaxLength(15) + self.UY_lineEdit_3.setObjectName("UY_lineEdit_3") + self.gridLayout_122.addWidget(self.UY_lineEdit_3, 0, 2, 1, 1) + self.show_area_radioButton_2 = QtWidgets.QRadioButton(self.tab_search) + self.show_area_radioButton_2.setChecked(True) + self.show_area_radioButton_2.setAutoExclusive(False) + self.show_area_radioButton_2.setObjectName("show_area_radioButton_2") + self.gridLayout_122.addWidget(self.show_area_radioButton_2, 0, 6, 1, 1) + self.gridLayout_115 = QtWidgets.QGridLayout() + self.gridLayout_115.setObjectName("gridLayout_115") + self.find_images_toolButton = QtWidgets.QToolButton(self.tab_search) + self.find_images_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon52 = QtGui.QIcon() + icon52.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.find_images_toolButton.setIcon(icon52) + self.find_images_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.find_images_toolButton.setObjectName("find_images_toolButton") + self.gridLayout_115.addWidget(self.find_images_toolButton, 1, 8, 1, 1) + self.label_35 = QtWidgets.QLabel(self.tab_search) + self.label_35.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_35.setObjectName("label_35") + self.gridLayout_115.addWidget(self.label_35, 1, 7, 1, 1) + self.gridLayout_114 = QtWidgets.QGridLayout() + self.gridLayout_114.setObjectName("gridLayout_114") + self.landsat_satellite_combo = QtWidgets.QComboBox(self.tab_search) + self.landsat_satellite_combo.setObjectName("landsat_satellite_combo") + self.gridLayout_114.addWidget(self.landsat_satellite_combo, 0, 1, 1, 1) + self.dateEdit_from = QtWidgets.QDateEdit(self.tab_search) + self.dateEdit_from.setDateTime(QtCore.QDateTime(QtCore.QDate(2016, 1, 1), QtCore.QTime(0, 0, 0))) + self.dateEdit_from.setMaximumDate(QtCore.QDate(2045, 12, 31)) + self.dateEdit_from.setMinimumDate(QtCore.QDate(1972, 1, 1)) + self.dateEdit_from.setCalendarPopup(True) + self.dateEdit_from.setDate(QtCore.QDate(2016, 1, 1)) + self.dateEdit_from.setObjectName("dateEdit_from") + self.gridLayout_114.addWidget(self.dateEdit_from, 0, 4, 1, 1) + self.label_110 = QtWidgets.QLabel(self.tab_search) + self.label_110.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_110.setAlignment(QtCore.Qt.AlignCenter) + self.label_110.setObjectName("label_110") + self.gridLayout_114.addWidget(self.label_110, 0, 8, 1, 1) + self.dateEdit_to = QtWidgets.QDateEdit(self.tab_search) + self.dateEdit_to.setMaximumDate(QtCore.QDate(2045, 12, 31)) + self.dateEdit_to.setMinimumDate(QtCore.QDate(1980, 1, 2)) + self.dateEdit_to.setCalendarPopup(True) + self.dateEdit_to.setDate(QtCore.QDate(2045, 12, 31)) + self.dateEdit_to.setObjectName("dateEdit_to") + self.gridLayout_114.addWidget(self.dateEdit_to, 0, 6, 1, 1) + self.label_112 = QtWidgets.QLabel(self.tab_search) + self.label_112.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_112.setAlignment(QtCore.Qt.AlignCenter) + self.label_112.setObjectName("label_112") + self.gridLayout_114.addWidget(self.label_112, 0, 5, 1, 1) + self.label_111 = QtWidgets.QLabel(self.tab_search) + self.label_111.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_111.setAlignment(QtCore.Qt.AlignCenter) + self.label_111.setObjectName("label_111") + self.gridLayout_114.addWidget(self.label_111, 0, 3, 1, 1) + self.cloud_cover_spinBox = QtWidgets.QSpinBox(self.tab_search) + self.cloud_cover_spinBox.setMinimumSize(QtCore.QSize(50, 0)) + self.cloud_cover_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.cloud_cover_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.cloud_cover_spinBox.setMinimum(0) + self.cloud_cover_spinBox.setMaximum(100) + self.cloud_cover_spinBox.setSingleStep(10) + self.cloud_cover_spinBox.setProperty("value", 100) + self.cloud_cover_spinBox.setObjectName("cloud_cover_spinBox") + self.gridLayout_114.addWidget(self.cloud_cover_spinBox, 0, 9, 1, 1) + self.label_114 = QtWidgets.QLabel(self.tab_search) + self.label_114.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_114.setAlignment(QtCore.Qt.AlignCenter) + self.label_114.setObjectName("label_114") + self.gridLayout_114.addWidget(self.label_114, 0, 0, 1, 1) + spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_114.addItem(spacerItem5, 0, 7, 1, 1) + spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_114.addItem(spacerItem6, 0, 2, 1, 1) + self.gridLayout_115.addLayout(self.gridLayout_114, 0, 0, 1, 9) + self.gridLayout_120 = QtWidgets.QGridLayout() + self.gridLayout_120.setObjectName("gridLayout_120") + self.label_194 = QtWidgets.QLabel(self.tab_search) + self.label_194.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_194.setAlignment(QtCore.Qt.AlignCenter) + self.label_194.setObjectName("label_194") + self.gridLayout_120.addWidget(self.label_194, 0, 0, 1, 1) + self.label_113 = QtWidgets.QLabel(self.tab_search) + self.label_113.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_113.setAlignment(QtCore.Qt.AlignCenter) + self.label_113.setObjectName("label_113") + self.gridLayout_120.addWidget(self.label_113, 0, 2, 1, 1) + self.imageID_lineEdit = QtWidgets.QLineEdit(self.tab_search) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.RGB_tableWidget.sizePolicy().hasHeightForWidth()) - self.RGB_tableWidget.setSizePolicy(sizePolicy) - self.RGB_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked) - self.RGB_tableWidget.setAlternatingRowColors(True) - self.RGB_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) - self.RGB_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.RGB_tableWidget.setObjectName("RGB_tableWidget") - self.RGB_tableWidget.setColumnCount(1) - self.RGB_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.RGB_tableWidget.setHorizontalHeaderItem(0, item) - self.RGB_tableWidget.horizontalHeader().setDefaultSectionSize(50) - self.RGB_tableWidget.horizontalHeader().setStretchLastSection(True) - self.RGB_tableWidget.verticalHeader().setDefaultSectionSize(20) - self.gridLayout_243.addWidget(self.RGB_tableWidget, 1, 0, 2, 1) - self.gridLayout_213.addLayout(self.gridLayout_243, 0, 0, 1, 1) - self.gridLayout_246 = QtWidgets.QGridLayout() - self.gridLayout_246.setObjectName("gridLayout_246") - self.label_196 = QtWidgets.QLabel(self.tab_RGB) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_196.sizePolicy().hasHeightForWidth()) - self.label_196.setSizePolicy(sizePolicy) - self.label_196.setStyleSheet("background-color : #656565; color : white") - self.label_196.setFrameShape(QtWidgets.QFrame.Panel) - self.label_196.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_196.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_196.setObjectName("label_196") - self.gridLayout_246.addWidget(self.label_196, 0, 0, 1, 2) - self.horizontalLayout_27 = QtWidgets.QHBoxLayout() - self.horizontalLayout_27.setObjectName("horizontalLayout_27") - self.label_192 = QtWidgets.QLabel(self.tab_RGB) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_192.sizePolicy().hasHeightForWidth()) - self.label_192.setSizePolicy(sizePolicy) - self.label_192.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_192.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_192.setObjectName("label_192") - self.horizontalLayout_27.addWidget(self.label_192) - self.all_RGB_list_toolButton = QtWidgets.QToolButton(self.tab_RGB) - self.all_RGB_list_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon67 = QtGui.QIcon() - icon67.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.all_RGB_list_toolButton.setIcon(icon67) - self.all_RGB_list_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.all_RGB_list_toolButton.setObjectName("all_RGB_list_toolButton") - self.horizontalLayout_27.addWidget(self.all_RGB_list_toolButton) - spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_27.addItem(spacerItem4) - self.gridLayout_246.addLayout(self.horizontalLayout_27, 1, 0, 1, 2) - self.gridLayout_213.addLayout(self.gridLayout_246, 1, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_RGB, "") - self.tab_band_set_list = QtWidgets.QWidget() - self.tab_band_set_list.setObjectName("tab_band_set_list") - self.gridLayout_197 = QtWidgets.QGridLayout(self.tab_band_set_list) - self.gridLayout_197.setObjectName("gridLayout_197") - self.gridLayout_267 = QtWidgets.QGridLayout() - self.gridLayout_267.setObjectName("gridLayout_267") - self.label_208 = QtWidgets.QLabel(self.tab_band_set_list) - self.label_208.setStyleSheet("background-color : #656565; color : white") - self.label_208.setFrameShape(QtWidgets.QFrame.Panel) - self.label_208.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_208.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_208.setObjectName("label_208") - self.gridLayout_267.addWidget(self.label_208, 0, 0, 1, 1) - self.band_set_filter_lineEdit = QtWidgets.QLineEdit(self.tab_band_set_list) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.band_set_filter_lineEdit.sizePolicy().hasHeightForWidth()) - self.band_set_filter_lineEdit.setSizePolicy(sizePolicy) - self.band_set_filter_lineEdit.setObjectName("band_set_filter_lineEdit") - self.gridLayout_267.addWidget(self.band_set_filter_lineEdit, 0, 1, 1, 1) - self.gridLayout_197.addLayout(self.gridLayout_267, 0, 0, 1, 1) - self.band_set_list_tableWidget = QtWidgets.QTableWidget(self.tab_band_set_list) - self.band_set_list_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.band_set_list_tableWidget.setAlternatingRowColors(True) - self.band_set_list_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) - self.band_set_list_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.band_set_list_tableWidget.setObjectName("band_set_list_tableWidget") - self.band_set_list_tableWidget.setColumnCount(3) - self.band_set_list_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.band_set_list_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.band_set_list_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.band_set_list_tableWidget.setHorizontalHeaderItem(2, item) - self.band_set_list_tableWidget.horizontalHeader().setDefaultSectionSize(68) - self.band_set_list_tableWidget.horizontalHeader().setStretchLastSection(True) - self.band_set_list_tableWidget.verticalHeader().setDefaultSectionSize(20) - self.gridLayout_197.addWidget(self.band_set_list_tableWidget, 1, 0, 2, 1) - self.verticalLayout_2 = QtWidgets.QVBoxLayout() - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.move_down_toolButton_4 = QtWidgets.QToolButton(self.tab_band_set_list) - self.move_down_toolButton_4.setStyleSheet("margin: 0px;padding: 0px;") - self.move_down_toolButton_4.setIcon(icon62) - self.move_down_toolButton_4.setIconSize(QtCore.QSize(22, 22)) - self.move_down_toolButton_4.setObjectName("move_down_toolButton_4") - self.verticalLayout_2.addWidget(self.move_down_toolButton_4) - self.move_up_toolButton_4 = QtWidgets.QToolButton(self.tab_band_set_list) - self.move_up_toolButton_4.setStyleSheet("margin: 0px;padding: 0px;") - self.move_up_toolButton_4.setIcon(icon61) - self.move_up_toolButton_4.setIconSize(QtCore.QSize(22, 22)) - self.move_up_toolButton_4.setObjectName("move_up_toolButton_4") - self.verticalLayout_2.addWidget(self.move_up_toolButton_4) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.verticalLayout_2.addItem(spacerItem5) - self.rgb_toolButton = QtWidgets.QToolButton(self.tab_band_set_list) - self.rgb_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.rgb_toolButton.setIcon(icon8) - self.rgb_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.rgb_toolButton.setObjectName("rgb_toolButton") - self.verticalLayout_2.addWidget(self.rgb_toolButton) - self.gridLayout_197.addLayout(self.verticalLayout_2, 1, 1, 1, 1) - self.gridLayout_269 = QtWidgets.QGridLayout() - self.gridLayout_269.setObjectName("gridLayout_269") - self.add_bandset_pushButton = QtWidgets.QToolButton(self.tab_band_set_list) - self.add_bandset_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.add_bandset_pushButton.setIcon(icon66) - self.add_bandset_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_bandset_pushButton.setObjectName("add_bandset_pushButton") - self.gridLayout_269.addWidget(self.add_bandset_pushButton, 2, 0, 1, 1) - self.export_bandset_List_toolButton = QtWidgets.QToolButton(self.tab_band_set_list) - self.export_bandset_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_bandset_List_toolButton.setIcon(icon53) - self.export_bandset_List_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_bandset_List_toolButton.setObjectName("export_bandset_List_toolButton") - self.gridLayout_269.addWidget(self.export_bandset_List_toolButton, 5, 0, 1, 1) - self.import_bandset_List_toolButton = QtWidgets.QToolButton(self.tab_band_set_list) - self.import_bandset_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_bandset_List_toolButton.setIcon(icon54) - self.import_bandset_List_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_bandset_List_toolButton.setObjectName("import_bandset_List_toolButton") - self.gridLayout_269.addWidget(self.import_bandset_List_toolButton, 6, 0, 1, 1) - spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_269.addItem(spacerItem6, 4, 0, 1, 1) - self.remove_bandset_toolButton = QtWidgets.QToolButton(self.tab_band_set_list) - self.remove_bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.remove_bandset_toolButton.setIcon(icon58) - self.remove_bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_bandset_toolButton.setObjectName("remove_bandset_toolButton") - self.gridLayout_269.addWidget(self.remove_bandset_toolButton, 3, 0, 1, 1) - spacerItem7 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_269.addItem(spacerItem7, 1, 0, 1, 1) - self.sort_by_date = QtWidgets.QToolButton(self.tab_band_set_list) - self.sort_by_date.setStyleSheet("margin: 0px;padding: 0px;") - self.sort_by_date.setIcon(icon60) - self.sort_by_date.setIconSize(QtCore.QSize(22, 22)) - self.sort_by_date.setObjectName("sort_by_date") - self.gridLayout_269.addWidget(self.sort_by_date, 0, 0, 1, 1) - self.gridLayout_197.addLayout(self.gridLayout_269, 2, 1, 1, 1) - self.tabWidget_5.addTab(self.tab_band_set_list, "") - self.tab_algorithm_weight = QtWidgets.QWidget() - self.tab_algorithm_weight.setObjectName("tab_algorithm_weight") - self.gridLayout_150 = QtWidgets.QGridLayout(self.tab_algorithm_weight) - self.gridLayout_150.setObjectName("gridLayout_150") - self.gridLayout_100 = QtWidgets.QGridLayout() - self.gridLayout_100.setObjectName("gridLayout_100") - self.gridLayout_108 = QtWidgets.QGridLayout() - self.gridLayout_108.setObjectName("gridLayout_108") - self.label_79 = QtWidgets.QLabel(self.tab_algorithm_weight) - self.label_79.setStyleSheet("background-color : #656565; color : white") - self.label_79.setFrameShape(QtWidgets.QFrame.Panel) - self.label_79.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_79.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_79.setObjectName("label_79") - self.gridLayout_108.addWidget(self.label_79, 0, 0, 1, 1) - self.gridLayout_100.addLayout(self.gridLayout_108, 0, 0, 1, 2) - self.gridLayout_101 = QtWidgets.QGridLayout() - self.gridLayout_101.setObjectName("gridLayout_101") - spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_101.addItem(spacerItem8, 6, 1, 1, 1) - self.gridLayout_104 = QtWidgets.QGridLayout() - self.gridLayout_104.setObjectName("gridLayout_104") - self.gridLayout_102 = QtWidgets.QGridLayout() - self.gridLayout_102.setObjectName("gridLayout_102") - self.reset_weights_pushButton = QtWidgets.QToolButton(self.tab_algorithm_weight) - self.reset_weights_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_weights_pushButton.setIcon(icon59) - self.reset_weights_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.reset_weights_pushButton.setObjectName("reset_weights_pushButton") - self.gridLayout_102.addWidget(self.reset_weights_pushButton, 0, 0, 1, 1) - self.gridLayout_104.addLayout(self.gridLayout_102, 0, 0, 1, 1) - self.gridLayout_101.addLayout(self.gridLayout_104, 5, 0, 1, 3) - spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_101.addItem(spacerItem9, 3, 1, 1, 1) - self.gridLayout_100.addLayout(self.gridLayout_101, 1, 1, 1, 1) - self.gridLayout_103 = QtWidgets.QGridLayout() - self.gridLayout_103.setObjectName("gridLayout_103") - self.set_weight_value_pushButton = QtWidgets.QToolButton(self.tab_algorithm_weight) - self.set_weight_value_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.set_weight_value_pushButton.setIcon(icon67) - self.set_weight_value_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.set_weight_value_pushButton.setObjectName("set_weight_value_pushButton") - self.gridLayout_103.addWidget(self.set_weight_value_pushButton, 1, 2, 1, 1) - self.label_131 = QtWidgets.QLabel(self.tab_algorithm_weight) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_131.sizePolicy().hasHeightForWidth()) - self.label_131.setSizePolicy(sizePolicy) - self.label_131.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_131.setObjectName("label_131") - self.gridLayout_103.addWidget(self.label_131, 1, 0, 1, 1) - self.weight_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_algorithm_weight) - self.weight_doubleSpinBox.setMaximum(1000.0) - self.weight_doubleSpinBox.setProperty("value", 1.0) - self.weight_doubleSpinBox.setObjectName("weight_doubleSpinBox") - self.gridLayout_103.addWidget(self.weight_doubleSpinBox, 1, 1, 1, 1) - spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_103.addItem(spacerItem10, 1, 3, 1, 1) - self.label_93 = QtWidgets.QLabel(self.tab_algorithm_weight) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_93.sizePolicy().hasHeightForWidth()) - self.label_93.setSizePolicy(sizePolicy) - self.label_93.setStyleSheet("background-color : #656565; color : white") - self.label_93.setFrameShape(QtWidgets.QFrame.Panel) - self.label_93.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_93.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_93.setObjectName("label_93") - self.gridLayout_103.addWidget(self.label_93, 0, 0, 1, 4) - self.gridLayout_100.addLayout(self.gridLayout_103, 2, 0, 1, 2) - self.alg_band_weight_tabWidget = QtWidgets.QTabWidget(self.tab_algorithm_weight) - self.alg_band_weight_tabWidget.setTabPosition(QtWidgets.QTabWidget.North) - self.alg_band_weight_tabWidget.setObjectName("alg_band_weight_tabWidget") - self.gridLayout_100.addWidget(self.alg_band_weight_tabWidget, 1, 0, 1, 1) - self.gridLayout_150.addLayout(self.gridLayout_100, 0, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_algorithm_weight, "") - self.tab_multiple_ROI = QtWidgets.QWidget() - self.tab_multiple_ROI.setObjectName("tab_multiple_ROI") - self.gridLayout_247 = QtWidgets.QGridLayout(self.tab_multiple_ROI) - self.gridLayout_247.setObjectName("gridLayout_247") - self.gridLayout_8 = QtWidgets.QGridLayout() - self.gridLayout_8.setObjectName("gridLayout_8") - self.point_distance_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.point_distance_spinBox.sizePolicy().hasHeightForWidth()) - self.point_distance_spinBox.setSizePolicy(sizePolicy) - self.point_distance_spinBox.setMinimumSize(QtCore.QSize(40, 0)) - self.point_distance_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.point_distance_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.point_distance_spinBox.setMinimum(1) - self.point_distance_spinBox.setMaximum(999999999) - self.point_distance_spinBox.setProperty("value", 100) - self.point_distance_spinBox.setObjectName("point_distance_spinBox") - self.gridLayout_8.addWidget(self.point_distance_spinBox, 1, 5, 1, 1) - self.point_grid_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.point_grid_spinBox.sizePolicy().hasHeightForWidth()) - self.point_grid_spinBox.setSizePolicy(sizePolicy) - self.point_grid_spinBox.setMinimumSize(QtCore.QSize(40, 0)) - self.point_grid_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.point_grid_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.point_grid_spinBox.setMinimum(1) - self.point_grid_spinBox.setMaximum(999999999) - self.point_grid_spinBox.setProperty("value", 10000) - self.point_grid_spinBox.setObjectName("point_grid_spinBox") - self.gridLayout_8.addWidget(self.point_grid_spinBox, 1, 3, 1, 1) - self.label_48 = QtWidgets.QLabel(self.tab_multiple_ROI) - self.label_48.setStyleSheet("background-color : #656565; color : white") - self.label_48.setFrameShape(QtWidgets.QFrame.Panel) - self.label_48.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_48.setObjectName("label_48") - self.gridLayout_8.addWidget(self.label_48, 0, 0, 1, 9) - self.label_139 = QtWidgets.QLabel(self.tab_multiple_ROI) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_139.sizePolicy().hasHeightForWidth()) - self.label_139.setSizePolicy(sizePolicy) - self.label_139.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_139.setObjectName("label_139") - self.gridLayout_8.addWidget(self.label_139, 1, 7, 1, 1) - self.label_19 = QtWidgets.QLabel(self.tab_multiple_ROI) - self.label_19.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_19.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_19.setObjectName("label_19") - self.gridLayout_8.addWidget(self.label_19, 1, 0, 1, 1) - self.point_number_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.point_number_spinBox.sizePolicy().hasHeightForWidth()) - self.point_number_spinBox.setSizePolicy(sizePolicy) - self.point_number_spinBox.setMinimumSize(QtCore.QSize(40, 0)) - self.point_number_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.point_number_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.point_number_spinBox.setMinimum(1) - self.point_number_spinBox.setMaximum(999999999) - self.point_number_spinBox.setProperty("value", 100) - self.point_number_spinBox.setObjectName("point_number_spinBox") - self.gridLayout_8.addWidget(self.point_number_spinBox, 1, 1, 1, 1) - self.add_random_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - self.add_random_point_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.add_random_point_pushButton.setIcon(icon67) - self.add_random_point_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_random_point_pushButton.setObjectName("add_random_point_pushButton") - self.gridLayout_8.addWidget(self.add_random_point_pushButton, 1, 8, 1, 1) - self.point_distance_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) - self.point_distance_checkBox.setObjectName("point_distance_checkBox") - self.gridLayout_8.addWidget(self.point_distance_checkBox, 1, 4, 1, 1) - self.point_grid_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) - self.point_grid_checkBox.setObjectName("point_grid_checkBox") - self.gridLayout_8.addWidget(self.point_grid_checkBox, 1, 2, 1, 1) - spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_8.addItem(spacerItem11, 1, 6, 1, 1) - self.stratified_point_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) - self.stratified_point_checkBox.setObjectName("stratified_point_checkBox") - self.gridLayout_8.addWidget(self.stratified_point_checkBox, 2, 0, 1, 2) - self.stratified_lineEdit = QtWidgets.QLineEdit(self.tab_multiple_ROI) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.stratified_lineEdit.sizePolicy().hasHeightForWidth()) - self.stratified_lineEdit.setSizePolicy(sizePolicy) - self.stratified_lineEdit.setMinimumSize(QtCore.QSize(400, 0)) - self.stratified_lineEdit.setMaxLength(10000) - self.stratified_lineEdit.setObjectName("stratified_lineEdit") - self.gridLayout_8.addWidget(self.stratified_lineEdit, 2, 2, 1, 4) - self.band_set_comb_spinBox_10 = QtWidgets.QSpinBox(self.tab_multiple_ROI) - self.band_set_comb_spinBox_10.setMinimum(1) - self.band_set_comb_spinBox_10.setMaximum(100000) - self.band_set_comb_spinBox_10.setObjectName("band_set_comb_spinBox_10") - self.gridLayout_8.addWidget(self.band_set_comb_spinBox_10, 2, 8, 1, 1) - self.label_25 = QtWidgets.QLabel(self.tab_multiple_ROI) - self.label_25.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_25.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_25.setObjectName("label_25") - self.gridLayout_8.addWidget(self.label_25, 2, 6, 1, 2) - self.gridLayout_247.addLayout(self.gridLayout_8, 0, 0, 1, 1) - self.gridLayout_32 = QtWidgets.QGridLayout() - self.gridLayout_32.setObjectName("gridLayout_32") - self.label_47 = QtWidgets.QLabel(self.tab_multiple_ROI) - self.label_47.setStyleSheet("background-color : #656565; color : white") - self.label_47.setFrameShape(QtWidgets.QFrame.Panel) - self.label_47.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_47.setObjectName("label_47") - self.gridLayout_32.addWidget(self.label_47, 0, 0, 1, 2) - self.point_tableWidget = QtWidgets.QTableWidget(self.tab_multiple_ROI) - self.point_tableWidget.setAlternatingRowColors(True) - self.point_tableWidget.setObjectName("point_tableWidget") - self.point_tableWidget.setColumnCount(10) - self.point_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(3, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(4, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(5, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(6, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(7, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(8, item) - item = QtWidgets.QTableWidgetItem() - self.point_tableWidget.setHorizontalHeaderItem(9, item) - self.point_tableWidget.horizontalHeader().setDefaultSectionSize(90) - self.point_tableWidget.verticalHeader().setDefaultSectionSize(24) - self.gridLayout_32.addWidget(self.point_tableWidget, 1, 0, 1, 1) - self.gridLayout_72 = QtWidgets.QGridLayout() - self.gridLayout_72.setObjectName("gridLayout_72") - self.gridLayout_39 = QtWidgets.QGridLayout() - self.gridLayout_39.setObjectName("gridLayout_39") - spacerItem12 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_39.addItem(spacerItem12, 3, 0, 1, 1) - self.add_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - self.add_point_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.add_point_pushButton.setIcon(icon66) - self.add_point_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_point_pushButton.setObjectName("add_point_pushButton") - self.gridLayout_39.addWidget(self.add_point_pushButton, 1, 0, 1, 1) - self.remove_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - self.remove_point_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.remove_point_pushButton.setIcon(icon58) - self.remove_point_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_point_pushButton.setObjectName("remove_point_pushButton") - self.gridLayout_39.addWidget(self.remove_point_pushButton, 2, 0, 1, 1) - self.export_point_list_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - self.export_point_list_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_point_list_pushButton.setIcon(icon53) - self.export_point_list_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.export_point_list_pushButton.setObjectName("export_point_list_pushButton") - self.gridLayout_39.addWidget(self.export_point_list_pushButton, 5, 0, 1, 1) - spacerItem13 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_39.addItem(spacerItem13, 6, 0, 1, 1) - self.import_point_list_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - self.import_point_list_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_point_list_pushButton.setIcon(icon54) - self.import_point_list_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.import_point_list_pushButton.setObjectName("import_point_list_pushButton") - self.gridLayout_39.addWidget(self.import_point_list_pushButton, 4, 0, 1, 1) - spacerItem14 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_39.addItem(spacerItem14, 0, 0, 1, 1) - self.gridLayout_72.addLayout(self.gridLayout_39, 2, 0, 1, 1) - self.gridLayout_32.addLayout(self.gridLayout_72, 1, 1, 1, 1) - self.gridLayout_73 = QtWidgets.QGridLayout() - self.gridLayout_73.setObjectName("gridLayout_73") - spacerItem15 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_73.addItem(spacerItem15, 1, 4, 1, 1) - self.signature_checkBox2 = QtWidgets.QCheckBox(self.tab_multiple_ROI) - self.signature_checkBox2.setChecked(True) - self.signature_checkBox2.setObjectName("signature_checkBox2") - self.gridLayout_73.addWidget(self.signature_checkBox2, 1, 5, 1, 1) - self.label_159 = QtWidgets.QLabel(self.tab_multiple_ROI) - self.label_159.setStyleSheet("background-color : #656565; color : white") - self.label_159.setFrameShape(QtWidgets.QFrame.Panel) - self.label_159.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_159.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_159.setObjectName("label_159") - self.gridLayout_73.addWidget(self.label_159, 0, 4, 1, 3) - self.save_point_rois_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.save_point_rois_pushButton.setFont(font) - self.save_point_rois_pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.save_point_rois_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.save_point_rois_pushButton.setIcon(icon64) - self.save_point_rois_pushButton.setIconSize(QtCore.QSize(34, 34)) - self.save_point_rois_pushButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.save_point_rois_pushButton.setObjectName("save_point_rois_pushButton") - self.gridLayout_73.addWidget(self.save_point_rois_pushButton, 1, 6, 1, 1) - self.gridLayout_32.addLayout(self.gridLayout_73, 3, 0, 1, 2) - self.gridLayout_247.addLayout(self.gridLayout_32, 1, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_multiple_ROI, "") - self.tab_Import = QtWidgets.QWidget() - self.tab_Import.setObjectName("tab_Import") - self.gridLayout_168 = QtWidgets.QGridLayout(self.tab_Import) - self.gridLayout_168.setObjectName("gridLayout_168") - self.toolBox_4 = QtWidgets.QToolBox(self.tab_Import) - self.toolBox_4.setObjectName("toolBox_4") - self.page_8 = QtWidgets.QWidget() - self.page_8.setGeometry(QtCore.QRect(0, 0, 357, 448)) - self.page_8.setObjectName("page_8") - self.gridLayout_4 = QtWidgets.QGridLayout(self.page_8) - self.gridLayout_4.setObjectName("gridLayout_4") - self.gridLayout_31 = QtWidgets.QGridLayout() - self.gridLayout_31.setObjectName("gridLayout_31") - self.usgs_chapter_comboBox = QtWidgets.QComboBox(self.page_8) - self.usgs_chapter_comboBox.setObjectName("usgs_chapter_comboBox") - self.gridLayout_31.addWidget(self.usgs_chapter_comboBox, 0, 1, 1, 1) - self.usgs_library_comboBox = QtWidgets.QComboBox(self.page_8) - self.usgs_library_comboBox.setObjectName("usgs_library_comboBox") - self.gridLayout_31.addWidget(self.usgs_library_comboBox, 1, 1, 1, 1) - self.gridLayout_14 = QtWidgets.QGridLayout() - self.gridLayout_14.setObjectName("gridLayout_14") - self.gridLayout_31.addLayout(self.gridLayout_14, 2, 1, 1, 1) - self.label_123 = QtWidgets.QLabel(self.page_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_123.sizePolicy().hasHeightForWidth()) - self.label_123.setSizePolicy(sizePolicy) - self.label_123.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_123.setObjectName("label_123") - self.gridLayout_31.addWidget(self.label_123, 0, 0, 1, 1) - self.label_124 = QtWidgets.QLabel(self.page_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_124.sizePolicy().hasHeightForWidth()) - self.label_124.setSizePolicy(sizePolicy) - self.label_124.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_124.setObjectName("label_124") - self.gridLayout_31.addWidget(self.label_124, 1, 0, 1, 1) - self.gridLayout_12 = QtWidgets.QGridLayout() - self.gridLayout_12.setObjectName("gridLayout_12") - spacerItem16 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_12.addItem(spacerItem16, 0, 0, 1, 1) - self.label_130 = QtWidgets.QLabel(self.page_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_130.sizePolicy().hasHeightForWidth()) - self.label_130.setSizePolicy(sizePolicy) - self.label_130.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_130.setObjectName("label_130") - self.gridLayout_12.addWidget(self.label_130, 0, 1, 1, 1) - self.add_usgs_library_pushButton = QtWidgets.QToolButton(self.page_8) - self.add_usgs_library_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.add_usgs_library_pushButton.setIcon(icon67) - self.add_usgs_library_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_usgs_library_pushButton.setObjectName("add_usgs_library_pushButton") - self.gridLayout_12.addWidget(self.add_usgs_library_pushButton, 0, 2, 1, 1) - self.gridLayout_31.addLayout(self.gridLayout_12, 3, 0, 1, 2) - self.USGS_library_textBrowser = QtWidgets.QTextBrowser(self.page_8) - self.USGS_library_textBrowser.setFrameShape(QtWidgets.QFrame.Panel) - self.USGS_library_textBrowser.setFrameShadow(QtWidgets.QFrame.Sunken) - self.USGS_library_textBrowser.setOpenExternalLinks(True) - self.USGS_library_textBrowser.setObjectName("USGS_library_textBrowser") - self.gridLayout_31.addWidget(self.USGS_library_textBrowser, 5, 0, 1, 2) - self.label = QtWidgets.QLabel(self.page_8) - font = QtGui.QFont() - font.setPointSize(8) - self.label.setFont(font) - self.label.setFrameShape(QtWidgets.QFrame.Panel) - self.label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label.setWordWrap(True) - self.label.setOpenExternalLinks(True) - self.label.setObjectName("label") - self.gridLayout_31.addWidget(self.label, 6, 0, 1, 2) - self.label_129 = QtWidgets.QLabel(self.page_8) - self.label_129.setStyleSheet("background-color : #656565; color : white") - self.label_129.setFrameShape(QtWidgets.QFrame.Panel) - self.label_129.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_129.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_129.setObjectName("label_129") - self.gridLayout_31.addWidget(self.label_129, 4, 0, 1, 2) - self.gridLayout_4.addLayout(self.gridLayout_31, 0, 1, 1, 1) - self.toolBox_4.addItem(self.page_8, "") - self.page_6 = QtWidgets.QWidget() - self.page_6.setGeometry(QtCore.QRect(0, 0, 604, 53)) - self.page_6.setObjectName("page_6") - self.gridLayout_175 = QtWidgets.QGridLayout(self.page_6) - self.gridLayout_175.setObjectName("gridLayout_175") - self.gridLayout_174 = QtWidgets.QGridLayout() - self.gridLayout_174.setObjectName("gridLayout_174") - self.label_9 = QtWidgets.QLabel(self.page_6) - self.label_9.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_9.setObjectName("label_9") - self.gridLayout_174.addWidget(self.label_9, 0, 0, 1, 1) - self.open_library_pushButton = QtWidgets.QToolButton(self.page_6) - self.open_library_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.open_library_pushButton.setIcon(icon65) - self.open_library_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.open_library_pushButton.setObjectName("open_library_pushButton") - self.gridLayout_174.addWidget(self.open_library_pushButton, 0, 1, 1, 1) - spacerItem17 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_174.addItem(spacerItem17, 2, 0, 1, 1) - self.gridLayout_175.addLayout(self.gridLayout_174, 0, 0, 1, 1) - self.toolBox_4.addItem(self.page_6, "") - self.page_9 = QtWidgets.QWidget() - self.page_9.setGeometry(QtCore.QRect(0, 0, 417, 165)) - self.page_9.setObjectName("page_9") - self.gridLayout_181 = QtWidgets.QGridLayout(self.page_9) - self.gridLayout_181.setObjectName("gridLayout_181") - self.gridLayout_178 = QtWidgets.QGridLayout() - self.gridLayout_178.setObjectName("gridLayout_178") - self.open_shapefile_pushButton = QtWidgets.QToolButton(self.page_9) - self.open_shapefile_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.open_shapefile_pushButton.setIcon(icon65) - self.open_shapefile_pushButton.setIconSize(QtCore.QSize(20, 20)) - self.open_shapefile_pushButton.setObjectName("open_shapefile_pushButton") - self.gridLayout_178.addWidget(self.open_shapefile_pushButton, 0, 2, 1, 1) - self.label_120 = QtWidgets.QLabel(self.page_9) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_120.sizePolicy().hasHeightForWidth()) - self.label_120.setSizePolicy(sizePolicy) - self.label_120.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_120.setObjectName("label_120") - self.gridLayout_178.addWidget(self.label_120, 0, 0, 1, 1) - self.gridLayout_179 = QtWidgets.QGridLayout() - self.gridLayout_179.setObjectName("gridLayout_179") - self.C_ID_combo = QtWidgets.QComboBox(self.page_9) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.C_ID_combo.sizePolicy().hasHeightForWidth()) - self.C_ID_combo.setSizePolicy(sizePolicy) - self.C_ID_combo.setObjectName("C_ID_combo") - self.gridLayout_179.addWidget(self.C_ID_combo, 2, 2, 1, 1) - self.MC_ID_combo = QtWidgets.QComboBox(self.page_9) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.MC_ID_combo.sizePolicy().hasHeightForWidth()) - self.MC_ID_combo.setSizePolicy(sizePolicy) - self.MC_ID_combo.setObjectName("MC_ID_combo") - self.gridLayout_179.addWidget(self.MC_ID_combo, 2, 0, 1, 1) - self.MC_Info_combo = QtWidgets.QComboBox(self.page_9) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.MC_Info_combo.sizePolicy().hasHeightForWidth()) - self.MC_Info_combo.setSizePolicy(sizePolicy) - self.MC_Info_combo.setObjectName("MC_Info_combo") - self.gridLayout_179.addWidget(self.MC_Info_combo, 2, 1, 1, 1) - self.label_99 = QtWidgets.QLabel(self.page_9) - self.label_99.setFrameShape(QtWidgets.QFrame.Panel) - self.label_99.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_99.setObjectName("label_99") - self.gridLayout_179.addWidget(self.label_99, 1, 3, 1, 1) - self.C_Info_combo = QtWidgets.QComboBox(self.page_9) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.C_Info_combo.sizePolicy().hasHeightForWidth()) - self.C_Info_combo.setSizePolicy(sizePolicy) - self.C_Info_combo.setObjectName("C_Info_combo") - self.gridLayout_179.addWidget(self.C_Info_combo, 2, 3, 1, 1) - self.label_119 = QtWidgets.QLabel(self.page_9) - self.label_119.setStyleSheet("background-color : #656565; color : white") - self.label_119.setFrameShape(QtWidgets.QFrame.Panel) - self.label_119.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_119.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_119.setObjectName("label_119") - self.gridLayout_179.addWidget(self.label_119, 0, 0, 1, 5) - self.MC_ID_combo_2 = QtWidgets.QLabel(self.page_9) - self.MC_ID_combo_2.setFrameShape(QtWidgets.QFrame.Panel) - self.MC_ID_combo_2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.MC_ID_combo_2.setObjectName("MC_ID_combo_2") - self.gridLayout_179.addWidget(self.MC_ID_combo_2, 1, 2, 1, 1) - self.label_121 = QtWidgets.QLabel(self.page_9) - self.label_121.setFrameShape(QtWidgets.QFrame.Panel) - self.label_121.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_121.setObjectName("label_121") - self.gridLayout_179.addWidget(self.label_121, 1, 0, 1, 1) - self.label_122 = QtWidgets.QLabel(self.page_9) - self.label_122.setFrameShape(QtWidgets.QFrame.Panel) - self.label_122.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_122.setObjectName("label_122") - self.gridLayout_179.addWidget(self.label_122, 1, 1, 1, 1) - self.gridLayout_178.addLayout(self.gridLayout_179, 3, 0, 1, 3) - spacerItem18 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_178.addItem(spacerItem18, 5, 0, 1, 1) - self.gridLayout_180 = QtWidgets.QGridLayout() - self.gridLayout_180.setObjectName("gridLayout_180") - self.label_2 = QtWidgets.QLabel(self.page_9) - self.label_2.setObjectName("label_2") - self.gridLayout_180.addWidget(self.label_2, 0, 2, 1, 1) - spacerItem19 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_180.addItem(spacerItem19, 0, 0, 1, 1) - self.signature_checkBox_2 = QtWidgets.QCheckBox(self.page_9) - self.signature_checkBox_2.setChecked(True) - self.signature_checkBox_2.setObjectName("signature_checkBox_2") - self.gridLayout_180.addWidget(self.signature_checkBox_2, 0, 1, 1, 1) - self.import_shapefile_pushButton = QtWidgets.QToolButton(self.page_9) - self.import_shapefile_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.import_shapefile_pushButton.setIcon(icon67) - self.import_shapefile_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.import_shapefile_pushButton.setObjectName("import_shapefile_pushButton") - self.gridLayout_180.addWidget(self.import_shapefile_pushButton, 0, 3, 1, 1) - self.gridLayout_178.addLayout(self.gridLayout_180, 4, 0, 1, 3) - self.select_shapefile_label = QtWidgets.QLabel(self.page_9) - self.select_shapefile_label.setFrameShape(QtWidgets.QFrame.Panel) - self.select_shapefile_label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.select_shapefile_label.setText("") - self.select_shapefile_label.setObjectName("select_shapefile_label") - self.gridLayout_178.addWidget(self.select_shapefile_label, 0, 1, 1, 1) - self.gridLayout_181.addLayout(self.gridLayout_178, 0, 1, 1, 1) - self.toolBox_4.addItem(self.page_9, "") - self.gridLayout_168.addWidget(self.toolBox_4, 0, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_Import, "") - self.tab_export = QtWidgets.QWidget() - self.tab_export.setObjectName("tab_export") - self.gridLayout_142 = QtWidgets.QGridLayout(self.tab_export) - self.gridLayout_142.setObjectName("gridLayout_142") - self.gridLayout_176 = QtWidgets.QGridLayout() - self.gridLayout_176.setObjectName("gridLayout_176") - self.label_97 = QtWidgets.QLabel(self.tab_export) - self.label_97.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_97.setObjectName("label_97") - self.gridLayout_176.addWidget(self.label_97, 1, 0, 1, 1) - self.export_SCP_pushButton = QtWidgets.QToolButton(self.tab_export) - self.export_SCP_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - icon68 = QtGui.QIcon() - icon68.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.export_SCP_pushButton.setIcon(icon68) - self.export_SCP_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.export_SCP_pushButton.setObjectName("export_SCP_pushButton") - self.gridLayout_176.addWidget(self.export_SCP_pushButton, 1, 1, 1, 1) - self.export_CSV_library_toolButton = QtWidgets.QToolButton(self.tab_export) - self.export_CSV_library_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon69 = QtGui.QIcon() - icon69.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.export_CSV_library_toolButton.setIcon(icon69) - self.export_CSV_library_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_CSV_library_toolButton.setObjectName("export_CSV_library_toolButton") - self.gridLayout_176.addWidget(self.export_CSV_library_toolButton, 3, 1, 1, 1) - self.label_96 = QtWidgets.QLabel(self.tab_export) - self.label_96.setStyleSheet("background-color : #656565; color : white") - self.label_96.setFrameShape(QtWidgets.QFrame.Panel) - self.label_96.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_96.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_96.setObjectName("label_96") - self.gridLayout_176.addWidget(self.label_96, 0, 0, 1, 2) - self.label_222 = QtWidgets.QLabel(self.tab_export) - self.label_222.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_222.setObjectName("label_222") - self.gridLayout_176.addWidget(self.label_222, 2, 0, 1, 1) - self.label_20 = QtWidgets.QLabel(self.tab_export) - self.label_20.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_20.setObjectName("label_20") - self.gridLayout_176.addWidget(self.label_20, 3, 0, 1, 1) - self.export_SHP_pushButton = QtWidgets.QToolButton(self.tab_export) - self.export_SHP_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.export_SHP_pushButton.setIcon(icon68) - self.export_SHP_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.export_SHP_pushButton.setObjectName("export_SHP_pushButton") - self.gridLayout_176.addWidget(self.export_SHP_pushButton, 2, 1, 1, 1) - spacerItem20 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_176.addItem(spacerItem20, 4, 0, 1, 1) - self.gridLayout_142.addLayout(self.gridLayout_176, 0, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_export, "") - self.tab_threshold = QtWidgets.QWidget() - self.tab_threshold.setObjectName("tab_threshold") - self.gridLayout_177 = QtWidgets.QGridLayout(self.tab_threshold) - self.gridLayout_177.setObjectName("gridLayout_177") - self.gridLayout_110 = QtWidgets.QGridLayout() - self.gridLayout_110.setObjectName("gridLayout_110") - self.gridLayout_161 = QtWidgets.QGridLayout() - self.gridLayout_161.setObjectName("gridLayout_161") - self.gridLayout_198 = QtWidgets.QGridLayout() - self.gridLayout_198.setObjectName("gridLayout_198") - spacerItem21 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_198.addItem(spacerItem21, 0, 0, 1, 1) - self.gridLayout_161.addLayout(self.gridLayout_198, 0, 0, 1, 1) - spacerItem22 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_161.addItem(spacerItem22, 3, 0, 1, 1) - self.gridLayout_129 = QtWidgets.QGridLayout() - self.gridLayout_129.setObjectName("gridLayout_129") - self.reset_threshold_pushButton = QtWidgets.QToolButton(self.tab_threshold) - self.reset_threshold_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_threshold_pushButton.setIcon(icon59) - self.reset_threshold_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.reset_threshold_pushButton.setObjectName("reset_threshold_pushButton") - self.gridLayout_129.addWidget(self.reset_threshold_pushButton, 0, 0, 1, 1) - self.gridLayout_161.addLayout(self.gridLayout_129, 1, 0, 1, 1) - self.gridLayout_110.addLayout(self.gridLayout_161, 1, 1, 1, 1) - self.signature_threshold_tableWidget = QtWidgets.QTableWidget(self.tab_threshold) - self.signature_threshold_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) - self.signature_threshold_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) - self.signature_threshold_tableWidget.setObjectName("signature_threshold_tableWidget") - self.signature_threshold_tableWidget.setColumnCount(7) - self.signature_threshold_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(3, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(4, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(5, item) - item = QtWidgets.QTableWidgetItem() - self.signature_threshold_tableWidget.setHorizontalHeaderItem(6, item) - self.signature_threshold_tableWidget.horizontalHeader().setDefaultSectionSize(50) - self.signature_threshold_tableWidget.horizontalHeader().setStretchLastSection(True) - self.signature_threshold_tableWidget.verticalHeader().setDefaultSectionSize(20) - self.gridLayout_110.addWidget(self.signature_threshold_tableWidget, 1, 0, 1, 1) - self.gridLayout_109 = QtWidgets.QGridLayout() - self.gridLayout_109.setObjectName("gridLayout_109") - self.label_80 = QtWidgets.QLabel(self.tab_threshold) - self.label_80.setStyleSheet("background-color : #656565; color : white") - self.label_80.setFrameShape(QtWidgets.QFrame.Panel) - self.label_80.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_80.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_80.setObjectName("label_80") - self.gridLayout_109.addWidget(self.label_80, 0, 0, 1, 1) - self.gridLayout_110.addLayout(self.gridLayout_109, 0, 0, 1, 2) - self.gridLayout_111 = QtWidgets.QGridLayout() - self.gridLayout_111.setObjectName("gridLayout_111") - self.label_85 = QtWidgets.QLabel(self.tab_threshold) - self.label_85.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_85.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_85.setObjectName("label_85") - self.gridLayout_111.addWidget(self.label_85, 1, 2, 1, 1) - self.multiplicative_threshold_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_threshold) - self.multiplicative_threshold_doubleSpinBox.setDecimals(1) - self.multiplicative_threshold_doubleSpinBox.setMaximum(10000.0) - self.multiplicative_threshold_doubleSpinBox.setProperty("value", 1.0) - self.multiplicative_threshold_doubleSpinBox.setObjectName("multiplicative_threshold_doubleSpinBox") - self.gridLayout_111.addWidget(self.multiplicative_threshold_doubleSpinBox, 1, 3, 1, 1) - self.automatic_threshold_pushButton = QtWidgets.QToolButton(self.tab_threshold) - self.automatic_threshold_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.automatic_threshold_pushButton.setIcon(icon67) - self.automatic_threshold_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.automatic_threshold_pushButton.setObjectName("automatic_threshold_pushButton") - self.gridLayout_111.addWidget(self.automatic_threshold_pushButton, 1, 4, 1, 1) - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() - self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.label_132 = QtWidgets.QLabel(self.tab_threshold) - self.label_132.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_132.setObjectName("label_132") - self.horizontalLayout_3.addWidget(self.label_132) - self.threshold_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_threshold) - self.threshold_doubleSpinBox.setDecimals(4) - self.threshold_doubleSpinBox.setMaximum(10000.0) - self.threshold_doubleSpinBox.setProperty("value", 0.0) - self.threshold_doubleSpinBox.setObjectName("threshold_doubleSpinBox") - self.horizontalLayout_3.addWidget(self.threshold_doubleSpinBox) - self.set_threshold_value_pushButton = QtWidgets.QToolButton(self.tab_threshold) - self.set_threshold_value_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.set_threshold_value_pushButton.setIcon(icon67) - self.set_threshold_value_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.set_threshold_value_pushButton.setObjectName("set_threshold_value_pushButton") - self.horizontalLayout_3.addWidget(self.set_threshold_value_pushButton) - self.gridLayout_111.addLayout(self.horizontalLayout_3, 1, 0, 1, 1) - spacerItem23 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_111.addItem(spacerItem23, 1, 1, 1, 1) - spacerItem24 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_111.addItem(spacerItem24, 1, 5, 1, 1) - self.label_88 = QtWidgets.QLabel(self.tab_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_88.sizePolicy().hasHeightForWidth()) - self.label_88.setSizePolicy(sizePolicy) - self.label_88.setStyleSheet("background-color : #656565; color : white") - self.label_88.setFrameShape(QtWidgets.QFrame.Panel) - self.label_88.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_88.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_88.setObjectName("label_88") - self.gridLayout_111.addWidget(self.label_88, 0, 0, 1, 6) - self.gridLayout_110.addLayout(self.gridLayout_111, 2, 0, 1, 2) - self.gridLayout_177.addLayout(self.gridLayout_110, 0, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_threshold, "") - self.tab_LCS_threshold = QtWidgets.QWidget() - self.tab_LCS_threshold.setObjectName("tab_LCS_threshold") - self.gridLayout_105 = QtWidgets.QGridLayout(self.tab_LCS_threshold) - self.gridLayout_105.setObjectName("gridLayout_105") - self.gridLayout_137 = QtWidgets.QGridLayout() - self.gridLayout_137.setObjectName("gridLayout_137") - self.LCS_tableWidget = QtWidgets.QTableWidget(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.LCS_tableWidget.sizePolicy().hasHeightForWidth()) - self.LCS_tableWidget.setSizePolicy(sizePolicy) - self.LCS_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.SelectedClicked) - self.LCS_tableWidget.setAlternatingRowColors(True) - self.LCS_tableWidget.setObjectName("LCS_tableWidget") - self.LCS_tableWidget.setColumnCount(5) - self.LCS_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.LCS_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.LCS_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.LCS_tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.LCS_tableWidget.setHorizontalHeaderItem(3, item) - item = QtWidgets.QTableWidgetItem() - self.LCS_tableWidget.setHorizontalHeaderItem(4, item) - self.LCS_tableWidget.horizontalHeader().setDefaultSectionSize(50) - self.LCS_tableWidget.horizontalHeader().setStretchLastSection(True) - self.LCS_tableWidget.verticalHeader().setDefaultSectionSize(20) - self.gridLayout_137.addWidget(self.LCS_tableWidget, 1, 0, 1, 1) - self.gridLayout_138 = QtWidgets.QGridLayout() - self.gridLayout_138.setObjectName("gridLayout_138") - self.label_86 = QtWidgets.QLabel(self.tab_LCS_threshold) - self.label_86.setStyleSheet("background-color : #656565; color : white") - self.label_86.setFrameShape(QtWidgets.QFrame.Panel) - self.label_86.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_86.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_86.setObjectName("label_86") - self.gridLayout_138.addWidget(self.label_86, 0, 0, 1, 1) - self.gridLayout_137.addLayout(self.gridLayout_138, 0, 0, 1, 2) - self.verticalLayout = QtWidgets.QVBoxLayout() - self.verticalLayout.setObjectName("verticalLayout") - self.signature_spectral_plot_toolButton_2 = QtWidgets.QToolButton(self.tab_LCS_threshold) - self.signature_spectral_plot_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - icon70 = QtGui.QIcon() - icon70.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.signature_spectral_plot_toolButton_2.setIcon(icon70) - self.signature_spectral_plot_toolButton_2.setIconSize(QtCore.QSize(22, 22)) - self.signature_spectral_plot_toolButton_2.setObjectName("signature_spectral_plot_toolButton_2") - self.verticalLayout.addWidget(self.signature_spectral_plot_toolButton_2) - self.gridLayout_137.addLayout(self.verticalLayout, 1, 1, 1, 1) - self.gridLayout_139 = QtWidgets.QGridLayout() - self.gridLayout_139.setObjectName("gridLayout_139") - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.label_102 = QtWidgets.QLabel(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_102.sizePolicy().hasHeightForWidth()) - self.label_102.setSizePolicy(sizePolicy) - self.label_102.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_102.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_102.setObjectName("label_102") - self.horizontalLayout.addWidget(self.label_102) - self.set_min_max_Button = QtWidgets.QToolButton(self.tab_LCS_threshold) - self.set_min_max_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.set_min_max_Button.setIcon(icon67) - self.set_min_max_Button.setIconSize(QtCore.QSize(22, 22)) - self.set_min_max_Button.setObjectName("set_min_max_Button") - self.horizontalLayout.addWidget(self.set_min_max_Button) - self.gridLayout_139.addLayout(self.horizontalLayout, 1, 0, 1, 1) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - spacerItem25 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_2.addItem(spacerItem25) - self.label_101 = QtWidgets.QLabel(self.tab_LCS_threshold) - self.label_101.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_101.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_101.setObjectName("label_101") - self.horizontalLayout_2.addWidget(self.label_101) - self.multiplicative_threshold_doubleSpinBox_2 = QtWidgets.QDoubleSpinBox(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.multiplicative_threshold_doubleSpinBox_2.sizePolicy().hasHeightForWidth()) - self.multiplicative_threshold_doubleSpinBox_2.setSizePolicy(sizePolicy) - self.multiplicative_threshold_doubleSpinBox_2.setDecimals(1) - self.multiplicative_threshold_doubleSpinBox_2.setMaximum(10000.0) - self.multiplicative_threshold_doubleSpinBox_2.setProperty("value", 1.0) - self.multiplicative_threshold_doubleSpinBox_2.setObjectName("multiplicative_threshold_doubleSpinBox_2") - self.horizontalLayout_2.addWidget(self.multiplicative_threshold_doubleSpinBox_2) - self.automatic_threshold_pushButton_2 = QtWidgets.QToolButton(self.tab_LCS_threshold) - self.automatic_threshold_pushButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.automatic_threshold_pushButton_2.setIcon(icon67) - self.automatic_threshold_pushButton_2.setIconSize(QtCore.QSize(22, 22)) - self.automatic_threshold_pushButton_2.setObjectName("automatic_threshold_pushButton_2") - self.horizontalLayout_2.addWidget(self.automatic_threshold_pushButton_2) - spacerItem26 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_2.addItem(spacerItem26) - self.gridLayout_140 = QtWidgets.QGridLayout() - self.gridLayout_140.setObjectName("gridLayout_140") - self.label_89 = QtWidgets.QLabel(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_89.sizePolicy().hasHeightForWidth()) - self.label_89.setSizePolicy(sizePolicy) - self.label_89.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_89.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_89.setObjectName("label_89") - self.gridLayout_140.addWidget(self.label_89, 0, 2, 1, 3) - self.LCS_pointerButton = QtWidgets.QToolButton(self.tab_LCS_threshold) - self.LCS_pointerButton.setStyleSheet("margin: 0px;padding: 0px;") - icon71 = QtGui.QIcon() - icon71.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_pointerButton.setIcon(icon71) - self.LCS_pointerButton.setIconSize(QtCore.QSize(22, 22)) - self.LCS_pointerButton.setObjectName("LCS_pointerButton") - self.gridLayout_140.addWidget(self.LCS_pointerButton, 0, 5, 1, 1) - self.gridLayout_144 = QtWidgets.QGridLayout() - self.gridLayout_144.setObjectName("gridLayout_144") - self.LCS_include_checkBox = QtWidgets.QCheckBox(self.tab_LCS_threshold) - self.LCS_include_checkBox.setText("") - self.LCS_include_checkBox.setIcon(icon57) - self.LCS_include_checkBox.setChecked(True) - self.LCS_include_checkBox.setObjectName("LCS_include_checkBox") - self.gridLayout_144.addWidget(self.LCS_include_checkBox, 0, 0, 1, 1) - self.LCS_cut_checkBox = QtWidgets.QCheckBox(self.tab_LCS_threshold) - self.LCS_cut_checkBox.setText("") - icon72 = QtGui.QIcon() - icon72.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_cut_checkBox.setIcon(icon72) - self.LCS_cut_checkBox.setObjectName("LCS_cut_checkBox") - self.gridLayout_144.addWidget(self.LCS_cut_checkBox, 1, 0, 1, 1) - self.gridLayout_140.addLayout(self.gridLayout_144, 0, 6, 1, 1) - self.label_178 = QtWidgets.QLabel(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_178.sizePolicy().hasHeightForWidth()) - self.label_178.setSizePolicy(sizePolicy) - self.label_178.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_178.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_178.setObjectName("label_178") - self.gridLayout_140.addWidget(self.label_178, 0, 0, 1, 1) - self.LCS_ROI_button = QtWidgets.QToolButton(self.tab_LCS_threshold) - self.LCS_ROI_button.setStyleSheet("margin: 0px;padding: 0px;") - icon73 = QtGui.QIcon() - icon73.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_ROI_button.setIcon(icon73) - self.LCS_ROI_button.setIconSize(QtCore.QSize(22, 22)) - self.LCS_ROI_button.setObjectName("LCS_ROI_button") - self.gridLayout_140.addWidget(self.LCS_ROI_button, 0, 1, 1, 1) - self.horizontalLayout_2.addLayout(self.gridLayout_140) - self.gridLayout_139.addLayout(self.horizontalLayout_2, 1, 1, 1, 1) - self.label_125 = QtWidgets.QLabel(self.tab_LCS_threshold) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_125.sizePolicy().hasHeightForWidth()) - self.label_125.setSizePolicy(sizePolicy) - self.label_125.setStyleSheet("background-color : #656565; color : white") - self.label_125.setFrameShape(QtWidgets.QFrame.Panel) - self.label_125.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_125.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_125.setObjectName("label_125") - self.gridLayout_139.addWidget(self.label_125, 0, 0, 1, 2) - self.gridLayout_137.addLayout(self.gridLayout_139, 2, 0, 1, 2) - self.gridLayout_105.addLayout(self.gridLayout_137, 0, 0, 1, 1) - self.tabWidget_5.addTab(self.tab_LCS_threshold, "") - self.gridLayout_216.addWidget(self.tabWidget_5, 0, 0, 1, 1) - self.SCP_tabs.addTab(self.tab_basic_tools, "") - self.tab_download_products = QtWidgets.QWidget() - self.tab_download_products.setObjectName("tab_download_products") - self.gridLayout_68 = QtWidgets.QGridLayout(self.tab_download_products) - self.gridLayout_68.setObjectName("gridLayout_68") - self.gridLayout_113 = QtWidgets.QGridLayout() - self.gridLayout_113.setObjectName("gridLayout_113") - self.tabWidget_3 = QtWidgets.QTabWidget(self.tab_download_products) - self.tabWidget_3.setStyleSheet("QTabBar::tab {\n" -"padding: 10px;\n" -"min-height: 18px;\n" -"}") - self.tabWidget_3.setTabPosition(QtWidgets.QTabWidget.North) - self.tabWidget_3.setObjectName("tabWidget_3") - self.tab_login = QtWidgets.QWidget() - self.tab_login.setObjectName("tab_login") - self.gridLayout_238 = QtWidgets.QGridLayout(self.tab_login) - self.gridLayout_238.setObjectName("gridLayout_238") - self.gridLayout_227 = QtWidgets.QGridLayout() - self.gridLayout_227.setObjectName("gridLayout_227") - self.remember_user_checkBox_2 = QtWidgets.QCheckBox(self.tab_login) - self.remember_user_checkBox_2.setChecked(True) - self.remember_user_checkBox_2.setObjectName("remember_user_checkBox_2") - self.gridLayout_227.addWidget(self.remember_user_checkBox_2, 1, 4, 1, 1) - self.password_usgs_lineEdit = QtWidgets.QLineEdit(self.tab_login) - self.password_usgs_lineEdit.setObjectName("password_usgs_lineEdit") - self.gridLayout_227.addWidget(self.password_usgs_lineEdit, 1, 3, 1, 1) - self.password_scihub_label_3 = QtWidgets.QLabel(self.tab_login) - self.password_scihub_label_3.setObjectName("password_scihub_label_3") - self.gridLayout_227.addWidget(self.password_scihub_label_3, 1, 2, 1, 1) - self.label_180 = QtWidgets.QLabel(self.tab_login) - self.label_180.setStyleSheet("background-color : #656565; color : white") - self.label_180.setFrameShape(QtWidgets.QFrame.Panel) - self.label_180.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_180.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_180.setOpenExternalLinks(True) - self.label_180.setObjectName("label_180") - self.gridLayout_227.addWidget(self.label_180, 0, 0, 1, 6) - self.user_usgs_lineEdit = QtWidgets.QLineEdit(self.tab_login) - self.user_usgs_lineEdit.setObjectName("user_usgs_lineEdit") - self.gridLayout_227.addWidget(self.user_usgs_lineEdit, 1, 1, 1, 1) - self.user_scihub_label_2 = QtWidgets.QLabel(self.tab_login) - self.user_scihub_label_2.setObjectName("user_scihub_label_2") - self.gridLayout_227.addWidget(self.user_scihub_label_2, 1, 0, 1, 1) - self.gridLayout_238.addLayout(self.gridLayout_227, 0, 0, 1, 1) - self.gridLayout_242 = QtWidgets.QGridLayout() - self.gridLayout_242.setObjectName("gridLayout_242") - self.remember_user_checkBox_3 = QtWidgets.QCheckBox(self.tab_login) - self.remember_user_checkBox_3.setChecked(True) - self.remember_user_checkBox_3.setObjectName("remember_user_checkBox_3") - self.gridLayout_242.addWidget(self.remember_user_checkBox_3, 1, 4, 1, 1) - self.password_usgs_lineEdit_2 = QtWidgets.QLineEdit(self.tab_login) - self.password_usgs_lineEdit_2.setObjectName("password_usgs_lineEdit_2") - self.gridLayout_242.addWidget(self.password_usgs_lineEdit_2, 1, 3, 1, 1) - self.password_scihub_label_4 = QtWidgets.QLabel(self.tab_login) - self.password_scihub_label_4.setObjectName("password_scihub_label_4") - self.gridLayout_242.addWidget(self.password_scihub_label_4, 1, 2, 1, 1) - self.label_191 = QtWidgets.QLabel(self.tab_login) - self.label_191.setStyleSheet("background-color : #656565; color : white") - self.label_191.setFrameShape(QtWidgets.QFrame.Panel) - self.label_191.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_191.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_191.setOpenExternalLinks(True) - self.label_191.setObjectName("label_191") - self.gridLayout_242.addWidget(self.label_191, 0, 0, 1, 6) - self.user_usgs_lineEdit_2 = QtWidgets.QLineEdit(self.tab_login) - self.user_usgs_lineEdit_2.setObjectName("user_usgs_lineEdit_2") - self.gridLayout_242.addWidget(self.user_usgs_lineEdit_2, 1, 1, 1, 1) - self.user_scihub_label_3 = QtWidgets.QLabel(self.tab_login) - self.user_scihub_label_3.setObjectName("user_scihub_label_3") - self.gridLayout_242.addWidget(self.user_scihub_label_3, 1, 0, 1, 1) - self.gridLayout_238.addLayout(self.gridLayout_242, 1, 0, 1, 1) - self.gridLayout_159 = QtWidgets.QGridLayout() - self.gridLayout_159.setObjectName("gridLayout_159") - self.user_scihub_lineEdit = QtWidgets.QLineEdit(self.tab_login) - self.user_scihub_lineEdit.setObjectName("user_scihub_lineEdit") - self.gridLayout_159.addWidget(self.user_scihub_lineEdit, 2, 1, 1, 1) - self.password_scihub_label = QtWidgets.QLabel(self.tab_login) - self.password_scihub_label.setObjectName("password_scihub_label") - self.gridLayout_159.addWidget(self.password_scihub_label, 2, 2, 1, 1) - self.label_147 = QtWidgets.QLabel(self.tab_login) - self.label_147.setStyleSheet("background-color : #656565; color : white") - self.label_147.setFrameShape(QtWidgets.QFrame.Panel) - self.label_147.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_147.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_147.setOpenExternalLinks(True) - self.label_147.setObjectName("label_147") - self.gridLayout_159.addWidget(self.label_147, 0, 0, 1, 6) - self.remember_user_checkBox = QtWidgets.QCheckBox(self.tab_login) - self.remember_user_checkBox.setChecked(True) - self.remember_user_checkBox.setObjectName("remember_user_checkBox") - self.gridLayout_159.addWidget(self.remember_user_checkBox, 2, 4, 1, 1) - self.user_scihub_label = QtWidgets.QLabel(self.tab_login) - self.user_scihub_label.setObjectName("user_scihub_label") - self.gridLayout_159.addWidget(self.user_scihub_label, 2, 0, 1, 1) - self.password_scihub_lineEdit = QtWidgets.QLineEdit(self.tab_login) - self.password_scihub_lineEdit.setObjectName("password_scihub_lineEdit") - self.gridLayout_159.addWidget(self.password_scihub_lineEdit, 2, 3, 1, 1) - self.horizontalLayout_10 = QtWidgets.QHBoxLayout() - self.horizontalLayout_10.setObjectName("horizontalLayout_10") - self.password_scihub_label_2 = QtWidgets.QLabel(self.tab_login) - self.password_scihub_label_2.setObjectName("password_scihub_label_2") - self.horizontalLayout_10.addWidget(self.password_scihub_label_2) - self.sentinel_service_lineEdit = QtWidgets.QLineEdit(self.tab_login) - self.sentinel_service_lineEdit.setText("") - self.sentinel_service_lineEdit.setObjectName("sentinel_service_lineEdit") - self.horizontalLayout_10.addWidget(self.sentinel_service_lineEdit) - self.reset_sentinel_service_toolButton = QtWidgets.QToolButton(self.tab_login) - self.reset_sentinel_service_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_sentinel_service_toolButton.setIcon(icon59) - self.reset_sentinel_service_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.reset_sentinel_service_toolButton.setObjectName("reset_sentinel_service_toolButton") - self.horizontalLayout_10.addWidget(self.reset_sentinel_service_toolButton) - self.gridLayout_159.addLayout(self.horizontalLayout_10, 1, 0, 1, 5) - self.sentinel2_alternative_search_checkBox = QtWidgets.QCheckBox(self.tab_login) - self.sentinel2_alternative_search_checkBox.setObjectName("sentinel2_alternative_search_checkBox") - self.gridLayout_159.addWidget(self.sentinel2_alternative_search_checkBox, 3, 0, 1, 5) - self.gridLayout_238.addLayout(self.gridLayout_159, 2, 0, 1, 1) - spacerItem27 = QtWidgets.QSpacerItem(20, 251, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_238.addItem(spacerItem27, 3, 0, 1, 1) - icon74 = QtGui.QIcon() - icon74.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_3.addTab(self.tab_login, icon74, "") - self.tab_search = QtWidgets.QWidget() - self.tab_search.setObjectName("tab_search") - self.gridLayout_264 = QtWidgets.QGridLayout(self.tab_search) - self.gridLayout_264.setObjectName("gridLayout_264") - self.gridLayout_search = QtWidgets.QGridLayout() - self.gridLayout_search.setObjectName("gridLayout_search") - self.gridLayout_132 = QtWidgets.QGridLayout() - self.gridLayout_132.setObjectName("gridLayout_132") - self.remove_image_toolButton = QtWidgets.QToolButton(self.tab_search) - self.remove_image_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.remove_image_toolButton.setIcon(icon58) - self.remove_image_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_image_toolButton.setObjectName("remove_image_toolButton") - self.gridLayout_132.addWidget(self.remove_image_toolButton, 1, 1, 1, 1) - self.toolButton_display = QtWidgets.QToolButton(self.tab_search) - self.toolButton_display.setStyleSheet("margin: 0px;padding: 0px;") - icon75 = QtGui.QIcon() - icon75.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.toolButton_display.setIcon(icon75) - self.toolButton_display.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_display.setObjectName("toolButton_display") - self.gridLayout_132.addWidget(self.toolButton_display, 0, 1, 1, 1) - self.clear_table_toolButton = QtWidgets.QToolButton(self.tab_search) - self.clear_table_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.clear_table_toolButton.setIcon(icon59) - self.clear_table_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.clear_table_toolButton.setObjectName("clear_table_toolButton") - self.gridLayout_132.addWidget(self.clear_table_toolButton, 2, 1, 1, 1) - self.export_table_pushButton = QtWidgets.QToolButton(self.tab_search) - self.export_table_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_table_pushButton.setIcon(icon53) - self.export_table_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.export_table_pushButton.setObjectName("export_table_pushButton") - self.gridLayout_132.addWidget(self.export_table_pushButton, 4, 1, 1, 1) - self.import_table_pushButton = QtWidgets.QToolButton(self.tab_search) - self.import_table_pushButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_table_pushButton.setIcon(icon54) - self.import_table_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.import_table_pushButton.setObjectName("import_table_pushButton") - self.gridLayout_132.addWidget(self.import_table_pushButton, 3, 1, 1, 1) - self.gridLayout_121 = QtWidgets.QGridLayout() - self.gridLayout_121.setObjectName("gridLayout_121") - self.image_preview_label = QtWidgets.QLabel(self.tab_search) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.image_preview_label.sizePolicy().hasHeightForWidth()) - self.image_preview_label.setSizePolicy(sizePolicy) - self.image_preview_label.setMinimumSize(QtCore.QSize(300, 300)) - self.image_preview_label.setFrameShape(QtWidgets.QFrame.Panel) - self.image_preview_label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.image_preview_label.setAlignment(QtCore.Qt.AlignCenter) - self.image_preview_label.setObjectName("image_preview_label") - self.gridLayout_121.addWidget(self.image_preview_label, 0, 0, 1, 1) - self.gridLayout_132.addLayout(self.gridLayout_121, 0, 0, 5, 1) - self.gridLayout_search.addLayout(self.gridLayout_132, 2, 1, 1, 1) - self.download_images_tableWidget = QtWidgets.QTableWidget(self.tab_search) - self.download_images_tableWidget.setFrameShadow(QtWidgets.QFrame.Sunken) - self.download_images_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.download_images_tableWidget.setTabKeyNavigation(True) - self.download_images_tableWidget.setAlternatingRowColors(True) - self.download_images_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.download_images_tableWidget.setObjectName("download_images_tableWidget") - self.download_images_tableWidget.setColumnCount(14) - self.download_images_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(3, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(4, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(5, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(6, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(7, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(8, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(9, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(10, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(11, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(12, item) - item = QtWidgets.QTableWidgetItem() - self.download_images_tableWidget.setHorizontalHeaderItem(13, item) - self.download_images_tableWidget.verticalHeader().setDefaultSectionSize(20) - self.gridLayout_search.addWidget(self.download_images_tableWidget, 2, 0, 1, 1) - self.label_100 = QtWidgets.QLabel(self.tab_search) - self.label_100.setStyleSheet("background-color : #656565; color : white") - self.label_100.setFrameShape(QtWidgets.QFrame.Panel) - self.label_100.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_100.setObjectName("label_100") - self.gridLayout_search.addWidget(self.label_100, 0, 0, 1, 1) - self.products_filter_lineEdit = QtWidgets.QLineEdit(self.tab_search) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.products_filter_lineEdit.sizePolicy().hasHeightForWidth()) - self.products_filter_lineEdit.setSizePolicy(sizePolicy) - self.products_filter_lineEdit.setObjectName("products_filter_lineEdit") - self.gridLayout_search.addWidget(self.products_filter_lineEdit, 0, 1, 1, 1) - self.gridLayout_264.addLayout(self.gridLayout_search, 1, 0, 1, 1) - self.gridLayout_133 = QtWidgets.QGridLayout() - self.gridLayout_133.setObjectName("gridLayout_133") - self.gridLayout_54 = QtWidgets.QGridLayout() - self.gridLayout_54.setObjectName("gridLayout_54") - self.toolButton_OSM = QtWidgets.QToolButton(self.tab_search) - self.toolButton_OSM.setStyleSheet("margin: 0px;padding: 0px;") - icon76 = QtGui.QIcon() - icon76.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.toolButton_OSM.setIcon(icon76) - self.toolButton_OSM.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_OSM.setObjectName("toolButton_OSM") - self.gridLayout_54.addWidget(self.toolButton_OSM, 0, 0, 1, 1) - self.label_205 = QtWidgets.QLabel(self.tab_search) - self.label_205.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_205.setAlignment(QtCore.Qt.AlignCenter) - self.label_205.setOpenExternalLinks(True) - self.label_205.setObjectName("label_205") - self.gridLayout_54.addWidget(self.label_205, 0, 1, 1, 1) - self.label_206 = QtWidgets.QLabel(self.tab_search) - self.label_206.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_206.setAlignment(QtCore.Qt.AlignCenter) - self.label_206.setOpenExternalLinks(True) - self.label_206.setObjectName("label_206") - self.gridLayout_54.addWidget(self.label_206, 0, 2, 1, 1) - spacerItem28 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_54.addItem(spacerItem28, 0, 3, 1, 2) - self.gridLayout_133.addLayout(self.gridLayout_54, 3, 0, 1, 2) - self.label_103 = QtWidgets.QLabel(self.tab_search) - self.label_103.setStyleSheet("background-color : #656565; color : white") - self.label_103.setFrameShape(QtWidgets.QFrame.Panel) - self.label_103.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_103.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_103.setObjectName("label_103") - self.gridLayout_133.addWidget(self.label_103, 0, 0, 1, 2) - self.gridLayout_122 = QtWidgets.QGridLayout() - self.gridLayout_122.setObjectName("gridLayout_122") - self.selectUL_toolButton_3 = QtWidgets.QToolButton(self.tab_search) - self.selectUL_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") - icon77 = QtGui.QIcon() - icon77.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.selectUL_toolButton_3.setIcon(icon77) - self.selectUL_toolButton_3.setIconSize(QtCore.QSize(22, 22)) - self.selectUL_toolButton_3.setObjectName("selectUL_toolButton_3") - self.gridLayout_122.addWidget(self.selectUL_toolButton_3, 0, 7, 1, 1) - self.LX_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) - self.LX_lineEdit_3.setText("") - self.LX_lineEdit_3.setMaxLength(15) - self.LX_lineEdit_3.setObjectName("LX_lineEdit_3") - self.gridLayout_122.addWidget(self.LX_lineEdit_3, 0, 4, 1, 1) - self.UX_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) - self.UX_lineEdit_3.setMaxLength(15) - self.UX_lineEdit_3.setObjectName("UX_lineEdit_3") - self.gridLayout_122.addWidget(self.UX_lineEdit_3, 0, 1, 1, 1) - self.label_105 = QtWidgets.QLabel(self.tab_search) - self.label_105.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_105.setAlignment(QtCore.Qt.AlignCenter) - self.label_105.setObjectName("label_105") - self.gridLayout_122.addWidget(self.label_105, 0, 3, 1, 1) - self.label_107 = QtWidgets.QLabel(self.tab_search) - self.label_107.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_107.setAlignment(QtCore.Qt.AlignCenter) - self.label_107.setObjectName("label_107") - self.gridLayout_122.addWidget(self.label_107, 0, 0, 1, 1) - self.LY_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) - self.LY_lineEdit_3.setMaxLength(15) - self.LY_lineEdit_3.setObjectName("LY_lineEdit_3") - self.gridLayout_122.addWidget(self.LY_lineEdit_3, 0, 5, 1, 1) - self.UY_lineEdit_3 = QtWidgets.QLineEdit(self.tab_search) - self.UY_lineEdit_3.setMaxLength(15) - self.UY_lineEdit_3.setObjectName("UY_lineEdit_3") - self.gridLayout_122.addWidget(self.UY_lineEdit_3, 0, 2, 1, 1) - self.show_area_radioButton_2 = QtWidgets.QRadioButton(self.tab_search) - self.show_area_radioButton_2.setChecked(True) - self.show_area_radioButton_2.setAutoExclusive(False) - self.show_area_radioButton_2.setObjectName("show_area_radioButton_2") - self.gridLayout_122.addWidget(self.show_area_radioButton_2, 0, 6, 1, 1) - self.gridLayout_115 = QtWidgets.QGridLayout() - self.gridLayout_115.setObjectName("gridLayout_115") - self.find_images_toolButton = QtWidgets.QToolButton(self.tab_search) - self.find_images_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon78 = QtGui.QIcon() - icon78.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.find_images_toolButton.setIcon(icon78) - self.find_images_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.find_images_toolButton.setObjectName("find_images_toolButton") - self.gridLayout_115.addWidget(self.find_images_toolButton, 1, 8, 1, 1) - self.label_35 = QtWidgets.QLabel(self.tab_search) - self.label_35.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_35.setObjectName("label_35") - self.gridLayout_115.addWidget(self.label_35, 1, 7, 1, 1) - self.gridLayout_114 = QtWidgets.QGridLayout() - self.gridLayout_114.setObjectName("gridLayout_114") - self.landsat_satellite_combo = QtWidgets.QComboBox(self.tab_search) - self.landsat_satellite_combo.setObjectName("landsat_satellite_combo") - self.gridLayout_114.addWidget(self.landsat_satellite_combo, 0, 1, 1, 1) - self.dateEdit_from = QtWidgets.QDateEdit(self.tab_search) - self.dateEdit_from.setDateTime(QtCore.QDateTime(QtCore.QDate(2016, 1, 1), QtCore.QTime(0, 0, 0))) - self.dateEdit_from.setMaximumDate(QtCore.QDate(2045, 12, 31)) - self.dateEdit_from.setMinimumDate(QtCore.QDate(1972, 1, 1)) - self.dateEdit_from.setCalendarPopup(True) - self.dateEdit_from.setDate(QtCore.QDate(2016, 1, 1)) - self.dateEdit_from.setObjectName("dateEdit_from") - self.gridLayout_114.addWidget(self.dateEdit_from, 0, 4, 1, 1) - self.label_110 = QtWidgets.QLabel(self.tab_search) - self.label_110.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_110.setAlignment(QtCore.Qt.AlignCenter) - self.label_110.setObjectName("label_110") - self.gridLayout_114.addWidget(self.label_110, 0, 8, 1, 1) - self.dateEdit_to = QtWidgets.QDateEdit(self.tab_search) - self.dateEdit_to.setMaximumDate(QtCore.QDate(2045, 12, 31)) - self.dateEdit_to.setMinimumDate(QtCore.QDate(1980, 1, 2)) - self.dateEdit_to.setCalendarPopup(True) - self.dateEdit_to.setDate(QtCore.QDate(2045, 12, 31)) - self.dateEdit_to.setObjectName("dateEdit_to") - self.gridLayout_114.addWidget(self.dateEdit_to, 0, 6, 1, 1) - self.label_112 = QtWidgets.QLabel(self.tab_search) - self.label_112.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_112.setAlignment(QtCore.Qt.AlignCenter) - self.label_112.setObjectName("label_112") - self.gridLayout_114.addWidget(self.label_112, 0, 5, 1, 1) - self.label_111 = QtWidgets.QLabel(self.tab_search) - self.label_111.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_111.setAlignment(QtCore.Qt.AlignCenter) - self.label_111.setObjectName("label_111") - self.gridLayout_114.addWidget(self.label_111, 0, 3, 1, 1) - self.cloud_cover_spinBox = QtWidgets.QSpinBox(self.tab_search) - self.cloud_cover_spinBox.setMinimumSize(QtCore.QSize(50, 0)) - self.cloud_cover_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.cloud_cover_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.cloud_cover_spinBox.setMinimum(0) - self.cloud_cover_spinBox.setMaximum(100) - self.cloud_cover_spinBox.setSingleStep(10) - self.cloud_cover_spinBox.setProperty("value", 100) - self.cloud_cover_spinBox.setObjectName("cloud_cover_spinBox") - self.gridLayout_114.addWidget(self.cloud_cover_spinBox, 0, 9, 1, 1) - self.label_114 = QtWidgets.QLabel(self.tab_search) - self.label_114.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_114.setAlignment(QtCore.Qt.AlignCenter) - self.label_114.setObjectName("label_114") - self.gridLayout_114.addWidget(self.label_114, 0, 0, 1, 1) - spacerItem29 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_114.addItem(spacerItem29, 0, 7, 1, 1) - spacerItem30 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_114.addItem(spacerItem30, 0, 2, 1, 1) - self.gridLayout_115.addLayout(self.gridLayout_114, 0, 0, 1, 9) - self.gridLayout_120 = QtWidgets.QGridLayout() - self.gridLayout_120.setObjectName("gridLayout_120") - self.label_194 = QtWidgets.QLabel(self.tab_search) - self.label_194.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_194.setAlignment(QtCore.Qt.AlignCenter) - self.label_194.setObjectName("label_194") - self.gridLayout_120.addWidget(self.label_194, 0, 0, 1, 1) - self.label_113 = QtWidgets.QLabel(self.tab_search) - self.label_113.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_113.setAlignment(QtCore.Qt.AlignCenter) - self.label_113.setObjectName("label_113") - self.gridLayout_120.addWidget(self.label_113, 0, 2, 1, 1) - self.imageID_lineEdit = QtWidgets.QLineEdit(self.tab_search) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.imageID_lineEdit.sizePolicy().hasHeightForWidth()) - self.imageID_lineEdit.setSizePolicy(sizePolicy) - self.imageID_lineEdit.setMinimumSize(QtCore.QSize(200, 0)) - self.imageID_lineEdit.setMaxLength(10000) - self.imageID_lineEdit.setObjectName("imageID_lineEdit") - self.gridLayout_120.addWidget(self.imageID_lineEdit, 0, 3, 1, 1) - self.result_number_spinBox_2 = QtWidgets.QSpinBox(self.tab_search) - self.result_number_spinBox_2.setMinimumSize(QtCore.QSize(50, 0)) - self.result_number_spinBox_2.setMaximumSize(QtCore.QSize(100, 16777215)) - self.result_number_spinBox_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.result_number_spinBox_2.setMinimum(5) - self.result_number_spinBox_2.setMaximum(2000) - self.result_number_spinBox_2.setSingleStep(5) - self.result_number_spinBox_2.setProperty("value", 20) - self.result_number_spinBox_2.setObjectName("result_number_spinBox_2") - self.gridLayout_120.addWidget(self.result_number_spinBox_2, 0, 1, 1, 1) - self.gridLayout_115.addLayout(self.gridLayout_120, 1, 0, 1, 7) - self.gridLayout_122.addLayout(self.gridLayout_115, 1, 0, 1, 8) - self.gridLayout_133.addLayout(self.gridLayout_122, 1, 0, 2, 2) - self.gridLayout_264.addLayout(self.gridLayout_133, 0, 0, 1, 1) - icon79 = QtGui.QIcon() - icon79.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_3.addTab(self.tab_search, icon79, "") - self.tab_options = QtWidgets.QWidget() - self.tab_options.setObjectName("tab_options") - self.gridLayout_199 = QtWidgets.QGridLayout(self.tab_options) - self.gridLayout_199.setObjectName("gridLayout_199") - self.gridLayout_116 = QtWidgets.QGridLayout() - self.gridLayout_116.setObjectName("gridLayout_116") - self.checkBox_band_6 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_6.setChecked(True) - self.checkBox_band_6.setObjectName("checkBox_band_6") - self.gridLayout_116.addWidget(self.checkBox_band_6, 1, 5, 1, 1) - self.checkBox_band_4 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_4.setChecked(True) - self.checkBox_band_4.setObjectName("checkBox_band_4") - self.gridLayout_116.addWidget(self.checkBox_band_4, 1, 3, 1, 1) - self.checkBox_band_1 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_1.setChecked(True) - self.checkBox_band_1.setObjectName("checkBox_band_1") - self.gridLayout_116.addWidget(self.checkBox_band_1, 1, 0, 1, 1) - self.checkBox_band_3 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_3.setChecked(True) - self.checkBox_band_3.setObjectName("checkBox_band_3") - self.gridLayout_116.addWidget(self.checkBox_band_3, 1, 2, 1, 1) - self.checkBox_band_12 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_12.setChecked(True) - self.checkBox_band_12.setObjectName("checkBox_band_12") - self.gridLayout_116.addWidget(self.checkBox_band_12, 2, 5, 1, 1) - self.checkBox_band_2 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_2.setChecked(True) - self.checkBox_band_2.setObjectName("checkBox_band_2") - self.gridLayout_116.addWidget(self.checkBox_band_2, 1, 1, 1, 1) - self.checkBox_band_11 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_11.setChecked(True) - self.checkBox_band_11.setObjectName("checkBox_band_11") - self.gridLayout_116.addWidget(self.checkBox_band_11, 2, 4, 1, 1) - self.checkBox_band_5 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_5.setChecked(True) - self.checkBox_band_5.setObjectName("checkBox_band_5") - self.gridLayout_116.addWidget(self.checkBox_band_5, 1, 4, 1, 1) - self.check_toolButton = QtWidgets.QToolButton(self.tab_options) - self.check_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.check_toolButton.setIcon(icon56) - self.check_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.check_toolButton.setObjectName("check_toolButton") - self.gridLayout_116.addWidget(self.check_toolButton, 1, 6, 1, 1) - self.label_108 = QtWidgets.QLabel(self.tab_options) - self.label_108.setStyleSheet("background-color : #656565; color : white") - self.label_108.setFrameShape(QtWidgets.QFrame.Panel) - self.label_108.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_108.setObjectName("label_108") - self.gridLayout_116.addWidget(self.label_108, 0, 0, 1, 7) - self.gridLayout_117 = QtWidgets.QGridLayout() - self.gridLayout_117.setObjectName("gridLayout_117") - spacerItem31 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_117.addItem(spacerItem31, 3, 1, 1, 1) - self.gridLayout_136 = QtWidgets.QGridLayout() - self.gridLayout_136.setObjectName("gridLayout_136") - self.checkBoxs_band_9 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_9.setChecked(True) - self.checkBoxs_band_9.setObjectName("checkBoxs_band_9") - self.gridLayout_136.addWidget(self.checkBoxs_band_9, 1, 8, 1, 1) - self.checkBoxs_band_1 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_1.setChecked(True) - self.checkBoxs_band_1.setObjectName("checkBoxs_band_1") - self.gridLayout_136.addWidget(self.checkBoxs_band_1, 1, 0, 1, 1) - self.check_toolButton_2 = QtWidgets.QToolButton(self.tab_options) - self.check_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.check_toolButton_2.setIcon(icon56) - self.check_toolButton_2.setIconSize(QtCore.QSize(22, 22)) - self.check_toolButton_2.setObjectName("check_toolButton_2") - self.gridLayout_136.addWidget(self.check_toolButton_2, 1, 14, 1, 1) - self.label_118 = QtWidgets.QLabel(self.tab_options) - self.label_118.setStyleSheet("background-color : #656565; color : white") - self.label_118.setFrameShape(QtWidgets.QFrame.Panel) - self.label_118.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_118.setObjectName("label_118") - self.gridLayout_136.addWidget(self.label_118, 0, 0, 1, 15) - self.checkBoxs_band_2 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_2.setChecked(True) - self.checkBoxs_band_2.setObjectName("checkBoxs_band_2") - self.gridLayout_136.addWidget(self.checkBoxs_band_2, 1, 1, 1, 1) - self.checkBoxs_band_3 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_3.setChecked(True) - self.checkBoxs_band_3.setObjectName("checkBoxs_band_3") - self.gridLayout_136.addWidget(self.checkBoxs_band_3, 1, 2, 1, 1) - self.checkBoxs_band_4 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_4.setChecked(True) - self.checkBoxs_band_4.setObjectName("checkBoxs_band_4") - self.gridLayout_136.addWidget(self.checkBoxs_band_4, 1, 3, 1, 1) - self.checkBoxs_band_5 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_5.setChecked(True) - self.checkBoxs_band_5.setObjectName("checkBoxs_band_5") - self.gridLayout_136.addWidget(self.checkBoxs_band_5, 1, 4, 1, 1) - self.checkBoxs_band_6 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_6.setChecked(True) - self.checkBoxs_band_6.setObjectName("checkBoxs_band_6") - self.gridLayout_136.addWidget(self.checkBoxs_band_6, 1, 5, 1, 1) - self.checkBoxs_band_7 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_7.setChecked(True) - self.checkBoxs_band_7.setObjectName("checkBoxs_band_7") - self.gridLayout_136.addWidget(self.checkBoxs_band_7, 1, 6, 1, 1) - self.checkBoxs_band_12 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_12.setChecked(True) - self.checkBoxs_band_12.setObjectName("checkBoxs_band_12") - self.gridLayout_136.addWidget(self.checkBoxs_band_12, 1, 11, 1, 1) - self.checkBoxs_band_8 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_8.setChecked(True) - self.checkBoxs_band_8.setObjectName("checkBoxs_band_8") - self.gridLayout_136.addWidget(self.checkBoxs_band_8, 1, 7, 1, 1) - self.checkBoxs_band_10 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_10.setChecked(True) - self.checkBoxs_band_10.setObjectName("checkBoxs_band_10") - self.gridLayout_136.addWidget(self.checkBoxs_band_10, 1, 9, 1, 1) - self.ancillary_data_checkBox = QtWidgets.QCheckBox(self.tab_options) - self.ancillary_data_checkBox.setChecked(True) - self.ancillary_data_checkBox.setObjectName("ancillary_data_checkBox") - self.gridLayout_136.addWidget(self.ancillary_data_checkBox, 1, 13, 1, 1) - self.checkBoxs_band_13 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_13.setChecked(True) - self.checkBoxs_band_13.setObjectName("checkBoxs_band_13") - self.gridLayout_136.addWidget(self.checkBoxs_band_13, 1, 12, 1, 1) - self.checkBoxs_band_11 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_band_11.setChecked(True) - self.checkBoxs_band_11.setObjectName("checkBoxs_band_11") - self.gridLayout_136.addWidget(self.checkBoxs_band_11, 1, 10, 1, 1) - self.gridLayout_117.addLayout(self.gridLayout_136, 0, 1, 1, 1) - self.gridLayout_160 = QtWidgets.QGridLayout() - self.gridLayout_160.setObjectName("gridLayout_160") - self.checkBoxs3_band_6 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_6.setChecked(True) - self.checkBoxs3_band_6.setObjectName("checkBoxs3_band_6") - self.gridLayout_160.addWidget(self.checkBoxs3_band_6, 1, 5, 1, 1) - self.checkBoxs3_band_2 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_2.setChecked(True) - self.checkBoxs3_band_2.setObjectName("checkBoxs3_band_2") - self.gridLayout_160.addWidget(self.checkBoxs3_band_2, 1, 1, 1, 1) - self.checkBoxs3_band_5 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_5.setChecked(True) - self.checkBoxs3_band_5.setObjectName("checkBoxs3_band_5") - self.gridLayout_160.addWidget(self.checkBoxs3_band_5, 1, 4, 1, 1) - self.checkBoxs3_band_8 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_8.setChecked(True) - self.checkBoxs3_band_8.setObjectName("checkBoxs3_band_8") - self.gridLayout_160.addWidget(self.checkBoxs3_band_8, 1, 7, 1, 1) - self.checkBoxs3_band_1 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_1.setChecked(True) - self.checkBoxs3_band_1.setObjectName("checkBoxs3_band_1") - self.gridLayout_160.addWidget(self.checkBoxs3_band_1, 1, 0, 1, 1) - self.checkBoxs3_band_16 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_16.setChecked(True) - self.checkBoxs3_band_16.setObjectName("checkBoxs3_band_16") - self.gridLayout_160.addWidget(self.checkBoxs3_band_16, 2, 4, 1, 1) - self.checkBoxs3_band_10 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_10.setChecked(True) - self.checkBoxs3_band_10.setObjectName("checkBoxs3_band_10") - self.gridLayout_160.addWidget(self.checkBoxs3_band_10, 1, 9, 1, 1) - self.checkBoxs3_band_12 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_12.setChecked(True) - self.checkBoxs3_band_12.setObjectName("checkBoxs3_band_12") - self.gridLayout_160.addWidget(self.checkBoxs3_band_12, 2, 0, 1, 1) - self.s3_ancillary_data_checkBox = QtWidgets.QCheckBox(self.tab_options) - self.s3_ancillary_data_checkBox.setChecked(True) - self.s3_ancillary_data_checkBox.setObjectName("s3_ancillary_data_checkBox") - self.gridLayout_160.addWidget(self.s3_ancillary_data_checkBox, 2, 10, 1, 1) - self.checkBoxs3_band_3 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_3.setChecked(True) - self.checkBoxs3_band_3.setObjectName("checkBoxs3_band_3") - self.gridLayout_160.addWidget(self.checkBoxs3_band_3, 1, 2, 1, 1) - self.label_127 = QtWidgets.QLabel(self.tab_options) - self.label_127.setStyleSheet("background-color : #656565; color : white") - self.label_127.setFrameShape(QtWidgets.QFrame.Panel) - self.label_127.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_127.setObjectName("label_127") - self.gridLayout_160.addWidget(self.label_127, 0, 0, 1, 12) - self.checkBoxs3_band_20 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_20.setChecked(True) - self.checkBoxs3_band_20.setObjectName("checkBoxs3_band_20") - self.gridLayout_160.addWidget(self.checkBoxs3_band_20, 2, 8, 1, 1) - self.checkBoxs3_band_17 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_17.setChecked(True) - self.checkBoxs3_band_17.setObjectName("checkBoxs3_band_17") - self.gridLayout_160.addWidget(self.checkBoxs3_band_17, 2, 5, 1, 1) - self.checkBoxs3_band_14 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_14.setChecked(True) - self.checkBoxs3_band_14.setObjectName("checkBoxs3_band_14") - self.gridLayout_160.addWidget(self.checkBoxs3_band_14, 2, 2, 1, 1) - self.checkBoxs3_band_9 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_9.setChecked(True) - self.checkBoxs3_band_9.setObjectName("checkBoxs3_band_9") - self.gridLayout_160.addWidget(self.checkBoxs3_band_9, 1, 8, 1, 1) - self.checkBoxs3_band_13 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_13.setChecked(True) - self.checkBoxs3_band_13.setObjectName("checkBoxs3_band_13") - self.gridLayout_160.addWidget(self.checkBoxs3_band_13, 2, 1, 1, 1) - self.checkBoxs3_band_19 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_19.setChecked(True) - self.checkBoxs3_band_19.setObjectName("checkBoxs3_band_19") - self.gridLayout_160.addWidget(self.checkBoxs3_band_19, 2, 7, 1, 1) - self.check_toolButton_3 = QtWidgets.QToolButton(self.tab_options) - self.check_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") - self.check_toolButton_3.setIcon(icon56) - self.check_toolButton_3.setIconSize(QtCore.QSize(22, 22)) - self.check_toolButton_3.setObjectName("check_toolButton_3") - self.gridLayout_160.addWidget(self.check_toolButton_3, 1, 11, 1, 1) - self.checkBoxs3_band_7 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_7.setChecked(True) - self.checkBoxs3_band_7.setObjectName("checkBoxs3_band_7") - self.gridLayout_160.addWidget(self.checkBoxs3_band_7, 1, 6, 1, 1) - self.checkBoxs3_band_4 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_4.setChecked(True) - self.checkBoxs3_band_4.setObjectName("checkBoxs3_band_4") - self.gridLayout_160.addWidget(self.checkBoxs3_band_4, 1, 3, 1, 1) - self.checkBoxs3_band_11 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_11.setChecked(True) - self.checkBoxs3_band_11.setObjectName("checkBoxs3_band_11") - self.gridLayout_160.addWidget(self.checkBoxs3_band_11, 1, 10, 1, 1) - self.checkBoxs3_band_15 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_15.setChecked(True) - self.checkBoxs3_band_15.setObjectName("checkBoxs3_band_15") - self.gridLayout_160.addWidget(self.checkBoxs3_band_15, 2, 3, 1, 1) - self.checkBoxs3_band_21 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_21.setChecked(True) - self.checkBoxs3_band_21.setObjectName("checkBoxs3_band_21") - self.gridLayout_160.addWidget(self.checkBoxs3_band_21, 2, 9, 1, 1) - self.checkBoxs3_band_18 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs3_band_18.setChecked(True) - self.checkBoxs3_band_18.setObjectName("checkBoxs3_band_18") - self.gridLayout_160.addWidget(self.checkBoxs3_band_18, 2, 6, 1, 1) - self.gridLayout_117.addLayout(self.gridLayout_160, 1, 1, 1, 1) - self.gridLayout_141 = QtWidgets.QGridLayout() - self.gridLayout_141.setObjectName("gridLayout_141") - self.checkBoxs_goes_band_1 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_1.setChecked(True) - self.checkBoxs_goes_band_1.setObjectName("checkBoxs_goes_band_1") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_1, 1, 0, 1, 1) - self.label_272 = QtWidgets.QLabel(self.tab_options) - self.label_272.setStyleSheet("background-color : #656565; color : white") - self.label_272.setFrameShape(QtWidgets.QFrame.Panel) - self.label_272.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_272.setObjectName("label_272") - self.gridLayout_141.addWidget(self.label_272, 0, 0, 1, 8) - self.checkBoxs_goes_band_5 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_5.setChecked(True) - self.checkBoxs_goes_band_5.setObjectName("checkBoxs_goes_band_5") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_5, 1, 4, 1, 1) - self.checkBoxs_goes_band_3 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_3.setChecked(True) - self.checkBoxs_goes_band_3.setObjectName("checkBoxs_goes_band_3") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_3, 1, 2, 1, 1) - self.checkBoxs_goes_band_4 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_4.setChecked(True) - self.checkBoxs_goes_band_4.setObjectName("checkBoxs_goes_band_4") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_4, 1, 3, 1, 1) - self.checkBoxs_goes_band_2 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_2.setChecked(True) - self.checkBoxs_goes_band_2.setObjectName("checkBoxs_goes_band_2") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_2, 1, 1, 1, 1) - self.checkBoxs_goes_band_6 = QtWidgets.QCheckBox(self.tab_options) - self.checkBoxs_goes_band_6.setChecked(True) - self.checkBoxs_goes_band_6.setObjectName("checkBoxs_goes_band_6") - self.gridLayout_141.addWidget(self.checkBoxs_goes_band_6, 1, 5, 1, 1) - self.check_toolButton_4 = QtWidgets.QToolButton(self.tab_options) - self.check_toolButton_4.setStyleSheet("margin: 0px;padding: 0px;") - self.check_toolButton_4.setIcon(icon56) - self.check_toolButton_4.setIconSize(QtCore.QSize(22, 22)) - self.check_toolButton_4.setObjectName("check_toolButton_4") - self.gridLayout_141.addWidget(self.check_toolButton_4, 1, 7, 1, 1) - spacerItem32 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_141.addItem(spacerItem32, 1, 6, 1, 1) - self.gridLayout_117.addLayout(self.gridLayout_141, 2, 1, 1, 1) - self.gridLayout_116.addLayout(self.gridLayout_117, 3, 0, 1, 7) - self.checkBox_band_8 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_8.setChecked(True) - self.checkBox_band_8.setObjectName("checkBox_band_8") - self.gridLayout_116.addWidget(self.checkBox_band_8, 2, 1, 1, 1) - self.checkBox_band_10 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_10.setChecked(True) - self.checkBox_band_10.setObjectName("checkBox_band_10") - self.gridLayout_116.addWidget(self.checkBox_band_10, 2, 3, 1, 1) - self.checkBox_band_9 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_9.setChecked(True) - self.checkBox_band_9.setObjectName("checkBox_band_9") - self.gridLayout_116.addWidget(self.checkBox_band_9, 2, 2, 1, 1) - self.checkBox_band_7 = QtWidgets.QCheckBox(self.tab_options) - self.checkBox_band_7.setChecked(True) - self.checkBox_band_7.setObjectName("checkBox_band_7") - self.gridLayout_116.addWidget(self.checkBox_band_7, 2, 0, 1, 1) - self.gridLayout_199.addLayout(self.gridLayout_116, 0, 0, 1, 1) - icon80 = QtGui.QIcon() - icon80.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_options.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_3.addTab(self.tab_options, icon80, "") - self.gridLayout_113.addWidget(self.tabWidget_3, 0, 1, 1, 1) - self.gridLayout_68.addLayout(self.gridLayout_113, 0, 0, 1, 1) - self.gridLayout_320 = QtWidgets.QGridLayout() - self.gridLayout_320.setObjectName("gridLayout_320") - self.label_258 = QtWidgets.QLabel(self.tab_download_products) - self.label_258.setStyleSheet("background-color : #656565; color : white") - self.label_258.setFrameShape(QtWidgets.QFrame.Panel) - self.label_258.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_258.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_258.setOpenExternalLinks(True) - self.label_258.setObjectName("label_258") - self.gridLayout_320.addWidget(self.label_258, 0, 0, 1, 8) - self.preprocess_checkBox = QtWidgets.QCheckBox(self.tab_download_products) - self.preprocess_checkBox.setChecked(True) - self.preprocess_checkBox.setObjectName("preprocess_checkBox") - self.gridLayout_320.addWidget(self.preprocess_checkBox, 1, 2, 1, 1) - self.load_in_QGIS_checkBox = QtWidgets.QCheckBox(self.tab_download_products) - self.load_in_QGIS_checkBox.setChecked(True) - self.load_in_QGIS_checkBox.setObjectName("load_in_QGIS_checkBox") - self.gridLayout_320.addWidget(self.load_in_QGIS_checkBox, 1, 3, 1, 1) - self.download_if_preview_in_legend_checkBox = QtWidgets.QCheckBox(self.tab_download_products) - self.download_if_preview_in_legend_checkBox.setChecked(True) - self.download_if_preview_in_legend_checkBox.setObjectName("download_if_preview_in_legend_checkBox") - self.gridLayout_320.addWidget(self.download_if_preview_in_legend_checkBox, 1, 1, 1, 1) - spacerItem33 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_320.addItem(spacerItem33, 1, 5, 1, 1) - self.export_links_Button = QtWidgets.QToolButton(self.tab_download_products) - self.export_links_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.export_links_Button.setIcon(icon53) - self.export_links_Button.setIconSize(QtCore.QSize(22, 22)) - self.export_links_Button.setObjectName("export_links_Button") - self.gridLayout_320.addWidget(self.export_links_Button, 1, 6, 1, 1) - self.download_images_Button = QtWidgets.QToolButton(self.tab_download_products) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.download_images_Button.setFont(font) - self.download_images_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.download_images_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.download_images_Button.setIcon(icon64) - self.download_images_Button.setIconSize(QtCore.QSize(34, 34)) - self.download_images_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.download_images_Button.setObjectName("download_images_Button") - self.gridLayout_320.addWidget(self.download_images_Button, 1, 7, 1, 1) - self.virtual_download_checkBox = QtWidgets.QCheckBox(self.tab_download_products) - self.virtual_download_checkBox.setObjectName("virtual_download_checkBox") - self.gridLayout_320.addWidget(self.virtual_download_checkBox, 1, 4, 1, 1) - self.gridLayout_68.addLayout(self.gridLayout_320, 1, 0, 1, 1) - self.SCP_tabs.addTab(self.tab_download_products, "") - self.tab_preprocessing = QtWidgets.QWidget() - self.tab_preprocessing.setStyleSheet("") - self.tab_preprocessing.setObjectName("tab_preprocessing") - self.gridLayout_6 = QtWidgets.QGridLayout(self.tab_preprocessing) - self.gridLayout_6.setObjectName("gridLayout_6") - self.tabWidget_preprocessing = QtWidgets.QTabWidget(self.tab_preprocessing) - self.tabWidget_preprocessing.setStyleSheet("") - self.tabWidget_preprocessing.setIconSize(QtCore.QSize(20, 20)) - self.tabWidget_preprocessing.setDocumentMode(True) - self.tabWidget_preprocessing.setObjectName("tabWidget_preprocessing") - self.tab_Landsat = QtWidgets.QWidget() - self.tab_Landsat.setObjectName("tab_Landsat") - self.gridLayout_18 = QtWidgets.QGridLayout(self.tab_Landsat) - self.gridLayout_18.setObjectName("gridLayout_18") - self.gridLayout_37 = QtWidgets.QGridLayout() - self.gridLayout_37.setObjectName("gridLayout_37") - self.label_36 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_36.sizePolicy().hasHeightForWidth()) - self.label_36.setSizePolicy(sizePolicy) - self.label_36.setMinimumSize(QtCore.QSize(229, 0)) - font = QtGui.QFont() - font.setBold(False) - font.setWeight(50) - self.label_36.setFont(font) - self.label_36.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_36.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_36.setObjectName("label_36") - self.gridLayout_37.addWidget(self.label_36, 1, 0, 1, 1) - self.label_37 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_37.sizePolicy().hasHeightForWidth()) - self.label_37.setSizePolicy(sizePolicy) - self.label_37.setStyleSheet("background-color : #656565; color : white") - self.label_37.setFrameShape(QtWidgets.QFrame.Panel) - self.label_37.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_37.setObjectName("label_37") - self.gridLayout_37.addWidget(self.label_37, 0, 0, 1, 4) - self.celsius_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) - self.celsius_checkBox.setChecked(False) - self.celsius_checkBox.setTristate(False) - self.celsius_checkBox.setObjectName("celsius_checkBox") - self.gridLayout_37.addWidget(self.celsius_checkBox, 3, 0, 1, 1) - self.DOS1_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) - self.DOS1_checkBox.setChecked(False) - self.DOS1_checkBox.setTristate(False) - self.DOS1_checkBox.setObjectName("DOS1_checkBox") - self.gridLayout_37.addWidget(self.DOS1_checkBox, 4, 0, 1, 1) - self.gridLayout_29 = QtWidgets.QGridLayout() - self.gridLayout_29.setObjectName("gridLayout_29") - self.nodata_spinBox_3 = QtWidgets.QSpinBox(self.tab_Landsat) - self.nodata_spinBox_3.setMinimum(-999) - self.nodata_spinBox_3.setMaximum(100000) - self.nodata_spinBox_3.setObjectName("nodata_spinBox_3") - self.gridLayout_29.addWidget(self.nodata_spinBox_3, 0, 2, 1, 1) - self.nodata_checkBox_2 = QtWidgets.QCheckBox(self.tab_Landsat) - self.nodata_checkBox_2.setChecked(True) - self.nodata_checkBox_2.setObjectName("nodata_checkBox_2") - self.gridLayout_29.addWidget(self.nodata_checkBox_2, 0, 1, 1, 1) - spacerItem34 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_29.addItem(spacerItem34, 0, 0, 1, 1) - self.gridLayout_37.addLayout(self.gridLayout_29, 4, 1, 1, 3) - self.label_41 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_41.sizePolicy().hasHeightForWidth()) - self.label_41.setSizePolicy(sizePolicy) - self.label_41.setMinimumSize(QtCore.QSize(229, 0)) - self.label_41.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_41.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_41.setObjectName("label_41") - self.gridLayout_37.addWidget(self.label_41, 2, 0, 1, 1) - self.toolButton_directoryInput = QtWidgets.QToolButton(self.tab_Landsat) - self.toolButton_directoryInput.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_directoryInput.setIcon(icon69) - self.toolButton_directoryInput.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_directoryInput.setObjectName("toolButton_directoryInput") - self.gridLayout_37.addWidget(self.toolButton_directoryInput, 1, 3, 1, 1) - self.label_26 = QtWidgets.QLabel(self.tab_Landsat) - self.label_26.setFrameShape(QtWidgets.QFrame.Panel) - self.label_26.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_26.setText("") - self.label_26.setObjectName("label_26") - self.gridLayout_37.addWidget(self.label_26, 1, 1, 1, 2) - self.label_27 = QtWidgets.QLabel(self.tab_Landsat) - self.label_27.setFrameShape(QtWidgets.QFrame.Panel) - self.label_27.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_27.setText("") - self.label_27.setObjectName("label_27") - self.gridLayout_37.addWidget(self.label_27, 2, 1, 1, 2) - self.gridLayout_183 = QtWidgets.QGridLayout() - self.gridLayout_183.setObjectName("gridLayout_183") - self.pansharpening_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) - self.pansharpening_checkBox.setChecked(False) - self.pansharpening_checkBox.setTristate(False) - self.pansharpening_checkBox.setObjectName("pansharpening_checkBox") - self.gridLayout_183.addWidget(self.pansharpening_checkBox, 0, 0, 1, 1) - self.create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) - self.create_bandset_checkBox.setChecked(True) - self.create_bandset_checkBox.setTristate(False) - self.create_bandset_checkBox.setObjectName("create_bandset_checkBox") - self.gridLayout_183.addWidget(self.create_bandset_checkBox, 1, 0, 1, 1) - self.add_new_bandset_checkBox_1 = QtWidgets.QCheckBox(self.tab_Landsat) - self.add_new_bandset_checkBox_1.setChecked(True) - self.add_new_bandset_checkBox_1.setTristate(False) - self.add_new_bandset_checkBox_1.setObjectName("add_new_bandset_checkBox_1") - self.gridLayout_183.addWidget(self.add_new_bandset_checkBox_1, 1, 1, 1, 1) - spacerItem35 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_183.addItem(spacerItem35, 1, 2, 1, 1) - self.gridLayout_37.addLayout(self.gridLayout_183, 5, 0, 1, 4) - self.toolButton_directoryInput_MTL = QtWidgets.QToolButton(self.tab_Landsat) - self.toolButton_directoryInput_MTL.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_directoryInput_MTL.setIcon(icon65) - self.toolButton_directoryInput_MTL.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_directoryInput_MTL.setObjectName("toolButton_directoryInput_MTL") - self.gridLayout_37.addWidget(self.toolButton_directoryInput_MTL, 2, 3, 1, 1) - self.gridLayout_18.addLayout(self.gridLayout_37, 0, 0, 1, 1) - self.gridLayout_95 = QtWidgets.QGridLayout() - self.gridLayout_95.setObjectName("gridLayout_95") - self.landsat_tableWidget = QtWidgets.QTableWidget(self.tab_Landsat) - self.landsat_tableWidget.setObjectName("landsat_tableWidget") - self.landsat_tableWidget.setColumnCount(13) - self.landsat_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(3, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(4, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(5, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(6, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(7, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(8, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(9, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(10, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(11, item) - item = QtWidgets.QTableWidgetItem() - self.landsat_tableWidget.setHorizontalHeaderItem(12, item) - self.landsat_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.gridLayout_95.addWidget(self.landsat_tableWidget, 1, 0, 1, 1) - self.gridLayout_15 = QtWidgets.QGridLayout() - self.gridLayout_15.setObjectName("gridLayout_15") - self.pushButton_remove_band = QtWidgets.QToolButton(self.tab_Landsat) - self.pushButton_remove_band.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_remove_band.setIcon(icon58) - self.pushButton_remove_band.setIconSize(QtCore.QSize(22, 22)) - self.pushButton_remove_band.setObjectName("pushButton_remove_band") - self.gridLayout_15.addWidget(self.pushButton_remove_band, 0, 0, 1, 1) - self.gridLayout_95.addLayout(self.gridLayout_15, 1, 1, 1, 1) - self.gridLayout_98 = QtWidgets.QGridLayout() - self.gridLayout_98.setObjectName("gridLayout_98") - self.satellite_label = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label.sizePolicy().hasHeightForWidth()) - self.satellite_label.setSizePolicy(sizePolicy) - self.satellite_label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label.setObjectName("satellite_label") - self.gridLayout_98.addWidget(self.satellite_label, 1, 0, 1, 1) - self.satellite_label_3 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_3.sizePolicy().hasHeightForWidth()) - self.satellite_label_3.setSizePolicy(sizePolicy) - self.satellite_label_3.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_3.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_3.setObjectName("satellite_label_3") - self.gridLayout_98.addWidget(self.satellite_label_3, 1, 4, 1, 1) - self.date_lineEdit = QtWidgets.QLineEdit(self.tab_Landsat) - self.date_lineEdit.setObjectName("date_lineEdit") - self.gridLayout_98.addWidget(self.date_lineEdit, 1, 3, 1, 1) - self.satellite_label_2 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_2.sizePolicy().hasHeightForWidth()) - self.satellite_label_2.setSizePolicy(sizePolicy) - self.satellite_label_2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_2.setObjectName("satellite_label_2") - self.gridLayout_98.addWidget(self.satellite_label_2, 1, 2, 1, 1) - self.satellite_label_4 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_4.sizePolicy().hasHeightForWidth()) - self.satellite_label_4.setSizePolicy(sizePolicy) - self.satellite_label_4.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_4.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_4.setObjectName("satellite_label_4") - self.gridLayout_98.addWidget(self.satellite_label_4, 1, 6, 1, 1) - self.sun_elev_lineEdit = QtWidgets.QLineEdit(self.tab_Landsat) - self.sun_elev_lineEdit.setObjectName("sun_elev_lineEdit") - self.gridLayout_98.addWidget(self.sun_elev_lineEdit, 1, 5, 1, 1) - self.earth_sun_dist_lineEdit = QtWidgets.QLineEdit(self.tab_Landsat) - self.earth_sun_dist_lineEdit.setObjectName("earth_sun_dist_lineEdit") - self.gridLayout_98.addWidget(self.earth_sun_dist_lineEdit, 1, 7, 1, 1) - self.label_74 = QtWidgets.QLabel(self.tab_Landsat) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_74.sizePolicy().hasHeightForWidth()) - self.label_74.setSizePolicy(sizePolicy) - self.label_74.setStyleSheet("background-color : #656565; color : white") - self.label_74.setFrameShape(QtWidgets.QFrame.Panel) - self.label_74.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_74.setObjectName("label_74") - self.gridLayout_98.addWidget(self.label_74, 0, 0, 1, 9) - self.satellite_lineEdit = QtWidgets.QLineEdit(self.tab_Landsat) - self.satellite_lineEdit.setObjectName("satellite_lineEdit") - self.gridLayout_98.addWidget(self.satellite_lineEdit, 1, 1, 1, 1) - self.gridLayout_95.addLayout(self.gridLayout_98, 0, 0, 1, 2) - self.gridLayout_18.addLayout(self.gridLayout_95, 1, 0, 1, 1) - self.gridLayout_97 = QtWidgets.QGridLayout() - self.gridLayout_97.setObjectName("gridLayout_97") - spacerItem36 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_97.addItem(spacerItem36, 1, 1, 1, 1) - self.label_161 = QtWidgets.QLabel(self.tab_Landsat) - self.label_161.setStyleSheet("background-color : #656565; color : white") - self.label_161.setFrameShape(QtWidgets.QFrame.Panel) - self.label_161.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_161.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_161.setObjectName("label_161") - self.gridLayout_97.addWidget(self.label_161, 0, 1, 1, 3) - self.pushButton_Conversion = QtWidgets.QToolButton(self.tab_Landsat) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion.setFont(font) - self.pushButton_Conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion.setIcon(icon64) - self.pushButton_Conversion.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion.setObjectName("pushButton_Conversion") - self.gridLayout_97.addWidget(self.pushButton_Conversion, 1, 3, 1, 1) - self.landsat_conversion = QtWidgets.QToolButton(self.tab_Landsat) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.landsat_conversion.setFont(font) - self.landsat_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.landsat_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.landsat_conversion.setIcon(icon48) - self.landsat_conversion.setIconSize(QtCore.QSize(34, 34)) - self.landsat_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.landsat_conversion.setObjectName("landsat_conversion") - self.gridLayout_97.addWidget(self.landsat_conversion, 1, 2, 1, 1) - self.gridLayout_18.addLayout(self.gridLayout_97, 2, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_Landsat, "") - self.tab_Sentinel1 = QtWidgets.QWidget() - self.tab_Sentinel1.setObjectName("tab_Sentinel1") - self.gridLayout_167 = QtWidgets.QGridLayout(self.tab_Sentinel1) - self.gridLayout_167.setObjectName("gridLayout_167") - self.gridLayout_265 = QtWidgets.QGridLayout() - self.gridLayout_265.setObjectName("gridLayout_265") - self.gridLayout_279 = QtWidgets.QGridLayout() - self.gridLayout_279.setObjectName("gridLayout_279") - self.S1_label_95 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S1_label_95.sizePolicy().hasHeightForWidth()) - self.S1_label_95.setSizePolicy(sizePolicy) - self.S1_label_95.setMinimumSize(QtCore.QSize(229, 0)) - self.S1_label_95.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S1_label_95.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.S1_label_95.setObjectName("S1_label_95") - self.gridLayout_279.addWidget(self.S1_label_95, 0, 0, 1, 1) - self.S1_label_96 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S1_label_96.sizePolicy().hasHeightForWidth()) - self.S1_label_96.setSizePolicy(sizePolicy) - self.S1_label_96.setFrameShape(QtWidgets.QFrame.Panel) - self.S1_label_96.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S1_label_96.setText("") - self.S1_label_96.setObjectName("S1_label_96") - self.gridLayout_279.addWidget(self.S1_label_96, 0, 1, 1, 1) - self.S1_toolButton_directoryInput_xml = QtWidgets.QToolButton(self.tab_Sentinel1) - self.S1_toolButton_directoryInput_xml.setStyleSheet("margin: 0px;padding: 0px;") - self.S1_toolButton_directoryInput_xml.setIcon(icon65) - self.S1_toolButton_directoryInput_xml.setIconSize(QtCore.QSize(22, 22)) - self.S1_toolButton_directoryInput_xml.setObjectName("S1_toolButton_directoryInput_xml") - self.gridLayout_279.addWidget(self.S1_toolButton_directoryInput_xml, 0, 2, 1, 1) - self.horizontalLayout_48 = QtWidgets.QHBoxLayout() - self.horizontalLayout_48.setObjectName("horizontalLayout_48") - self.S1_label_97 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S1_label_97.sizePolicy().hasHeightForWidth()) - self.S1_label_97.setSizePolicy(sizePolicy) - self.S1_label_97.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S1_label_97.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.S1_label_97.setObjectName("S1_label_97") - self.horizontalLayout_48.addWidget(self.S1_label_97) - self.VH_checkBox_S1 = QtWidgets.QCheckBox(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.VH_checkBox_S1.sizePolicy().hasHeightForWidth()) - self.VH_checkBox_S1.setSizePolicy(sizePolicy) - self.VH_checkBox_S1.setChecked(True) - self.VH_checkBox_S1.setTristate(False) - self.VH_checkBox_S1.setObjectName("VH_checkBox_S1") - self.horizontalLayout_48.addWidget(self.VH_checkBox_S1) - self.VV_checkBox_S1 = QtWidgets.QCheckBox(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.VV_checkBox_S1.sizePolicy().hasHeightForWidth()) - self.VV_checkBox_S1.setSizePolicy(sizePolicy) - self.VV_checkBox_S1.setChecked(True) - self.VV_checkBox_S1.setTristate(False) - self.VV_checkBox_S1.setObjectName("VV_checkBox_S1") - self.horizontalLayout_48.addWidget(self.VV_checkBox_S1) - self.gridLayout_279.addLayout(self.horizontalLayout_48, 1, 0, 1, 1) - self.gridLayout_265.addLayout(self.gridLayout_279, 3, 0, 1, 3) - self.label_209 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_209.sizePolicy().hasHeightForWidth()) - self.label_209.setSizePolicy(sizePolicy) - self.label_209.setStyleSheet("background-color : #656565; color : white") - self.label_209.setFrameShape(QtWidgets.QFrame.Panel) - self.label_209.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_209.setObjectName("label_209") - self.gridLayout_265.addWidget(self.label_209, 0, 0, 1, 3) - self.S1_create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel1) - self.S1_create_bandset_checkBox.setChecked(True) - self.S1_create_bandset_checkBox.setTristate(False) - self.S1_create_bandset_checkBox.setObjectName("S1_create_bandset_checkBox") - self.gridLayout_265.addWidget(self.S1_create_bandset_checkBox, 5, 0, 1, 1) - self.add_new_bandset_checkBox_6 = QtWidgets.QCheckBox(self.tab_Sentinel1) - self.add_new_bandset_checkBox_6.setChecked(True) - self.add_new_bandset_checkBox_6.setTristate(False) - self.add_new_bandset_checkBox_6.setObjectName("add_new_bandset_checkBox_6") - self.gridLayout_265.addWidget(self.add_new_bandset_checkBox_6, 5, 1, 1, 2) - self.gridLayout_266 = QtWidgets.QGridLayout() - self.gridLayout_266.setObjectName("gridLayout_266") - self.S1_label_87 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S1_label_87.sizePolicy().hasHeightForWidth()) - self.S1_label_87.setSizePolicy(sizePolicy) - self.S1_label_87.setFrameShape(QtWidgets.QFrame.Panel) - self.S1_label_87.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S1_label_87.setText("") - self.S1_label_87.setObjectName("S1_label_87") - self.gridLayout_266.addWidget(self.S1_label_87, 0, 1, 1, 1) - self.S1_toolButton_fileInput = QtWidgets.QToolButton(self.tab_Sentinel1) - self.S1_toolButton_fileInput.setStyleSheet("margin: 0px;padding: 0px;") - self.S1_toolButton_fileInput.setIcon(icon65) - self.S1_toolButton_fileInput.setIconSize(QtCore.QSize(22, 22)) - self.S1_toolButton_fileInput.setObjectName("S1_toolButton_fileInput") - self.gridLayout_266.addWidget(self.S1_toolButton_fileInput, 0, 2, 1, 1) - self.label_207 = QtWidgets.QLabel(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_207.sizePolicy().hasHeightForWidth()) - self.label_207.setSizePolicy(sizePolicy) - self.label_207.setMinimumSize(QtCore.QSize(229, 0)) - self.label_207.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_207.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_207.setObjectName("label_207") - self.gridLayout_266.addWidget(self.label_207, 0, 0, 1, 1) - self.gridLayout_265.addLayout(self.gridLayout_266, 2, 0, 1, 3) - self.horizontalLayout_46 = QtWidgets.QHBoxLayout() - self.horizontalLayout_46.setObjectName("horizontalLayout_46") - self.projection_checkBox_S1 = QtWidgets.QCheckBox(self.tab_Sentinel1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.projection_checkBox_S1.sizePolicy().hasHeightForWidth()) - self.projection_checkBox_S1.setSizePolicy(sizePolicy) - self.projection_checkBox_S1.setTristate(False) - self.projection_checkBox_S1.setObjectName("projection_checkBox_S1") - self.horizontalLayout_46.addWidget(self.projection_checkBox_S1) - self.band_set_comb_spinBox_11 = QtWidgets.QSpinBox(self.tab_Sentinel1) - self.band_set_comb_spinBox_11.setMinimum(1) - self.band_set_comb_spinBox_11.setMaximum(100000) - self.band_set_comb_spinBox_11.setObjectName("band_set_comb_spinBox_11") - self.horizontalLayout_46.addWidget(self.band_set_comb_spinBox_11) - spacerItem37 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_46.addItem(spacerItem37) - self.convert_to_db_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel1) - self.convert_to_db_checkBox.setChecked(True) - self.convert_to_db_checkBox.setTristate(False) - self.convert_to_db_checkBox.setObjectName("convert_to_db_checkBox") - self.horizontalLayout_46.addWidget(self.convert_to_db_checkBox) - spacerItem38 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_46.addItem(spacerItem38) - self.S1_nodata_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel1) - self.S1_nodata_checkBox.setChecked(True) - self.S1_nodata_checkBox.setObjectName("S1_nodata_checkBox") - self.horizontalLayout_46.addWidget(self.S1_nodata_checkBox) - self.S1_nodata_spinBox = QtWidgets.QSpinBox(self.tab_Sentinel1) - self.S1_nodata_spinBox.setMinimum(-999) - self.S1_nodata_spinBox.setMaximum(100000) - self.S1_nodata_spinBox.setObjectName("S1_nodata_spinBox") - self.horizontalLayout_46.addWidget(self.S1_nodata_spinBox) - self.gridLayout_265.addLayout(self.horizontalLayout_46, 4, 0, 1, 3) - self.gridLayout_167.addLayout(self.gridLayout_265, 0, 0, 1, 1) - spacerItem39 = QtWidgets.QSpacerItem(20, 296, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_167.addItem(spacerItem39, 1, 0, 1, 1) - self.gridLayout_268 = QtWidgets.QGridLayout() - self.gridLayout_268.setObjectName("gridLayout_268") - self.label_210 = QtWidgets.QLabel(self.tab_Sentinel1) - self.label_210.setStyleSheet("background-color : #656565; color : white") - self.label_210.setFrameShape(QtWidgets.QFrame.Panel) - self.label_210.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_210.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_210.setObjectName("label_210") - self.gridLayout_268.addWidget(self.label_210, 0, 0, 1, 3) - spacerItem40 = QtWidgets.QSpacerItem(782, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_268.addItem(spacerItem40, 1, 0, 1, 1) - self.pushButton_Conversion_6 = QtWidgets.QToolButton(self.tab_Sentinel1) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_6.setFont(font) - self.pushButton_Conversion_6.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_6.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_6.setIcon(icon64) - self.pushButton_Conversion_6.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_6.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_6.setObjectName("pushButton_Conversion_6") - self.gridLayout_268.addWidget(self.pushButton_Conversion_6, 1, 2, 1, 1) - self.sentinel1_conversion = QtWidgets.QToolButton(self.tab_Sentinel1) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.sentinel1_conversion.setFont(font) - self.sentinel1_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.sentinel1_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.sentinel1_conversion.setIcon(icon48) - self.sentinel1_conversion.setIconSize(QtCore.QSize(34, 34)) - self.sentinel1_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.sentinel1_conversion.setObjectName("sentinel1_conversion") - self.gridLayout_268.addWidget(self.sentinel1_conversion, 1, 1, 1, 1) - self.gridLayout_167.addLayout(self.gridLayout_268, 2, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_Sentinel1, "") - self.tab_Sentinel2 = QtWidgets.QWidget() - self.tab_Sentinel2.setObjectName("tab_Sentinel2") - self.gridLayout_164 = QtWidgets.QGridLayout(self.tab_Sentinel2) - self.gridLayout_164.setObjectName("gridLayout_164") - self.gridLayout_146 = QtWidgets.QGridLayout() - self.gridLayout_146.setObjectName("gridLayout_146") - self.label_90 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_90.sizePolicy().hasHeightForWidth()) - self.label_90.setSizePolicy(sizePolicy) - self.label_90.setMinimumSize(QtCore.QSize(229, 0)) - self.label_90.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_90.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_90.setObjectName("label_90") - self.gridLayout_146.addWidget(self.label_90, 1, 0, 1, 1) - self.gridLayout_147 = QtWidgets.QGridLayout() - self.gridLayout_147.setObjectName("gridLayout_147") - self.S2_toolButton_directoryInput = QtWidgets.QToolButton(self.tab_Sentinel2) - self.S2_toolButton_directoryInput.setStyleSheet("margin: 0px;padding: 0px;") - self.S2_toolButton_directoryInput.setIcon(icon69) - self.S2_toolButton_directoryInput.setIconSize(QtCore.QSize(22, 22)) - self.S2_toolButton_directoryInput.setObjectName("S2_toolButton_directoryInput") - self.gridLayout_147.addWidget(self.S2_toolButton_directoryInput, 0, 1, 1, 1) - self.S2_label_86 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S2_label_86.sizePolicy().hasHeightForWidth()) - self.S2_label_86.setSizePolicy(sizePolicy) - self.S2_label_86.setFrameShape(QtWidgets.QFrame.Panel) - self.S2_label_86.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S2_label_86.setText("") - self.S2_label_86.setObjectName("S2_label_86") - self.gridLayout_147.addWidget(self.S2_label_86, 0, 0, 1, 1) - self.gridLayout_146.addLayout(self.gridLayout_147, 1, 1, 1, 2) - self.DOS1_checkBox_S2 = QtWidgets.QCheckBox(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.DOS1_checkBox_S2.sizePolicy().hasHeightForWidth()) - self.DOS1_checkBox_S2.setSizePolicy(sizePolicy) - self.DOS1_checkBox_S2.setChecked(False) - self.DOS1_checkBox_S2.setTristate(False) - self.DOS1_checkBox_S2.setObjectName("DOS1_checkBox_S2") - self.gridLayout_146.addWidget(self.DOS1_checkBox_S2, 3, 0, 1, 1) - self.gridLayout_148 = QtWidgets.QGridLayout() - self.gridLayout_148.setObjectName("gridLayout_148") - self.S2_nodata_spinBox = QtWidgets.QSpinBox(self.tab_Sentinel2) - self.S2_nodata_spinBox.setMinimum(-999) - self.S2_nodata_spinBox.setMaximum(100000) - self.S2_nodata_spinBox.setObjectName("S2_nodata_spinBox") - self.gridLayout_148.addWidget(self.S2_nodata_spinBox, 0, 2, 1, 1) - self.S2_nodata_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel2) - self.S2_nodata_checkBox.setChecked(True) - self.S2_nodata_checkBox.setObjectName("S2_nodata_checkBox") - self.gridLayout_148.addWidget(self.S2_nodata_checkBox, 0, 1, 1, 1) - spacerItem41 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_148.addItem(spacerItem41, 0, 0, 1, 1) - self.gridLayout_146.addLayout(self.gridLayout_148, 3, 1, 1, 2) - self.label_91 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_91.sizePolicy().hasHeightForWidth()) - self.label_91.setSizePolicy(sizePolicy) - self.label_91.setStyleSheet("background-color : #656565; color : white") - self.label_91.setFrameShape(QtWidgets.QFrame.Panel) - self.label_91.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_91.setObjectName("label_91") - self.gridLayout_146.addWidget(self.label_91, 0, 0, 1, 3) - self.S2_label_93 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S2_label_93.sizePolicy().hasHeightForWidth()) - self.S2_label_93.setSizePolicy(sizePolicy) - self.S2_label_93.setMinimumSize(QtCore.QSize(229, 0)) - self.S2_label_93.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S2_label_93.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.S2_label_93.setObjectName("S2_label_93") - self.gridLayout_146.addWidget(self.S2_label_93, 2, 0, 1, 1) - self.gridLayout_156 = QtWidgets.QGridLayout() - self.gridLayout_156.setObjectName("gridLayout_156") - self.S2_label_94 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S2_label_94.sizePolicy().hasHeightForWidth()) - self.S2_label_94.setSizePolicy(sizePolicy) - self.S2_label_94.setFrameShape(QtWidgets.QFrame.Panel) - self.S2_label_94.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S2_label_94.setText("") - self.S2_label_94.setObjectName("S2_label_94") - self.gridLayout_156.addWidget(self.S2_label_94, 0, 0, 1, 1) - self.S2_toolButton_directoryInput_xml2 = QtWidgets.QToolButton(self.tab_Sentinel2) - self.S2_toolButton_directoryInput_xml2.setStyleSheet("margin: 0px;padding: 0px;") - self.S2_toolButton_directoryInput_xml2.setIcon(icon65) - self.S2_toolButton_directoryInput_xml2.setIconSize(QtCore.QSize(22, 22)) - self.S2_toolButton_directoryInput_xml2.setObjectName("S2_toolButton_directoryInput_xml2") - self.gridLayout_156.addWidget(self.S2_toolButton_directoryInput_xml2, 0, 1, 1, 1) - self.gridLayout_146.addLayout(self.gridLayout_156, 2, 1, 1, 2) - self.S2_create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel2) - self.S2_create_bandset_checkBox.setChecked(True) - self.S2_create_bandset_checkBox.setTristate(False) - self.S2_create_bandset_checkBox.setObjectName("S2_create_bandset_checkBox") - self.gridLayout_146.addWidget(self.S2_create_bandset_checkBox, 5, 0, 1, 1) - self.add_new_bandset_checkBox_2 = QtWidgets.QCheckBox(self.tab_Sentinel2) - self.add_new_bandset_checkBox_2.setChecked(True) - self.add_new_bandset_checkBox_2.setTristate(False) - self.add_new_bandset_checkBox_2.setObjectName("add_new_bandset_checkBox_2") - self.gridLayout_146.addWidget(self.add_new_bandset_checkBox_2, 5, 1, 1, 2) - self.preprocess_b_1_9_10_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel2) - self.preprocess_b_1_9_10_checkBox.setTristate(False) - self.preprocess_b_1_9_10_checkBox.setObjectName("preprocess_b_1_9_10_checkBox") - self.gridLayout_146.addWidget(self.preprocess_b_1_9_10_checkBox, 4, 0, 1, 1) - self.gridLayout_164.addLayout(self.gridLayout_146, 0, 0, 1, 1) - self.gridLayout_166 = QtWidgets.QGridLayout() - self.gridLayout_166.setObjectName("gridLayout_166") - self.S2_satellite_lineEdit = QtWidgets.QLineEdit(self.tab_Sentinel2) - self.S2_satellite_lineEdit.setObjectName("S2_satellite_lineEdit") - self.gridLayout_166.addWidget(self.S2_satellite_lineEdit, 1, 1, 1, 1) - self.satellite_label_5 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_5.sizePolicy().hasHeightForWidth()) - self.satellite_label_5.setSizePolicy(sizePolicy) - self.satellite_label_5.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_5.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_5.setObjectName("satellite_label_5") - self.gridLayout_166.addWidget(self.satellite_label_5, 1, 0, 1, 1) - spacerItem42 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_166.addItem(spacerItem42, 1, 2, 1, 1) - self.satellite_label_6 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_6.sizePolicy().hasHeightForWidth()) - self.satellite_label_6.setSizePolicy(sizePolicy) - self.satellite_label_6.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_6.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_6.setObjectName("satellite_label_6") - self.gridLayout_166.addWidget(self.satellite_label_6, 1, 7, 1, 1) - self.S2_product_lineEdit = QtWidgets.QLineEdit(self.tab_Sentinel2) - self.S2_product_lineEdit.setObjectName("S2_product_lineEdit") - self.gridLayout_166.addWidget(self.S2_product_lineEdit, 1, 8, 1, 1) - self.label_92 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_92.sizePolicy().hasHeightForWidth()) - self.label_92.setSizePolicy(sizePolicy) - self.label_92.setStyleSheet("background-color : #656565; color : white") - self.label_92.setFrameShape(QtWidgets.QFrame.Panel) - self.label_92.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_92.setObjectName("label_92") - self.gridLayout_166.addWidget(self.label_92, 0, 0, 1, 9) - self.date_lineEdit_3 = QtWidgets.QLineEdit(self.tab_Sentinel2) - self.date_lineEdit_3.setObjectName("date_lineEdit_3") - self.gridLayout_166.addWidget(self.date_lineEdit_3, 1, 4, 1, 1) - spacerItem43 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_166.addItem(spacerItem43, 1, 6, 1, 1) - self.satellite_label_15 = QtWidgets.QLabel(self.tab_Sentinel2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_15.sizePolicy().hasHeightForWidth()) - self.satellite_label_15.setSizePolicy(sizePolicy) - self.satellite_label_15.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_15.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_15.setObjectName("satellite_label_15") - self.gridLayout_166.addWidget(self.satellite_label_15, 1, 3, 1, 1) - self.gridLayout_164.addLayout(self.gridLayout_166, 1, 0, 1, 1) - self.gridLayout_162 = QtWidgets.QGridLayout() - self.gridLayout_162.setObjectName("gridLayout_162") - self.sentinel_2_tableWidget = QtWidgets.QTableWidget(self.tab_Sentinel2) - self.sentinel_2_tableWidget.setTextElideMode(QtCore.Qt.ElideMiddle) - self.sentinel_2_tableWidget.setObjectName("sentinel_2_tableWidget") - self.sentinel_2_tableWidget.setColumnCount(3) - self.sentinel_2_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.sentinel_2_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.sentinel_2_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.sentinel_2_tableWidget.setHorizontalHeaderItem(2, item) - self.sentinel_2_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.sentinel_2_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_162.addWidget(self.sentinel_2_tableWidget, 0, 0, 1, 1) - self.S2_pushButton_remove_band = QtWidgets.QToolButton(self.tab_Sentinel2) - self.S2_pushButton_remove_band.setStyleSheet("margin: 0px;padding: 0px;") - self.S2_pushButton_remove_band.setIcon(icon58) - self.S2_pushButton_remove_band.setIconSize(QtCore.QSize(22, 22)) - self.S2_pushButton_remove_band.setObjectName("S2_pushButton_remove_band") - self.gridLayout_162.addWidget(self.S2_pushButton_remove_band, 0, 1, 1, 1) - self.gridLayout_164.addLayout(self.gridLayout_162, 2, 0, 1, 1) - self.gridLayout_165 = QtWidgets.QGridLayout() - self.gridLayout_165.setObjectName("gridLayout_165") - spacerItem44 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_165.addItem(spacerItem44, 1, 1, 1, 1) - self.label_162 = QtWidgets.QLabel(self.tab_Sentinel2) - self.label_162.setStyleSheet("background-color : #656565; color : white") - self.label_162.setFrameShape(QtWidgets.QFrame.Panel) - self.label_162.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_162.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_162.setObjectName("label_162") - self.gridLayout_165.addWidget(self.label_162, 0, 1, 1, 3) - self.pushButton_Conversion_2 = QtWidgets.QToolButton(self.tab_Sentinel2) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_2.setFont(font) - self.pushButton_Conversion_2.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_2.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_2.setIcon(icon64) - self.pushButton_Conversion_2.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_2.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_2.setObjectName("pushButton_Conversion_2") - self.gridLayout_165.addWidget(self.pushButton_Conversion_2, 1, 3, 1, 1) - self.sentinel2_conversion = QtWidgets.QToolButton(self.tab_Sentinel2) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.sentinel2_conversion.setFont(font) - self.sentinel2_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.sentinel2_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.sentinel2_conversion.setIcon(icon48) - self.sentinel2_conversion.setIconSize(QtCore.QSize(34, 34)) - self.sentinel2_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.sentinel2_conversion.setObjectName("sentinel2_conversion") - self.gridLayout_165.addWidget(self.sentinel2_conversion, 1, 2, 1, 1) - self.gridLayout_164.addLayout(self.gridLayout_165, 3, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_Sentinel2, "") - self.tab_Sentinel3 = QtWidgets.QWidget() - self.tab_Sentinel3.setObjectName("tab_Sentinel3") - self.gridLayout_158 = QtWidgets.QGridLayout(self.tab_Sentinel3) - self.gridLayout_158.setObjectName("gridLayout_158") - self.gridLayout_153 = QtWidgets.QGridLayout() - self.gridLayout_153.setObjectName("gridLayout_153") - self.gridLayout_157 = QtWidgets.QGridLayout() - self.gridLayout_157.setObjectName("gridLayout_157") - self.S2_nodata_spinBox_2 = QtWidgets.QSpinBox(self.tab_Sentinel3) - self.S2_nodata_spinBox_2.setMinimum(-999) - self.S2_nodata_spinBox_2.setMaximum(100000) - self.S2_nodata_spinBox_2.setObjectName("S2_nodata_spinBox_2") - self.gridLayout_157.addWidget(self.S2_nodata_spinBox_2, 0, 2, 1, 1) - self.S3_nodata_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel3) - self.S3_nodata_checkBox.setChecked(True) - self.S3_nodata_checkBox.setObjectName("S3_nodata_checkBox") - self.gridLayout_157.addWidget(self.S3_nodata_checkBox, 0, 1, 1, 1) - spacerItem45 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_157.addItem(spacerItem45, 0, 0, 1, 1) - self.gridLayout_153.addLayout(self.gridLayout_157, 3, 1, 1, 2) - self.label_109 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_109.sizePolicy().hasHeightForWidth()) - self.label_109.setSizePolicy(sizePolicy) - self.label_109.setStyleSheet("background-color : #656565; color : white") - self.label_109.setFrameShape(QtWidgets.QFrame.Panel) - self.label_109.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_109.setObjectName("label_109") - self.gridLayout_153.addWidget(self.label_109, 0, 0, 1, 3) - self.S3_create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_Sentinel3) - self.S3_create_bandset_checkBox.setChecked(True) - self.S3_create_bandset_checkBox.setTristate(False) - self.S3_create_bandset_checkBox.setObjectName("S3_create_bandset_checkBox") - self.gridLayout_153.addWidget(self.S3_create_bandset_checkBox, 4, 0, 1, 1) - self.label_106 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_106.sizePolicy().hasHeightForWidth()) - self.label_106.setSizePolicy(sizePolicy) - self.label_106.setMinimumSize(QtCore.QSize(229, 0)) - self.label_106.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_106.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_106.setObjectName("label_106") - self.gridLayout_153.addWidget(self.label_106, 2, 0, 1, 1) - self.gridLayout_155 = QtWidgets.QGridLayout() - self.gridLayout_155.setObjectName("gridLayout_155") - self.S3_toolButton_directoryInput = QtWidgets.QToolButton(self.tab_Sentinel3) - self.S3_toolButton_directoryInput.setStyleSheet("margin: 0px;padding: 0px;") - self.S3_toolButton_directoryInput.setIcon(icon69) - self.S3_toolButton_directoryInput.setIconSize(QtCore.QSize(22, 22)) - self.S3_toolButton_directoryInput.setObjectName("S3_toolButton_directoryInput") - self.gridLayout_155.addWidget(self.S3_toolButton_directoryInput, 0, 1, 1, 1) - self.S3_label_87 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.S3_label_87.sizePolicy().hasHeightForWidth()) - self.S3_label_87.setSizePolicy(sizePolicy) - self.S3_label_87.setFrameShape(QtWidgets.QFrame.Panel) - self.S3_label_87.setFrameShadow(QtWidgets.QFrame.Sunken) - self.S3_label_87.setText("") - self.S3_label_87.setObjectName("S3_label_87") - self.gridLayout_155.addWidget(self.S3_label_87, 0, 0, 1, 1) - self.gridLayout_153.addLayout(self.gridLayout_155, 2, 1, 1, 2) - self.DOS1_checkBox_S3 = QtWidgets.QCheckBox(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.DOS1_checkBox_S3.sizePolicy().hasHeightForWidth()) - self.DOS1_checkBox_S3.setSizePolicy(sizePolicy) - self.DOS1_checkBox_S3.setChecked(False) - self.DOS1_checkBox_S3.setTristate(False) - self.DOS1_checkBox_S3.setObjectName("DOS1_checkBox_S3") - self.gridLayout_153.addWidget(self.DOS1_checkBox_S3, 3, 0, 1, 1) - self.add_new_bandset_checkBox_3 = QtWidgets.QCheckBox(self.tab_Sentinel3) - self.add_new_bandset_checkBox_3.setChecked(True) - self.add_new_bandset_checkBox_3.setTristate(False) - self.add_new_bandset_checkBox_3.setObjectName("add_new_bandset_checkBox_3") - self.gridLayout_153.addWidget(self.add_new_bandset_checkBox_3, 4, 1, 1, 2) - self.gridLayout_158.addLayout(self.gridLayout_153, 0, 0, 1, 1) - self.gridLayout_212 = QtWidgets.QGridLayout() - self.gridLayout_212.setObjectName("gridLayout_212") - self.sentinel_3_tableWidget = QtWidgets.QTableWidget(self.tab_Sentinel3) - self.sentinel_3_tableWidget.setTextElideMode(QtCore.Qt.ElideMiddle) - self.sentinel_3_tableWidget.setObjectName("sentinel_3_tableWidget") - self.sentinel_3_tableWidget.setColumnCount(1) - self.sentinel_3_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.sentinel_3_tableWidget.setHorizontalHeaderItem(0, item) - self.sentinel_3_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.sentinel_3_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_212.addWidget(self.sentinel_3_tableWidget, 1, 0, 1, 1) - self.gridLayout_229 = QtWidgets.QGridLayout() - self.gridLayout_229.setObjectName("gridLayout_229") - self.S3_pushButton_remove_band = QtWidgets.QToolButton(self.tab_Sentinel3) - self.S3_pushButton_remove_band.setStyleSheet("margin: 0px;padding: 0px;") - self.S3_pushButton_remove_band.setIcon(icon58) - self.S3_pushButton_remove_band.setIconSize(QtCore.QSize(22, 22)) - self.S3_pushButton_remove_band.setObjectName("S3_pushButton_remove_band") - self.gridLayout_229.addWidget(self.S3_pushButton_remove_band, 0, 0, 1, 1) - self.gridLayout_212.addLayout(self.gridLayout_229, 1, 1, 1, 1) - self.gridLayout_230 = QtWidgets.QGridLayout() - self.gridLayout_230.setObjectName("gridLayout_230") - self.S3_satellite_lineEdit = QtWidgets.QLineEdit(self.tab_Sentinel3) - self.S3_satellite_lineEdit.setObjectName("S3_satellite_lineEdit") - self.gridLayout_230.addWidget(self.S3_satellite_lineEdit, 1, 1, 1, 1) - self.satellite_label_12 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_12.sizePolicy().hasHeightForWidth()) - self.satellite_label_12.setSizePolicy(sizePolicy) - self.satellite_label_12.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_12.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_12.setObjectName("satellite_label_12") - self.gridLayout_230.addWidget(self.satellite_label_12, 1, 0, 1, 1) - spacerItem46 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_230.addItem(spacerItem46, 1, 2, 1, 1) - self.satellite_label_14 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_14.sizePolicy().hasHeightForWidth()) - self.satellite_label_14.setSizePolicy(sizePolicy) - self.satellite_label_14.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_14.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_14.setObjectName("satellite_label_14") - self.gridLayout_230.addWidget(self.satellite_label_14, 1, 3, 1, 1) - self.S3_product_lineEdit = QtWidgets.QLineEdit(self.tab_Sentinel3) - self.S3_product_lineEdit.setObjectName("S3_product_lineEdit") - self.gridLayout_230.addWidget(self.S3_product_lineEdit, 1, 4, 1, 1) - self.label_115 = QtWidgets.QLabel(self.tab_Sentinel3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_115.sizePolicy().hasHeightForWidth()) - self.label_115.setSizePolicy(sizePolicy) - self.label_115.setStyleSheet("background-color : #656565; color : white") - self.label_115.setFrameShape(QtWidgets.QFrame.Panel) - self.label_115.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_115.setObjectName("label_115") - self.gridLayout_230.addWidget(self.label_115, 0, 0, 1, 5) - self.gridLayout_212.addLayout(self.gridLayout_230, 0, 0, 1, 2) - self.gridLayout_232 = QtWidgets.QGridLayout() - self.gridLayout_232.setObjectName("gridLayout_232") - spacerItem47 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_232.addItem(spacerItem47, 1, 1, 1, 1) - self.label_181 = QtWidgets.QLabel(self.tab_Sentinel3) - self.label_181.setStyleSheet("background-color : #656565; color : white") - self.label_181.setFrameShape(QtWidgets.QFrame.Panel) - self.label_181.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_181.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_181.setObjectName("label_181") - self.gridLayout_232.addWidget(self.label_181, 0, 1, 1, 3) - self.pushButton_Conversion_5 = QtWidgets.QToolButton(self.tab_Sentinel3) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_5.setFont(font) - self.pushButton_Conversion_5.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_5.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_5.setIcon(icon64) - self.pushButton_Conversion_5.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_5.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_5.setObjectName("pushButton_Conversion_5") - self.gridLayout_232.addWidget(self.pushButton_Conversion_5, 1, 3, 1, 1) - self.sentinel3_conversion = QtWidgets.QToolButton(self.tab_Sentinel3) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.sentinel3_conversion.setFont(font) - self.sentinel3_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.sentinel3_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.sentinel3_conversion.setIcon(icon48) - self.sentinel3_conversion.setIconSize(QtCore.QSize(34, 34)) - self.sentinel3_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.sentinel3_conversion.setObjectName("sentinel3_conversion") - self.gridLayout_232.addWidget(self.sentinel3_conversion, 1, 2, 1, 1) - self.gridLayout_212.addLayout(self.gridLayout_232, 2, 0, 1, 2) - self.gridLayout_158.addLayout(self.gridLayout_212, 1, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_Sentinel3, "") - self.tab_ASTER = QtWidgets.QWidget() - self.tab_ASTER.setObjectName("tab_ASTER") - self.gridLayout_118 = QtWidgets.QGridLayout(self.tab_ASTER) - self.gridLayout_118.setObjectName("gridLayout_118") - self.gridLayout_92 = QtWidgets.QGridLayout() - self.gridLayout_92.setObjectName("gridLayout_92") - self.gridLayout_94 = QtWidgets.QGridLayout() - self.gridLayout_94.setObjectName("gridLayout_94") - self.nodata_spinBox_6 = QtWidgets.QSpinBox(self.tab_ASTER) - self.nodata_spinBox_6.setMinimum(-999) - self.nodata_spinBox_6.setMaximum(100000) - self.nodata_spinBox_6.setObjectName("nodata_spinBox_6") - self.gridLayout_94.addWidget(self.nodata_spinBox_6, 0, 2, 1, 1) - self.nodata_checkBox_5 = QtWidgets.QCheckBox(self.tab_ASTER) - self.nodata_checkBox_5.setChecked(True) - self.nodata_checkBox_5.setObjectName("nodata_checkBox_5") - self.gridLayout_94.addWidget(self.nodata_checkBox_5, 0, 1, 1, 1) - spacerItem48 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_94.addItem(spacerItem48, 0, 0, 1, 1) - self.gridLayout_92.addLayout(self.gridLayout_94, 3, 1, 1, 3) - self.label_143 = QtWidgets.QLabel(self.tab_ASTER) - self.label_143.setFrameShape(QtWidgets.QFrame.Panel) - self.label_143.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_143.setText("") - self.label_143.setObjectName("label_143") - self.gridLayout_92.addWidget(self.label_143, 1, 1, 1, 2) - self.toolButton_directoryInput_ASTER = QtWidgets.QToolButton(self.tab_ASTER) - self.toolButton_directoryInput_ASTER.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_directoryInput_ASTER.setIcon(icon65) - self.toolButton_directoryInput_ASTER.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_directoryInput_ASTER.setObjectName("toolButton_directoryInput_ASTER") - self.gridLayout_92.addWidget(self.toolButton_directoryInput_ASTER, 1, 3, 1, 1) - self.DOS1_checkBox_2 = QtWidgets.QCheckBox(self.tab_ASTER) - self.DOS1_checkBox_2.setChecked(False) - self.DOS1_checkBox_2.setTristate(False) - self.DOS1_checkBox_2.setObjectName("DOS1_checkBox_2") - self.gridLayout_92.addWidget(self.DOS1_checkBox_2, 3, 0, 1, 1) - self.label_67 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_67.sizePolicy().hasHeightForWidth()) - self.label_67.setSizePolicy(sizePolicy) - self.label_67.setStyleSheet("background-color : #656565; color : white") - self.label_67.setFrameShape(QtWidgets.QFrame.Panel) - self.label_67.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_67.setObjectName("label_67") - self.gridLayout_92.addWidget(self.label_67, 0, 0, 1, 4) - self.label_55 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_55.sizePolicy().hasHeightForWidth()) - self.label_55.setSizePolicy(sizePolicy) - self.label_55.setMinimumSize(QtCore.QSize(229, 0)) - self.label_55.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_55.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_55.setObjectName("label_55") - self.gridLayout_92.addWidget(self.label_55, 1, 0, 1, 1) - self.gridLayout_221 = QtWidgets.QGridLayout() - self.gridLayout_221.setObjectName("gridLayout_221") - self.create_bandset_checkBox_2 = QtWidgets.QCheckBox(self.tab_ASTER) - self.create_bandset_checkBox_2.setChecked(True) - self.create_bandset_checkBox_2.setTristate(False) - self.create_bandset_checkBox_2.setObjectName("create_bandset_checkBox_2") - self.gridLayout_221.addWidget(self.create_bandset_checkBox_2, 0, 0, 1, 1) - self.add_new_bandset_checkBox_4 = QtWidgets.QCheckBox(self.tab_ASTER) - self.add_new_bandset_checkBox_4.setChecked(True) - self.add_new_bandset_checkBox_4.setTristate(False) - self.add_new_bandset_checkBox_4.setObjectName("add_new_bandset_checkBox_4") - self.gridLayout_221.addWidget(self.add_new_bandset_checkBox_4, 0, 1, 1, 1) - spacerItem49 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_221.addItem(spacerItem49, 0, 2, 1, 1) - self.gridLayout_92.addLayout(self.gridLayout_221, 4, 0, 1, 4) - self.celsius_checkBox_2 = QtWidgets.QCheckBox(self.tab_ASTER) - self.celsius_checkBox_2.setChecked(False) - self.celsius_checkBox_2.setTristate(False) - self.celsius_checkBox_2.setObjectName("celsius_checkBox_2") - self.gridLayout_92.addWidget(self.celsius_checkBox_2, 2, 0, 1, 3) - self.gridLayout_118.addLayout(self.gridLayout_92, 0, 0, 1, 1) - self.gridLayout_96 = QtWidgets.QGridLayout() - self.gridLayout_96.setObjectName("gridLayout_96") - self.ASTER_tableWidget = QtWidgets.QTableWidget(self.tab_ASTER) - self.ASTER_tableWidget.setObjectName("ASTER_tableWidget") - self.ASTER_tableWidget.setColumnCount(3) - self.ASTER_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.ASTER_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.ASTER_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.ASTER_tableWidget.setHorizontalHeaderItem(2, item) - self.ASTER_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.ASTER_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_96.addWidget(self.ASTER_tableWidget, 1, 0, 1, 1) - self.gridLayout_222 = QtWidgets.QGridLayout() - self.gridLayout_222.setObjectName("gridLayout_222") - self.pushButton_remove_band_2 = QtWidgets.QToolButton(self.tab_ASTER) - self.pushButton_remove_band_2.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_remove_band_2.setIcon(icon58) - self.pushButton_remove_band_2.setIconSize(QtCore.QSize(22, 22)) - self.pushButton_remove_band_2.setObjectName("pushButton_remove_band_2") - self.gridLayout_222.addWidget(self.pushButton_remove_band_2, 0, 0, 1, 1) - self.gridLayout_96.addLayout(self.gridLayout_222, 1, 1, 1, 1) - self.gridLayout_223 = QtWidgets.QGridLayout() - self.gridLayout_223.setObjectName("gridLayout_223") - self.date_lineEdit_2 = QtWidgets.QLineEdit(self.tab_ASTER) - self.date_lineEdit_2.setObjectName("date_lineEdit_2") - self.gridLayout_223.addWidget(self.date_lineEdit_2, 1, 2, 1, 1) - self.earth_sun_dist_lineEdit_2 = QtWidgets.QLineEdit(self.tab_ASTER) - self.earth_sun_dist_lineEdit_2.setObjectName("earth_sun_dist_lineEdit_2") - self.gridLayout_223.addWidget(self.earth_sun_dist_lineEdit_2, 1, 6, 1, 1) - self.satellite_label_9 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_9.sizePolicy().hasHeightForWidth()) - self.satellite_label_9.setSizePolicy(sizePolicy) - self.satellite_label_9.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_9.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_9.setObjectName("satellite_label_9") - self.gridLayout_223.addWidget(self.satellite_label_9, 1, 5, 1, 1) - self.satellite_label_8 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_8.sizePolicy().hasHeightForWidth()) - self.satellite_label_8.setSizePolicy(sizePolicy) - self.satellite_label_8.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_8.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_8.setObjectName("satellite_label_8") - self.gridLayout_223.addWidget(self.satellite_label_8, 1, 1, 1, 1) - self.satellite_label_7 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_7.sizePolicy().hasHeightForWidth()) - self.satellite_label_7.setSizePolicy(sizePolicy) - self.satellite_label_7.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_7.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_7.setObjectName("satellite_label_7") - self.gridLayout_223.addWidget(self.satellite_label_7, 1, 3, 1, 1) - self.sun_elev_lineEdit_2 = QtWidgets.QLineEdit(self.tab_ASTER) - self.sun_elev_lineEdit_2.setObjectName("sun_elev_lineEdit_2") - self.gridLayout_223.addWidget(self.sun_elev_lineEdit_2, 1, 4, 1, 1) - self.ulm_lineEdit = QtWidgets.QLineEdit(self.tab_ASTER) - self.ulm_lineEdit.setObjectName("ulm_lineEdit") - self.gridLayout_223.addWidget(self.ulm_lineEdit, 1, 10, 1, 1) - self.satellite_label_10 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_10.sizePolicy().hasHeightForWidth()) - self.satellite_label_10.setSizePolicy(sizePolicy) - self.satellite_label_10.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_10.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_10.setObjectName("satellite_label_10") - self.gridLayout_223.addWidget(self.satellite_label_10, 1, 7, 1, 1) - self.utm_zone_lineEdit = QtWidgets.QLineEdit(self.tab_ASTER) - self.utm_zone_lineEdit.setObjectName("utm_zone_lineEdit") - self.gridLayout_223.addWidget(self.utm_zone_lineEdit, 1, 8, 1, 1) - self.satellite_label_11 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_11.sizePolicy().hasHeightForWidth()) - self.satellite_label_11.setSizePolicy(sizePolicy) - self.satellite_label_11.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_11.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_11.setObjectName("satellite_label_11") - self.gridLayout_223.addWidget(self.satellite_label_11, 1, 9, 1, 1) - self.satellite_label_17 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_17.sizePolicy().hasHeightForWidth()) - self.satellite_label_17.setSizePolicy(sizePolicy) - self.satellite_label_17.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_17.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_17.setObjectName("satellite_label_17") - self.gridLayout_223.addWidget(self.satellite_label_17, 1, 11, 1, 1) - self.lrm_lineEdit = QtWidgets.QLineEdit(self.tab_ASTER) - self.lrm_lineEdit.setObjectName("lrm_lineEdit") - self.gridLayout_223.addWidget(self.lrm_lineEdit, 1, 12, 1, 1) - self.label_160 = QtWidgets.QLabel(self.tab_ASTER) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_160.sizePolicy().hasHeightForWidth()) - self.label_160.setSizePolicy(sizePolicy) - self.label_160.setStyleSheet("background-color : #656565; color : white") - self.label_160.setFrameShape(QtWidgets.QFrame.Panel) - self.label_160.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_160.setObjectName("label_160") - self.gridLayout_223.addWidget(self.label_160, 0, 0, 1, 13) - self.gridLayout_96.addLayout(self.gridLayout_223, 0, 0, 1, 2) - self.gridLayout_118.addLayout(self.gridLayout_96, 1, 0, 1, 1) - self.gridLayout_224 = QtWidgets.QGridLayout() - self.gridLayout_224.setObjectName("gridLayout_224") - spacerItem50 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_224.addItem(spacerItem50, 1, 1, 1, 1) - self.label_163 = QtWidgets.QLabel(self.tab_ASTER) - self.label_163.setStyleSheet("background-color : #656565; color : white") - self.label_163.setFrameShape(QtWidgets.QFrame.Panel) - self.label_163.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_163.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_163.setObjectName("label_163") - self.gridLayout_224.addWidget(self.label_163, 0, 1, 1, 3) - self.pushButton_Conversion_3 = QtWidgets.QToolButton(self.tab_ASTER) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_3.setFont(font) - self.pushButton_Conversion_3.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_3.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_3.setIcon(icon64) - self.pushButton_Conversion_3.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_3.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_3.setObjectName("pushButton_Conversion_3") - self.gridLayout_224.addWidget(self.pushButton_Conversion_3, 1, 3, 1, 1) - self.aster_conversion = QtWidgets.QToolButton(self.tab_ASTER) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.aster_conversion.setFont(font) - self.aster_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.aster_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.aster_conversion.setIcon(icon48) - self.aster_conversion.setIconSize(QtCore.QSize(34, 34)) - self.aster_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.aster_conversion.setObjectName("aster_conversion") - self.gridLayout_224.addWidget(self.aster_conversion, 1, 2, 1, 1) - self.gridLayout_118.addLayout(self.gridLayout_224, 2, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_ASTER, "") - self.tab_MODIS = QtWidgets.QWidget() - self.tab_MODIS.setObjectName("tab_MODIS") - self.gridLayout_70 = QtWidgets.QGridLayout(self.tab_MODIS) - self.gridLayout_70.setObjectName("gridLayout_70") - self.gridLayout_270 = QtWidgets.QGridLayout() - self.gridLayout_270.setObjectName("gridLayout_270") - self.label_218 = QtWidgets.QLabel(self.tab_MODIS) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_218.sizePolicy().hasHeightForWidth()) - self.label_218.setSizePolicy(sizePolicy) - self.label_218.setStyleSheet("background-color : #656565; color : white") - self.label_218.setFrameShape(QtWidgets.QFrame.Panel) - self.label_218.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_218.setObjectName("label_218") - self.gridLayout_270.addWidget(self.label_218, 0, 0, 1, 4) - self.label_217 = QtWidgets.QLabel(self.tab_MODIS) - self.label_217.setFrameShape(QtWidgets.QFrame.Panel) - self.label_217.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_217.setText("") - self.label_217.setObjectName("label_217") - self.gridLayout_270.addWidget(self.label_217, 2, 1, 1, 2) - self.gridLayout_272 = QtWidgets.QGridLayout() - self.gridLayout_272.setObjectName("gridLayout_272") - self.create_bandset_checkBox_3 = QtWidgets.QCheckBox(self.tab_MODIS) - self.create_bandset_checkBox_3.setChecked(True) - self.create_bandset_checkBox_3.setTristate(False) - self.create_bandset_checkBox_3.setObjectName("create_bandset_checkBox_3") - self.gridLayout_272.addWidget(self.create_bandset_checkBox_3, 0, 0, 1, 1) - self.add_new_bandset_checkBox_5 = QtWidgets.QCheckBox(self.tab_MODIS) - self.add_new_bandset_checkBox_5.setChecked(True) - self.add_new_bandset_checkBox_5.setTristate(False) - self.add_new_bandset_checkBox_5.setObjectName("add_new_bandset_checkBox_5") - self.gridLayout_272.addWidget(self.add_new_bandset_checkBox_5, 0, 1, 1, 1) - spacerItem51 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_272.addItem(spacerItem51, 0, 2, 1, 1) - self.gridLayout_270.addLayout(self.gridLayout_272, 4, 0, 1, 4) - self.label_219 = QtWidgets.QLabel(self.tab_MODIS) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_219.sizePolicy().hasHeightForWidth()) - self.label_219.setSizePolicy(sizePolicy) - self.label_219.setMinimumSize(QtCore.QSize(229, 0)) - self.label_219.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_219.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_219.setObjectName("label_219") - self.gridLayout_270.addWidget(self.label_219, 2, 0, 1, 1) - self.toolButton_directoryInput_MODIS = QtWidgets.QToolButton(self.tab_MODIS) - self.toolButton_directoryInput_MODIS.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_directoryInput_MODIS.setIcon(icon65) - self.toolButton_directoryInput_MODIS.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_directoryInput_MODIS.setObjectName("toolButton_directoryInput_MODIS") - self.gridLayout_270.addWidget(self.toolButton_directoryInput_MODIS, 2, 3, 1, 1) - self.gridLayout_271 = QtWidgets.QGridLayout() - self.gridLayout_271.setObjectName("gridLayout_271") - self.nodata_spinBox_8 = QtWidgets.QSpinBox(self.tab_MODIS) - self.nodata_spinBox_8.setMinimum(-100000) - self.nodata_spinBox_8.setMaximum(100000) - self.nodata_spinBox_8.setProperty("value", -999) - self.nodata_spinBox_8.setObjectName("nodata_spinBox_8") - self.gridLayout_271.addWidget(self.nodata_spinBox_8, 0, 2, 1, 1) - self.nodata_checkBox_7 = QtWidgets.QCheckBox(self.tab_MODIS) - self.nodata_checkBox_7.setChecked(True) - self.nodata_checkBox_7.setObjectName("nodata_checkBox_7") - self.gridLayout_271.addWidget(self.nodata_checkBox_7, 0, 1, 1, 1) - spacerItem52 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_271.addItem(spacerItem52, 0, 0, 1, 1) - self.gridLayout_270.addLayout(self.gridLayout_271, 3, 1, 1, 3) - self.reproject_modis_checkBox = QtWidgets.QCheckBox(self.tab_MODIS) - self.reproject_modis_checkBox.setChecked(True) - self.reproject_modis_checkBox.setTristate(False) - self.reproject_modis_checkBox.setObjectName("reproject_modis_checkBox") - self.gridLayout_270.addWidget(self.reproject_modis_checkBox, 3, 0, 1, 1) - self.gridLayout_70.addLayout(self.gridLayout_270, 0, 0, 1, 1) - self.gridLayout_273 = QtWidgets.QGridLayout() - self.gridLayout_273.setObjectName("gridLayout_273") - self.MODIS_tableWidget = QtWidgets.QTableWidget(self.tab_MODIS) - self.MODIS_tableWidget.setObjectName("MODIS_tableWidget") - self.MODIS_tableWidget.setColumnCount(2) - self.MODIS_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.MODIS_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.MODIS_tableWidget.setHorizontalHeaderItem(1, item) - self.MODIS_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.MODIS_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_273.addWidget(self.MODIS_tableWidget, 1, 0, 1, 1) - self.gridLayout_274 = QtWidgets.QGridLayout() - self.gridLayout_274.setObjectName("gridLayout_274") - self.pushButton_remove_band_3 = QtWidgets.QToolButton(self.tab_MODIS) - self.pushButton_remove_band_3.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_remove_band_3.setIcon(icon58) - self.pushButton_remove_band_3.setIconSize(QtCore.QSize(22, 22)) - self.pushButton_remove_band_3.setObjectName("pushButton_remove_band_3") - self.gridLayout_274.addWidget(self.pushButton_remove_band_3, 0, 0, 1, 1) - self.gridLayout_273.addLayout(self.gridLayout_274, 1, 1, 1, 1) - self.gridLayout_275 = QtWidgets.QGridLayout() - self.gridLayout_275.setObjectName("gridLayout_275") - self.satellite_label_16 = QtWidgets.QLabel(self.tab_MODIS) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_16.sizePolicy().hasHeightForWidth()) - self.satellite_label_16.setSizePolicy(sizePolicy) - self.satellite_label_16.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_16.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_16.setObjectName("satellite_label_16") - self.gridLayout_275.addWidget(self.satellite_label_16, 1, 4, 1, 1) - self.MODIS_ID_lineEdit = QtWidgets.QLineEdit(self.tab_MODIS) - self.MODIS_ID_lineEdit.setObjectName("MODIS_ID_lineEdit") - self.gridLayout_275.addWidget(self.MODIS_ID_lineEdit, 1, 2, 1, 1) - self.satellite_label_13 = QtWidgets.QLabel(self.tab_MODIS) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_13.sizePolicy().hasHeightForWidth()) - self.satellite_label_13.setSizePolicy(sizePolicy) - self.satellite_label_13.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_13.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_13.setObjectName("satellite_label_13") - self.gridLayout_275.addWidget(self.satellite_label_13, 1, 1, 1, 1) - self.MODIS_date_lineEdit = QtWidgets.QLineEdit(self.tab_MODIS) - self.MODIS_date_lineEdit.setObjectName("MODIS_date_lineEdit") - self.gridLayout_275.addWidget(self.MODIS_date_lineEdit, 1, 5, 1, 1) - self.label_220 = QtWidgets.QLabel(self.tab_MODIS) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_220.sizePolicy().hasHeightForWidth()) - self.label_220.setSizePolicy(sizePolicy) - self.label_220.setStyleSheet("background-color : #656565; color : white") - self.label_220.setFrameShape(QtWidgets.QFrame.Panel) - self.label_220.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_220.setObjectName("label_220") - self.gridLayout_275.addWidget(self.label_220, 0, 0, 1, 6) - spacerItem53 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_275.addItem(spacerItem53, 1, 3, 1, 1) - self.gridLayout_273.addLayout(self.gridLayout_275, 0, 0, 1, 2) - self.gridLayout_70.addLayout(self.gridLayout_273, 1, 0, 1, 1) - self.gridLayout_276 = QtWidgets.QGridLayout() - self.gridLayout_276.setObjectName("gridLayout_276") - spacerItem54 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_276.addItem(spacerItem54, 1, 1, 1, 1) - self.label_221 = QtWidgets.QLabel(self.tab_MODIS) - self.label_221.setStyleSheet("background-color : #656565; color : white") - self.label_221.setFrameShape(QtWidgets.QFrame.Panel) - self.label_221.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_221.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_221.setObjectName("label_221") - self.gridLayout_276.addWidget(self.label_221, 0, 1, 1, 3) - self.pushButton_Conversion_4 = QtWidgets.QToolButton(self.tab_MODIS) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_4.setFont(font) - self.pushButton_Conversion_4.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_4.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_4.setIcon(icon64) - self.pushButton_Conversion_4.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_4.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_4.setObjectName("pushButton_Conversion_4") - self.gridLayout_276.addWidget(self.pushButton_Conversion_4, 1, 3, 1, 1) - self.modis_conversion = QtWidgets.QToolButton(self.tab_MODIS) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.modis_conversion.setFont(font) - self.modis_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.modis_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.modis_conversion.setIcon(icon48) - self.modis_conversion.setIconSize(QtCore.QSize(34, 34)) - self.modis_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.modis_conversion.setObjectName("modis_conversion") - self.gridLayout_276.addWidget(self.modis_conversion, 1, 2, 1, 1) - self.gridLayout_70.addLayout(self.gridLayout_276, 2, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_MODIS, "") - self.tab_spectral_distance = QtWidgets.QWidget() - self.tab_spectral_distance.setObjectName("tab_spectral_distance") - self.gridLayout_61 = QtWidgets.QGridLayout(self.tab_spectral_distance) - self.gridLayout_61.setObjectName("gridLayout_61") - self.gridLayout_119 = QtWidgets.QGridLayout() - self.gridLayout_119.setObjectName("gridLayout_119") - self.label_142 = QtWidgets.QLabel(self.tab_spectral_distance) - self.label_142.setStyleSheet("background-color : #656565; color : white") - self.label_142.setFrameShape(QtWidgets.QFrame.Panel) - self.label_142.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_142.setObjectName("label_142") - self.gridLayout_119.addWidget(self.label_142, 0, 0, 1, 1) - self.gridLayout_61.addLayout(self.gridLayout_119, 0, 0, 1, 1) - self.horizontalLayout_22 = QtWidgets.QHBoxLayout() - self.horizontalLayout_22.setObjectName("horizontalLayout_22") - self.label_64 = QtWidgets.QLabel(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_64.sizePolicy().hasHeightForWidth()) - self.label_64.setSizePolicy(sizePolicy) - self.label_64.setMinimumSize(QtCore.QSize(229, 0)) - self.label_64.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_64.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_64.setObjectName("label_64") - self.horizontalLayout_22.addWidget(self.label_64) - self.vector_name_combo = QtWidgets.QComboBox(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.vector_name_combo.sizePolicy().hasHeightForWidth()) - self.vector_name_combo.setSizePolicy(sizePolicy) - self.vector_name_combo.setObjectName("vector_name_combo") - self.horizontalLayout_22.addWidget(self.vector_name_combo) - self.toolButton_reload_16 = QtWidgets.QToolButton(self.tab_spectral_distance) - self.toolButton_reload_16.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_16.setIcon(icon55) - self.toolButton_reload_16.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_16.setObjectName("toolButton_reload_16") - self.horizontalLayout_22.addWidget(self.toolButton_reload_16) - self.gridLayout_61.addLayout(self.horizontalLayout_22, 1, 0, 1, 1) - self.horizontalLayout_19 = QtWidgets.QHBoxLayout() - self.horizontalLayout_19.setObjectName("horizontalLayout_19") - self.field_checkBox = QtWidgets.QCheckBox(self.tab_spectral_distance) - self.field_checkBox.setChecked(True) - self.field_checkBox.setObjectName("field_checkBox") - self.horizontalLayout_19.addWidget(self.field_checkBox) - self.field_comboBox = QtWidgets.QComboBox(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.field_comboBox.sizePolicy().hasHeightForWidth()) - self.field_comboBox.setSizePolicy(sizePolicy) - self.field_comboBox.setObjectName("field_comboBox") - self.horizontalLayout_19.addWidget(self.field_comboBox) - self.gridLayout_61.addLayout(self.horizontalLayout_19, 2, 0, 1, 1) - self.horizontalLayout_25 = QtWidgets.QHBoxLayout() - self.horizontalLayout_25.setObjectName("horizontalLayout_25") - self.constant_value_checkBox = QtWidgets.QCheckBox(self.tab_spectral_distance) - self.constant_value_checkBox.setObjectName("constant_value_checkBox") - self.horizontalLayout_25.addWidget(self.constant_value_checkBox) - self.constant_value_spinBox = QtWidgets.QSpinBox(self.tab_spectral_distance) - self.constant_value_spinBox.setMinimum(-100000) - self.constant_value_spinBox.setMaximum(100000) - self.constant_value_spinBox.setProperty("value", 1) - self.constant_value_spinBox.setObjectName("constant_value_spinBox") - self.horizontalLayout_25.addWidget(self.constant_value_spinBox) - self.gridLayout_61.addLayout(self.horizontalLayout_25, 3, 0, 1, 1) - self.horizontalLayout_20 = QtWidgets.QHBoxLayout() - self.horizontalLayout_20.setObjectName("horizontalLayout_20") - self.label_157 = QtWidgets.QLabel(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_157.sizePolicy().hasHeightForWidth()) - self.label_157.setSizePolicy(sizePolicy) - self.label_157.setMinimumSize(QtCore.QSize(229, 0)) - self.label_157.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_157.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_157.setObjectName("label_157") - self.horizontalLayout_20.addWidget(self.label_157) - self.conversion_type_combo = QtWidgets.QComboBox(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.conversion_type_combo.sizePolicy().hasHeightForWidth()) - self.conversion_type_combo.setSizePolicy(sizePolicy) - self.conversion_type_combo.setObjectName("conversion_type_combo") - self.horizontalLayout_20.addWidget(self.conversion_type_combo) - self.gridLayout_61.addLayout(self.horizontalLayout_20, 4, 0, 1, 1) - self.gridLayout_194 = QtWidgets.QGridLayout() - self.gridLayout_194.setObjectName("gridLayout_194") - self.label_156 = QtWidgets.QLabel(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_156.sizePolicy().hasHeightForWidth()) - self.label_156.setSizePolicy(sizePolicy) - self.label_156.setMinimumSize(QtCore.QSize(229, 0)) - self.label_156.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_156.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_156.setObjectName("label_156") - self.gridLayout_194.addWidget(self.label_156, 0, 0, 1, 1) - self.toolButton_reload_17 = QtWidgets.QToolButton(self.tab_spectral_distance) - self.toolButton_reload_17.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_17.setIcon(icon55) - self.toolButton_reload_17.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_17.setObjectName("toolButton_reload_17") - self.gridLayout_194.addWidget(self.toolButton_reload_17, 0, 2, 1, 1) - self.reference_raster_name_combo = QtWidgets.QComboBox(self.tab_spectral_distance) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reference_raster_name_combo.sizePolicy().hasHeightForWidth()) - self.reference_raster_name_combo.setSizePolicy(sizePolicy) - self.reference_raster_name_combo.setObjectName("reference_raster_name_combo") - self.gridLayout_194.addWidget(self.reference_raster_name_combo, 0, 1, 1, 1) - self.gridLayout_61.addLayout(self.gridLayout_194, 5, 0, 1, 1) - self.horizontalLayout_47 = QtWidgets.QHBoxLayout() - self.horizontalLayout_47.setObjectName("horizontalLayout_47") - self.extent_checkBox_2 = QtWidgets.QCheckBox(self.tab_spectral_distance) - self.extent_checkBox_2.setObjectName("extent_checkBox_2") - self.horizontalLayout_47.addWidget(self.extent_checkBox_2) - self.gridLayout_61.addLayout(self.horizontalLayout_47, 6, 0, 1, 1) - self.gridLayout_210 = QtWidgets.QGridLayout() - self.gridLayout_210.setObjectName("gridLayout_210") - spacerItem55 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_210.addItem(spacerItem55, 0, 2, 1, 1) - self.label_167 = QtWidgets.QLabel(self.tab_spectral_distance) - self.label_167.setStyleSheet("background-color : #656565; color : white") - self.label_167.setFrameShape(QtWidgets.QFrame.Panel) - self.label_167.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_167.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_167.setObjectName("label_167") - self.gridLayout_210.addWidget(self.label_167, 1, 0, 1, 3) - spacerItem56 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_210.addItem(spacerItem56, 2, 0, 1, 1) - self.convert_vector_toolButton = QtWidgets.QToolButton(self.tab_spectral_distance) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.convert_vector_toolButton.setFont(font) - self.convert_vector_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.convert_vector_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.convert_vector_toolButton.setIcon(icon64) - self.convert_vector_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.convert_vector_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.convert_vector_toolButton.setObjectName("convert_vector_toolButton") - self.gridLayout_210.addWidget(self.convert_vector_toolButton, 2, 2, 1, 1) - self.vector_to_raster = QtWidgets.QToolButton(self.tab_spectral_distance) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.vector_to_raster.setFont(font) - self.vector_to_raster.setLayoutDirection(QtCore.Qt.RightToLeft) - self.vector_to_raster.setStyleSheet("margin: 0px;padding: 0px;") - self.vector_to_raster.setIcon(icon48) - self.vector_to_raster.setIconSize(QtCore.QSize(34, 34)) - self.vector_to_raster.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.vector_to_raster.setObjectName("vector_to_raster") - self.gridLayout_210.addWidget(self.vector_to_raster, 2, 1, 1, 1) - self.gridLayout_61.addLayout(self.gridLayout_210, 7, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_spectral_distance, "") - self.tab_clip = QtWidgets.QWidget() - self.tab_clip.setObjectName("tab_clip") - self.gridLayout_58 = QtWidgets.QGridLayout(self.tab_clip) - self.gridLayout_58.setObjectName("gridLayout_58") - self.gridLayout_51 = QtWidgets.QGridLayout() - self.gridLayout_51.setObjectName("gridLayout_51") - self.label_128 = QtWidgets.QLabel(self.tab_clip) - self.label_128.setStyleSheet("background-color : #656565; color : white") - self.label_128.setFrameShape(QtWidgets.QFrame.Panel) - self.label_128.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_128.setObjectName("label_128") - self.gridLayout_51.addWidget(self.label_128, 0, 0, 1, 1) - self.gridLayout_58.addLayout(self.gridLayout_51, 0, 0, 1, 1) - self.gridLayout_24 = QtWidgets.QGridLayout() - self.gridLayout_24.setObjectName("gridLayout_24") - self.nodata_spinBox = QtWidgets.QSpinBox(self.tab_clip) - self.nodata_spinBox.setMinimum(-2147483647) - self.nodata_spinBox.setMaximum(2147483647) - self.nodata_spinBox.setObjectName("nodata_spinBox") - self.gridLayout_24.addWidget(self.nodata_spinBox, 1, 1, 1, 1) - self.band_set_comb_spinBox_2 = QtWidgets.QSpinBox(self.tab_clip) - self.band_set_comb_spinBox_2.setMinimum(1) - self.band_set_comb_spinBox_2.setMaximum(100000) - self.band_set_comb_spinBox_2.setObjectName("band_set_comb_spinBox_2") - self.gridLayout_24.addWidget(self.band_set_comb_spinBox_2, 0, 1, 1, 1) - self.label_251 = QtWidgets.QLabel(self.tab_clip) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_251.sizePolicy().hasHeightForWidth()) - self.label_251.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setBold(False) - font.setWeight(50) - self.label_251.setFont(font) - self.label_251.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_251.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_251.setObjectName("label_251") - self.gridLayout_24.addWidget(self.label_251, 0, 0, 1, 1) - self.label_62 = QtWidgets.QLabel(self.tab_clip) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_62.sizePolicy().hasHeightForWidth()) - self.label_62.setSizePolicy(sizePolicy) - self.label_62.setMinimumSize(QtCore.QSize(150, 0)) - self.label_62.setMaximumSize(QtCore.QSize(100, 16777215)) - font = QtGui.QFont() - font.setBold(False) - font.setWeight(50) - self.label_62.setFont(font) - self.label_62.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_62.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_62.setObjectName("label_62") - self.gridLayout_24.addWidget(self.label_62, 2, 0, 1, 1) - self.label_16 = QtWidgets.QLabel(self.tab_clip) - self.label_16.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_16.setObjectName("label_16") - self.gridLayout_24.addWidget(self.label_16, 1, 0, 1, 1) - spacerItem57 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_24.addItem(spacerItem57, 1, 2, 1, 1) - self.output_clip_name_lineEdit = QtWidgets.QLineEdit(self.tab_clip) - self.output_clip_name_lineEdit.setMaxLength(10) - self.output_clip_name_lineEdit.setObjectName("output_clip_name_lineEdit") - self.gridLayout_24.addWidget(self.output_clip_name_lineEdit, 2, 1, 1, 2) - self.gridLayout_58.addLayout(self.gridLayout_24, 1, 0, 1, 1) - self.gridLayout_20 = QtWidgets.QGridLayout() - self.gridLayout_20.setObjectName("gridLayout_20") - spacerItem58 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_20.addItem(spacerItem58, 1, 8, 1, 1) - self.LX_lineEdit = QtWidgets.QLineEdit(self.tab_clip) - self.LX_lineEdit.setMaxLength(10) - self.LX_lineEdit.setObjectName("LX_lineEdit") - self.gridLayout_20.addWidget(self.LX_lineEdit, 1, 6, 1, 1) - self.UX_lineEdit = QtWidgets.QLineEdit(self.tab_clip) - self.UX_lineEdit.setMaxLength(10) - self.UX_lineEdit.setObjectName("UX_lineEdit") - self.gridLayout_20.addWidget(self.UX_lineEdit, 1, 3, 1, 1) - self.UY_lineEdit = QtWidgets.QLineEdit(self.tab_clip) - self.UY_lineEdit.setMaxLength(10) - self.UY_lineEdit.setObjectName("UY_lineEdit") - self.gridLayout_20.addWidget(self.UY_lineEdit, 1, 4, 1, 1) - self.LY_lineEdit = QtWidgets.QLineEdit(self.tab_clip) - self.LY_lineEdit.setMaxLength(10) - self.LY_lineEdit.setObjectName("LY_lineEdit") - self.gridLayout_20.addWidget(self.LY_lineEdit, 1, 7, 1, 1) - self.label_12 = QtWidgets.QLabel(self.tab_clip) - self.label_12.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_12.setAlignment(QtCore.Qt.AlignCenter) - self.label_12.setObjectName("label_12") - self.gridLayout_20.addWidget(self.label_12, 1, 5, 1, 1) - self.selectUL_toolButton = QtWidgets.QToolButton(self.tab_clip) - self.selectUL_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.selectUL_toolButton.setIcon(icon77) - self.selectUL_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.selectUL_toolButton.setObjectName("selectUL_toolButton") - self.gridLayout_20.addWidget(self.selectUL_toolButton, 1, 10, 1, 1) - self.label_29 = QtWidgets.QLabel(self.tab_clip) - self.label_29.setStyleSheet("background-color : #656565; color : white") - self.label_29.setFrameShape(QtWidgets.QFrame.Panel) - self.label_29.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_29.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_29.setObjectName("label_29") - self.gridLayout_20.addWidget(self.label_29, 0, 0, 1, 11) - self.show_area_radioButton_3 = QtWidgets.QRadioButton(self.tab_clip) - self.show_area_radioButton_3.setChecked(True) - self.show_area_radioButton_3.setAutoExclusive(False) - self.show_area_radioButton_3.setObjectName("show_area_radioButton_3") - self.gridLayout_20.addWidget(self.show_area_radioButton_3, 1, 9, 1, 1) - self.label_11 = QtWidgets.QLabel(self.tab_clip) - self.label_11.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_11.setAlignment(QtCore.Qt.AlignCenter) - self.label_11.setObjectName("label_11") - self.gridLayout_20.addWidget(self.label_11, 1, 0, 1, 3) - self.gridLayout_58.addLayout(self.gridLayout_20, 2, 0, 1, 1) - self.gridLayout_22 = QtWidgets.QGridLayout() - self.gridLayout_22.setObjectName("gridLayout_22") - self.shapefile_comboBox = QtWidgets.QComboBox(self.tab_clip) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.shapefile_comboBox.sizePolicy().hasHeightForWidth()) - self.shapefile_comboBox.setSizePolicy(sizePolicy) - self.shapefile_comboBox.setObjectName("shapefile_comboBox") - self.gridLayout_22.addWidget(self.shapefile_comboBox, 0, 1, 1, 1) - self.shapefile_checkBox = QtWidgets.QCheckBox(self.tab_clip) - self.shapefile_checkBox.setObjectName("shapefile_checkBox") - self.gridLayout_22.addWidget(self.shapefile_checkBox, 0, 0, 1, 1) - self.toolButton_reload_8 = QtWidgets.QToolButton(self.tab_clip) - self.toolButton_reload_8.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_8.setIcon(icon55) - self.toolButton_reload_8.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_8.setObjectName("toolButton_reload_8") - self.gridLayout_22.addWidget(self.toolButton_reload_8, 0, 2, 1, 1) - self.temporary_ROI_checkBox = QtWidgets.QCheckBox(self.tab_clip) - self.temporary_ROI_checkBox.setObjectName("temporary_ROI_checkBox") - self.gridLayout_22.addWidget(self.temporary_ROI_checkBox, 2, 0, 1, 1) - self.gridLayout_19 = QtWidgets.QGridLayout() - self.gridLayout_19.setObjectName("gridLayout_19") - self.vector_field_checkBox = QtWidgets.QCheckBox(self.tab_clip) - self.vector_field_checkBox.setObjectName("vector_field_checkBox") - self.gridLayout_19.addWidget(self.vector_field_checkBox, 0, 0, 1, 1) - self.class_field_comboBox_3 = QtWidgets.QComboBox(self.tab_clip) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_field_comboBox_3.sizePolicy().hasHeightForWidth()) - self.class_field_comboBox_3.setSizePolicy(sizePolicy) - self.class_field_comboBox_3.setObjectName("class_field_comboBox_3") - self.gridLayout_19.addWidget(self.class_field_comboBox_3, 0, 1, 1, 1) - self.gridLayout_22.addLayout(self.gridLayout_19, 1, 1, 1, 1) - self.gridLayout_58.addLayout(self.gridLayout_22, 3, 0, 1, 1) - self.gridLayout_28 = QtWidgets.QGridLayout() - self.gridLayout_28.setObjectName("gridLayout_28") - spacerItem59 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_28.addItem(spacerItem59, 2, 0, 1, 1) - self.label_164 = QtWidgets.QLabel(self.tab_clip) - self.label_164.setStyleSheet("background-color : #656565; color : white") - self.label_164.setFrameShape(QtWidgets.QFrame.Panel) - self.label_164.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_164.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_164.setObjectName("label_164") - self.gridLayout_28.addWidget(self.label_164, 1, 0, 1, 3) - self.clip_Button = QtWidgets.QToolButton(self.tab_clip) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.clip_Button.setFont(font) - self.clip_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.clip_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.clip_Button.setIcon(icon64) - self.clip_Button.setIconSize(QtCore.QSize(34, 34)) - self.clip_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.clip_Button.setObjectName("clip_Button") - self.gridLayout_28.addWidget(self.clip_Button, 2, 2, 1, 1) - spacerItem60 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_28.addItem(spacerItem60, 0, 0, 1, 1) - self.clip_multiple_rasters = QtWidgets.QToolButton(self.tab_clip) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.clip_multiple_rasters.setFont(font) - self.clip_multiple_rasters.setLayoutDirection(QtCore.Qt.RightToLeft) - self.clip_multiple_rasters.setStyleSheet("margin: 0px;padding: 0px;") - self.clip_multiple_rasters.setIcon(icon48) - self.clip_multiple_rasters.setIconSize(QtCore.QSize(34, 34)) - self.clip_multiple_rasters.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.clip_multiple_rasters.setObjectName("clip_multiple_rasters") - self.gridLayout_28.addWidget(self.clip_multiple_rasters, 2, 1, 1, 1) - self.gridLayout_58.addLayout(self.gridLayout_28, 4, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_clip, "") - self.tab_reproject_bands = QtWidgets.QWidget() - self.tab_reproject_bands.setObjectName("tab_reproject_bands") - self.gridLayout_295 = QtWidgets.QGridLayout(self.tab_reproject_bands) - self.gridLayout_295.setObjectName("gridLayout_295") - self.gridLayout_289 = QtWidgets.QGridLayout() - self.gridLayout_289.setObjectName("gridLayout_289") - self.band_set_comb_spinBox_14 = QtWidgets.QSpinBox(self.tab_reproject_bands) - self.band_set_comb_spinBox_14.setMinimum(1) - self.band_set_comb_spinBox_14.setMaximum(100000) - self.band_set_comb_spinBox_14.setObjectName("band_set_comb_spinBox_14") - self.gridLayout_289.addWidget(self.band_set_comb_spinBox_14, 1, 1, 1, 1) - self.label_264 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_264.sizePolicy().hasHeightForWidth()) - self.label_264.setSizePolicy(sizePolicy) - self.label_264.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_264.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_264.setObjectName("label_264") - self.gridLayout_289.addWidget(self.label_264, 1, 0, 1, 1) - spacerItem61 = QtWidgets.QSpacerItem(605, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_289.addItem(spacerItem61, 1, 2, 1, 1) - self.label_249 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_249.sizePolicy().hasHeightForWidth()) - self.label_249.setSizePolicy(sizePolicy) - self.label_249.setStyleSheet("background-color : #656565; color : white") - self.label_249.setFrameShape(QtWidgets.QFrame.Panel) - self.label_249.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_249.setObjectName("label_249") - self.gridLayout_289.addWidget(self.label_249, 0, 0, 1, 3) - self.gridLayout_295.addLayout(self.gridLayout_289, 0, 0, 1, 1) - self.gridLayout_291 = QtWidgets.QGridLayout() - self.gridLayout_291.setObjectName("gridLayout_291") - self.raster_align_comboBox = QtWidgets.QComboBox(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.raster_align_comboBox.sizePolicy().hasHeightForWidth()) - self.raster_align_comboBox.setSizePolicy(sizePolicy) - self.raster_align_comboBox.setObjectName("raster_align_comboBox") - self.gridLayout_291.addWidget(self.raster_align_comboBox, 0, 2, 1, 1) - self.use_align_raster_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) - self.use_align_raster_checkBox.setObjectName("use_align_raster_checkBox") - self.gridLayout_291.addWidget(self.use_align_raster_checkBox, 0, 0, 1, 1) - self.toolButton_reload_25 = QtWidgets.QToolButton(self.tab_reproject_bands) - self.toolButton_reload_25.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_25.setIcon(icon55) - self.toolButton_reload_25.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_25.setObjectName("toolButton_reload_25") - self.gridLayout_291.addWidget(self.toolButton_reload_25, 0, 3, 1, 1) - self.same_extent_raster_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) - self.same_extent_raster_checkBox.setObjectName("same_extent_raster_checkBox") - self.gridLayout_291.addWidget(self.same_extent_raster_checkBox, 0, 1, 1, 1) - self.gridLayout_295.addLayout(self.gridLayout_291, 1, 0, 1, 1) - self.gridLayout_292 = QtWidgets.QGridLayout() - self.gridLayout_292.setObjectName("gridLayout_292") - self.epsg_code_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) - self.epsg_code_lineEdit.setText("") - self.epsg_code_lineEdit.setMaxLength(10) - self.epsg_code_lineEdit.setObjectName("epsg_code_lineEdit") - self.gridLayout_292.addWidget(self.epsg_code_lineEdit, 0, 1, 1, 1) - self.use_epsg_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) - self.use_epsg_checkBox.setObjectName("use_epsg_checkBox") - self.gridLayout_292.addWidget(self.use_epsg_checkBox, 0, 0, 1, 1) - self.label_267 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_267.sizePolicy().hasHeightForWidth()) - self.label_267.setSizePolicy(sizePolicy) - self.label_267.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_267.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_267.setObjectName("label_267") - self.gridLayout_292.addWidget(self.label_267, 0, 6, 1, 1) - self.label_266 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_266.sizePolicy().hasHeightForWidth()) - self.label_266.setSizePolicy(sizePolicy) - self.label_266.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_266.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_266.setObjectName("label_266") - self.gridLayout_292.addWidget(self.label_266, 0, 3, 1, 1) - self.x_resolution_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) - self.x_resolution_lineEdit.setText("") - self.x_resolution_lineEdit.setMaxLength(10) - self.x_resolution_lineEdit.setObjectName("x_resolution_lineEdit") - self.gridLayout_292.addWidget(self.x_resolution_lineEdit, 0, 4, 1, 1) - self.y_resolution_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) - self.y_resolution_lineEdit.setText("") - self.y_resolution_lineEdit.setMaxLength(10) - self.y_resolution_lineEdit.setObjectName("y_resolution_lineEdit") - self.gridLayout_292.addWidget(self.y_resolution_lineEdit, 0, 7, 1, 1) - spacerItem62 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_292.addItem(spacerItem62, 0, 2, 1, 1) - spacerItem63 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_292.addItem(spacerItem63, 0, 5, 1, 1) - self.gridLayout_295.addLayout(self.gridLayout_292, 2, 0, 1, 1) - self.horizontalLayout_63 = QtWidgets.QHBoxLayout() - self.horizontalLayout_63.setObjectName("horizontalLayout_63") - self.resample_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) - self.resample_checkBox.setObjectName("resample_checkBox") - self.horizontalLayout_63.addWidget(self.resample_checkBox) - self.resample_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) - self.resample_lineEdit.setMaxLength(10) - self.resample_lineEdit.setObjectName("resample_lineEdit") - self.horizontalLayout_63.addWidget(self.resample_lineEdit) - self.gridLayout_295.addLayout(self.horizontalLayout_63, 3, 0, 1, 1) - self.horizontalLayout_64 = QtWidgets.QHBoxLayout() - self.horizontalLayout_64.setObjectName("horizontalLayout_64") - self.label_269 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_269.sizePolicy().hasHeightForWidth()) - self.label_269.setSizePolicy(sizePolicy) - self.label_269.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_269.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_269.setObjectName("label_269") - self.horizontalLayout_64.addWidget(self.label_269) - self.resampling_method_comboBox = QtWidgets.QComboBox(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.resampling_method_comboBox.sizePolicy().hasHeightForWidth()) - self.resampling_method_comboBox.setSizePolicy(sizePolicy) - self.resampling_method_comboBox.setObjectName("resampling_method_comboBox") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.resampling_method_comboBox.addItem("") - self.horizontalLayout_64.addWidget(self.resampling_method_comboBox) - spacerItem64 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_64.addItem(spacerItem64) - self.label_270 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_270.sizePolicy().hasHeightForWidth()) - self.label_270.setSizePolicy(sizePolicy) - self.label_270.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_270.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_270.setObjectName("label_270") - self.horizontalLayout_64.addWidget(self.label_270) - self.raster_type_combo_2 = QtWidgets.QComboBox(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.raster_type_combo_2.sizePolicy().hasHeightForWidth()) - self.raster_type_combo_2.setSizePolicy(sizePolicy) - self.raster_type_combo_2.setObjectName("raster_type_combo_2") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.raster_type_combo_2.addItem("") - self.horizontalLayout_64.addWidget(self.raster_type_combo_2) - self.gridLayout_295.addLayout(self.horizontalLayout_64, 4, 0, 1, 1) - self.horizontalLayout_66 = QtWidgets.QHBoxLayout() - self.horizontalLayout_66.setObjectName("horizontalLayout_66") - self.change_nodata_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) - self.change_nodata_checkBox.setObjectName("change_nodata_checkBox") - self.horizontalLayout_66.addWidget(self.change_nodata_checkBox) - self.nodata_spinBox_14 = QtWidgets.QSpinBox(self.tab_reproject_bands) - self.nodata_spinBox_14.setMinimum(-2147483647) - self.nodata_spinBox_14.setMaximum(2147483647) - self.nodata_spinBox_14.setProperty("value", -32768) - self.nodata_spinBox_14.setObjectName("nodata_spinBox_14") - self.horizontalLayout_66.addWidget(self.nodata_spinBox_14) - spacerItem65 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_66.addItem(spacerItem65) - self.gridLayout_295.addLayout(self.horizontalLayout_66, 5, 0, 1, 1) - self.horizontalLayout_68 = QtWidgets.QHBoxLayout() - self.horizontalLayout_68.setObjectName("horizontalLayout_68") - self.label_265 = QtWidgets.QLabel(self.tab_reproject_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_265.sizePolicy().hasHeightForWidth()) - self.label_265.setSizePolicy(sizePolicy) - self.label_265.setMinimumSize(QtCore.QSize(229, 0)) - self.label_265.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_265.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_265.setObjectName("label_265") - self.horizontalLayout_68.addWidget(self.label_265) - self.reproj_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) - self.reproj_output_name_lineEdit.setMaxLength(10) - self.reproj_output_name_lineEdit.setObjectName("reproj_output_name_lineEdit") - self.horizontalLayout_68.addWidget(self.reproj_output_name_lineEdit) - self.gridLayout_295.addLayout(self.horizontalLayout_68, 6, 0, 1, 1) - spacerItem66 = QtWidgets.QSpacerItem(20, 198, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_295.addItem(spacerItem66, 7, 0, 1, 1) - self.gridLayout_290 = QtWidgets.QGridLayout() - self.gridLayout_290.setObjectName("gridLayout_290") - self.label_263 = QtWidgets.QLabel(self.tab_reproject_bands) - self.label_263.setStyleSheet("background-color : #656565; color : white") - self.label_263.setFrameShape(QtWidgets.QFrame.Panel) - self.label_263.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_263.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_263.setObjectName("label_263") - self.gridLayout_290.addWidget(self.label_263, 0, 0, 1, 2) - self.horizontalLayout_59 = QtWidgets.QHBoxLayout() - self.horizontalLayout_59.setObjectName("horizontalLayout_59") - spacerItem67 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_59.addItem(spacerItem67) - self.reproject_raster_bands = QtWidgets.QToolButton(self.tab_reproject_bands) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.reproject_raster_bands.setFont(font) - self.reproject_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) - self.reproject_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") - self.reproject_raster_bands.setIcon(icon48) - self.reproject_raster_bands.setIconSize(QtCore.QSize(34, 34)) - self.reproject_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.reproject_raster_bands.setObjectName("reproject_raster_bands") - self.horizontalLayout_59.addWidget(self.reproject_raster_bands) - self.reproject_Button = QtWidgets.QToolButton(self.tab_reproject_bands) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.reproject_Button.setFont(font) - self.reproject_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.reproject_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reproject_Button.setIcon(icon64) - self.reproject_Button.setIconSize(QtCore.QSize(34, 34)) - self.reproject_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.reproject_Button.setObjectName("reproject_Button") - self.horizontalLayout_59.addWidget(self.reproject_Button) - self.gridLayout_290.addLayout(self.horizontalLayout_59, 2, 0, 1, 2) - self.gridLayout_295.addLayout(self.gridLayout_290, 8, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_reproject_bands, "") - self.tab_split_raster = QtWidgets.QWidget() - self.tab_split_raster.setObjectName("tab_split_raster") - self.gridLayout_57 = QtWidgets.QGridLayout(self.tab_split_raster) - self.gridLayout_57.setObjectName("gridLayout_57") - spacerItem68 = QtWidgets.QSpacerItem(20, 302, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_57.addItem(spacerItem68, 3, 1, 1, 1) - self.gridLayout_190 = QtWidgets.QGridLayout() - self.gridLayout_190.setObjectName("gridLayout_190") - self.raster_name_combo = QtWidgets.QComboBox(self.tab_split_raster) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.raster_name_combo.sizePolicy().hasHeightForWidth()) - self.raster_name_combo.setSizePolicy(sizePolicy) - self.raster_name_combo.setObjectName("raster_name_combo") - self.gridLayout_190.addWidget(self.raster_name_combo, 1, 1, 1, 1) - self.label_57 = QtWidgets.QLabel(self.tab_split_raster) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_57.sizePolicy().hasHeightForWidth()) - self.label_57.setSizePolicy(sizePolicy) - self.label_57.setStyleSheet("background-color : #656565; color : white") - self.label_57.setFrameShape(QtWidgets.QFrame.Panel) - self.label_57.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_57.setObjectName("label_57") - self.gridLayout_190.addWidget(self.label_57, 0, 0, 1, 3) - self.label_50 = QtWidgets.QLabel(self.tab_split_raster) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.imageID_lineEdit.sizePolicy().hasHeightForWidth()) + self.imageID_lineEdit.setSizePolicy(sizePolicy) + self.imageID_lineEdit.setMinimumSize(QtCore.QSize(200, 0)) + self.imageID_lineEdit.setMaxLength(10000) + self.imageID_lineEdit.setObjectName("imageID_lineEdit") + self.gridLayout_120.addWidget(self.imageID_lineEdit, 0, 3, 1, 1) + self.result_number_spinBox_2 = QtWidgets.QSpinBox(self.tab_search) + self.result_number_spinBox_2.setMinimumSize(QtCore.QSize(50, 0)) + self.result_number_spinBox_2.setMaximumSize(QtCore.QSize(100, 16777215)) + self.result_number_spinBox_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.result_number_spinBox_2.setMinimum(5) + self.result_number_spinBox_2.setMaximum(2000) + self.result_number_spinBox_2.setSingleStep(5) + self.result_number_spinBox_2.setProperty("value", 20) + self.result_number_spinBox_2.setObjectName("result_number_spinBox_2") + self.gridLayout_120.addWidget(self.result_number_spinBox_2, 0, 1, 1, 1) + self.gridLayout_115.addLayout(self.gridLayout_120, 1, 0, 1, 7) + self.gridLayout_122.addLayout(self.gridLayout_115, 1, 0, 1, 8) + self.gridLayout_133.addLayout(self.gridLayout_122, 1, 0, 2, 2) + self.gridLayout_87.addLayout(self.gridLayout_133, 0, 0, 1, 1) + self.gridLayout_search = QtWidgets.QGridLayout() + self.gridLayout_search.setObjectName("gridLayout_search") + self.gridLayout_132 = QtWidgets.QGridLayout() + self.gridLayout_132.setObjectName("gridLayout_132") + self.remove_image_toolButton = QtWidgets.QToolButton(self.tab_search) + self.remove_image_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.remove_image_toolButton.setIcon(icon41) + self.remove_image_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.remove_image_toolButton.setObjectName("remove_image_toolButton") + self.gridLayout_132.addWidget(self.remove_image_toolButton, 1, 1, 1, 1) + self.toolButton_display = QtWidgets.QToolButton(self.tab_search) + self.toolButton_display.setStyleSheet("margin: 0px;padding: 0px;") + icon53 = QtGui.QIcon() + icon53.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.toolButton_display.setIcon(icon53) + self.toolButton_display.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_display.setObjectName("toolButton_display") + self.gridLayout_132.addWidget(self.toolButton_display, 0, 1, 1, 1) + self.clear_table_toolButton = QtWidgets.QToolButton(self.tab_search) + self.clear_table_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.clear_table_toolButton.setIcon(icon45) + self.clear_table_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.clear_table_toolButton.setObjectName("clear_table_toolButton") + self.gridLayout_132.addWidget(self.clear_table_toolButton, 2, 1, 1, 1) + self.export_table_pushButton = QtWidgets.QToolButton(self.tab_search) + self.export_table_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.export_table_pushButton.setIcon(icon47) + self.export_table_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.export_table_pushButton.setObjectName("export_table_pushButton") + self.gridLayout_132.addWidget(self.export_table_pushButton, 4, 1, 1, 1) + self.import_table_pushButton = QtWidgets.QToolButton(self.tab_search) + self.import_table_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.import_table_pushButton.setIcon(icon46) + self.import_table_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.import_table_pushButton.setObjectName("import_table_pushButton") + self.gridLayout_132.addWidget(self.import_table_pushButton, 3, 1, 1, 1) + self.gridLayout_121 = QtWidgets.QGridLayout() + self.gridLayout_121.setObjectName("gridLayout_121") + self.image_preview_label = QtWidgets.QLabel(self.tab_search) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_50.sizePolicy().hasHeightForWidth()) - self.label_50.setSizePolicy(sizePolicy) - self.label_50.setMinimumSize(QtCore.QSize(229, 0)) - self.label_50.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_50.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_50.setObjectName("label_50") - self.gridLayout_190.addWidget(self.label_50, 1, 0, 1, 1) - self.toolButton_reload_9 = QtWidgets.QToolButton(self.tab_split_raster) - self.toolButton_reload_9.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_9.setIcon(icon55) - self.toolButton_reload_9.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_9.setObjectName("toolButton_reload_9") - self.gridLayout_190.addWidget(self.toolButton_reload_9, 1, 2, 1, 1) - self.gridLayout_57.addLayout(self.gridLayout_190, 0, 0, 1, 4) - self.label_165 = QtWidgets.QLabel(self.tab_split_raster) - self.label_165.setStyleSheet("background-color : #656565; color : white") - self.label_165.setFrameShape(QtWidgets.QFrame.Panel) - self.label_165.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_165.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_165.setObjectName("label_165") - self.gridLayout_57.addWidget(self.label_165, 4, 0, 1, 4) - self.horizontalLayout_57 = QtWidgets.QHBoxLayout() - self.horizontalLayout_57.setObjectName("horizontalLayout_57") - self.label_61 = QtWidgets.QLabel(self.tab_split_raster) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.image_preview_label.sizePolicy().hasHeightForWidth()) + self.image_preview_label.setSizePolicy(sizePolicy) + self.image_preview_label.setMinimumSize(QtCore.QSize(300, 300)) + self.image_preview_label.setFrameShape(QtWidgets.QFrame.Panel) + self.image_preview_label.setFrameShadow(QtWidgets.QFrame.Sunken) + self.image_preview_label.setAlignment(QtCore.Qt.AlignCenter) + self.image_preview_label.setObjectName("image_preview_label") + self.gridLayout_121.addWidget(self.image_preview_label, 0, 0, 1, 1) + self.gridLayout_132.addLayout(self.gridLayout_121, 0, 0, 5, 1) + self.gridLayout_search.addLayout(self.gridLayout_132, 2, 1, 1, 1) + self.download_images_tableWidget = QtWidgets.QTableWidget(self.tab_search) + self.download_images_tableWidget.setFrameShadow(QtWidgets.QFrame.Sunken) + self.download_images_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.download_images_tableWidget.setTabKeyNavigation(True) + self.download_images_tableWidget.setAlternatingRowColors(True) + self.download_images_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.download_images_tableWidget.setObjectName("download_images_tableWidget") + self.download_images_tableWidget.setColumnCount(15) + self.download_images_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(6, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(7, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(8, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(9, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(10, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(11, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(12, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(13, item) + item = QtWidgets.QTableWidgetItem() + self.download_images_tableWidget.setHorizontalHeaderItem(14, item) + self.download_images_tableWidget.horizontalHeader().setStretchLastSection(True) + self.download_images_tableWidget.verticalHeader().setDefaultSectionSize(22) + self.gridLayout_search.addWidget(self.download_images_tableWidget, 2, 0, 1, 1) + self.label_100 = QtWidgets.QLabel(self.tab_search) + self.label_100.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_100.setFrameShape(QtWidgets.QFrame.Panel) + self.label_100.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_100.setObjectName("label_100") + self.gridLayout_search.addWidget(self.label_100, 0, 0, 1, 1) + self.products_filter_lineEdit = QtWidgets.QLineEdit(self.tab_search) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_61.sizePolicy().hasHeightForWidth()) - self.label_61.setSizePolicy(sizePolicy) - self.label_61.setMinimumSize(QtCore.QSize(229, 0)) - self.label_61.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_61.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_61.setObjectName("label_61") - self.horizontalLayout_57.addWidget(self.label_61) - self.output_name_lineEdit = QtWidgets.QLineEdit(self.tab_split_raster) - self.output_name_lineEdit.setMaxLength(10) - self.output_name_lineEdit.setObjectName("output_name_lineEdit") - self.horizontalLayout_57.addWidget(self.output_name_lineEdit) - self.gridLayout_57.addLayout(self.horizontalLayout_57, 1, 0, 1, 4) - self.horizontalLayout_54 = QtWidgets.QHBoxLayout() - self.horizontalLayout_54.setObjectName("horizontalLayout_54") - spacerItem69 = QtWidgets.QSpacerItem(667, 38, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_54.addItem(spacerItem69) - self.split_raster_bands = QtWidgets.QToolButton(self.tab_split_raster) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.split_raster_bands.setFont(font) - self.split_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) - self.split_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") - self.split_raster_bands.setIcon(icon48) - self.split_raster_bands.setIconSize(QtCore.QSize(34, 34)) - self.split_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.split_raster_bands.setObjectName("split_raster_bands") - self.horizontalLayout_54.addWidget(self.split_raster_bands) - self.split_Button = QtWidgets.QToolButton(self.tab_split_raster) + sizePolicy.setHeightForWidth(self.products_filter_lineEdit.sizePolicy().hasHeightForWidth()) + self.products_filter_lineEdit.setSizePolicy(sizePolicy) + self.products_filter_lineEdit.setObjectName("products_filter_lineEdit") + self.gridLayout_search.addWidget(self.products_filter_lineEdit, 0, 1, 1, 1) + self.gridLayout_87.addLayout(self.gridLayout_search, 1, 0, 1, 1) + icon54 = QtGui.QIcon() + icon54.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget_3.addTab(self.tab_search, icon54, "") + self.tab_login = QtWidgets.QWidget() + self.tab_login.setObjectName("tab_login") + self.gridLayout_238 = QtWidgets.QGridLayout(self.tab_login) + self.gridLayout_238.setObjectName("gridLayout_238") + spacerItem7 = QtWidgets.QSpacerItem(20, 251, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_238.addItem(spacerItem7, 1, 0, 1, 1) + self.gridLayout_242 = QtWidgets.QGridLayout() + self.gridLayout_242.setObjectName("gridLayout_242") + self.remember_user_checkBox_3 = QtWidgets.QCheckBox(self.tab_login) + self.remember_user_checkBox_3.setObjectName("remember_user_checkBox_3") + self.gridLayout_242.addWidget(self.remember_user_checkBox_3, 1, 4, 1, 1) + self.password_earthdata_lineEdit = QtWidgets.QLineEdit(self.tab_login) + self.password_earthdata_lineEdit.setObjectName("password_earthdata_lineEdit") + self.gridLayout_242.addWidget(self.password_earthdata_lineEdit, 1, 3, 1, 1) + self.password_scihub_label_4 = QtWidgets.QLabel(self.tab_login) + self.password_scihub_label_4.setObjectName("password_scihub_label_4") + self.gridLayout_242.addWidget(self.password_scihub_label_4, 1, 2, 1, 1) + self.label_191 = QtWidgets.QLabel(self.tab_login) + self.label_191.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_191.setFrameShape(QtWidgets.QFrame.Panel) + self.label_191.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_191.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_191.setOpenExternalLinks(True) + self.label_191.setObjectName("label_191") + self.gridLayout_242.addWidget(self.label_191, 0, 0, 1, 6) + self.user_earthdata_lineEdit = QtWidgets.QLineEdit(self.tab_login) + self.user_earthdata_lineEdit.setObjectName("user_earthdata_lineEdit") + self.gridLayout_242.addWidget(self.user_earthdata_lineEdit, 1, 1, 1, 1) + self.user_scihub_label_3 = QtWidgets.QLabel(self.tab_login) + self.user_scihub_label_3.setObjectName("user_scihub_label_3") + self.gridLayout_242.addWidget(self.user_scihub_label_3, 1, 0, 1, 1) + self.gridLayout_238.addLayout(self.gridLayout_242, 0, 0, 1, 1) + icon55 = QtGui.QIcon() + icon55.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget_3.addTab(self.tab_login, icon55, "") + self.gridLayout_113.addWidget(self.tabWidget_3, 0, 1, 1, 1) + self.gridLayout_68.addLayout(self.gridLayout_113, 0, 0, 1, 1) + self.gridLayout_320 = QtWidgets.QGridLayout() + self.gridLayout_320.setObjectName("gridLayout_320") + self.label_258 = QtWidgets.QLabel(self.tab_download_products) + self.label_258.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_258.setFrameShape(QtWidgets.QFrame.Panel) + self.label_258.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_258.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_258.setOpenExternalLinks(True) + self.label_258.setObjectName("label_258") + self.gridLayout_320.addWidget(self.label_258, 0, 0, 1, 8) + self.load_in_QGIS_checkBox = QtWidgets.QCheckBox(self.tab_download_products) + self.load_in_QGIS_checkBox.setObjectName("load_in_QGIS_checkBox") + self.gridLayout_320.addWidget(self.load_in_QGIS_checkBox, 2, 3, 1, 1) + self.download_if_preview_in_legend_checkBox = QtWidgets.QCheckBox(self.tab_download_products) + self.download_if_preview_in_legend_checkBox.setChecked(True) + self.download_if_preview_in_legend_checkBox.setObjectName("download_if_preview_in_legend_checkBox") + self.gridLayout_320.addWidget(self.download_if_preview_in_legend_checkBox, 2, 1, 1, 1) + self.export_links_Button = QtWidgets.QToolButton(self.tab_download_products) + self.export_links_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.export_links_Button.setIcon(icon47) + self.export_links_Button.setIconSize(QtCore.QSize(22, 22)) + self.export_links_Button.setObjectName("export_links_Button") + self.gridLayout_320.addWidget(self.export_links_Button, 2, 6, 1, 1) + self.virtual_download_checkBox = QtWidgets.QCheckBox(self.tab_download_products) + self.virtual_download_checkBox.setObjectName("virtual_download_checkBox") + self.gridLayout_320.addWidget(self.virtual_download_checkBox, 2, 4, 1, 1) + self.preprocess_checkBox = QtWidgets.QCheckBox(self.tab_download_products) + self.preprocess_checkBox.setChecked(True) + self.preprocess_checkBox.setObjectName("preprocess_checkBox") + self.gridLayout_320.addWidget(self.preprocess_checkBox, 2, 2, 1, 1) + self.download_images_Button = QtWidgets.QToolButton(self.tab_download_products) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.split_Button.setFont(font) - self.split_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.split_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.split_Button.setIcon(icon64) - self.split_Button.setIconSize(QtCore.QSize(34, 34)) - self.split_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.split_Button.setObjectName("split_Button") - self.horizontalLayout_54.addWidget(self.split_Button) - self.gridLayout_57.addLayout(self.horizontalLayout_54, 5, 0, 1, 4) - self.tabWidget_preprocessing.addTab(self.tab_split_raster, "") - self.tab_stack_bands = QtWidgets.QWidget() - self.tab_stack_bands.setObjectName("tab_stack_bands") - self.gridLayout_23 = QtWidgets.QGridLayout(self.tab_stack_bands) - self.gridLayout_23.setObjectName("gridLayout_23") - self.label_252 = QtWidgets.QLabel(self.tab_stack_bands) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + self.download_images_Button.setFont(font) + self.download_images_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.download_images_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.download_images_Button.setIcon(icon44) + self.download_images_Button.setIconSize(QtCore.QSize(34, 34)) + self.download_images_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.download_images_Button.setObjectName("download_images_Button") + self.gridLayout_320.addWidget(self.download_images_Button, 2, 7, 1, 1) + spacerItem8 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_320.addItem(spacerItem8, 2, 5, 1, 1) + self.gridLayout_136 = QtWidgets.QGridLayout() + self.gridLayout_136.setObjectName("gridLayout_136") + self.checkBoxs_band_1 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_1.setChecked(True) + self.checkBoxs_band_1.setObjectName("checkBoxs_band_1") + self.gridLayout_136.addWidget(self.checkBoxs_band_1, 0, 1, 1, 1) + self.checkBoxs_band_8A = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_8A.setChecked(True) + self.checkBoxs_band_8A.setObjectName("checkBoxs_band_8A") + self.gridLayout_136.addWidget(self.checkBoxs_band_8A, 0, 9, 1, 1) + self.checkBoxs_band_4 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_4.setChecked(True) + self.checkBoxs_band_4.setObjectName("checkBoxs_band_4") + self.gridLayout_136.addWidget(self.checkBoxs_band_4, 0, 4, 1, 1) + self.checkBoxs_band_11 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_11.setChecked(True) + self.checkBoxs_band_11.setObjectName("checkBoxs_band_11") + self.gridLayout_136.addWidget(self.checkBoxs_band_11, 0, 12, 1, 1) + self.checkBoxs_band_5 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_5.setChecked(True) + self.checkBoxs_band_5.setObjectName("checkBoxs_band_5") + self.gridLayout_136.addWidget(self.checkBoxs_band_5, 0, 5, 1, 1) + self.checkBoxs_band_6 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_6.setChecked(True) + self.checkBoxs_band_6.setObjectName("checkBoxs_band_6") + self.gridLayout_136.addWidget(self.checkBoxs_band_6, 0, 6, 1, 1) + self.checkBoxs_band_7 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_7.setChecked(True) + self.checkBoxs_band_7.setObjectName("checkBoxs_band_7") + self.gridLayout_136.addWidget(self.checkBoxs_band_7, 0, 7, 1, 1) + self.checkBoxs_band_2 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_2.setChecked(True) + self.checkBoxs_band_2.setObjectName("checkBoxs_band_2") + self.gridLayout_136.addWidget(self.checkBoxs_band_2, 0, 2, 1, 1) + self.checkBoxs_band_9 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_9.setChecked(True) + self.checkBoxs_band_9.setObjectName("checkBoxs_band_9") + self.gridLayout_136.addWidget(self.checkBoxs_band_9, 0, 10, 1, 1) + self.check_toolButton_2 = QtWidgets.QToolButton(self.tab_download_products) + self.check_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") + icon56 = QtGui.QIcon() + icon56.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.check_toolButton_2.setIcon(icon56) + self.check_toolButton_2.setIconSize(QtCore.QSize(22, 22)) + self.check_toolButton_2.setObjectName("check_toolButton_2") + self.gridLayout_136.addWidget(self.check_toolButton_2, 0, 15, 1, 1) + self.ancillary_data_checkBox = QtWidgets.QCheckBox(self.tab_download_products) + self.ancillary_data_checkBox.setChecked(True) + self.ancillary_data_checkBox.setObjectName("ancillary_data_checkBox") + self.gridLayout_136.addWidget(self.ancillary_data_checkBox, 0, 14, 1, 1) + self.checkBoxs_band_3 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_3.setChecked(True) + self.checkBoxs_band_3.setObjectName("checkBoxs_band_3") + self.gridLayout_136.addWidget(self.checkBoxs_band_3, 0, 3, 1, 1) + self.checkBoxs_band_8 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_8.setChecked(True) + self.checkBoxs_band_8.setObjectName("checkBoxs_band_8") + self.gridLayout_136.addWidget(self.checkBoxs_band_8, 0, 8, 1, 1) + self.checkBoxs_band_10 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_10.setChecked(True) + self.checkBoxs_band_10.setObjectName("checkBoxs_band_10") + self.gridLayout_136.addWidget(self.checkBoxs_band_10, 0, 11, 1, 1) + self.checkBoxs_band_12 = QtWidgets.QCheckBox(self.tab_download_products) + self.checkBoxs_band_12.setChecked(True) + self.checkBoxs_band_12.setObjectName("checkBoxs_band_12") + self.gridLayout_136.addWidget(self.checkBoxs_band_12, 0, 13, 1, 1) + self.label_3 = QtWidgets.QLabel(self.tab_download_products) + self.label_3.setObjectName("label_3") + self.gridLayout_136.addWidget(self.label_3, 0, 0, 1, 1) + self.gridLayout_320.addLayout(self.gridLayout_136, 1, 0, 1, 8) + self.gridLayout_68.addLayout(self.gridLayout_320, 1, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_download_products, "") + self.tab_basic_tools = QtWidgets.QWidget() + self.tab_basic_tools.setObjectName("tab_basic_tools") + self.gridLayout_216 = QtWidgets.QGridLayout(self.tab_basic_tools) + self.gridLayout_216.setContentsMargins(3, 3, 3, 3) + self.gridLayout_216.setObjectName("gridLayout_216") + self.tabWidget_5 = QtWidgets.QTabWidget(self.tab_basic_tools) + self.tabWidget_5.setStyleSheet("") + self.tabWidget_5.setIconSize(QtCore.QSize(20, 20)) + self.tabWidget_5.setDocumentMode(True) + self.tabWidget_5.setObjectName("tabWidget_5") + self.tab_RGB = QtWidgets.QWidget() + self.tab_RGB.setObjectName("tab_RGB") + self.gridLayout_213 = QtWidgets.QGridLayout(self.tab_RGB) + self.gridLayout_213.setObjectName("gridLayout_213") + self.gridLayout_243 = QtWidgets.QGridLayout() + self.gridLayout_243.setObjectName("gridLayout_243") + self.gridLayout_234 = QtWidgets.QGridLayout() + self.gridLayout_234.setObjectName("gridLayout_234") + self.label_126 = QtWidgets.QLabel(self.tab_RGB) + self.label_126.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_126.setFrameShape(QtWidgets.QFrame.Panel) + self.label_126.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_126.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_126.setObjectName("label_126") + self.gridLayout_234.addWidget(self.label_126, 0, 0, 1, 1) + self.gridLayout_243.addLayout(self.gridLayout_234, 0, 0, 1, 2) + self.gridLayout_244 = QtWidgets.QGridLayout() + self.gridLayout_244.setObjectName("gridLayout_244") + spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_244.addItem(spacerItem9, 3, 0, 1, 1) + self.sort_by_name_toolButton_2 = QtWidgets.QToolButton(self.tab_RGB) + self.sort_by_name_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") + self.sort_by_name_toolButton_2.setIcon(icon48) + self.sort_by_name_toolButton_2.setIconSize(QtCore.QSize(22, 22)) + self.sort_by_name_toolButton_2.setObjectName("sort_by_name_toolButton_2") + self.gridLayout_244.addWidget(self.sort_by_name_toolButton_2, 2, 0, 1, 1) + self.move_down_toolButton_3 = QtWidgets.QToolButton(self.tab_RGB) + self.move_down_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") + self.move_down_toolButton_3.setIcon(icon40) + self.move_down_toolButton_3.setIconSize(QtCore.QSize(22, 22)) + self.move_down_toolButton_3.setObjectName("move_down_toolButton_3") + self.gridLayout_244.addWidget(self.move_down_toolButton_3, 1, 0, 1, 1) + self.move_up_toolButton_3 = QtWidgets.QToolButton(self.tab_RGB) + self.move_up_toolButton_3.setStyleSheet("margin: 0px;padding: 0px;") + self.move_up_toolButton_3.setIcon(icon38) + self.move_up_toolButton_3.setIconSize(QtCore.QSize(22, 22)) + self.move_up_toolButton_3.setObjectName("move_up_toolButton_3") + self.gridLayout_244.addWidget(self.move_up_toolButton_3, 0, 0, 1, 1) + self.gridLayout_243.addLayout(self.gridLayout_244, 1, 1, 1, 1) + self.gridLayout_245 = QtWidgets.QGridLayout() + self.gridLayout_245.setObjectName("gridLayout_245") + self.add_RGB_pushButton = QtWidgets.QToolButton(self.tab_RGB) + self.add_RGB_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.add_RGB_pushButton.setIcon(icon49) + self.add_RGB_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_RGB_pushButton.setObjectName("add_RGB_pushButton") + self.gridLayout_245.addWidget(self.add_RGB_pushButton, 0, 0, 1, 1) + self.export_RGB_List_toolButton = QtWidgets.QToolButton(self.tab_RGB) + self.export_RGB_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.export_RGB_List_toolButton.setIcon(icon47) + self.export_RGB_List_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.export_RGB_List_toolButton.setObjectName("export_RGB_List_toolButton") + self.gridLayout_245.addWidget(self.export_RGB_List_toolButton, 4, 0, 1, 1) + self.import_RGB_List_toolButton = QtWidgets.QToolButton(self.tab_RGB) + self.import_RGB_List_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.import_RGB_List_toolButton.setIcon(icon46) + self.import_RGB_List_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.import_RGB_List_toolButton.setObjectName("import_RGB_List_toolButton") + self.gridLayout_245.addWidget(self.import_RGB_List_toolButton, 5, 0, 1, 1) + self.clear_RGB_list_toolButton = QtWidgets.QToolButton(self.tab_RGB) + self.clear_RGB_list_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.clear_RGB_list_toolButton.setIcon(icon45) + self.clear_RGB_list_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.clear_RGB_list_toolButton.setObjectName("clear_RGB_list_toolButton") + self.gridLayout_245.addWidget(self.clear_RGB_list_toolButton, 2, 0, 1, 1) + self.remove_RGB_toolButton = QtWidgets.QToolButton(self.tab_RGB) + self.remove_RGB_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.remove_RGB_toolButton.setIcon(icon41) + self.remove_RGB_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.remove_RGB_toolButton.setObjectName("remove_RGB_toolButton") + self.gridLayout_245.addWidget(self.remove_RGB_toolButton, 1, 0, 1, 1) + spacerItem10 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_245.addItem(spacerItem10, 3, 0, 1, 1) + self.gridLayout_243.addLayout(self.gridLayout_245, 2, 1, 1, 1) + self.RGB_tableWidget = QtWidgets.QTableWidget(self.tab_RGB) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_252.sizePolicy().hasHeightForWidth()) - self.label_252.setSizePolicy(sizePolicy) - self.label_252.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_252.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_252.setObjectName("label_252") - self.gridLayout_23.addWidget(self.label_252, 1, 0, 1, 1) - self.band_set_comb_spinBox_3 = QtWidgets.QSpinBox(self.tab_stack_bands) - self.band_set_comb_spinBox_3.setMinimum(1) - self.band_set_comb_spinBox_3.setMaximum(100000) - self.band_set_comb_spinBox_3.setObjectName("band_set_comb_spinBox_3") - self.gridLayout_23.addWidget(self.band_set_comb_spinBox_3, 1, 1, 1, 1) - spacerItem70 = QtWidgets.QSpacerItem(647, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_23.addItem(spacerItem70, 1, 3, 1, 1) - spacerItem71 = QtWidgets.QSpacerItem(20, 339, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_23.addItem(spacerItem71, 2, 0, 1, 1) - self.horizontalLayout_53 = QtWidgets.QHBoxLayout() - self.horizontalLayout_53.setObjectName("horizontalLayout_53") - spacerItem72 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_53.addItem(spacerItem72) - self.stack_raster_bands = QtWidgets.QToolButton(self.tab_stack_bands) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.stack_raster_bands.setFont(font) - self.stack_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) - self.stack_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") - self.stack_raster_bands.setIcon(icon48) - self.stack_raster_bands.setIconSize(QtCore.QSize(34, 34)) - self.stack_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.stack_raster_bands.setObjectName("stack_raster_bands") - self.horizontalLayout_53.addWidget(self.stack_raster_bands) - self.stack_Button = QtWidgets.QToolButton(self.tab_stack_bands) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.stack_Button.setFont(font) - self.stack_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.stack_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.stack_Button.setIcon(icon64) - self.stack_Button.setIconSize(QtCore.QSize(34, 34)) - self.stack_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.stack_Button.setObjectName("stack_Button") - self.horizontalLayout_53.addWidget(self.stack_Button) - self.gridLayout_23.addLayout(self.horizontalLayout_53, 4, 0, 1, 4) - self.label_223 = QtWidgets.QLabel(self.tab_stack_bands) - self.label_223.setStyleSheet("background-color : #656565; color : white") - self.label_223.setFrameShape(QtWidgets.QFrame.Panel) - self.label_223.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_223.setObjectName("label_223") - self.gridLayout_23.addWidget(self.label_223, 0, 0, 1, 4) - self.label_226 = QtWidgets.QLabel(self.tab_stack_bands) - self.label_226.setStyleSheet("background-color : #656565; color : white") - self.label_226.setFrameShape(QtWidgets.QFrame.Panel) - self.label_226.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_226.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_226.setObjectName("label_226") - self.gridLayout_23.addWidget(self.label_226, 3, 0, 1, 4) - self.tabWidget_preprocessing.addTab(self.tab_stack_bands, "") - self.tab_mosaic_band_sets = QtWidgets.QWidget() - self.tab_mosaic_band_sets.setObjectName("tab_mosaic_band_sets") - self.gridLayout_278 = QtWidgets.QGridLayout(self.tab_mosaic_band_sets) - self.gridLayout_278.setObjectName("gridLayout_278") - self.horizontalLayout_28 = QtWidgets.QHBoxLayout() - self.horizontalLayout_28.setObjectName("horizontalLayout_28") - self.label_134 = QtWidgets.QLabel(self.tab_mosaic_band_sets) - self.label_134.setStyleSheet("background-color : #656565; color : white") - self.label_134.setFrameShape(QtWidgets.QFrame.Panel) - self.label_134.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_134.setObjectName("label_134") - self.horizontalLayout_28.addWidget(self.label_134) - self.gridLayout_278.addLayout(self.horizontalLayout_28, 0, 0, 1, 1) - self.gridLayout_66 = QtWidgets.QGridLayout() - self.gridLayout_66.setObjectName("gridLayout_66") - self.label_135 = QtWidgets.QLabel(self.tab_mosaic_band_sets) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.RGB_tableWidget.sizePolicy().hasHeightForWidth()) + self.RGB_tableWidget.setSizePolicy(sizePolicy) + self.RGB_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked) + self.RGB_tableWidget.setAlternatingRowColors(True) + self.RGB_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.RGB_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.RGB_tableWidget.setObjectName("RGB_tableWidget") + self.RGB_tableWidget.setColumnCount(1) + self.RGB_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.RGB_tableWidget.setHorizontalHeaderItem(0, item) + self.RGB_tableWidget.horizontalHeader().setDefaultSectionSize(50) + self.RGB_tableWidget.horizontalHeader().setStretchLastSection(True) + self.RGB_tableWidget.verticalHeader().setDefaultSectionSize(22) + self.gridLayout_243.addWidget(self.RGB_tableWidget, 1, 0, 2, 1) + self.gridLayout_213.addLayout(self.gridLayout_243, 0, 0, 1, 1) + self.gridLayout_246 = QtWidgets.QGridLayout() + self.gridLayout_246.setObjectName("gridLayout_246") + self.label_196 = QtWidgets.QLabel(self.tab_RGB) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_135.sizePolicy().hasHeightForWidth()) - self.label_135.setSizePolicy(sizePolicy) - self.label_135.setMinimumSize(QtCore.QSize(229, 0)) - self.label_135.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_135.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_135.setObjectName("label_135") - self.gridLayout_66.addWidget(self.label_135, 3, 0, 1, 1) - self.nodata_checkBox_9 = QtWidgets.QCheckBox(self.tab_mosaic_band_sets) - self.nodata_checkBox_9.setChecked(True) - self.nodata_checkBox_9.setObjectName("nodata_checkBox_9") - self.gridLayout_66.addWidget(self.nodata_checkBox_9, 1, 0, 1, 1) - self.nodata_spinBox_10 = QtWidgets.QSpinBox(self.tab_mosaic_band_sets) - self.nodata_spinBox_10.setMinimum(-2147483647) - self.nodata_spinBox_10.setMaximum(2147483647) - self.nodata_spinBox_10.setObjectName("nodata_spinBox_10") - self.gridLayout_66.addWidget(self.nodata_spinBox_10, 1, 1, 1, 1) - spacerItem73 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_66.addItem(spacerItem73, 1, 2, 1, 1) - self.mosaic_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_mosaic_band_sets) - self.mosaic_output_name_lineEdit.setMaxLength(10) - self.mosaic_output_name_lineEdit.setObjectName("mosaic_output_name_lineEdit") - self.gridLayout_66.addWidget(self.mosaic_output_name_lineEdit, 3, 1, 1, 2) - self.label_144 = QtWidgets.QLabel(self.tab_mosaic_band_sets) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_196.sizePolicy().hasHeightForWidth()) + self.label_196.setSizePolicy(sizePolicy) + self.label_196.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_196.setFrameShape(QtWidgets.QFrame.Panel) + self.label_196.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_196.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_196.setObjectName("label_196") + self.gridLayout_246.addWidget(self.label_196, 0, 0, 1, 2) + self.horizontalLayout_27 = QtWidgets.QHBoxLayout() + self.horizontalLayout_27.setObjectName("horizontalLayout_27") + self.label_192 = QtWidgets.QLabel(self.tab_RGB) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_144.sizePolicy().hasHeightForWidth()) - self.label_144.setSizePolicy(sizePolicy) - self.label_144.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_144.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_144.setObjectName("label_144") - self.gridLayout_66.addWidget(self.label_144, 0, 0, 1, 1) - self.mosaic_band_sets_lineEdit = QtWidgets.QLineEdit(self.tab_mosaic_band_sets) - self.mosaic_band_sets_lineEdit.setObjectName("mosaic_band_sets_lineEdit") - self.gridLayout_66.addWidget(self.mosaic_band_sets_lineEdit, 0, 1, 1, 2) - self.mosaic_virtual_checkBox = QtWidgets.QCheckBox(self.tab_mosaic_band_sets) - self.mosaic_virtual_checkBox.setObjectName("mosaic_virtual_checkBox") - self.gridLayout_66.addWidget(self.mosaic_virtual_checkBox, 2, 0, 1, 1) - self.gridLayout_278.addLayout(self.gridLayout_66, 1, 0, 1, 1) - spacerItem74 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_278.addItem(spacerItem74, 2, 0, 1, 1) - self.gridLayout_228 = QtWidgets.QGridLayout() - self.gridLayout_228.setObjectName("gridLayout_228") - spacerItem75 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_228.addItem(spacerItem75, 1, 0, 1, 1) - self.mosaic_bandsets_toolButton = QtWidgets.QToolButton(self.tab_mosaic_band_sets) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.mosaic_bandsets_toolButton.setFont(font) - self.mosaic_bandsets_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.mosaic_bandsets_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.mosaic_bandsets_toolButton.setIcon(icon64) - self.mosaic_bandsets_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.mosaic_bandsets_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.mosaic_bandsets_toolButton.setObjectName("mosaic_bandsets_toolButton") - self.gridLayout_228.addWidget(self.mosaic_bandsets_toolButton, 1, 2, 1, 1) - self.mosaic_bandsets = QtWidgets.QToolButton(self.tab_mosaic_band_sets) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.mosaic_bandsets.setFont(font) - self.mosaic_bandsets.setLayoutDirection(QtCore.Qt.RightToLeft) - self.mosaic_bandsets.setStyleSheet("margin: 0px;padding: 0px;") - self.mosaic_bandsets.setIcon(icon48) - self.mosaic_bandsets.setIconSize(QtCore.QSize(34, 34)) - self.mosaic_bandsets.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.mosaic_bandsets.setObjectName("mosaic_bandsets") - self.gridLayout_228.addWidget(self.mosaic_bandsets, 1, 1, 1, 1) - self.label_182 = QtWidgets.QLabel(self.tab_mosaic_band_sets) - self.label_182.setStyleSheet("background-color : #656565; color : white") - self.label_182.setFrameShape(QtWidgets.QFrame.Panel) - self.label_182.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_182.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_182.setObjectName("label_182") - self.gridLayout_228.addWidget(self.label_182, 0, 0, 1, 3) - self.gridLayout_278.addLayout(self.gridLayout_228, 3, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_mosaic_band_sets, "") - self.tab_cloud_mask = QtWidgets.QWidget() - self.tab_cloud_mask.setObjectName("tab_cloud_mask") - self.gridLayout_296 = QtWidgets.QGridLayout(self.tab_cloud_mask) - self.gridLayout_296.setObjectName("gridLayout_296") - self.gridLayout_261 = QtWidgets.QGridLayout() - self.gridLayout_261.setObjectName("gridLayout_261") - self.label_260 = QtWidgets.QLabel(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_192.sizePolicy().hasHeightForWidth()) + self.label_192.setSizePolicy(sizePolicy) + self.label_192.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_192.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_192.setObjectName("label_192") + self.horizontalLayout_27.addWidget(self.label_192) + self.all_RGB_list_toolButton = QtWidgets.QToolButton(self.tab_RGB) + self.all_RGB_list_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon57 = QtGui.QIcon() + icon57.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.all_RGB_list_toolButton.setIcon(icon57) + self.all_RGB_list_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.all_RGB_list_toolButton.setObjectName("all_RGB_list_toolButton") + self.horizontalLayout_27.addWidget(self.all_RGB_list_toolButton) + spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_27.addItem(spacerItem11) + self.gridLayout_246.addLayout(self.horizontalLayout_27, 1, 0, 1, 2) + self.gridLayout_213.addLayout(self.gridLayout_246, 1, 0, 1, 1) + self.tabWidget_5.addTab(self.tab_RGB, "") + self.tab_multiple_ROI = QtWidgets.QWidget() + self.tab_multiple_ROI.setObjectName("tab_multiple_ROI") + self.gridLayout_247 = QtWidgets.QGridLayout(self.tab_multiple_ROI) + self.gridLayout_247.setObjectName("gridLayout_247") + self.gridLayout_8 = QtWidgets.QGridLayout() + self.gridLayout_8.setObjectName("gridLayout_8") + self.point_distance_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_260.sizePolicy().hasHeightForWidth()) - self.label_260.setSizePolicy(sizePolicy) - self.label_260.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_260.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_260.setObjectName("label_260") - self.gridLayout_261.addWidget(self.label_260, 0, 0, 1, 1) - spacerItem76 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_261.addItem(spacerItem76, 0, 2, 1, 1) - self.band_set_comb_spinBox_9 = QtWidgets.QSpinBox(self.tab_cloud_mask) - self.band_set_comb_spinBox_9.setMinimum(1) - self.band_set_comb_spinBox_9.setMaximum(100000) - self.band_set_comb_spinBox_9.setObjectName("band_set_comb_spinBox_9") - self.gridLayout_261.addWidget(self.band_set_comb_spinBox_9, 0, 1, 1, 1) - self.gridLayout_296.addLayout(self.gridLayout_261, 1, 0, 1, 2) - self.gridLayout_106 = QtWidgets.QGridLayout() - self.gridLayout_106.setObjectName("gridLayout_106") - self.classification_name_combo_4 = QtWidgets.QComboBox(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_name_combo_4.sizePolicy().hasHeightForWidth()) - self.classification_name_combo_4.setSizePolicy(sizePolicy) - self.classification_name_combo_4.setObjectName("classification_name_combo_4") - self.gridLayout_106.addWidget(self.classification_name_combo_4, 0, 1, 1, 1) - self.cloud_mask_classes_lineEdit = QtWidgets.QLineEdit(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.point_distance_spinBox.sizePolicy().hasHeightForWidth()) + self.point_distance_spinBox.setSizePolicy(sizePolicy) + self.point_distance_spinBox.setMinimumSize(QtCore.QSize(40, 0)) + self.point_distance_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.point_distance_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.point_distance_spinBox.setMinimum(1) + self.point_distance_spinBox.setMaximum(999999999) + self.point_distance_spinBox.setProperty("value", 100) + self.point_distance_spinBox.setObjectName("point_distance_spinBox") + self.gridLayout_8.addWidget(self.point_distance_spinBox, 1, 5, 1, 1) + self.point_grid_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.cloud_mask_classes_lineEdit.sizePolicy().hasHeightForWidth()) - self.cloud_mask_classes_lineEdit.setSizePolicy(sizePolicy) - self.cloud_mask_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) - self.cloud_mask_classes_lineEdit.setText("") - self.cloud_mask_classes_lineEdit.setMaxLength(10000) - self.cloud_mask_classes_lineEdit.setObjectName("cloud_mask_classes_lineEdit") - self.gridLayout_106.addWidget(self.cloud_mask_classes_lineEdit, 1, 1, 1, 1) - self.label_203 = QtWidgets.QLabel(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.point_grid_spinBox.sizePolicy().hasHeightForWidth()) + self.point_grid_spinBox.setSizePolicy(sizePolicy) + self.point_grid_spinBox.setMinimumSize(QtCore.QSize(40, 0)) + self.point_grid_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.point_grid_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.point_grid_spinBox.setMinimum(1) + self.point_grid_spinBox.setMaximum(999999999) + self.point_grid_spinBox.setProperty("value", 10000) + self.point_grid_spinBox.setObjectName("point_grid_spinBox") + self.gridLayout_8.addWidget(self.point_grid_spinBox, 1, 3, 1, 1) + self.label_48 = QtWidgets.QLabel(self.tab_multiple_ROI) + self.label_48.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_48.setFrameShape(QtWidgets.QFrame.Panel) + self.label_48.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_48.setObjectName("label_48") + self.gridLayout_8.addWidget(self.label_48, 0, 0, 1, 9) + self.label_139 = QtWidgets.QLabel(self.tab_multiple_ROI) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_203.sizePolicy().hasHeightForWidth()) - self.label_203.setSizePolicy(sizePolicy) - self.label_203.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_203.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_203.setObjectName("label_203") - self.gridLayout_106.addWidget(self.label_203, 1, 0, 1, 1) - self.label_186 = QtWidgets.QLabel(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_139.sizePolicy().hasHeightForWidth()) + self.label_139.setSizePolicy(sizePolicy) + self.label_139.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_139.setObjectName("label_139") + self.gridLayout_8.addWidget(self.label_139, 1, 7, 1, 1) + self.label_19 = QtWidgets.QLabel(self.tab_multiple_ROI) + self.label_19.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_19.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_19.setObjectName("label_19") + self.gridLayout_8.addWidget(self.label_19, 1, 0, 1, 1) + self.point_number_spinBox = QtWidgets.QSpinBox(self.tab_multiple_ROI) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_186.sizePolicy().hasHeightForWidth()) - self.label_186.setSizePolicy(sizePolicy) - self.label_186.setMinimumSize(QtCore.QSize(229, 0)) - self.label_186.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_186.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_186.setObjectName("label_186") - self.gridLayout_106.addWidget(self.label_186, 0, 0, 1, 1) - self.toolButton_reload_23 = QtWidgets.QToolButton(self.tab_cloud_mask) - self.toolButton_reload_23.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_23.setIcon(icon55) - self.toolButton_reload_23.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_23.setObjectName("toolButton_reload_23") - self.gridLayout_106.addWidget(self.toolButton_reload_23, 0, 2, 1, 1) - self.gridLayout_296.addLayout(self.gridLayout_106, 2, 0, 1, 2) - self.gridLayout_143 = QtWidgets.QGridLayout() - self.gridLayout_143.setObjectName("gridLayout_143") - self.label_140 = QtWidgets.QLabel(self.tab_cloud_mask) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.point_number_spinBox.sizePolicy().hasHeightForWidth()) + self.point_number_spinBox.setSizePolicy(sizePolicy) + self.point_number_spinBox.setMinimumSize(QtCore.QSize(40, 0)) + self.point_number_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.point_number_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.point_number_spinBox.setMinimum(1) + self.point_number_spinBox.setMaximum(999999999) + self.point_number_spinBox.setProperty("value", 100) + self.point_number_spinBox.setObjectName("point_number_spinBox") + self.gridLayout_8.addWidget(self.point_number_spinBox, 1, 1, 1, 1) + self.add_random_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + self.add_random_point_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.add_random_point_pushButton.setIcon(icon57) + self.add_random_point_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_random_point_pushButton.setObjectName("add_random_point_pushButton") + self.gridLayout_8.addWidget(self.add_random_point_pushButton, 1, 8, 1, 1) + self.point_distance_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) + self.point_distance_checkBox.setObjectName("point_distance_checkBox") + self.gridLayout_8.addWidget(self.point_distance_checkBox, 1, 4, 1, 1) + self.point_grid_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) + self.point_grid_checkBox.setObjectName("point_grid_checkBox") + self.gridLayout_8.addWidget(self.point_grid_checkBox, 1, 2, 1, 1) + spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_8.addItem(spacerItem12, 1, 6, 1, 1) + self.stratified_point_checkBox = QtWidgets.QCheckBox(self.tab_multiple_ROI) + self.stratified_point_checkBox.setObjectName("stratified_point_checkBox") + self.gridLayout_8.addWidget(self.stratified_point_checkBox, 2, 0, 1, 2) + self.stratified_lineEdit = QtWidgets.QLineEdit(self.tab_multiple_ROI) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_140.sizePolicy().hasHeightForWidth()) - self.label_140.setSizePolicy(sizePolicy) - self.label_140.setMinimumSize(QtCore.QSize(229, 0)) - self.label_140.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_140.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_140.setObjectName("label_140") - self.gridLayout_143.addWidget(self.label_140, 1, 0, 1, 1) - self.mask_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_cloud_mask) - self.mask_output_name_lineEdit.setMaxLength(10) - self.mask_output_name_lineEdit.setObjectName("mask_output_name_lineEdit") - self.gridLayout_143.addWidget(self.mask_output_name_lineEdit, 1, 1, 1, 1) - self.gridLayout_145 = QtWidgets.QGridLayout() - self.gridLayout_145.setObjectName("gridLayout_145") - self.cloud_buffer_spinBox = QtWidgets.QSpinBox(self.tab_cloud_mask) - self.cloud_buffer_spinBox.setMinimum(1) - self.cloud_buffer_spinBox.setMaximum(1000) - self.cloud_buffer_spinBox.setProperty("value", 1) - self.cloud_buffer_spinBox.setObjectName("cloud_buffer_spinBox") - self.gridLayout_145.addWidget(self.cloud_buffer_spinBox, 0, 1, 1, 1) - spacerItem77 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_145.addItem(spacerItem77, 0, 2, 1, 1) - self.cloud_buffer_checkBox = QtWidgets.QCheckBox(self.tab_cloud_mask) - self.cloud_buffer_checkBox.setEnabled(True) - self.cloud_buffer_checkBox.setObjectName("cloud_buffer_checkBox") - self.gridLayout_145.addWidget(self.cloud_buffer_checkBox, 0, 0, 1, 1) - self.nodata_spinBox_11 = QtWidgets.QSpinBox(self.tab_cloud_mask) - self.nodata_spinBox_11.setMinimum(-2147483647) - self.nodata_spinBox_11.setMaximum(2147483647) - self.nodata_spinBox_11.setProperty("value", -32768) - self.nodata_spinBox_11.setObjectName("nodata_spinBox_11") - self.gridLayout_145.addWidget(self.nodata_spinBox_11, 1, 1, 1, 1) - self.label_141 = QtWidgets.QLabel(self.tab_cloud_mask) + sizePolicy.setHeightForWidth(self.stratified_lineEdit.sizePolicy().hasHeightForWidth()) + self.stratified_lineEdit.setSizePolicy(sizePolicy) + self.stratified_lineEdit.setMinimumSize(QtCore.QSize(400, 0)) + self.stratified_lineEdit.setMaxLength(10000) + self.stratified_lineEdit.setObjectName("stratified_lineEdit") + self.gridLayout_8.addWidget(self.stratified_lineEdit, 2, 2, 1, 4) + self.band_set_comb_spinBox_10 = QtWidgets.QSpinBox(self.tab_multiple_ROI) + self.band_set_comb_spinBox_10.setMinimum(1) + self.band_set_comb_spinBox_10.setMaximum(100000) + self.band_set_comb_spinBox_10.setObjectName("band_set_comb_spinBox_10") + self.gridLayout_8.addWidget(self.band_set_comb_spinBox_10, 2, 8, 1, 1) + self.label_25 = QtWidgets.QLabel(self.tab_multiple_ROI) + self.label_25.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_25.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_25.setObjectName("label_25") + self.gridLayout_8.addWidget(self.label_25, 2, 6, 1, 2) + self.gridLayout_247.addLayout(self.gridLayout_8, 0, 0, 1, 1) + self.gridLayout_32 = QtWidgets.QGridLayout() + self.gridLayout_32.setObjectName("gridLayout_32") + self.label_47 = QtWidgets.QLabel(self.tab_multiple_ROI) + self.label_47.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_47.setFrameShape(QtWidgets.QFrame.Panel) + self.label_47.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_47.setObjectName("label_47") + self.gridLayout_32.addWidget(self.label_47, 0, 0, 1, 2) + self.point_tableWidget = QtWidgets.QTableWidget(self.tab_multiple_ROI) + self.point_tableWidget.setAlternatingRowColors(True) + self.point_tableWidget.setObjectName("point_tableWidget") + self.point_tableWidget.setColumnCount(10) + self.point_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(6, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(7, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(8, item) + item = QtWidgets.QTableWidgetItem() + self.point_tableWidget.setHorizontalHeaderItem(9, item) + self.point_tableWidget.horizontalHeader().setDefaultSectionSize(90) + self.point_tableWidget.verticalHeader().setDefaultSectionSize(24) + self.gridLayout_32.addWidget(self.point_tableWidget, 1, 0, 1, 1) + self.gridLayout_72 = QtWidgets.QGridLayout() + self.gridLayout_72.setObjectName("gridLayout_72") + self.gridLayout_39 = QtWidgets.QGridLayout() + self.gridLayout_39.setObjectName("gridLayout_39") + spacerItem13 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_39.addItem(spacerItem13, 3, 0, 1, 1) + self.add_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + self.add_point_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.add_point_pushButton.setIcon(icon49) + self.add_point_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_point_pushButton.setObjectName("add_point_pushButton") + self.gridLayout_39.addWidget(self.add_point_pushButton, 1, 0, 1, 1) + self.remove_point_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + self.remove_point_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.remove_point_pushButton.setIcon(icon41) + self.remove_point_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.remove_point_pushButton.setObjectName("remove_point_pushButton") + self.gridLayout_39.addWidget(self.remove_point_pushButton, 2, 0, 1, 1) + self.export_point_list_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + self.export_point_list_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.export_point_list_pushButton.setIcon(icon47) + self.export_point_list_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.export_point_list_pushButton.setObjectName("export_point_list_pushButton") + self.gridLayout_39.addWidget(self.export_point_list_pushButton, 5, 0, 1, 1) + spacerItem14 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_39.addItem(spacerItem14, 6, 0, 1, 1) + self.import_point_list_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + self.import_point_list_pushButton.setStyleSheet("margin: 0px;padding: 0px") + self.import_point_list_pushButton.setIcon(icon46) + self.import_point_list_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.import_point_list_pushButton.setObjectName("import_point_list_pushButton") + self.gridLayout_39.addWidget(self.import_point_list_pushButton, 4, 0, 1, 1) + spacerItem15 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_39.addItem(spacerItem15, 0, 0, 1, 1) + self.gridLayout_72.addLayout(self.gridLayout_39, 2, 0, 1, 1) + self.gridLayout_32.addLayout(self.gridLayout_72, 1, 1, 1, 1) + self.gridLayout_73 = QtWidgets.QGridLayout() + self.gridLayout_73.setObjectName("gridLayout_73") + spacerItem16 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_73.addItem(spacerItem16, 1, 4, 1, 1) + self.signature_checkBox2 = QtWidgets.QCheckBox(self.tab_multiple_ROI) + self.signature_checkBox2.setChecked(True) + self.signature_checkBox2.setObjectName("signature_checkBox2") + self.gridLayout_73.addWidget(self.signature_checkBox2, 1, 5, 1, 1) + self.label_159 = QtWidgets.QLabel(self.tab_multiple_ROI) + self.label_159.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_159.setFrameShape(QtWidgets.QFrame.Panel) + self.label_159.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_159.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_159.setObjectName("label_159") + self.gridLayout_73.addWidget(self.label_159, 0, 4, 1, 3) + self.save_point_rois_pushButton = QtWidgets.QToolButton(self.tab_multiple_ROI) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.save_point_rois_pushButton.setFont(font) + self.save_point_rois_pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.save_point_rois_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.save_point_rois_pushButton.setIcon(icon44) + self.save_point_rois_pushButton.setIconSize(QtCore.QSize(34, 34)) + self.save_point_rois_pushButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.save_point_rois_pushButton.setObjectName("save_point_rois_pushButton") + self.gridLayout_73.addWidget(self.save_point_rois_pushButton, 1, 6, 1, 1) + self.gridLayout_32.addLayout(self.gridLayout_73, 3, 0, 1, 2) + self.gridLayout_247.addLayout(self.gridLayout_32, 1, 0, 1, 1) + self.tabWidget_5.addTab(self.tab_multiple_ROI, "") + self.tab_Import = QtWidgets.QWidget() + self.tab_Import.setObjectName("tab_Import") + self.gridLayout_168 = QtWidgets.QGridLayout(self.tab_Import) + self.gridLayout_168.setObjectName("gridLayout_168") + self.toolBox_4 = QtWidgets.QToolBox(self.tab_Import) + self.toolBox_4.setObjectName("toolBox_4") + self.page_8 = QtWidgets.QWidget() + self.page_8.setGeometry(QtCore.QRect(0, 0, 461, 432)) + self.page_8.setObjectName("page_8") + self.gridLayout_4 = QtWidgets.QGridLayout(self.page_8) + self.gridLayout_4.setObjectName("gridLayout_4") + self.gridLayout_31 = QtWidgets.QGridLayout() + self.gridLayout_31.setObjectName("gridLayout_31") + self.usgs_chapter_comboBox = QtWidgets.QComboBox(self.page_8) + self.usgs_chapter_comboBox.setObjectName("usgs_chapter_comboBox") + self.gridLayout_31.addWidget(self.usgs_chapter_comboBox, 0, 1, 1, 1) + self.usgs_library_comboBox = QtWidgets.QComboBox(self.page_8) + self.usgs_library_comboBox.setObjectName("usgs_library_comboBox") + self.gridLayout_31.addWidget(self.usgs_library_comboBox, 1, 1, 1, 1) + self.gridLayout_14 = QtWidgets.QGridLayout() + self.gridLayout_14.setObjectName("gridLayout_14") + self.gridLayout_31.addLayout(self.gridLayout_14, 2, 1, 1, 1) + self.label_123 = QtWidgets.QLabel(self.page_8) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_141.sizePolicy().hasHeightForWidth()) - self.label_141.setSizePolicy(sizePolicy) - self.label_141.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_141.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_141.setObjectName("label_141") - self.gridLayout_145.addWidget(self.label_141, 1, 0, 1, 1) - self.gridLayout_143.addLayout(self.gridLayout_145, 0, 0, 1, 2) - self.gridLayout_296.addLayout(self.gridLayout_143, 3, 0, 1, 2) - spacerItem78 = QtWidgets.QSpacerItem(20, 173, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_296.addItem(spacerItem78, 4, 1, 1, 1) - self.gridLayout_257 = QtWidgets.QGridLayout() - self.gridLayout_257.setObjectName("gridLayout_257") - self.cloud_mask_toolButton = QtWidgets.QToolButton(self.tab_cloud_mask) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.cloud_mask_toolButton.setFont(font) - self.cloud_mask_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.cloud_mask_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.cloud_mask_toolButton.setIcon(icon64) - self.cloud_mask_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.cloud_mask_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.cloud_mask_toolButton.setObjectName("cloud_mask_toolButton") - self.gridLayout_257.addWidget(self.cloud_mask_toolButton, 1, 2, 1, 1) - self.cloud_masking = QtWidgets.QToolButton(self.tab_cloud_mask) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.cloud_masking.setFont(font) - self.cloud_masking.setLayoutDirection(QtCore.Qt.RightToLeft) - self.cloud_masking.setStyleSheet("margin: 0px;padding: 0px;") - self.cloud_masking.setIcon(icon48) - self.cloud_masking.setIconSize(QtCore.QSize(34, 34)) - self.cloud_masking.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.cloud_masking.setObjectName("cloud_masking") - self.gridLayout_257.addWidget(self.cloud_masking, 1, 1, 1, 1) - spacerItem79 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_257.addItem(spacerItem79, 1, 0, 1, 1) - self.label_185 = QtWidgets.QLabel(self.tab_cloud_mask) - self.label_185.setStyleSheet("background-color : #656565; color : white") - self.label_185.setFrameShape(QtWidgets.QFrame.Panel) - self.label_185.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_185.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_185.setObjectName("label_185") - self.gridLayout_257.addWidget(self.label_185, 0, 0, 1, 3) - self.gridLayout_296.addLayout(self.gridLayout_257, 5, 0, 1, 2) - self.horizontalLayout_33 = QtWidgets.QHBoxLayout() - self.horizontalLayout_33.setObjectName("horizontalLayout_33") - self.label_138 = QtWidgets.QLabel(self.tab_cloud_mask) - self.label_138.setStyleSheet("background-color : #656565; color : white") - self.label_138.setFrameShape(QtWidgets.QFrame.Panel) - self.label_138.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_138.setObjectName("label_138") - self.horizontalLayout_33.addWidget(self.label_138) - self.gridLayout_296.addLayout(self.horizontalLayout_33, 0, 0, 1, 2) - self.tabWidget_preprocessing.addTab(self.tab_cloud_mask, "") - self.tab_GOES = QtWidgets.QWidget() - self.tab_GOES.setObjectName("tab_GOES") - self.gridLayout_308 = QtWidgets.QGridLayout(self.tab_GOES) - self.gridLayout_308.setObjectName("gridLayout_308") - self.gridLayout_297 = QtWidgets.QGridLayout() - self.gridLayout_297.setObjectName("gridLayout_297") - self.gridLayout_298 = QtWidgets.QGridLayout() - self.gridLayout_298.setObjectName("gridLayout_298") - self.GOES_nodata_spinBox = QtWidgets.QSpinBox(self.tab_GOES) - self.GOES_nodata_spinBox.setMinimum(-999) - self.GOES_nodata_spinBox.setMaximum(100000) - self.GOES_nodata_spinBox.setObjectName("GOES_nodata_spinBox") - self.gridLayout_298.addWidget(self.GOES_nodata_spinBox, 0, 2, 1, 1) - self.GOES_nodata_checkBox = QtWidgets.QCheckBox(self.tab_GOES) - self.GOES_nodata_checkBox.setChecked(True) - self.GOES_nodata_checkBox.setObjectName("GOES_nodata_checkBox") - self.gridLayout_298.addWidget(self.GOES_nodata_checkBox, 0, 1, 1, 1) - spacerItem80 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_298.addItem(spacerItem80, 0, 0, 1, 1) - self.gridLayout_297.addLayout(self.gridLayout_298, 3, 1, 1, 2) - self.label_273 = QtWidgets.QLabel(self.tab_GOES) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_123.sizePolicy().hasHeightForWidth()) + self.label_123.setSizePolicy(sizePolicy) + self.label_123.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_123.setObjectName("label_123") + self.gridLayout_31.addWidget(self.label_123, 0, 0, 1, 1) + self.label_124 = QtWidgets.QLabel(self.page_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_124.sizePolicy().hasHeightForWidth()) + self.label_124.setSizePolicy(sizePolicy) + self.label_124.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_124.setObjectName("label_124") + self.gridLayout_31.addWidget(self.label_124, 1, 0, 1, 1) + self.gridLayout_12 = QtWidgets.QGridLayout() + self.gridLayout_12.setObjectName("gridLayout_12") + spacerItem17 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_12.addItem(spacerItem17, 0, 0, 1, 1) + self.label_130 = QtWidgets.QLabel(self.page_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_273.sizePolicy().hasHeightForWidth()) - self.label_273.setSizePolicy(sizePolicy) - self.label_273.setStyleSheet("background-color : #656565; color : white") - self.label_273.setFrameShape(QtWidgets.QFrame.Panel) - self.label_273.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_273.setObjectName("label_273") - self.gridLayout_297.addWidget(self.label_273, 0, 0, 1, 3) - self.GOES_create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_GOES) - self.GOES_create_bandset_checkBox.setChecked(True) - self.GOES_create_bandset_checkBox.setTristate(False) - self.GOES_create_bandset_checkBox.setObjectName("GOES_create_bandset_checkBox") - self.gridLayout_297.addWidget(self.GOES_create_bandset_checkBox, 4, 0, 1, 1) - self.label_274 = QtWidgets.QLabel(self.tab_GOES) + sizePolicy.setHeightForWidth(self.label_130.sizePolicy().hasHeightForWidth()) + self.label_130.setSizePolicy(sizePolicy) + self.label_130.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_130.setObjectName("label_130") + self.gridLayout_12.addWidget(self.label_130, 0, 1, 1, 1) + self.add_usgs_library_pushButton = QtWidgets.QToolButton(self.page_8) + self.add_usgs_library_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.add_usgs_library_pushButton.setIcon(icon57) + self.add_usgs_library_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_usgs_library_pushButton.setObjectName("add_usgs_library_pushButton") + self.gridLayout_12.addWidget(self.add_usgs_library_pushButton, 0, 2, 1, 1) + self.gridLayout_31.addLayout(self.gridLayout_12, 3, 0, 1, 2) + self.USGS_library_textBrowser = QtWidgets.QTextBrowser(self.page_8) + self.USGS_library_textBrowser.setFrameShape(QtWidgets.QFrame.Panel) + self.USGS_library_textBrowser.setFrameShadow(QtWidgets.QFrame.Sunken) + self.USGS_library_textBrowser.setOpenExternalLinks(True) + self.USGS_library_textBrowser.setObjectName("USGS_library_textBrowser") + self.gridLayout_31.addWidget(self.USGS_library_textBrowser, 5, 0, 1, 2) + self.label = QtWidgets.QLabel(self.page_8) + font = QtGui.QFont() + font.setPointSize(8) + self.label.setFont(font) + self.label.setFrameShape(QtWidgets.QFrame.Panel) + self.label.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label.setWordWrap(True) + self.label.setOpenExternalLinks(True) + self.label.setObjectName("label") + self.gridLayout_31.addWidget(self.label, 6, 0, 1, 2) + self.label_129 = QtWidgets.QLabel(self.page_8) + self.label_129.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_129.setFrameShape(QtWidgets.QFrame.Panel) + self.label_129.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_129.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_129.setObjectName("label_129") + self.gridLayout_31.addWidget(self.label_129, 4, 0, 1, 2) + self.gridLayout_4.addLayout(self.gridLayout_31, 0, 1, 1, 1) + self.toolBox_4.addItem(self.page_8, "") + self.page_9 = QtWidgets.QWidget() + self.page_9.setGeometry(QtCore.QRect(0, 0, 461, 169)) + self.page_9.setObjectName("page_9") + self.gridLayout_181 = QtWidgets.QGridLayout(self.page_9) + self.gridLayout_181.setObjectName("gridLayout_181") + self.gridLayout_178 = QtWidgets.QGridLayout() + self.gridLayout_178.setObjectName("gridLayout_178") + self.open_shapefile_pushButton = QtWidgets.QToolButton(self.page_9) + self.open_shapefile_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.open_shapefile_pushButton.setIcon(icon43) + self.open_shapefile_pushButton.setIconSize(QtCore.QSize(20, 20)) + self.open_shapefile_pushButton.setObjectName("open_shapefile_pushButton") + self.gridLayout_178.addWidget(self.open_shapefile_pushButton, 0, 2, 1, 1) + self.label_120 = QtWidgets.QLabel(self.page_9) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_274.sizePolicy().hasHeightForWidth()) - self.label_274.setSizePolicy(sizePolicy) - self.label_274.setMinimumSize(QtCore.QSize(229, 0)) - self.label_274.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_274.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_274.setObjectName("label_274") - self.gridLayout_297.addWidget(self.label_274, 2, 0, 1, 1) - self.gridLayout_299 = QtWidgets.QGridLayout() - self.gridLayout_299.setObjectName("gridLayout_299") - self.GOES_toolButton_directoryInput = QtWidgets.QToolButton(self.tab_GOES) - self.GOES_toolButton_directoryInput.setStyleSheet("margin: 0px;padding: 0px;") - self.GOES_toolButton_directoryInput.setIcon(icon69) - self.GOES_toolButton_directoryInput.setIconSize(QtCore.QSize(22, 22)) - self.GOES_toolButton_directoryInput.setObjectName("GOES_toolButton_directoryInput") - self.gridLayout_299.addWidget(self.GOES_toolButton_directoryInput, 0, 1, 1, 1) - self.GOES_label = QtWidgets.QLabel(self.tab_GOES) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) + sizePolicy.setHeightForWidth(self.label_120.sizePolicy().hasHeightForWidth()) + self.label_120.setSizePolicy(sizePolicy) + self.label_120.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_120.setObjectName("label_120") + self.gridLayout_178.addWidget(self.label_120, 0, 0, 1, 1) + self.gridLayout_179 = QtWidgets.QGridLayout() + self.gridLayout_179.setObjectName("gridLayout_179") + self.C_ID_combo = QtWidgets.QComboBox(self.page_9) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.C_ID_combo.sizePolicy().hasHeightForWidth()) + self.C_ID_combo.setSizePolicy(sizePolicy) + self.C_ID_combo.setObjectName("C_ID_combo") + self.gridLayout_179.addWidget(self.C_ID_combo, 2, 2, 1, 1) + self.MC_ID_combo = QtWidgets.QComboBox(self.page_9) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.MC_ID_combo.sizePolicy().hasHeightForWidth()) + self.MC_ID_combo.setSizePolicy(sizePolicy) + self.MC_ID_combo.setObjectName("MC_ID_combo") + self.gridLayout_179.addWidget(self.MC_ID_combo, 2, 0, 1, 1) + self.MC_Info_combo = QtWidgets.QComboBox(self.page_9) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.MC_Info_combo.sizePolicy().hasHeightForWidth()) + self.MC_Info_combo.setSizePolicy(sizePolicy) + self.MC_Info_combo.setObjectName("MC_Info_combo") + self.gridLayout_179.addWidget(self.MC_Info_combo, 2, 1, 1, 1) + self.label_99 = QtWidgets.QLabel(self.page_9) + self.label_99.setFrameShape(QtWidgets.QFrame.Panel) + self.label_99.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_99.setObjectName("label_99") + self.gridLayout_179.addWidget(self.label_99, 1, 3, 1, 1) + self.C_Info_combo = QtWidgets.QComboBox(self.page_9) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.GOES_label.sizePolicy().hasHeightForWidth()) - self.GOES_label.setSizePolicy(sizePolicy) - self.GOES_label.setFrameShape(QtWidgets.QFrame.Panel) - self.GOES_label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.GOES_label.setText("") - self.GOES_label.setObjectName("GOES_label") - self.gridLayout_299.addWidget(self.GOES_label, 0, 0, 1, 1) - self.gridLayout_297.addLayout(self.gridLayout_299, 2, 1, 1, 2) - self.add_new_bandset_checkBox_7 = QtWidgets.QCheckBox(self.tab_GOES) - self.add_new_bandset_checkBox_7.setChecked(True) - self.add_new_bandset_checkBox_7.setTristate(False) - self.add_new_bandset_checkBox_7.setObjectName("add_new_bandset_checkBox_7") - self.gridLayout_297.addWidget(self.add_new_bandset_checkBox_7, 4, 1, 1, 2) - self.gridLayout_308.addLayout(self.gridLayout_297, 0, 0, 1, 1) - self.gridLayout_304 = QtWidgets.QGridLayout() - self.gridLayout_304.setObjectName("gridLayout_304") - self.GOES_tableWidget = QtWidgets.QTableWidget(self.tab_GOES) - self.GOES_tableWidget.setTextElideMode(QtCore.Qt.ElideMiddle) - self.GOES_tableWidget.setObjectName("GOES_tableWidget") - self.GOES_tableWidget.setColumnCount(1) - self.GOES_tableWidget.setRowCount(0) + sizePolicy.setHeightForWidth(self.C_Info_combo.sizePolicy().hasHeightForWidth()) + self.C_Info_combo.setSizePolicy(sizePolicy) + self.C_Info_combo.setObjectName("C_Info_combo") + self.gridLayout_179.addWidget(self.C_Info_combo, 2, 3, 1, 1) + self.label_119 = QtWidgets.QLabel(self.page_9) + self.label_119.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_119.setFrameShape(QtWidgets.QFrame.Panel) + self.label_119.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_119.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_119.setObjectName("label_119") + self.gridLayout_179.addWidget(self.label_119, 0, 0, 1, 5) + self.MC_ID_combo_2 = QtWidgets.QLabel(self.page_9) + self.MC_ID_combo_2.setFrameShape(QtWidgets.QFrame.Panel) + self.MC_ID_combo_2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.MC_ID_combo_2.setObjectName("MC_ID_combo_2") + self.gridLayout_179.addWidget(self.MC_ID_combo_2, 1, 2, 1, 1) + self.label_121 = QtWidgets.QLabel(self.page_9) + self.label_121.setFrameShape(QtWidgets.QFrame.Panel) + self.label_121.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_121.setObjectName("label_121") + self.gridLayout_179.addWidget(self.label_121, 1, 0, 1, 1) + self.label_122 = QtWidgets.QLabel(self.page_9) + self.label_122.setFrameShape(QtWidgets.QFrame.Panel) + self.label_122.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_122.setObjectName("label_122") + self.gridLayout_179.addWidget(self.label_122, 1, 1, 1, 1) + self.gridLayout_178.addLayout(self.gridLayout_179, 3, 0, 1, 3) + spacerItem18 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_178.addItem(spacerItem18, 5, 0, 1, 1) + self.gridLayout_180 = QtWidgets.QGridLayout() + self.gridLayout_180.setObjectName("gridLayout_180") + self.label_2 = QtWidgets.QLabel(self.page_9) + self.label_2.setObjectName("label_2") + self.gridLayout_180.addWidget(self.label_2, 0, 2, 1, 1) + spacerItem19 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_180.addItem(spacerItem19, 0, 0, 1, 1) + self.signature_checkBox_2 = QtWidgets.QCheckBox(self.page_9) + self.signature_checkBox_2.setChecked(True) + self.signature_checkBox_2.setObjectName("signature_checkBox_2") + self.gridLayout_180.addWidget(self.signature_checkBox_2, 0, 1, 1, 1) + self.import_shapefile_pushButton = QtWidgets.QToolButton(self.page_9) + self.import_shapefile_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.import_shapefile_pushButton.setIcon(icon57) + self.import_shapefile_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.import_shapefile_pushButton.setObjectName("import_shapefile_pushButton") + self.gridLayout_180.addWidget(self.import_shapefile_pushButton, 0, 3, 1, 1) + self.gridLayout_178.addLayout(self.gridLayout_180, 4, 0, 1, 3) + self.select_shapefile_label = QtWidgets.QLabel(self.page_9) + self.select_shapefile_label.setFrameShape(QtWidgets.QFrame.Panel) + self.select_shapefile_label.setFrameShadow(QtWidgets.QFrame.Sunken) + self.select_shapefile_label.setText("") + self.select_shapefile_label.setObjectName("select_shapefile_label") + self.gridLayout_178.addWidget(self.select_shapefile_label, 0, 1, 1, 1) + self.gridLayout_181.addLayout(self.gridLayout_178, 0, 1, 1, 1) + self.toolBox_4.addItem(self.page_9, "") + self.page_6 = QtWidgets.QWidget() + self.page_6.setGeometry(QtCore.QRect(0, 0, 771, 53)) + self.page_6.setObjectName("page_6") + self.gridLayout_175 = QtWidgets.QGridLayout(self.page_6) + self.gridLayout_175.setObjectName("gridLayout_175") + self.gridLayout_174 = QtWidgets.QGridLayout() + self.gridLayout_174.setObjectName("gridLayout_174") + self.label_9 = QtWidgets.QLabel(self.page_6) + self.label_9.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_9.setObjectName("label_9") + self.gridLayout_174.addWidget(self.label_9, 0, 0, 1, 1) + self.open_library_pushButton = QtWidgets.QToolButton(self.page_6) + self.open_library_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.open_library_pushButton.setIcon(icon43) + self.open_library_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.open_library_pushButton.setObjectName("open_library_pushButton") + self.gridLayout_174.addWidget(self.open_library_pushButton, 0, 1, 1, 1) + spacerItem20 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_174.addItem(spacerItem20, 2, 0, 1, 1) + self.gridLayout_175.addLayout(self.gridLayout_174, 0, 0, 1, 1) + self.toolBox_4.addItem(self.page_6, "") + self.gridLayout_168.addWidget(self.toolBox_4, 0, 0, 1, 1) + self.tabWidget_5.addTab(self.tab_Import, "") + self.tab_export = QtWidgets.QWidget() + self.tab_export.setObjectName("tab_export") + self.gridLayout_142 = QtWidgets.QGridLayout(self.tab_export) + self.gridLayout_142.setObjectName("gridLayout_142") + self.gridLayout_176 = QtWidgets.QGridLayout() + self.gridLayout_176.setObjectName("gridLayout_176") + self.label_97 = QtWidgets.QLabel(self.tab_export) + self.label_97.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_97.setObjectName("label_97") + self.gridLayout_176.addWidget(self.label_97, 1, 0, 1, 1) + self.export_SCP_pushButton = QtWidgets.QToolButton(self.tab_export) + self.export_SCP_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + icon58 = QtGui.QIcon() + icon58.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.export_SCP_pushButton.setIcon(icon58) + self.export_SCP_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.export_SCP_pushButton.setObjectName("export_SCP_pushButton") + self.gridLayout_176.addWidget(self.export_SCP_pushButton, 1, 1, 1, 1) + self.export_CSV_library_toolButton = QtWidgets.QToolButton(self.tab_export) + self.export_CSV_library_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon59 = QtGui.QIcon() + icon59.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.export_CSV_library_toolButton.setIcon(icon59) + self.export_CSV_library_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.export_CSV_library_toolButton.setObjectName("export_CSV_library_toolButton") + self.gridLayout_176.addWidget(self.export_CSV_library_toolButton, 3, 1, 1, 1) + self.label_96 = QtWidgets.QLabel(self.tab_export) + self.label_96.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_96.setFrameShape(QtWidgets.QFrame.Panel) + self.label_96.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_96.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_96.setObjectName("label_96") + self.gridLayout_176.addWidget(self.label_96, 0, 0, 1, 2) + self.label_222 = QtWidgets.QLabel(self.tab_export) + self.label_222.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_222.setObjectName("label_222") + self.gridLayout_176.addWidget(self.label_222, 2, 0, 1, 1) + self.label_20 = QtWidgets.QLabel(self.tab_export) + self.label_20.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_20.setObjectName("label_20") + self.gridLayout_176.addWidget(self.label_20, 3, 0, 1, 1) + self.export_SHP_pushButton = QtWidgets.QToolButton(self.tab_export) + self.export_SHP_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.export_SHP_pushButton.setIcon(icon58) + self.export_SHP_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.export_SHP_pushButton.setObjectName("export_SHP_pushButton") + self.gridLayout_176.addWidget(self.export_SHP_pushButton, 2, 1, 1, 1) + spacerItem21 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_176.addItem(spacerItem21, 4, 0, 1, 1) + self.gridLayout_142.addLayout(self.gridLayout_176, 0, 0, 1, 1) + self.tabWidget_5.addTab(self.tab_export, "") + self.tab_threshold = QtWidgets.QWidget() + self.tab_threshold.setObjectName("tab_threshold") + self.gridLayout_177 = QtWidgets.QGridLayout(self.tab_threshold) + self.gridLayout_177.setObjectName("gridLayout_177") + self.gridLayout_110 = QtWidgets.QGridLayout() + self.gridLayout_110.setObjectName("gridLayout_110") + self.gridLayout_161 = QtWidgets.QGridLayout() + self.gridLayout_161.setObjectName("gridLayout_161") + self.gridLayout_198 = QtWidgets.QGridLayout() + self.gridLayout_198.setObjectName("gridLayout_198") + spacerItem22 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_198.addItem(spacerItem22, 0, 0, 1, 1) + self.gridLayout_161.addLayout(self.gridLayout_198, 0, 0, 1, 1) + spacerItem23 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_161.addItem(spacerItem23, 3, 0, 1, 1) + self.gridLayout_129 = QtWidgets.QGridLayout() + self.gridLayout_129.setObjectName("gridLayout_129") + self.reset_threshold_pushButton = QtWidgets.QToolButton(self.tab_threshold) + self.reset_threshold_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.reset_threshold_pushButton.setIcon(icon45) + self.reset_threshold_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.reset_threshold_pushButton.setObjectName("reset_threshold_pushButton") + self.gridLayout_129.addWidget(self.reset_threshold_pushButton, 0, 0, 1, 1) + self.gridLayout_161.addLayout(self.gridLayout_129, 1, 0, 1, 1) + self.gridLayout_110.addLayout(self.gridLayout_161, 1, 1, 1, 1) + self.signature_threshold_tableWidget = QtWidgets.QTableWidget(self.tab_threshold) + self.signature_threshold_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.signature_threshold_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) + self.signature_threshold_tableWidget.setObjectName("signature_threshold_tableWidget") + self.signature_threshold_tableWidget.setColumnCount(7) + self.signature_threshold_tableWidget.setRowCount(0) item = QtWidgets.QTableWidgetItem() - self.GOES_tableWidget.setHorizontalHeaderItem(0, item) - self.GOES_tableWidget.horizontalHeader().setDefaultSectionSize(155) - self.GOES_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_304.addWidget(self.GOES_tableWidget, 1, 0, 1, 1) - self.gridLayout_305 = QtWidgets.QGridLayout() - self.gridLayout_305.setObjectName("gridLayout_305") - self.GOES_pushButton_remove_band = QtWidgets.QToolButton(self.tab_GOES) - self.GOES_pushButton_remove_band.setStyleSheet("margin: 0px;padding: 0px;") - self.GOES_pushButton_remove_band.setIcon(icon58) - self.GOES_pushButton_remove_band.setIconSize(QtCore.QSize(22, 22)) - self.GOES_pushButton_remove_band.setObjectName("GOES_pushButton_remove_band") - self.gridLayout_305.addWidget(self.GOES_pushButton_remove_band, 0, 0, 1, 1) - self.gridLayout_304.addLayout(self.gridLayout_305, 1, 1, 1, 1) - self.gridLayout_306 = QtWidgets.QGridLayout() - self.gridLayout_306.setObjectName("gridLayout_306") - self.label_277 = QtWidgets.QLabel(self.tab_GOES) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + self.signature_threshold_tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.signature_threshold_tableWidget.setHorizontalHeaderItem(6, item) + self.signature_threshold_tableWidget.horizontalHeader().setDefaultSectionSize(50) + self.signature_threshold_tableWidget.horizontalHeader().setStretchLastSection(True) + self.signature_threshold_tableWidget.verticalHeader().setDefaultSectionSize(22) + self.gridLayout_110.addWidget(self.signature_threshold_tableWidget, 1, 0, 1, 1) + self.gridLayout_109 = QtWidgets.QGridLayout() + self.gridLayout_109.setObjectName("gridLayout_109") + self.label_80 = QtWidgets.QLabel(self.tab_threshold) + self.label_80.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_80.setFrameShape(QtWidgets.QFrame.Panel) + self.label_80.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_80.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_80.setObjectName("label_80") + self.gridLayout_109.addWidget(self.label_80, 0, 0, 1, 1) + self.gridLayout_110.addLayout(self.gridLayout_109, 0, 0, 1, 2) + self.gridLayout_111 = QtWidgets.QGridLayout() + self.gridLayout_111.setObjectName("gridLayout_111") + self.label_85 = QtWidgets.QLabel(self.tab_threshold) + self.label_85.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_85.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_85.setObjectName("label_85") + self.gridLayout_111.addWidget(self.label_85, 1, 2, 1, 1) + self.multiplicative_threshold_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_threshold) + self.multiplicative_threshold_doubleSpinBox.setDecimals(1) + self.multiplicative_threshold_doubleSpinBox.setMaximum(10000.0) + self.multiplicative_threshold_doubleSpinBox.setProperty("value", 1.0) + self.multiplicative_threshold_doubleSpinBox.setObjectName("multiplicative_threshold_doubleSpinBox") + self.gridLayout_111.addWidget(self.multiplicative_threshold_doubleSpinBox, 1, 3, 1, 1) + self.automatic_threshold_pushButton = QtWidgets.QToolButton(self.tab_threshold) + self.automatic_threshold_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.automatic_threshold_pushButton.setIcon(icon57) + self.automatic_threshold_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.automatic_threshold_pushButton.setObjectName("automatic_threshold_pushButton") + self.gridLayout_111.addWidget(self.automatic_threshold_pushButton, 1, 4, 1, 1) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.label_132 = QtWidgets.QLabel(self.tab_threshold) + self.label_132.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_132.setObjectName("label_132") + self.horizontalLayout_3.addWidget(self.label_132) + self.threshold_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_threshold) + self.threshold_doubleSpinBox.setDecimals(4) + self.threshold_doubleSpinBox.setMaximum(10000.0) + self.threshold_doubleSpinBox.setProperty("value", 0.0) + self.threshold_doubleSpinBox.setObjectName("threshold_doubleSpinBox") + self.horizontalLayout_3.addWidget(self.threshold_doubleSpinBox) + self.set_threshold_value_pushButton = QtWidgets.QToolButton(self.tab_threshold) + self.set_threshold_value_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.set_threshold_value_pushButton.setIcon(icon57) + self.set_threshold_value_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.set_threshold_value_pushButton.setObjectName("set_threshold_value_pushButton") + self.horizontalLayout_3.addWidget(self.set_threshold_value_pushButton) + self.gridLayout_111.addLayout(self.horizontalLayout_3, 1, 0, 1, 1) + spacerItem24 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_111.addItem(spacerItem24, 1, 1, 1, 1) + spacerItem25 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_111.addItem(spacerItem25, 1, 5, 1, 1) + self.label_88 = QtWidgets.QLabel(self.tab_threshold) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_277.sizePolicy().hasHeightForWidth()) - self.label_277.setSizePolicy(sizePolicy) - self.label_277.setStyleSheet("background-color : #656565; color : white") - self.label_277.setFrameShape(QtWidgets.QFrame.Panel) - self.label_277.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_277.setObjectName("label_277") - self.gridLayout_306.addWidget(self.label_277, 0, 0, 1, 4) - self.satellite_label_20 = QtWidgets.QLabel(self.tab_GOES) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_88.sizePolicy().hasHeightForWidth()) + self.label_88.setSizePolicy(sizePolicy) + self.label_88.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_88.setFrameShape(QtWidgets.QFrame.Panel) + self.label_88.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_88.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_88.setObjectName("label_88") + self.gridLayout_111.addWidget(self.label_88, 0, 0, 1, 6) + self.gridLayout_110.addLayout(self.gridLayout_111, 2, 0, 1, 2) + self.gridLayout_177.addLayout(self.gridLayout_110, 0, 0, 1, 1) + self.tabWidget_5.addTab(self.tab_threshold, "") + self.gridLayout_216.addWidget(self.tabWidget_5, 0, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_basic_tools, "") + self.tab_preprocessing = QtWidgets.QWidget() + self.tab_preprocessing.setStyleSheet("") + self.tab_preprocessing.setObjectName("tab_preprocessing") + self.gridLayout_6 = QtWidgets.QGridLayout(self.tab_preprocessing) + self.gridLayout_6.setContentsMargins(3, 3, 3, 3) + self.gridLayout_6.setObjectName("gridLayout_6") + self.tabWidget_preprocessing = QtWidgets.QTabWidget(self.tab_preprocessing) + self.tabWidget_preprocessing.setStyleSheet("") + self.tabWidget_preprocessing.setIconSize(QtCore.QSize(20, 20)) + self.tabWidget_preprocessing.setDocumentMode(True) + self.tabWidget_preprocessing.setObjectName("tabWidget_preprocessing") + self.tab_Landsat = QtWidgets.QWidget() + self.tab_Landsat.setObjectName("tab_Landsat") + self.gridLayout_18 = QtWidgets.QGridLayout(self.tab_Landsat) + self.gridLayout_18.setObjectName("gridLayout_18") + self.gridLayout_37 = QtWidgets.QGridLayout() + self.gridLayout_37.setObjectName("gridLayout_37") + self.label_36 = QtWidgets.QLabel(self.tab_Landsat) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.satellite_label_20.sizePolicy().hasHeightForWidth()) - self.satellite_label_20.setSizePolicy(sizePolicy) - self.satellite_label_20.setFrameShadow(QtWidgets.QFrame.Sunken) - self.satellite_label_20.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.satellite_label_20.setObjectName("satellite_label_20") - self.gridLayout_306.addWidget(self.satellite_label_20, 1, 0, 1, 1) - self.GOES_satellite_lineEdit = QtWidgets.QLineEdit(self.tab_GOES) - self.GOES_satellite_lineEdit.setObjectName("GOES_satellite_lineEdit") - self.gridLayout_306.addWidget(self.GOES_satellite_lineEdit, 1, 1, 1, 1) - spacerItem81 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_306.addItem(spacerItem81, 1, 2, 1, 1) - self.gridLayout_304.addLayout(self.gridLayout_306, 0, 0, 1, 2) - self.gridLayout_307 = QtWidgets.QGridLayout() - self.gridLayout_307.setObjectName("gridLayout_307") - spacerItem82 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_307.addItem(spacerItem82, 1, 1, 1, 1) - self.label_278 = QtWidgets.QLabel(self.tab_GOES) - self.label_278.setStyleSheet("background-color : #656565; color : white") - self.label_278.setFrameShape(QtWidgets.QFrame.Panel) - self.label_278.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_278.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_278.setObjectName("label_278") - self.gridLayout_307.addWidget(self.label_278, 0, 1, 1, 3) - self.pushButton_Conversion_8 = QtWidgets.QToolButton(self.tab_GOES) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.pushButton_Conversion_8.setFont(font) - self.pushButton_Conversion_8.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pushButton_Conversion_8.setStyleSheet("margin: 0px;padding: 0px;") - self.pushButton_Conversion_8.setIcon(icon64) - self.pushButton_Conversion_8.setIconSize(QtCore.QSize(34, 34)) - self.pushButton_Conversion_8.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pushButton_Conversion_8.setObjectName("pushButton_Conversion_8") - self.gridLayout_307.addWidget(self.pushButton_Conversion_8, 1, 3, 1, 1) - self.goes_conversion = QtWidgets.QToolButton(self.tab_GOES) + sizePolicy.setHeightForWidth(self.label_36.sizePolicy().hasHeightForWidth()) + self.label_36.setSizePolicy(sizePolicy) + self.label_36.setMinimumSize(QtCore.QSize(229, 0)) font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.goes_conversion.setFont(font) - self.goes_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.goes_conversion.setStyleSheet("margin: 0px;padding: 0px;") - self.goes_conversion.setIcon(icon48) - self.goes_conversion.setIconSize(QtCore.QSize(34, 34)) - self.goes_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.goes_conversion.setObjectName("goes_conversion") - self.gridLayout_307.addWidget(self.goes_conversion, 1, 2, 1, 1) - self.gridLayout_304.addLayout(self.gridLayout_307, 2, 0, 1, 2) - self.gridLayout_308.addLayout(self.gridLayout_304, 1, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_GOES, "") - self.tab_neighbor_pixels = QtWidgets.QWidget() - self.tab_neighbor_pixels.setObjectName("tab_neighbor_pixels") - self.gridLayout_310 = QtWidgets.QGridLayout(self.tab_neighbor_pixels) - self.gridLayout_310.setObjectName("gridLayout_310") - self.gridLayout_240 = QtWidgets.QGridLayout() - self.gridLayout_240.setObjectName("gridLayout_240") - self.label_283 = QtWidgets.QLabel(self.tab_neighbor_pixels) - self.label_283.setStyleSheet("background-color : #656565; color : white") - self.label_283.setFrameShape(QtWidgets.QFrame.Panel) - self.label_283.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_283.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_283.setObjectName("label_283") - self.gridLayout_240.addWidget(self.label_283, 8, 0, 1, 3) - self.gridLayout_309 = QtWidgets.QGridLayout() - self.gridLayout_309.setObjectName("gridLayout_309") - self.label_287 = QtWidgets.QLabel(self.tab_neighbor_pixels) + font.setBold(False) + font.setWeight(50) + self.label_36.setFont(font) + self.label_36.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_36.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_36.setObjectName("label_36") + self.gridLayout_37.addWidget(self.label_36, 1, 0, 1, 1) + self.label_37 = QtWidgets.QLabel(self.tab_Landsat) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_287.sizePolicy().hasHeightForWidth()) - self.label_287.setSizePolicy(sizePolicy) - self.label_287.setFrameShape(QtWidgets.QFrame.Panel) - self.label_287.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_287.setText("") - self.label_287.setObjectName("label_287") - self.gridLayout_309.addWidget(self.label_287, 0, 1, 1, 1) - self.label_281 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy.setHeightForWidth(self.label_37.sizePolicy().hasHeightForWidth()) + self.label_37.setSizePolicy(sizePolicy) + self.label_37.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_37.setFrameShape(QtWidgets.QFrame.Panel) + self.label_37.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_37.setObjectName("label_37") + self.gridLayout_37.addWidget(self.label_37, 0, 0, 1, 4) + self.label_41 = QtWidgets.QLabel(self.tab_Landsat) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_281.sizePolicy().hasHeightForWidth()) - self.label_281.setSizePolicy(sizePolicy) - self.label_281.setMinimumSize(QtCore.QSize(229, 0)) - font = QtGui.QFont() - font.setBold(False) - font.setWeight(50) - self.label_281.setFont(font) - self.label_281.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_281.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_281.setObjectName("label_281") - self.gridLayout_309.addWidget(self.label_281, 0, 0, 1, 1) - self.toolButton_input_matrix = QtWidgets.QToolButton(self.tab_neighbor_pixels) - self.toolButton_input_matrix.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_input_matrix.setIcon(icon65) - self.toolButton_input_matrix.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_input_matrix.setObjectName("toolButton_input_matrix") - self.gridLayout_309.addWidget(self.toolButton_input_matrix, 0, 2, 1, 1) - self.horizontalLayout_71 = QtWidgets.QHBoxLayout() - self.horizontalLayout_71.setObjectName("horizontalLayout_71") - self.label_279 = QtWidgets.QLabel(self.tab_neighbor_pixels) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_41.sizePolicy().hasHeightForWidth()) + self.label_41.setSizePolicy(sizePolicy) + self.label_41.setMinimumSize(QtCore.QSize(229, 0)) + self.label_41.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_41.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_41.setObjectName("label_41") + self.gridLayout_37.addWidget(self.label_41, 2, 0, 1, 1) + self.toolButton_directoryInput = QtWidgets.QToolButton(self.tab_Landsat) + self.toolButton_directoryInput.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_directoryInput.setIcon(icon59) + self.toolButton_directoryInput.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_directoryInput.setObjectName("toolButton_directoryInput") + self.gridLayout_37.addWidget(self.toolButton_directoryInput, 1, 3, 1, 1) + self.label_26 = QtWidgets.QLabel(self.tab_Landsat) + self.label_26.setFrameShape(QtWidgets.QFrame.Panel) + self.label_26.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_26.setText("") + self.label_26.setObjectName("label_26") + self.gridLayout_37.addWidget(self.label_26, 1, 1, 1, 2) + self.label_27 = QtWidgets.QLabel(self.tab_Landsat) + self.label_27.setFrameShape(QtWidgets.QFrame.Panel) + self.label_27.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_27.setText("") + self.label_27.setObjectName("label_27") + self.gridLayout_37.addWidget(self.label_27, 2, 1, 1, 2) + self.gridLayout_183 = QtWidgets.QGridLayout() + self.gridLayout_183.setObjectName("gridLayout_183") + self.create_bandset_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) + self.create_bandset_checkBox.setChecked(True) + self.create_bandset_checkBox.setTristate(False) + self.create_bandset_checkBox.setObjectName("create_bandset_checkBox") + self.gridLayout_183.addWidget(self.create_bandset_checkBox, 1, 0, 1, 1) + spacerItem26 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_183.addItem(spacerItem26, 1, 2, 1, 1) + self.DOS1_checkBox = QtWidgets.QCheckBox(self.tab_Landsat) + self.DOS1_checkBox.setChecked(False) + self.DOS1_checkBox.setTristate(False) + self.DOS1_checkBox.setObjectName("DOS1_checkBox") + self.gridLayout_183.addWidget(self.DOS1_checkBox, 0, 0, 1, 1) + self.add_new_bandset_radioButton_1 = QtWidgets.QRadioButton(self.tab_Landsat) + self.add_new_bandset_radioButton_1.setChecked(True) + self.add_new_bandset_radioButton_1.setObjectName("add_new_bandset_radioButton_1") + self.gridLayout_183.addWidget(self.add_new_bandset_radioButton_1, 1, 1, 1, 1) + self.gridLayout_37.addLayout(self.gridLayout_183, 5, 0, 1, 4) + self.toolButton_directoryInput_MTL = QtWidgets.QToolButton(self.tab_Landsat) + self.toolButton_directoryInput_MTL.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_directoryInput_MTL.setIcon(icon43) + self.toolButton_directoryInput_MTL.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_directoryInput_MTL.setObjectName("toolButton_directoryInput_MTL") + self.gridLayout_37.addWidget(self.toolButton_directoryInput_MTL, 2, 3, 1, 1) + self.gridLayout_29 = QtWidgets.QGridLayout() + self.gridLayout_29.setObjectName("gridLayout_29") + self.nodata_spinBox_3 = QtWidgets.QSpinBox(self.tab_Landsat) + self.nodata_spinBox_3.setMinimum(-999) + self.nodata_spinBox_3.setMaximum(100000) + self.nodata_spinBox_3.setObjectName("nodata_spinBox_3") + self.gridLayout_29.addWidget(self.nodata_spinBox_3, 0, 1, 1, 1) + self.nodata_checkBox_2 = QtWidgets.QCheckBox(self.tab_Landsat) + self.nodata_checkBox_2.setChecked(True) + self.nodata_checkBox_2.setObjectName("nodata_checkBox_2") + self.gridLayout_29.addWidget(self.nodata_checkBox_2, 0, 0, 1, 1) + spacerItem27 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_29.addItem(spacerItem27, 0, 2, 1, 1) + self.gridLayout_37.addLayout(self.gridLayout_29, 4, 0, 1, 4) + self.gridLayout_18.addLayout(self.gridLayout_37, 0, 0, 1, 1) + self.gridLayout_95 = QtWidgets.QGridLayout() + self.gridLayout_95.setObjectName("gridLayout_95") + self.bands_tableWidget = QtWidgets.QTableWidget(self.tab_Landsat) + self.bands_tableWidget.setWordWrap(False) + self.bands_tableWidget.setObjectName("bands_tableWidget") + self.bands_tableWidget.setColumnCount(15) + self.bands_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(6, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(7, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(8, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(9, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(10, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(11, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(12, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(13, item) + item = QtWidgets.QTableWidgetItem() + self.bands_tableWidget.setHorizontalHeaderItem(14, item) + self.bands_tableWidget.horizontalHeader().setDefaultSectionSize(155) + self.gridLayout_95.addWidget(self.bands_tableWidget, 1, 0, 1, 1) + self.gridLayout_15 = QtWidgets.QGridLayout() + self.gridLayout_15.setObjectName("gridLayout_15") + self.pushButton_remove_band = QtWidgets.QToolButton(self.tab_Landsat) + self.pushButton_remove_band.setStyleSheet("margin: 0px;padding: 0px;") + self.pushButton_remove_band.setIcon(icon41) + self.pushButton_remove_band.setIconSize(QtCore.QSize(22, 22)) + self.pushButton_remove_band.setObjectName("pushButton_remove_band") + self.gridLayout_15.addWidget(self.pushButton_remove_band, 0, 0, 1, 1) + self.gridLayout_95.addLayout(self.gridLayout_15, 1, 1, 1, 1) + self.gridLayout_98 = QtWidgets.QGridLayout() + self.gridLayout_98.setObjectName("gridLayout_98") + self.label_74 = QtWidgets.QLabel(self.tab_Landsat) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_279.sizePolicy().hasHeightForWidth()) - self.label_279.setSizePolicy(sizePolicy) - self.label_279.setMinimumSize(QtCore.QSize(229, 0)) - self.label_279.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_279.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_279.setObjectName("label_279") - self.horizontalLayout_71.addWidget(self.label_279) - self.neighbor_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_neighbor_pixels) - self.neighbor_output_name_lineEdit.setMaxLength(10) - self.neighbor_output_name_lineEdit.setObjectName("neighbor_output_name_lineEdit") - self.horizontalLayout_71.addWidget(self.neighbor_output_name_lineEdit) - self.gridLayout_309.addLayout(self.horizontalLayout_71, 2, 0, 1, 3) - self.neighbor_virtual_checkBox = QtWidgets.QCheckBox(self.tab_neighbor_pixels) - self.neighbor_virtual_checkBox.setObjectName("neighbor_virtual_checkBox") - self.gridLayout_309.addWidget(self.neighbor_virtual_checkBox, 1, 0, 1, 1) - self.gridLayout_240.addLayout(self.gridLayout_309, 2, 0, 1, 3) - self.neighbor_pixels = QtWidgets.QToolButton(self.tab_neighbor_pixels) + sizePolicy.setHeightForWidth(self.label_74.sizePolicy().hasHeightForWidth()) + self.label_74.setSizePolicy(sizePolicy) + self.label_74.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_74.setFrameShape(QtWidgets.QFrame.Panel) + self.label_74.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_74.setObjectName("label_74") + self.gridLayout_98.addWidget(self.label_74, 0, 0, 1, 2) + self.gridLayout_95.addLayout(self.gridLayout_98, 0, 0, 1, 2) + self.gridLayout_18.addLayout(self.gridLayout_95, 1, 0, 1, 1) + self.gridLayout_97 = QtWidgets.QGridLayout() + self.gridLayout_97.setObjectName("gridLayout_97") + spacerItem28 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_97.addItem(spacerItem28, 1, 1, 1, 1) + self.label_161 = QtWidgets.QLabel(self.tab_Landsat) + self.label_161.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_161.setFrameShape(QtWidgets.QFrame.Panel) + self.label_161.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_161.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_161.setObjectName("label_161") + self.gridLayout_97.addWidget(self.label_161, 0, 1, 1, 3) + self.pushButton_Conversion = QtWidgets.QToolButton(self.tab_Landsat) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.neighbor_pixels.setFont(font) - self.neighbor_pixels.setLayoutDirection(QtCore.Qt.RightToLeft) - self.neighbor_pixels.setStyleSheet("margin: 0px;padding: 0px;") - self.neighbor_pixels.setIcon(icon48) - self.neighbor_pixels.setIconSize(QtCore.QSize(34, 34)) - self.neighbor_pixels.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.neighbor_pixels.setObjectName("neighbor_pixels") - self.gridLayout_240.addWidget(self.neighbor_pixels, 9, 1, 1, 1) - spacerItem83 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_240.addItem(spacerItem83, 9, 0, 1, 1) - self.class_neighbor_toolButton = QtWidgets.QToolButton(self.tab_neighbor_pixels) + self.pushButton_Conversion.setFont(font) + self.pushButton_Conversion.setLayoutDirection(QtCore.Qt.RightToLeft) + self.pushButton_Conversion.setStyleSheet("margin: 0px;padding: 0px;") + self.pushButton_Conversion.setIcon(icon44) + self.pushButton_Conversion.setIconSize(QtCore.QSize(34, 34)) + self.pushButton_Conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.pushButton_Conversion.setObjectName("pushButton_Conversion") + self.gridLayout_97.addWidget(self.pushButton_Conversion, 1, 3, 1, 1) + self.landsat_conversion = QtWidgets.QToolButton(self.tab_Landsat) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.class_neighbor_toolButton.setFont(font) - self.class_neighbor_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.class_neighbor_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.class_neighbor_toolButton.setIcon(icon64) - self.class_neighbor_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.class_neighbor_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.class_neighbor_toolButton.setObjectName("class_neighbor_toolButton") - self.gridLayout_240.addWidget(self.class_neighbor_toolButton, 9, 2, 1, 1) - spacerItem84 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_240.addItem(spacerItem84, 7, 2, 1, 1) - self.horizontalLayout_70 = QtWidgets.QHBoxLayout() - self.horizontalLayout_70.setObjectName("horizontalLayout_70") - self.label_286 = QtWidgets.QLabel(self.tab_neighbor_pixels) - self.label_286.setStyleSheet("background-color : #656565; color : white") - self.label_286.setFrameShape(QtWidgets.QFrame.Panel) - self.label_286.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_286.setObjectName("label_286") - self.horizontalLayout_70.addWidget(self.label_286) - self.gridLayout_240.addLayout(self.horizontalLayout_70, 0, 0, 1, 3) - self.gridLayout_277 = QtWidgets.QGridLayout() - self.gridLayout_277.setObjectName("gridLayout_277") - self.statistic_lineEdit_2 = QtWidgets.QLineEdit(self.tab_neighbor_pixels) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + self.landsat_conversion.setFont(font) + self.landsat_conversion.setLayoutDirection(QtCore.Qt.RightToLeft) + self.landsat_conversion.setStyleSheet("margin: 0px;padding: 0px;") + self.landsat_conversion.setIcon(icon33) + self.landsat_conversion.setIconSize(QtCore.QSize(34, 34)) + self.landsat_conversion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.landsat_conversion.setObjectName("landsat_conversion") + self.gridLayout_97.addWidget(self.landsat_conversion, 1, 2, 1, 1) + self.gridLayout_18.addLayout(self.gridLayout_97, 2, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_Landsat, "") + self.tab_spectral_distance = QtWidgets.QWidget() + self.tab_spectral_distance.setObjectName("tab_spectral_distance") + self.gridLayout_61 = QtWidgets.QGridLayout(self.tab_spectral_distance) + self.gridLayout_61.setObjectName("gridLayout_61") + self.gridLayout_119 = QtWidgets.QGridLayout() + self.gridLayout_119.setObjectName("gridLayout_119") + self.label_142 = QtWidgets.QLabel(self.tab_spectral_distance) + self.label_142.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_142.setFrameShape(QtWidgets.QFrame.Panel) + self.label_142.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_142.setObjectName("label_142") + self.gridLayout_119.addWidget(self.label_142, 0, 0, 1, 1) + self.gridLayout_61.addLayout(self.gridLayout_119, 0, 0, 1, 1) + self.horizontalLayout_22 = QtWidgets.QHBoxLayout() + self.horizontalLayout_22.setObjectName("horizontalLayout_22") + self.label_64 = QtWidgets.QLabel(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.statistic_lineEdit_2.sizePolicy().hasHeightForWidth()) - self.statistic_lineEdit_2.setSizePolicy(sizePolicy) - self.statistic_lineEdit_2.setMaximumSize(QtCore.QSize(200, 16777215)) - self.statistic_lineEdit_2.setText("") - self.statistic_lineEdit_2.setMaxLength(10000) - self.statistic_lineEdit_2.setObjectName("statistic_lineEdit_2") - self.gridLayout_277.addWidget(self.statistic_lineEdit_2, 1, 2, 1, 1) - self.statistic_name_combobox_2 = QtWidgets.QComboBox(self.tab_neighbor_pixels) + sizePolicy.setHeightForWidth(self.label_64.sizePolicy().hasHeightForWidth()) + self.label_64.setSizePolicy(sizePolicy) + self.label_64.setMinimumSize(QtCore.QSize(229, 0)) + self.label_64.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_64.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_64.setObjectName("label_64") + self.horizontalLayout_22.addWidget(self.label_64) + self.vector_name_combo = QtWidgets.QComboBox(self.tab_spectral_distance) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.statistic_name_combobox_2.sizePolicy().hasHeightForWidth()) - self.statistic_name_combobox_2.setSizePolicy(sizePolicy) - self.statistic_name_combobox_2.setMaximumSize(QtCore.QSize(200, 16777215)) - self.statistic_name_combobox_2.setObjectName("statistic_name_combobox_2") - self.gridLayout_277.addWidget(self.statistic_name_combobox_2, 1, 1, 1, 1) - self.label_284 = QtWidgets.QLabel(self.tab_neighbor_pixels) - self.label_284.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_284.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_284.setObjectName("label_284") - self.gridLayout_277.addWidget(self.label_284, 1, 0, 1, 1) - spacerItem85 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_277.addItem(spacerItem85, 1, 3, 1, 1) - self.label_285 = QtWidgets.QLabel(self.tab_neighbor_pixels) - self.label_285.setStyleSheet("background-color : #656565; color : white") - self.label_285.setFrameShape(QtWidgets.QFrame.Panel) - self.label_285.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_285.setObjectName("label_285") - self.gridLayout_277.addWidget(self.label_285, 0, 0, 1, 4) - self.gridLayout_240.addLayout(self.gridLayout_277, 6, 0, 1, 3) - self.gridLayout_300 = QtWidgets.QGridLayout() - self.gridLayout_300.setObjectName("gridLayout_300") - self.label_282 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy.setHeightForWidth(self.vector_name_combo.sizePolicy().hasHeightForWidth()) + self.vector_name_combo.setSizePolicy(sizePolicy) + self.vector_name_combo.setObjectName("vector_name_combo") + self.horizontalLayout_22.addWidget(self.vector_name_combo) + self.toolButton_reload_16 = QtWidgets.QToolButton(self.tab_spectral_distance) + self.toolButton_reload_16.setStyleSheet("margin: 0px;padding: 0px;") + icon60 = QtGui.QIcon() + icon60.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.toolButton_reload_16.setIcon(icon60) + self.toolButton_reload_16.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_16.setObjectName("toolButton_reload_16") + self.horizontalLayout_22.addWidget(self.toolButton_reload_16) + self.gridLayout_61.addLayout(self.horizontalLayout_22, 1, 0, 1, 1) + self.horizontalLayout_20 = QtWidgets.QHBoxLayout() + self.horizontalLayout_20.setObjectName("horizontalLayout_20") + self.label_157 = QtWidgets.QLabel(self.tab_spectral_distance) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_282.sizePolicy().hasHeightForWidth()) - self.label_282.setSizePolicy(sizePolicy) - self.label_282.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_282.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_282.setObjectName("label_282") - self.gridLayout_300.addWidget(self.label_282, 0, 0, 1, 1) - self.label_280 = QtWidgets.QLabel(self.tab_neighbor_pixels) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) + sizePolicy.setHeightForWidth(self.label_157.sizePolicy().hasHeightForWidth()) + self.label_157.setSizePolicy(sizePolicy) + self.label_157.setMinimumSize(QtCore.QSize(229, 0)) + self.label_157.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_157.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_157.setObjectName("label_157") + self.horizontalLayout_20.addWidget(self.label_157) + self.conversion_type_combo = QtWidgets.QComboBox(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_280.sizePolicy().hasHeightForWidth()) - self.label_280.setSizePolicy(sizePolicy) - self.label_280.setMinimumSize(QtCore.QSize(229, 0)) - self.label_280.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_280.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_280.setObjectName("label_280") - self.gridLayout_300.addWidget(self.label_280, 1, 0, 1, 1) - self.band_set_comb_spinBox_15 = QtWidgets.QSpinBox(self.tab_neighbor_pixels) - self.band_set_comb_spinBox_15.setMinimum(1) - self.band_set_comb_spinBox_15.setMaximum(100000) - self.band_set_comb_spinBox_15.setObjectName("band_set_comb_spinBox_15") - self.gridLayout_300.addWidget(self.band_set_comb_spinBox_15, 0, 1, 1, 1) - self.class_neighbor_threshold_spinBox = QtWidgets.QSpinBox(self.tab_neighbor_pixels) - self.class_neighbor_threshold_spinBox.setMinimum(1) - self.class_neighbor_threshold_spinBox.setMaximum(1000) - self.class_neighbor_threshold_spinBox.setProperty("value", 1) - self.class_neighbor_threshold_spinBox.setObjectName("class_neighbor_threshold_spinBox") - self.gridLayout_300.addWidget(self.class_neighbor_threshold_spinBox, 1, 1, 1, 1) - spacerItem86 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_300.addItem(spacerItem86, 1, 3, 1, 1) - self.circular_structure_checkBox = QtWidgets.QCheckBox(self.tab_neighbor_pixels) - self.circular_structure_checkBox.setObjectName("circular_structure_checkBox") - self.gridLayout_300.addWidget(self.circular_structure_checkBox, 1, 2, 1, 1) - self.gridLayout_240.addLayout(self.gridLayout_300, 1, 0, 1, 3) - self.horizontalLayout_72 = QtWidgets.QHBoxLayout() - self.horizontalLayout_72.setObjectName("horizontalLayout_72") - spacerItem87 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_72.addItem(spacerItem87) - self.gridLayout_240.addLayout(self.horizontalLayout_72, 3, 0, 1, 3) - self.gridLayout_310.addLayout(self.gridLayout_240, 0, 0, 1, 1) - self.tabWidget_preprocessing.addTab(self.tab_neighbor_pixels, "") - self.gridLayout_6.addWidget(self.tabWidget_preprocessing, 0, 0, 1, 1) - self.SCP_tabs.addTab(self.tab_preprocessing, "") - self.tab_band_processing = QtWidgets.QWidget() - self.tab_band_processing.setObjectName("tab_band_processing") - self.gridLayout_163 = QtWidgets.QGridLayout(self.tab_band_processing) - self.gridLayout_163.setObjectName("gridLayout_163") - self.tabWidget_4 = QtWidgets.QTabWidget(self.tab_band_processing) - self.tabWidget_4.setStyleSheet("") - self.tabWidget_4.setIconSize(QtCore.QSize(20, 20)) - self.tabWidget_4.setDocumentMode(True) - self.tabWidget_4.setObjectName("tabWidget_4") - self.tab_bandset_combination_2 = QtWidgets.QWidget() - self.tab_bandset_combination_2.setObjectName("tab_bandset_combination_2") - self.gridLayout_62 = QtWidgets.QGridLayout(self.tab_bandset_combination_2) - self.gridLayout_62.setObjectName("gridLayout_62") - self.toolBox_band_set_combination = QtWidgets.QToolBox(self.tab_bandset_combination_2) - self.toolBox_band_set_combination.setObjectName("toolBox_band_set_combination") - self.page_29 = QtWidgets.QWidget() - self.page_29.setGeometry(QtCore.QRect(0, 0, 723, 351)) - self.page_29.setObjectName("page_29") - self.gridLayout_330 = QtWidgets.QGridLayout(self.page_29) - self.gridLayout_330.setObjectName("gridLayout_330") - self.gridLayout_333 = QtWidgets.QGridLayout() - self.gridLayout_333.setObjectName("gridLayout_333") - spacerItem88 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_333.addItem(spacerItem88, 0, 2, 1, 1) - spacerItem89 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_333.addItem(spacerItem89, 2, 0, 1, 1) - self.label_253 = QtWidgets.QLabel(self.page_29) - self.label_253.setStyleSheet("background-color : #656565; color : white") - self.label_253.setFrameShape(QtWidgets.QFrame.Panel) - self.label_253.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_253.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_253.setObjectName("label_253") - self.gridLayout_333.addWidget(self.label_253, 1, 0, 1, 3) - self.calculateBandSetComb_toolButton = QtWidgets.QToolButton(self.page_29) + sizePolicy.setHeightForWidth(self.conversion_type_combo.sizePolicy().hasHeightForWidth()) + self.conversion_type_combo.setSizePolicy(sizePolicy) + self.conversion_type_combo.setObjectName("conversion_type_combo") + self.conversion_type_combo.addItem("") + self.conversion_type_combo.addItem("") + self.conversion_type_combo.addItem("") + self.horizontalLayout_20.addWidget(self.conversion_type_combo) + spacerItem29 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_20.addItem(spacerItem29) + self.label_158 = QtWidgets.QLabel(self.tab_spectral_distance) + self.label_158.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_158.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_158.setObjectName("label_158") + self.horizontalLayout_20.addWidget(self.label_158) + self.area_precision_lineEdit = QtWidgets.QLineEdit(self.tab_spectral_distance) + self.area_precision_lineEdit.setObjectName("area_precision_lineEdit") + self.horizontalLayout_20.addWidget(self.area_precision_lineEdit) + self.gridLayout_61.addLayout(self.horizontalLayout_20, 5, 0, 1, 1) + self.horizontalLayout_47 = QtWidgets.QHBoxLayout() + self.horizontalLayout_47.setObjectName("horizontalLayout_47") + self.nodata_checkBox_10 = QtWidgets.QCheckBox(self.tab_spectral_distance) + self.nodata_checkBox_10.setObjectName("nodata_checkBox_10") + self.horizontalLayout_47.addWidget(self.nodata_checkBox_10) + self.nodata_spinBox_12 = QtWidgets.QSpinBox(self.tab_spectral_distance) + self.nodata_spinBox_12.setMinimum(-2147483647) + self.nodata_spinBox_12.setMaximum(2147483647) + self.nodata_spinBox_12.setObjectName("nodata_spinBox_12") + self.horizontalLayout_47.addWidget(self.nodata_spinBox_12) + spacerItem30 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_47.addItem(spacerItem30) + self.gridLayout_61.addLayout(self.horizontalLayout_47, 6, 0, 1, 1) + self.horizontalLayout_25 = QtWidgets.QHBoxLayout() + self.horizontalLayout_25.setObjectName("horizontalLayout_25") + self.constant_value_radioButton = QtWidgets.QRadioButton(self.tab_spectral_distance) + self.constant_value_radioButton.setObjectName("constant_value_radioButton") + self.horizontalLayout_25.addWidget(self.constant_value_radioButton) + self.constant_value_spinBox = QtWidgets.QSpinBox(self.tab_spectral_distance) + self.constant_value_spinBox.setMinimum(-100000) + self.constant_value_spinBox.setMaximum(100000) + self.constant_value_spinBox.setProperty("value", 1) + self.constant_value_spinBox.setObjectName("constant_value_spinBox") + self.horizontalLayout_25.addWidget(self.constant_value_spinBox) + spacerItem31 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_25.addItem(spacerItem31) + self.gridLayout_61.addLayout(self.horizontalLayout_25, 3, 0, 1, 1) + self.horizontalLayout_19 = QtWidgets.QHBoxLayout() + self.horizontalLayout_19.setObjectName("horizontalLayout_19") + self.field_radioButton = QtWidgets.QRadioButton(self.tab_spectral_distance) + self.field_radioButton.setChecked(True) + self.field_radioButton.setObjectName("field_radioButton") + self.horizontalLayout_19.addWidget(self.field_radioButton) + self.field_comboBox = QtWidgets.QComboBox(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.field_comboBox.sizePolicy().hasHeightForWidth()) + self.field_comboBox.setSizePolicy(sizePolicy) + self.field_comboBox.setObjectName("field_comboBox") + self.horizontalLayout_19.addWidget(self.field_comboBox) + self.gridLayout_61.addLayout(self.horizontalLayout_19, 2, 0, 1, 1) + self.gridLayout_194 = QtWidgets.QGridLayout() + self.gridLayout_194.setObjectName("gridLayout_194") + self.label_156 = QtWidgets.QLabel(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_156.sizePolicy().hasHeightForWidth()) + self.label_156.setSizePolicy(sizePolicy) + self.label_156.setMinimumSize(QtCore.QSize(229, 0)) + self.label_156.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_156.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_156.setObjectName("label_156") + self.gridLayout_194.addWidget(self.label_156, 0, 0, 1, 1) + self.extent_checkBox_2 = QtWidgets.QCheckBox(self.tab_spectral_distance) + self.extent_checkBox_2.setChecked(True) + self.extent_checkBox_2.setObjectName("extent_checkBox_2") + self.gridLayout_194.addWidget(self.extent_checkBox_2, 2, 0, 1, 1) + self.toolButton_reload_17 = QtWidgets.QToolButton(self.tab_spectral_distance) + self.toolButton_reload_17.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_17.setIcon(icon60) + self.toolButton_reload_17.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_17.setObjectName("toolButton_reload_17") + self.gridLayout_194.addWidget(self.toolButton_reload_17, 0, 3, 1, 1) + self.label_169 = QtWidgets.QLabel(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_169.sizePolicy().hasHeightForWidth()) + self.label_169.setSizePolicy(sizePolicy) + self.label_169.setMinimumSize(QtCore.QSize(229, 0)) + self.label_169.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_169.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_169.setObjectName("label_169") + self.gridLayout_194.addWidget(self.label_169, 1, 0, 1, 1) + self.pixel_size_lineEdit = QtWidgets.QLineEdit(self.tab_spectral_distance) + self.pixel_size_lineEdit.setText("") + self.pixel_size_lineEdit.setObjectName("pixel_size_lineEdit") + self.gridLayout_194.addWidget(self.pixel_size_lineEdit, 1, 1, 1, 1) + self.reference_raster_name_combo = QtWidgets.QComboBox(self.tab_spectral_distance) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.reference_raster_name_combo.sizePolicy().hasHeightForWidth()) + self.reference_raster_name_combo.setSizePolicy(sizePolicy) + self.reference_raster_name_combo.setObjectName("reference_raster_name_combo") + self.gridLayout_194.addWidget(self.reference_raster_name_combo, 0, 1, 1, 2) + self.gridLayout_61.addLayout(self.gridLayout_194, 4, 0, 1, 1) + self.gridLayout_210 = QtWidgets.QGridLayout() + self.gridLayout_210.setObjectName("gridLayout_210") + spacerItem32 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_210.addItem(spacerItem32, 0, 2, 1, 1) + self.label_167 = QtWidgets.QLabel(self.tab_spectral_distance) + self.label_167.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_167.setFrameShape(QtWidgets.QFrame.Panel) + self.label_167.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_167.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_167.setObjectName("label_167") + self.gridLayout_210.addWidget(self.label_167, 1, 0, 1, 3) + spacerItem33 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_210.addItem(spacerItem33, 2, 0, 1, 1) + self.convert_vector_toolButton = QtWidgets.QToolButton(self.tab_spectral_distance) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.calculateBandSetComb_toolButton.setFont(font) - self.calculateBandSetComb_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.calculateBandSetComb_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculateBandSetComb_toolButton.setIcon(icon64) - self.calculateBandSetComb_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.calculateBandSetComb_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.calculateBandSetComb_toolButton.setObjectName("calculateBandSetComb_toolButton") - self.gridLayout_333.addWidget(self.calculateBandSetComb_toolButton, 2, 2, 1, 1) - self.band_combination = QtWidgets.QToolButton(self.page_29) + self.convert_vector_toolButton.setFont(font) + self.convert_vector_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.convert_vector_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.convert_vector_toolButton.setIcon(icon44) + self.convert_vector_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.convert_vector_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.convert_vector_toolButton.setObjectName("convert_vector_toolButton") + self.gridLayout_210.addWidget(self.convert_vector_toolButton, 2, 2, 1, 1) + self.vector_to_raster = QtWidgets.QToolButton(self.tab_spectral_distance) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.band_combination.setFont(font) - self.band_combination.setLayoutDirection(QtCore.Qt.RightToLeft) - self.band_combination.setStyleSheet("margin: 0px;padding: 0px;") - self.band_combination.setIcon(icon48) - self.band_combination.setIconSize(QtCore.QSize(34, 34)) - self.band_combination.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.band_combination.setObjectName("band_combination") - self.gridLayout_333.addWidget(self.band_combination, 2, 1, 1, 1) - self.gridLayout_330.addLayout(self.gridLayout_333, 2, 1, 1, 1) - self.gridLayout_331 = QtWidgets.QGridLayout() - self.gridLayout_331.setObjectName("gridLayout_331") - self.label_250 = QtWidgets.QLabel(self.page_29) + self.vector_to_raster.setFont(font) + self.vector_to_raster.setLayoutDirection(QtCore.Qt.RightToLeft) + self.vector_to_raster.setStyleSheet("margin: 0px;padding: 0px;") + self.vector_to_raster.setIcon(icon33) + self.vector_to_raster.setIconSize(QtCore.QSize(34, 34)) + self.vector_to_raster.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.vector_to_raster.setObjectName("vector_to_raster") + self.gridLayout_210.addWidget(self.vector_to_raster, 2, 1, 1, 1) + self.gridLayout_61.addLayout(self.gridLayout_210, 7, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_spectral_distance, "") + self.tab_clip = QtWidgets.QWidget() + self.tab_clip.setObjectName("tab_clip") + self.gridLayout_58 = QtWidgets.QGridLayout(self.tab_clip) + self.gridLayout_58.setObjectName("gridLayout_58") + self.gridLayout_51 = QtWidgets.QGridLayout() + self.gridLayout_51.setObjectName("gridLayout_51") + self.label_128 = QtWidgets.QLabel(self.tab_clip) + self.label_128.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_128.setFrameShape(QtWidgets.QFrame.Panel) + self.label_128.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_128.setObjectName("label_128") + self.gridLayout_51.addWidget(self.label_128, 0, 0, 1, 1) + self.gridLayout_58.addLayout(self.gridLayout_51, 0, 0, 1, 1) + self.gridLayout_24 = QtWidgets.QGridLayout() + self.gridLayout_24.setObjectName("gridLayout_24") + self.output_clip_name_lineEdit = QtWidgets.QLineEdit(self.tab_clip) + self.output_clip_name_lineEdit.setMaxLength(10) + self.output_clip_name_lineEdit.setObjectName("output_clip_name_lineEdit") + self.gridLayout_24.addWidget(self.output_clip_name_lineEdit, 1, 1, 1, 2) + self.clip_virtual_checkBox = QtWidgets.QCheckBox(self.tab_clip) + self.clip_virtual_checkBox.setObjectName("clip_virtual_checkBox") + self.gridLayout_24.addWidget(self.clip_virtual_checkBox, 2, 0, 1, 1) + self.label_62 = QtWidgets.QLabel(self.tab_clip) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_250.sizePolicy().hasHeightForWidth()) - self.label_250.setSizePolicy(sizePolicy) - self.label_250.setMinimumSize(QtCore.QSize(229, 0)) - self.label_250.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_250.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_250.setWordWrap(True) - self.label_250.setObjectName("label_250") - self.gridLayout_331.addWidget(self.label_250, 1, 0, 1, 2) - self.band_set_comb_spinBox = QtWidgets.QSpinBox(self.page_29) - self.band_set_comb_spinBox.setMinimum(1) - self.band_set_comb_spinBox.setMaximum(100000) - self.band_set_comb_spinBox.setObjectName("band_set_comb_spinBox") - self.gridLayout_331.addWidget(self.band_set_comb_spinBox, 1, 2, 1, 1) - spacerItem90 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_331.addItem(spacerItem90, 1, 3, 1, 1) - self.gridLayout_330.addLayout(self.gridLayout_331, 1, 1, 1, 1) - self.horizontalLayout_34 = QtWidgets.QHBoxLayout() - self.horizontalLayout_34.setObjectName("horizontalLayout_34") - self.label_72 = QtWidgets.QLabel(self.page_29) - self.label_72.setStyleSheet("background-color : #656565; color : white") - self.label_72.setFrameShape(QtWidgets.QFrame.Panel) - self.label_72.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_72.setObjectName("label_72") - self.horizontalLayout_34.addWidget(self.label_72) - self.gridLayout_330.addLayout(self.horizontalLayout_34, 0, 1, 1, 1) - self.toolBox_band_set_combination.addItem(self.page_29, "") - self.page_30 = QtWidgets.QWidget() - self.page_30.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_30.setObjectName("page_30") - self.gridLayout_334 = QtWidgets.QGridLayout(self.page_30) - self.gridLayout_334.setObjectName("gridLayout_334") - self.gridLayout_335 = QtWidgets.QGridLayout() - self.gridLayout_335.setObjectName("gridLayout_335") - self.band_set_comb_textBrowser = QtWidgets.QTextBrowser(self.page_30) + sizePolicy.setHeightForWidth(self.label_62.sizePolicy().hasHeightForWidth()) + self.label_62.setSizePolicy(sizePolicy) + self.label_62.setMinimumSize(QtCore.QSize(150, 0)) + self.label_62.setMaximumSize(QtCore.QSize(100, 16777215)) font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.band_set_comb_textBrowser.setFont(font) - self.band_set_comb_textBrowser.setTabChangesFocus(True) - self.band_set_comb_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.band_set_comb_textBrowser.setTabStopWidth(120) - self.band_set_comb_textBrowser.setOpenLinks(False) - self.band_set_comb_textBrowser.setObjectName("band_set_comb_textBrowser") - self.gridLayout_335.addWidget(self.band_set_comb_textBrowser, 0, 0, 1, 1) - self.gridLayout_334.addLayout(self.gridLayout_335, 0, 0, 1, 1) - self.toolBox_band_set_combination.addItem(self.page_30, "") - self.gridLayout_62.addWidget(self.toolBox_band_set_combination, 0, 0, 1, 1) - self.tabWidget_4.addTab(self.tab_bandset_combination_2, "") - self.PCA_tab = QtWidgets.QWidget() - self.PCA_tab.setObjectName("PCA_tab") - self.gridLayout_170 = QtWidgets.QGridLayout(self.PCA_tab) - self.gridLayout_170.setObjectName("gridLayout_170") - self.toolBox_PCA = QtWidgets.QToolBox(self.PCA_tab) - self.toolBox_PCA.setStyleSheet("") - self.toolBox_PCA.setObjectName("toolBox_PCA") - self.page_16 = QtWidgets.QWidget() - self.page_16.setGeometry(QtCore.QRect(0, 0, 459, 196)) - self.page_16.setObjectName("page_16") - self.gridLayout_182 = QtWidgets.QGridLayout(self.page_16) - self.gridLayout_182.setObjectName("gridLayout_182") - self.horizontalLayout_5 = QtWidgets.QHBoxLayout() - self.horizontalLayout_5.setObjectName("horizontalLayout_5") - self.label_58 = QtWidgets.QLabel(self.page_16) - self.label_58.setStyleSheet("background-color : #656565; color : white") - self.label_58.setFrameShape(QtWidgets.QFrame.Panel) - self.label_58.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_58.setObjectName("label_58") - self.horizontalLayout_5.addWidget(self.label_58) - self.gridLayout_182.addLayout(self.horizontalLayout_5, 0, 0, 1, 1) - self.gridLayout_173 = QtWidgets.QGridLayout() - self.gridLayout_173.setObjectName("gridLayout_173") - self.nodata_checkBox_4 = QtWidgets.QCheckBox(self.page_16) - self.nodata_checkBox_4.setObjectName("nodata_checkBox_4") - self.gridLayout_173.addWidget(self.nodata_checkBox_4, 2, 0, 1, 1) - self.num_comp_checkBox = QtWidgets.QCheckBox(self.page_16) - self.num_comp_checkBox.setObjectName("num_comp_checkBox") - self.gridLayout_173.addWidget(self.num_comp_checkBox, 1, 0, 1, 1) - self.nodata_spinBox_5 = QtWidgets.QSpinBox(self.page_16) - self.nodata_spinBox_5.setMinimum(-999999999) - self.nodata_spinBox_5.setMaximum(999999999) - self.nodata_spinBox_5.setProperty("value", 0) - self.nodata_spinBox_5.setObjectName("nodata_spinBox_5") - self.gridLayout_173.addWidget(self.nodata_spinBox_5, 2, 1, 1, 1) - spacerItem91 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_173.addItem(spacerItem91, 3, 4, 1, 1) - self.pca_Button = QtWidgets.QToolButton(self.page_16) + font.setBold(False) + font.setWeight(50) + self.label_62.setFont(font) + self.label_62.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_62.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_62.setObjectName("label_62") + self.gridLayout_24.addWidget(self.label_62, 1, 0, 1, 1) + self.band_set_comb_spinBox_2 = QtWidgets.QSpinBox(self.tab_clip) + self.band_set_comb_spinBox_2.setMinimum(1) + self.band_set_comb_spinBox_2.setMaximum(100000) + self.band_set_comb_spinBox_2.setObjectName("band_set_comb_spinBox_2") + self.gridLayout_24.addWidget(self.band_set_comb_spinBox_2, 0, 1, 1, 1) + self.label_251 = QtWidgets.QLabel(self.tab_clip) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_251.sizePolicy().hasHeightForWidth()) + self.label_251.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setBold(False) + font.setWeight(50) + self.label_251.setFont(font) + self.label_251.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_251.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_251.setObjectName("label_251") + self.gridLayout_24.addWidget(self.label_251, 0, 0, 1, 1) + self.gridLayout_58.addLayout(self.gridLayout_24, 1, 0, 1, 1) + self.gridLayout_20 = QtWidgets.QGridLayout() + self.gridLayout_20.setObjectName("gridLayout_20") + self.show_area_radioButton_3 = QtWidgets.QRadioButton(self.tab_clip) + self.show_area_radioButton_3.setChecked(True) + self.show_area_radioButton_3.setAutoExclusive(False) + self.show_area_radioButton_3.setObjectName("show_area_radioButton_3") + self.gridLayout_20.addWidget(self.show_area_radioButton_3, 1, 10, 1, 1) + self.LY_lineEdit = QtWidgets.QLineEdit(self.tab_clip) + self.LY_lineEdit.setMaxLength(10) + self.LY_lineEdit.setObjectName("LY_lineEdit") + self.gridLayout_20.addWidget(self.LY_lineEdit, 1, 8, 1, 1) + self.label_11 = QtWidgets.QLabel(self.tab_clip) + self.label_11.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_11.setAlignment(QtCore.Qt.AlignCenter) + self.label_11.setObjectName("label_11") + self.gridLayout_20.addWidget(self.label_11, 1, 1, 1, 3) + self.LX_lineEdit = QtWidgets.QLineEdit(self.tab_clip) + self.LX_lineEdit.setMaxLength(10) + self.LX_lineEdit.setObjectName("LX_lineEdit") + self.gridLayout_20.addWidget(self.LX_lineEdit, 1, 7, 1, 1) + self.selectUL_toolButton = QtWidgets.QToolButton(self.tab_clip) + self.selectUL_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.selectUL_toolButton.setIcon(icon51) + self.selectUL_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.selectUL_toolButton.setObjectName("selectUL_toolButton") + self.gridLayout_20.addWidget(self.selectUL_toolButton, 1, 11, 1, 1) + spacerItem34 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_20.addItem(spacerItem34, 1, 9, 1, 1) + self.label_12 = QtWidgets.QLabel(self.tab_clip) + self.label_12.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_12.setAlignment(QtCore.Qt.AlignCenter) + self.label_12.setObjectName("label_12") + self.gridLayout_20.addWidget(self.label_12, 1, 6, 1, 1) + self.UY_lineEdit = QtWidgets.QLineEdit(self.tab_clip) + self.UY_lineEdit.setMaxLength(10) + self.UY_lineEdit.setObjectName("UY_lineEdit") + self.gridLayout_20.addWidget(self.UY_lineEdit, 1, 5, 1, 1) + self.UX_lineEdit = QtWidgets.QLineEdit(self.tab_clip) + self.UX_lineEdit.setMaxLength(10) + self.UX_lineEdit.setObjectName("UX_lineEdit") + self.gridLayout_20.addWidget(self.UX_lineEdit, 1, 4, 1, 1) + self.coordinates_radioButton = QtWidgets.QRadioButton(self.tab_clip) + self.coordinates_radioButton.setChecked(True) + self.coordinates_radioButton.setObjectName("coordinates_radioButton") + self.gridLayout_20.addWidget(self.coordinates_radioButton, 1, 0, 1, 1) + self.label_29 = QtWidgets.QLabel(self.tab_clip) + self.label_29.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_29.setFrameShape(QtWidgets.QFrame.Panel) + self.label_29.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_29.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_29.setObjectName("label_29") + self.gridLayout_20.addWidget(self.label_29, 0, 0, 1, 12) + self.gridLayout_58.addLayout(self.gridLayout_20, 2, 0, 1, 1) + self.gridLayout_22 = QtWidgets.QGridLayout() + self.gridLayout_22.setObjectName("gridLayout_22") + self.shapefile_comboBox = QtWidgets.QComboBox(self.tab_clip) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.shapefile_comboBox.sizePolicy().hasHeightForWidth()) + self.shapefile_comboBox.setSizePolicy(sizePolicy) + self.shapefile_comboBox.setObjectName("shapefile_comboBox") + self.gridLayout_22.addWidget(self.shapefile_comboBox, 0, 1, 1, 1) + self.toolButton_reload_8 = QtWidgets.QToolButton(self.tab_clip) + self.toolButton_reload_8.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_8.setIcon(icon60) + self.toolButton_reload_8.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_8.setObjectName("toolButton_reload_8") + self.gridLayout_22.addWidget(self.toolButton_reload_8, 0, 2, 1, 1) + self.gridLayout_19 = QtWidgets.QGridLayout() + self.gridLayout_19.setObjectName("gridLayout_19") + self.vector_field_checkBox = QtWidgets.QCheckBox(self.tab_clip) + self.vector_field_checkBox.setObjectName("vector_field_checkBox") + self.gridLayout_19.addWidget(self.vector_field_checkBox, 0, 0, 1, 1) + self.class_field_comboBox_3 = QtWidgets.QComboBox(self.tab_clip) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.class_field_comboBox_3.sizePolicy().hasHeightForWidth()) + self.class_field_comboBox_3.setSizePolicy(sizePolicy) + self.class_field_comboBox_3.setObjectName("class_field_comboBox_3") + self.gridLayout_19.addWidget(self.class_field_comboBox_3, 0, 1, 1, 1) + self.gridLayout_22.addLayout(self.gridLayout_19, 1, 1, 1, 1) + self.temporary_ROI_radioButton = QtWidgets.QRadioButton(self.tab_clip) + self.temporary_ROI_radioButton.setObjectName("temporary_ROI_radioButton") + self.gridLayout_22.addWidget(self.temporary_ROI_radioButton, 2, 0, 1, 1) + self.vector_radioButton = QtWidgets.QRadioButton(self.tab_clip) + self.vector_radioButton.setObjectName("vector_radioButton") + self.gridLayout_22.addWidget(self.vector_radioButton, 0, 0, 1, 1) + self.gridLayout_58.addLayout(self.gridLayout_22, 3, 0, 1, 1) + self.gridLayout_28 = QtWidgets.QGridLayout() + self.gridLayout_28.setObjectName("gridLayout_28") + spacerItem35 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_28.addItem(spacerItem35, 2, 0, 1, 1) + self.label_164 = QtWidgets.QLabel(self.tab_clip) + self.label_164.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_164.setFrameShape(QtWidgets.QFrame.Panel) + self.label_164.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_164.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_164.setObjectName("label_164") + self.gridLayout_28.addWidget(self.label_164, 1, 0, 1, 3) + self.clip_Button = QtWidgets.QToolButton(self.tab_clip) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.pca_Button.setFont(font) - self.pca_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pca_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.pca_Button.setIcon(icon64) - self.pca_Button.setIconSize(QtCore.QSize(34, 34)) - self.pca_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pca_Button.setObjectName("pca_Button") - self.gridLayout_173.addWidget(self.pca_Button, 5, 4, 1, 1) - self.label_254 = QtWidgets.QLabel(self.page_16) + self.clip_Button.setFont(font) + self.clip_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.clip_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.clip_Button.setIcon(icon44) + self.clip_Button.setIconSize(QtCore.QSize(34, 34)) + self.clip_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.clip_Button.setObjectName("clip_Button") + self.gridLayout_28.addWidget(self.clip_Button, 2, 2, 1, 1) + spacerItem36 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_28.addItem(spacerItem36, 0, 0, 1, 1) + self.clip_multiple_rasters = QtWidgets.QToolButton(self.tab_clip) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.clip_multiple_rasters.setFont(font) + self.clip_multiple_rasters.setLayoutDirection(QtCore.Qt.RightToLeft) + self.clip_multiple_rasters.setStyleSheet("margin: 0px;padding: 0px;") + self.clip_multiple_rasters.setIcon(icon33) + self.clip_multiple_rasters.setIconSize(QtCore.QSize(34, 34)) + self.clip_multiple_rasters.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.clip_multiple_rasters.setObjectName("clip_multiple_rasters") + self.gridLayout_28.addWidget(self.clip_multiple_rasters, 2, 1, 1, 1) + self.gridLayout_58.addLayout(self.gridLayout_28, 4, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_clip, "") + self.tab_reproject_bands = QtWidgets.QWidget() + self.tab_reproject_bands.setObjectName("tab_reproject_bands") + self.gridLayout_56 = QtWidgets.QGridLayout(self.tab_reproject_bands) + self.gridLayout_56.setObjectName("gridLayout_56") + self.gridLayout_289 = QtWidgets.QGridLayout() + self.gridLayout_289.setObjectName("gridLayout_289") + self.band_set_comb_spinBox_14 = QtWidgets.QSpinBox(self.tab_reproject_bands) + self.band_set_comb_spinBox_14.setMinimum(1) + self.band_set_comb_spinBox_14.setMaximum(100000) + self.band_set_comb_spinBox_14.setObjectName("band_set_comb_spinBox_14") + self.gridLayout_289.addWidget(self.band_set_comb_spinBox_14, 1, 1, 1, 1) + self.label_264 = QtWidgets.QLabel(self.tab_reproject_bands) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_254.sizePolicy().hasHeightForWidth()) - self.label_254.setSizePolicy(sizePolicy) - self.label_254.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_254.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_254.setObjectName("label_254") - self.gridLayout_173.addWidget(self.label_254, 0, 0, 1, 1) - self.band_set_comb_spinBox_4 = QtWidgets.QSpinBox(self.page_16) - self.band_set_comb_spinBox_4.setMinimum(1) - self.band_set_comb_spinBox_4.setMaximum(100000) - self.band_set_comb_spinBox_4.setObjectName("band_set_comb_spinBox_4") - self.gridLayout_173.addWidget(self.band_set_comb_spinBox_4, 0, 1, 1, 1) - self.pca_components_spinBox = QtWidgets.QSpinBox(self.page_16) - self.pca_components_spinBox.setMinimum(2) - self.pca_components_spinBox.setMaximum(1000) - self.pca_components_spinBox.setObjectName("pca_components_spinBox") - self.gridLayout_173.addWidget(self.pca_components_spinBox, 1, 1, 1, 1) - self.label_166 = QtWidgets.QLabel(self.page_16) - self.label_166.setStyleSheet("background-color : #656565; color : white") - self.label_166.setFrameShape(QtWidgets.QFrame.Panel) - self.label_166.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_166.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_166.setObjectName("label_166") - self.gridLayout_173.addWidget(self.label_166, 4, 0, 1, 5) - spacerItem92 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_173.addItem(spacerItem92, 5, 2, 1, 1) - self.pca = QtWidgets.QToolButton(self.page_16) + sizePolicy.setHeightForWidth(self.label_264.sizePolicy().hasHeightForWidth()) + self.label_264.setSizePolicy(sizePolicy) + self.label_264.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_264.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_264.setObjectName("label_264") + self.gridLayout_289.addWidget(self.label_264, 1, 0, 1, 1) + spacerItem37 = QtWidgets.QSpacerItem(605, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_289.addItem(spacerItem37, 1, 2, 1, 1) + self.label_249 = QtWidgets.QLabel(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_249.sizePolicy().hasHeightForWidth()) + self.label_249.setSizePolicy(sizePolicy) + self.label_249.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_249.setFrameShape(QtWidgets.QFrame.Panel) + self.label_249.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_249.setObjectName("label_249") + self.gridLayout_289.addWidget(self.label_249, 0, 0, 1, 3) + self.gridLayout_56.addLayout(self.gridLayout_289, 0, 0, 1, 1) + self.gridLayout_291 = QtWidgets.QGridLayout() + self.gridLayout_291.setObjectName("gridLayout_291") + self.align_radioButton = QtWidgets.QRadioButton(self.tab_reproject_bands) + self.align_radioButton.setObjectName("align_radioButton") + self.gridLayout_291.addWidget(self.align_radioButton, 0, 0, 1, 1) + self.toolButton_reload_25 = QtWidgets.QToolButton(self.tab_reproject_bands) + self.toolButton_reload_25.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_25.setIcon(icon60) + self.toolButton_reload_25.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_25.setObjectName("toolButton_reload_25") + self.gridLayout_291.addWidget(self.toolButton_reload_25, 0, 3, 1, 1) + self.same_extent_raster_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) + self.same_extent_raster_checkBox.setObjectName("same_extent_raster_checkBox") + self.gridLayout_291.addWidget(self.same_extent_raster_checkBox, 0, 1, 1, 1) + self.raster_align_comboBox = QtWidgets.QComboBox(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.raster_align_comboBox.sizePolicy().hasHeightForWidth()) + self.raster_align_comboBox.setSizePolicy(sizePolicy) + self.raster_align_comboBox.setObjectName("raster_align_comboBox") + self.gridLayout_291.addWidget(self.raster_align_comboBox, 0, 2, 1, 1) + self.gridLayout_56.addLayout(self.gridLayout_291, 1, 0, 1, 1) + self.gridLayout_292 = QtWidgets.QGridLayout() + self.gridLayout_292.setObjectName("gridLayout_292") + self.epsg_radioButton = QtWidgets.QRadioButton(self.tab_reproject_bands) + self.epsg_radioButton.setChecked(True) + self.epsg_radioButton.setObjectName("epsg_radioButton") + self.gridLayout_292.addWidget(self.epsg_radioButton, 0, 0, 1, 2) + self.y_resolution_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.y_resolution_lineEdit.setText("") + self.y_resolution_lineEdit.setMaxLength(10) + self.y_resolution_lineEdit.setObjectName("y_resolution_lineEdit") + self.gridLayout_292.addWidget(self.y_resolution_lineEdit, 1, 6, 1, 1) + self.label_267 = QtWidgets.QLabel(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_267.sizePolicy().hasHeightForWidth()) + self.label_267.setSizePolicy(sizePolicy) + self.label_267.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_267.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_267.setObjectName("label_267") + self.gridLayout_292.addWidget(self.label_267, 1, 5, 1, 1) + self.label_266 = QtWidgets.QLabel(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_266.sizePolicy().hasHeightForWidth()) + self.label_266.setSizePolicy(sizePolicy) + self.label_266.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_266.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_266.setObjectName("label_266") + self.gridLayout_292.addWidget(self.label_266, 1, 0, 1, 2) + self.epsg_code_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.epsg_code_lineEdit.setText("") + self.epsg_code_lineEdit.setMaxLength(10) + self.epsg_code_lineEdit.setObjectName("epsg_code_lineEdit") + self.gridLayout_292.addWidget(self.epsg_code_lineEdit, 0, 2, 1, 2) + self.x_resolution_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.x_resolution_lineEdit.setText("") + self.x_resolution_lineEdit.setMaxLength(10) + self.x_resolution_lineEdit.setObjectName("x_resolution_lineEdit") + self.gridLayout_292.addWidget(self.x_resolution_lineEdit, 1, 2, 1, 2) + spacerItem38 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_292.addItem(spacerItem38, 1, 7, 1, 1) + spacerItem39 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_292.addItem(spacerItem39, 1, 4, 1, 1) + spacerItem40 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_292.addItem(spacerItem40, 0, 4, 1, 4) + self.gridLayout_56.addLayout(self.gridLayout_292, 2, 0, 1, 1) + self.horizontalLayout_63 = QtWidgets.QHBoxLayout() + self.horizontalLayout_63.setObjectName("horizontalLayout_63") + self.resample_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) + self.resample_checkBox.setObjectName("resample_checkBox") + self.horizontalLayout_63.addWidget(self.resample_checkBox) + self.resample_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.resample_lineEdit.setMaxLength(10) + self.resample_lineEdit.setObjectName("resample_lineEdit") + self.horizontalLayout_63.addWidget(self.resample_lineEdit) + self.gridLayout_56.addLayout(self.horizontalLayout_63, 3, 0, 1, 1) + self.horizontalLayout_64 = QtWidgets.QHBoxLayout() + self.horizontalLayout_64.setObjectName("horizontalLayout_64") + self.label_269 = QtWidgets.QLabel(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_269.sizePolicy().hasHeightForWidth()) + self.label_269.setSizePolicy(sizePolicy) + self.label_269.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_269.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_269.setObjectName("label_269") + self.horizontalLayout_64.addWidget(self.label_269) + self.resampling_method_comboBox = QtWidgets.QComboBox(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.resampling_method_comboBox.sizePolicy().hasHeightForWidth()) + self.resampling_method_comboBox.setSizePolicy(sizePolicy) + self.resampling_method_comboBox.setObjectName("resampling_method_comboBox") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.resampling_method_comboBox.addItem("") + self.horizontalLayout_64.addWidget(self.resampling_method_comboBox) + spacerItem41 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_64.addItem(spacerItem41) + self.label_270 = QtWidgets.QLabel(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_270.sizePolicy().hasHeightForWidth()) + self.label_270.setSizePolicy(sizePolicy) + self.label_270.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_270.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_270.setObjectName("label_270") + self.horizontalLayout_64.addWidget(self.label_270) + self.raster_type_combo_2 = QtWidgets.QComboBox(self.tab_reproject_bands) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.raster_type_combo_2.sizePolicy().hasHeightForWidth()) + self.raster_type_combo_2.setSizePolicy(sizePolicy) + self.raster_type_combo_2.setObjectName("raster_type_combo_2") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.raster_type_combo_2.addItem("") + self.horizontalLayout_64.addWidget(self.raster_type_combo_2) + self.gridLayout_56.addLayout(self.horizontalLayout_64, 4, 0, 1, 1) + self.horizontalLayout_66 = QtWidgets.QHBoxLayout() + self.horizontalLayout_66.setObjectName("horizontalLayout_66") + self.change_nodata_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) + self.change_nodata_checkBox.setObjectName("change_nodata_checkBox") + self.horizontalLayout_66.addWidget(self.change_nodata_checkBox) + self.nodata_spinBox_14 = QtWidgets.QSpinBox(self.tab_reproject_bands) + self.nodata_spinBox_14.setMinimum(-2147483647) + self.nodata_spinBox_14.setMaximum(2147483647) + self.nodata_spinBox_14.setProperty("value", -32768) + self.nodata_spinBox_14.setObjectName("nodata_spinBox_14") + self.horizontalLayout_66.addWidget(self.nodata_spinBox_14) + spacerItem42 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_66.addItem(spacerItem42) + self.gridLayout_56.addLayout(self.horizontalLayout_66, 5, 0, 1, 1) + self.horizontalLayout_68 = QtWidgets.QHBoxLayout() + self.horizontalLayout_68.setObjectName("horizontalLayout_68") + self.label_265 = QtWidgets.QLabel(self.tab_reproject_bands) + self.label_265.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_265.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_265.setObjectName("label_265") + self.horizontalLayout_68.addWidget(self.label_265) + self.reproj_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.reproj_output_name_lineEdit.setMaxLength(10) + self.reproj_output_name_lineEdit.setObjectName("reproj_output_name_lineEdit") + self.horizontalLayout_68.addWidget(self.reproj_output_name_lineEdit) + self.virtual_output_checkBox_4 = QtWidgets.QCheckBox(self.tab_reproject_bands) + self.virtual_output_checkBox_4.setObjectName("virtual_output_checkBox_4") + self.horizontalLayout_68.addWidget(self.virtual_output_checkBox_4) + self.gridLayout_56.addLayout(self.horizontalLayout_68, 6, 0, 1, 1) + self.horizontalLayout_80 = QtWidgets.QHBoxLayout() + self.horizontalLayout_80.setObjectName("horizontalLayout_80") + self.compress_checkBox = QtWidgets.QCheckBox(self.tab_reproject_bands) + self.compress_checkBox.setChecked(True) + self.compress_checkBox.setObjectName("compress_checkBox") + self.horizontalLayout_80.addWidget(self.compress_checkBox) + self.resample_lineEdit_2 = QtWidgets.QLineEdit(self.tab_reproject_bands) + self.resample_lineEdit_2.setMaxLength(10) + self.resample_lineEdit_2.setObjectName("resample_lineEdit_2") + self.horizontalLayout_80.addWidget(self.resample_lineEdit_2) + spacerItem43 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_80.addItem(spacerItem43) + self.gridLayout_56.addLayout(self.horizontalLayout_80, 7, 0, 1, 1) + spacerItem44 = QtWidgets.QSpacerItem(20, 198, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_56.addItem(spacerItem44, 8, 0, 1, 1) + self.gridLayout_290 = QtWidgets.QGridLayout() + self.gridLayout_290.setObjectName("gridLayout_290") + self.label_263 = QtWidgets.QLabel(self.tab_reproject_bands) + self.label_263.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_263.setFrameShape(QtWidgets.QFrame.Panel) + self.label_263.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_263.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_263.setObjectName("label_263") + self.gridLayout_290.addWidget(self.label_263, 0, 0, 1, 2) + self.horizontalLayout_59 = QtWidgets.QHBoxLayout() + self.horizontalLayout_59.setObjectName("horizontalLayout_59") + spacerItem45 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_59.addItem(spacerItem45) + self.reproject_raster_bands = QtWidgets.QToolButton(self.tab_reproject_bands) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.pca.setFont(font) - self.pca.setLayoutDirection(QtCore.Qt.RightToLeft) - self.pca.setStyleSheet("margin: 0px;padding: 0px;") - self.pca.setIcon(icon48) - self.pca.setIconSize(QtCore.QSize(34, 34)) - self.pca.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.pca.setObjectName("pca") - self.gridLayout_173.addWidget(self.pca, 5, 3, 1, 1) - self.gridLayout_182.addLayout(self.gridLayout_173, 1, 0, 1, 1) - self.toolBox_PCA.addItem(self.page_16, "") - self.page_17 = QtWidgets.QWidget() - self.page_17.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_17.setObjectName("page_17") - self.gridLayout_200 = QtWidgets.QGridLayout(self.page_17) - self.gridLayout_200.setObjectName("gridLayout_200") - self.gridLayout_201 = QtWidgets.QGridLayout() - self.gridLayout_201.setObjectName("gridLayout_201") - self.report_textBrowser_2 = QtWidgets.QTextBrowser(self.page_17) + self.reproject_raster_bands.setFont(font) + self.reproject_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) + self.reproject_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") + self.reproject_raster_bands.setIcon(icon33) + self.reproject_raster_bands.setIconSize(QtCore.QSize(34, 34)) + self.reproject_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.reproject_raster_bands.setObjectName("reproject_raster_bands") + self.horizontalLayout_59.addWidget(self.reproject_raster_bands) + self.reproject_Button = QtWidgets.QToolButton(self.tab_reproject_bands) font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.report_textBrowser_2.setFont(font) - self.report_textBrowser_2.setTabChangesFocus(True) - self.report_textBrowser_2.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.report_textBrowser_2.setTabStopWidth(160) - self.report_textBrowser_2.setOpenLinks(False) - self.report_textBrowser_2.setObjectName("report_textBrowser_2") - self.gridLayout_201.addWidget(self.report_textBrowser_2, 0, 0, 1, 1) - self.gridLayout_200.addLayout(self.gridLayout_201, 0, 0, 1, 1) - self.toolBox_PCA.addItem(self.page_17, "") - self.gridLayout_170.addWidget(self.toolBox_PCA, 0, 0, 1, 1) - self.tabWidget_4.addTab(self.PCA_tab, "") - self.tab_kmeans = QtWidgets.QWidget() - self.tab_kmeans.setObjectName("tab_kmeans") - self.gridLayout_208 = QtWidgets.QGridLayout(self.tab_kmeans) - self.gridLayout_208.setObjectName("gridLayout_208") - self.toolBox_kmeans = QtWidgets.QToolBox(self.tab_kmeans) - self.toolBox_kmeans.setStyleSheet("") - self.toolBox_kmeans.setObjectName("toolBox_kmeans") - self.page_18 = QtWidgets.QWidget() - self.page_18.setGeometry(QtCore.QRect(0, 0, 764, 390)) - self.page_18.setObjectName("page_18") - self.gridLayout_152 = QtWidgets.QGridLayout(self.page_18) - self.gridLayout_152.setObjectName("gridLayout_152") - self.horizontalLayout_29 = QtWidgets.QHBoxLayout() - self.horizontalLayout_29.setObjectName("horizontalLayout_29") - self.label_78 = QtWidgets.QLabel(self.page_18) - self.label_78.setStyleSheet("background-color : #656565; color : white") - self.label_78.setFrameShape(QtWidgets.QFrame.Panel) - self.label_78.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_78.setObjectName("label_78") - self.horizontalLayout_29.addWidget(self.label_78) - self.gridLayout_152.addLayout(self.horizontalLayout_29, 0, 0, 1, 1) - self.gridLayout_151 = QtWidgets.QGridLayout() - self.gridLayout_151.setObjectName("gridLayout_151") - self.isodata_radioButton = QtWidgets.QRadioButton(self.page_18) - self.isodata_radioButton.setChecked(False) - self.isodata_radioButton.setAutoExclusive(False) - self.isodata_radioButton.setObjectName("isodata_radioButton") - self.gridLayout_151.addWidget(self.isodata_radioButton, 0, 5, 1, 1) - self.band_set_comb_spinBox_5 = QtWidgets.QSpinBox(self.page_18) - self.band_set_comb_spinBox_5.setMinimum(1) - self.band_set_comb_spinBox_5.setMaximum(100000) - self.band_set_comb_spinBox_5.setObjectName("band_set_comb_spinBox_5") - self.gridLayout_151.addWidget(self.band_set_comb_spinBox_5, 0, 1, 1, 1) - self.label_230 = QtWidgets.QLabel(self.page_18) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_230.sizePolicy().hasHeightForWidth()) - self.label_230.setSizePolicy(sizePolicy) - self.label_230.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_230.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_230.setObjectName("label_230") - self.gridLayout_151.addWidget(self.label_230, 0, 3, 1, 1) - self.label_255 = QtWidgets.QLabel(self.page_18) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_255.sizePolicy().hasHeightForWidth()) - self.label_255.setSizePolicy(sizePolicy) - self.label_255.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_255.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_255.setObjectName("label_255") - self.gridLayout_151.addWidget(self.label_255, 0, 0, 1, 1) - self.kmeans_radioButton = QtWidgets.QRadioButton(self.page_18) - self.kmeans_radioButton.setChecked(True) - self.kmeans_radioButton.setAutoExclusive(False) - self.kmeans_radioButton.setObjectName("kmeans_radioButton") - self.gridLayout_151.addWidget(self.kmeans_radioButton, 0, 4, 1, 1) - spacerItem93 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_151.addItem(spacerItem93, 0, 2, 1, 1) - spacerItem94 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_151.addItem(spacerItem94, 0, 6, 1, 1) - self.gridLayout_152.addLayout(self.gridLayout_151, 1, 0, 1, 1) - self.gridLayout_125 = QtWidgets.QGridLayout() - self.gridLayout_125.setObjectName("gridLayout_125") - self.label_225 = QtWidgets.QLabel(self.page_18) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_225.sizePolicy().hasHeightForWidth()) - self.label_225.setSizePolicy(sizePolicy) - self.label_225.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_225.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_225.setObjectName("label_225") - self.gridLayout_125.addWidget(self.label_225, 1, 0, 1, 1) - self.thresh_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.page_18) - self.thresh_doubleSpinBox.setDecimals(7) - self.thresh_doubleSpinBox.setMinimum(1e-06) - self.thresh_doubleSpinBox.setMaximum(10000000.0) - self.thresh_doubleSpinBox.setSingleStep(1e-05) - self.thresh_doubleSpinBox.setProperty("value", 0.0001) - self.thresh_doubleSpinBox.setObjectName("thresh_doubleSpinBox") - self.gridLayout_125.addWidget(self.thresh_doubleSpinBox, 0, 1, 1, 1) - self.std_dev_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.page_18) - self.std_dev_doubleSpinBox.setDecimals(7) - self.std_dev_doubleSpinBox.setMinimum(1e-06) - self.std_dev_doubleSpinBox.setMaximum(1000000000.0) - self.std_dev_doubleSpinBox.setSingleStep(1e-05) - self.std_dev_doubleSpinBox.setProperty("value", 0.0001) - self.std_dev_doubleSpinBox.setObjectName("std_dev_doubleSpinBox") - self.gridLayout_125.addWidget(self.std_dev_doubleSpinBox, 2, 1, 1, 1) - self.kmean_threshold_checkBox = QtWidgets.QCheckBox(self.page_18) - self.kmean_threshold_checkBox.setChecked(True) - self.kmean_threshold_checkBox.setObjectName("kmean_threshold_checkBox") - self.gridLayout_125.addWidget(self.kmean_threshold_checkBox, 0, 0, 1, 1) - self.nodata_spinBox_9 = QtWidgets.QSpinBox(self.page_18) - self.nodata_spinBox_9.setMinimum(-999999999) - self.nodata_spinBox_9.setMaximum(999999999) - self.nodata_spinBox_9.setProperty("value", 0) - self.nodata_spinBox_9.setObjectName("nodata_spinBox_9") - self.gridLayout_125.addWidget(self.nodata_spinBox_9, 4, 1, 1, 1) - self.kmeans_iter_spinBox = QtWidgets.QSpinBox(self.page_18) - self.kmeans_iter_spinBox.setMinimum(1) - self.kmeans_iter_spinBox.setMaximum(1000) - self.kmeans_iter_spinBox.setProperty("value", 10) - self.kmeans_iter_spinBox.setObjectName("kmeans_iter_spinBox") - self.gridLayout_125.addWidget(self.kmeans_iter_spinBox, 1, 1, 1, 1) - self.label_228 = QtWidgets.QLabel(self.page_18) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) + font.setBold(True) + font.setWeight(75) + self.reproject_Button.setFont(font) + self.reproject_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.reproject_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.reproject_Button.setIcon(icon44) + self.reproject_Button.setIconSize(QtCore.QSize(34, 34)) + self.reproject_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.reproject_Button.setObjectName("reproject_Button") + self.horizontalLayout_59.addWidget(self.reproject_Button) + self.gridLayout_290.addLayout(self.horizontalLayout_59, 2, 0, 1, 2) + self.gridLayout_56.addLayout(self.gridLayout_290, 9, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_reproject_bands, "") + self.tab_split_raster = QtWidgets.QWidget() + self.tab_split_raster.setObjectName("tab_split_raster") + self.gridLayout_57 = QtWidgets.QGridLayout(self.tab_split_raster) + self.gridLayout_57.setObjectName("gridLayout_57") + spacerItem46 = QtWidgets.QSpacerItem(20, 302, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_57.addItem(spacerItem46, 3, 1, 1, 1) + self.gridLayout_190 = QtWidgets.QGridLayout() + self.gridLayout_190.setObjectName("gridLayout_190") + self.raster_name_combo = QtWidgets.QComboBox(self.tab_split_raster) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_228.sizePolicy().hasHeightForWidth()) - self.label_228.setSizePolicy(sizePolicy) - self.label_228.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_228.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_228.setWordWrap(True) - self.label_228.setObjectName("label_228") - self.gridLayout_125.addWidget(self.label_228, 2, 0, 1, 1) - self.nodata_checkBox_8 = QtWidgets.QCheckBox(self.page_18) - self.nodata_checkBox_8.setObjectName("nodata_checkBox_8") - self.gridLayout_125.addWidget(self.nodata_checkBox_8, 4, 0, 1, 1) - self.kmeans_classes_spinBox = QtWidgets.QSpinBox(self.page_18) - self.kmeans_classes_spinBox.setMinimum(1) - self.kmeans_classes_spinBox.setMaximum(1000) - self.kmeans_classes_spinBox.setProperty("value", 10) - self.kmeans_classes_spinBox.setObjectName("kmeans_classes_spinBox") - self.gridLayout_125.addWidget(self.kmeans_classes_spinBox, 0, 3, 1, 1) - self.label_224 = QtWidgets.QLabel(self.page_18) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.raster_name_combo.sizePolicy().hasHeightForWidth()) + self.raster_name_combo.setSizePolicy(sizePolicy) + self.raster_name_combo.setObjectName("raster_name_combo") + self.gridLayout_190.addWidget(self.raster_name_combo, 1, 1, 1, 1) + self.label_57 = QtWidgets.QLabel(self.tab_split_raster) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_224.sizePolicy().hasHeightForWidth()) - self.label_224.setSizePolicy(sizePolicy) - self.label_224.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_224.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_224.setObjectName("label_224") - self.gridLayout_125.addWidget(self.label_224, 0, 2, 1, 1) - spacerItem95 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_125.addItem(spacerItem95, 0, 4, 1, 1) - self.label_229 = QtWidgets.QLabel(self.page_18) + sizePolicy.setHeightForWidth(self.label_57.sizePolicy().hasHeightForWidth()) + self.label_57.setSizePolicy(sizePolicy) + self.label_57.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_57.setFrameShape(QtWidgets.QFrame.Panel) + self.label_57.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_57.setObjectName("label_57") + self.gridLayout_190.addWidget(self.label_57, 0, 0, 1, 3) + self.label_50 = QtWidgets.QLabel(self.tab_split_raster) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_229.sizePolicy().hasHeightForWidth()) - self.label_229.setSizePolicy(sizePolicy) - self.label_229.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_229.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_229.setWordWrap(True) - self.label_229.setObjectName("label_229") - self.gridLayout_125.addWidget(self.label_229, 2, 2, 1, 1) - self.min_size_class_spinBox = QtWidgets.QSpinBox(self.page_18) - self.min_size_class_spinBox.setMinimum(1) - self.min_size_class_spinBox.setMaximum(1000000) - self.min_size_class_spinBox.setProperty("value", 10) - self.min_size_class_spinBox.setObjectName("min_size_class_spinBox") - self.gridLayout_125.addWidget(self.min_size_class_spinBox, 2, 3, 1, 1) - self.gridLayout_152.addLayout(self.gridLayout_125, 2, 0, 1, 1) - self.gridLayout_231 = QtWidgets.QGridLayout() - self.gridLayout_231.setObjectName("gridLayout_231") - self.gridLayout_135 = QtWidgets.QGridLayout() - self.gridLayout_135.setObjectName("gridLayout_135") - self.min_distance_radioButton = QtWidgets.QRadioButton(self.page_18) - self.min_distance_radioButton.setChecked(True) - self.min_distance_radioButton.setAutoExclusive(False) - self.min_distance_radioButton.setObjectName("min_distance_radioButton") - self.gridLayout_135.addWidget(self.min_distance_radioButton, 2, 1, 1, 1) - self.kmean_save_siglist_checkBox = QtWidgets.QCheckBox(self.page_18) - self.kmean_save_siglist_checkBox.setObjectName("kmean_save_siglist_checkBox") - self.gridLayout_135.addWidget(self.kmean_save_siglist_checkBox, 3, 0, 1, 4) - self.label_227 = QtWidgets.QLabel(self.page_18) + sizePolicy.setHeightForWidth(self.label_50.sizePolicy().hasHeightForWidth()) + self.label_50.setSizePolicy(sizePolicy) + self.label_50.setMinimumSize(QtCore.QSize(229, 0)) + self.label_50.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_50.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_50.setObjectName("label_50") + self.gridLayout_190.addWidget(self.label_50, 1, 0, 1, 1) + self.toolButton_reload_9 = QtWidgets.QToolButton(self.tab_split_raster) + self.toolButton_reload_9.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_9.setIcon(icon60) + self.toolButton_reload_9.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_9.setObjectName("toolButton_reload_9") + self.gridLayout_190.addWidget(self.toolButton_reload_9, 1, 2, 1, 1) + self.gridLayout_57.addLayout(self.gridLayout_190, 0, 0, 1, 4) + self.label_165 = QtWidgets.QLabel(self.tab_split_raster) + self.label_165.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_165.setFrameShape(QtWidgets.QFrame.Panel) + self.label_165.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_165.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_165.setObjectName("label_165") + self.gridLayout_57.addWidget(self.label_165, 4, 0, 1, 4) + self.horizontalLayout_57 = QtWidgets.QHBoxLayout() + self.horizontalLayout_57.setObjectName("horizontalLayout_57") + self.label_61 = QtWidgets.QLabel(self.tab_split_raster) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_227.sizePolicy().hasHeightForWidth()) - self.label_227.setSizePolicy(sizePolicy) - self.label_227.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_227.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_227.setObjectName("label_227") - self.gridLayout_135.addWidget(self.label_227, 2, 0, 1, 1) - self.horizontalLayout_30 = QtWidgets.QHBoxLayout() - self.horizontalLayout_30.setObjectName("horizontalLayout_30") - self.label_104 = QtWidgets.QLabel(self.page_18) - self.label_104.setStyleSheet("background-color : #656565; color : white") - self.label_104.setFrameShape(QtWidgets.QFrame.Panel) - self.label_104.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_104.setObjectName("label_104") - self.horizontalLayout_30.addWidget(self.label_104) - self.gridLayout_135.addLayout(self.horizontalLayout_30, 0, 0, 1, 4) - self.gridLayout_10 = QtWidgets.QGridLayout() - self.gridLayout_10.setObjectName("gridLayout_10") - self.gridLayout_226 = QtWidgets.QGridLayout() - self.gridLayout_226.setObjectName("gridLayout_226") - self.kmean_siglist_radioButton = QtWidgets.QRadioButton(self.page_18) - self.kmean_siglist_radioButton.setChecked(False) - self.kmean_siglist_radioButton.setAutoExclusive(False) - self.kmean_siglist_radioButton.setObjectName("kmean_siglist_radioButton") - self.gridLayout_226.addWidget(self.kmean_siglist_radioButton, 0, 1, 1, 1) - self.kmean_randomsiglist_radioButton = QtWidgets.QRadioButton(self.page_18) - self.kmean_randomsiglist_radioButton.setChecked(False) - self.kmean_randomsiglist_radioButton.setAutoExclusive(False) - self.kmean_randomsiglist_radioButton.setObjectName("kmean_randomsiglist_radioButton") - self.gridLayout_226.addWidget(self.kmean_randomsiglist_radioButton, 0, 2, 1, 1) - self.kmean_minmax_radioButton = QtWidgets.QRadioButton(self.page_18) - self.kmean_minmax_radioButton.setChecked(True) - self.kmean_minmax_radioButton.setAutoExclusive(False) - self.kmean_minmax_radioButton.setObjectName("kmean_minmax_radioButton") - self.gridLayout_226.addWidget(self.kmean_minmax_radioButton, 0, 0, 1, 1) - self.gridLayout_10.addLayout(self.gridLayout_226, 1, 0, 1, 1) - self.gridLayout_135.addLayout(self.gridLayout_10, 1, 0, 1, 4) - self.spectral_angle_map_radioButton = QtWidgets.QRadioButton(self.page_18) - self.spectral_angle_map_radioButton.setChecked(False) - self.spectral_angle_map_radioButton.setAutoExclusive(False) - self.spectral_angle_map_radioButton.setObjectName("spectral_angle_map_radioButton") - self.gridLayout_135.addWidget(self.spectral_angle_map_radioButton, 2, 2, 1, 1) - self.gridLayout_231.addLayout(self.gridLayout_135, 0, 0, 1, 4) - self.label_179 = QtWidgets.QLabel(self.page_18) - self.label_179.setStyleSheet("background-color : #656565; color : white") - self.label_179.setFrameShape(QtWidgets.QFrame.Panel) - self.label_179.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_179.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_179.setObjectName("label_179") - self.gridLayout_231.addWidget(self.label_179, 2, 0, 1, 4) - spacerItem96 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_231.addItem(spacerItem96, 3, 0, 1, 2) - self.kmeans_Button = QtWidgets.QToolButton(self.page_18) + sizePolicy.setHeightForWidth(self.label_61.sizePolicy().hasHeightForWidth()) + self.label_61.setSizePolicy(sizePolicy) + self.label_61.setMinimumSize(QtCore.QSize(229, 0)) + self.label_61.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_61.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_61.setObjectName("label_61") + self.horizontalLayout_57.addWidget(self.label_61) + self.output_name_lineEdit = QtWidgets.QLineEdit(self.tab_split_raster) + self.output_name_lineEdit.setMaxLength(10) + self.output_name_lineEdit.setObjectName("output_name_lineEdit") + self.horizontalLayout_57.addWidget(self.output_name_lineEdit) + self.gridLayout_57.addLayout(self.horizontalLayout_57, 1, 0, 1, 4) + self.horizontalLayout_54 = QtWidgets.QHBoxLayout() + self.horizontalLayout_54.setObjectName("horizontalLayout_54") + spacerItem47 = QtWidgets.QSpacerItem(667, 38, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_54.addItem(spacerItem47) + self.split_raster_bands = QtWidgets.QToolButton(self.tab_split_raster) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.kmeans_Button.setFont(font) - self.kmeans_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.kmeans_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.kmeans_Button.setIcon(icon64) - self.kmeans_Button.setIconSize(QtCore.QSize(34, 34)) - self.kmeans_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.kmeans_Button.setObjectName("kmeans_Button") - self.gridLayout_231.addWidget(self.kmeans_Button, 3, 3, 1, 1) - self.clustering = QtWidgets.QToolButton(self.page_18) + self.split_raster_bands.setFont(font) + self.split_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) + self.split_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") + self.split_raster_bands.setIcon(icon33) + self.split_raster_bands.setIconSize(QtCore.QSize(34, 34)) + self.split_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.split_raster_bands.setObjectName("split_raster_bands") + self.horizontalLayout_54.addWidget(self.split_raster_bands) + self.split_Button = QtWidgets.QToolButton(self.tab_split_raster) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.clustering.setFont(font) - self.clustering.setLayoutDirection(QtCore.Qt.RightToLeft) - self.clustering.setStyleSheet("margin: 0px;padding: 0px;") - self.clustering.setIcon(icon48) - self.clustering.setIconSize(QtCore.QSize(34, 34)) - self.clustering.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.clustering.setObjectName("clustering") - self.gridLayout_231.addWidget(self.clustering, 3, 2, 1, 1) - spacerItem97 = QtWidgets.QSpacerItem(38, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_231.addItem(spacerItem97, 1, 3, 1, 1) - self.gridLayout_152.addLayout(self.gridLayout_231, 3, 0, 1, 1) - self.toolBox_kmeans.addItem(self.page_18, "") - self.page_23 = QtWidgets.QWidget() - self.page_23.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_23.setObjectName("page_23") - self.gridLayout_235 = QtWidgets.QGridLayout(self.page_23) - self.gridLayout_235.setObjectName("gridLayout_235") - self.gridLayout_236 = QtWidgets.QGridLayout() - self.gridLayout_236.setObjectName("gridLayout_236") - self.report_textBrowser_3 = QtWidgets.QTextBrowser(self.page_23) - font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.report_textBrowser_3.setFont(font) - self.report_textBrowser_3.setTabChangesFocus(True) - self.report_textBrowser_3.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.report_textBrowser_3.setTabStopWidth(160) - self.report_textBrowser_3.setOpenLinks(False) - self.report_textBrowser_3.setObjectName("report_textBrowser_3") - self.gridLayout_236.addWidget(self.report_textBrowser_3, 0, 0, 1, 1) - self.gridLayout_235.addLayout(self.gridLayout_236, 0, 0, 1, 1) - self.toolBox_kmeans.addItem(self.page_23, "") - self.gridLayout_208.addWidget(self.toolBox_kmeans, 0, 0, 1, 1) - self.tabWidget_4.addTab(self.tab_kmeans, "") - self.tab_spectral_dist = QtWidgets.QWidget() - self.tab_spectral_dist.setObjectName("tab_spectral_dist") - self.gridLayout_154 = QtWidgets.QGridLayout(self.tab_spectral_dist) - self.gridLayout_154.setObjectName("gridLayout_154") - self.gridLayout_149 = QtWidgets.QGridLayout() - self.gridLayout_149.setObjectName("gridLayout_149") - self.min_distance_radioButton_2 = QtWidgets.QRadioButton(self.tab_spectral_dist) - self.min_distance_radioButton_2.setChecked(True) - self.min_distance_radioButton_2.setAutoExclusive(False) - self.min_distance_radioButton_2.setObjectName("min_distance_radioButton_2") - self.gridLayout_149.addWidget(self.min_distance_radioButton_2, 2, 1, 1, 1) - self.label_231 = QtWidgets.QLabel(self.tab_spectral_dist) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_231.sizePolicy().hasHeightForWidth()) - self.label_231.setSizePolicy(sizePolicy) - self.label_231.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_231.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_231.setObjectName("label_231") - self.gridLayout_149.addWidget(self.label_231, 2, 0, 1, 1) - self.spectral_angle_map_radioButton_2 = QtWidgets.QRadioButton(self.tab_spectral_dist) - self.spectral_angle_map_radioButton_2.setChecked(False) - self.spectral_angle_map_radioButton_2.setAutoExclusive(False) - self.spectral_angle_map_radioButton_2.setObjectName("spectral_angle_map_radioButton_2") - self.gridLayout_149.addWidget(self.spectral_angle_map_radioButton_2, 2, 2, 1, 1) - self.horizontalLayout_32 = QtWidgets.QHBoxLayout() - self.horizontalLayout_32.setObjectName("horizontalLayout_32") - self.horizontalLayout_31 = QtWidgets.QHBoxLayout() - self.horizontalLayout_31.setObjectName("horizontalLayout_31") - self.label_137 = QtWidgets.QLabel(self.tab_spectral_dist) - self.label_137.setStyleSheet("background-color : #656565; color : white") - self.label_137.setFrameShape(QtWidgets.QFrame.Panel) - self.label_137.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_137.setObjectName("label_137") - self.horizontalLayout_31.addWidget(self.label_137) - self.horizontalLayout_32.addLayout(self.horizontalLayout_31) - self.gridLayout_149.addLayout(self.horizontalLayout_32, 0, 0, 1, 4) - self.distance_threshold_checkBox = QtWidgets.QCheckBox(self.tab_spectral_dist) - self.distance_threshold_checkBox.setChecked(True) - self.distance_threshold_checkBox.setObjectName("distance_threshold_checkBox") - self.gridLayout_149.addWidget(self.distance_threshold_checkBox, 3, 0, 1, 1) - self.thresh_doubleSpinBox_2 = QtWidgets.QDoubleSpinBox(self.tab_spectral_dist) - self.thresh_doubleSpinBox_2.setDecimals(7) - self.thresh_doubleSpinBox_2.setMinimum(1e-06) - self.thresh_doubleSpinBox_2.setMaximum(1000.0) - self.thresh_doubleSpinBox_2.setSingleStep(1.0) - self.thresh_doubleSpinBox_2.setProperty("value", 0.1) - self.thresh_doubleSpinBox_2.setObjectName("thresh_doubleSpinBox_2") - self.gridLayout_149.addWidget(self.thresh_doubleSpinBox_2, 3, 1, 1, 1) - self.gridLayout_41 = QtWidgets.QGridLayout() - self.gridLayout_41.setObjectName("gridLayout_41") - self.label_256 = QtWidgets.QLabel(self.tab_spectral_dist) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_256.sizePolicy().hasHeightForWidth()) - self.label_256.setSizePolicy(sizePolicy) - self.label_256.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_256.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_256.setObjectName("label_256") - self.gridLayout_41.addWidget(self.label_256, 0, 0, 1, 1) - self.band_set_comb_spinBox_7 = QtWidgets.QSpinBox(self.tab_spectral_dist) - self.band_set_comb_spinBox_7.setMinimum(1) - self.band_set_comb_spinBox_7.setMaximum(100000) - self.band_set_comb_spinBox_7.setProperty("value", 2) - self.band_set_comb_spinBox_7.setObjectName("band_set_comb_spinBox_7") - self.gridLayout_41.addWidget(self.band_set_comb_spinBox_7, 1, 1, 1, 1) - self.label_257 = QtWidgets.QLabel(self.tab_spectral_dist) + self.split_Button.setFont(font) + self.split_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.split_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.split_Button.setIcon(icon44) + self.split_Button.setIconSize(QtCore.QSize(34, 34)) + self.split_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.split_Button.setObjectName("split_Button") + self.horizontalLayout_54.addWidget(self.split_Button) + self.gridLayout_57.addLayout(self.horizontalLayout_54, 5, 0, 1, 4) + self.tabWidget_preprocessing.addTab(self.tab_split_raster, "") + self.tab_stack_bands = QtWidgets.QWidget() + self.tab_stack_bands.setObjectName("tab_stack_bands") + self.gridLayout_23 = QtWidgets.QGridLayout(self.tab_stack_bands) + self.gridLayout_23.setObjectName("gridLayout_23") + self.label_252 = QtWidgets.QLabel(self.tab_stack_bands) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_257.sizePolicy().hasHeightForWidth()) - self.label_257.setSizePolicy(sizePolicy) - self.label_257.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_257.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_257.setObjectName("label_257") - self.gridLayout_41.addWidget(self.label_257, 1, 0, 1, 1) - self.band_set_comb_spinBox_6 = QtWidgets.QSpinBox(self.tab_spectral_dist) - self.band_set_comb_spinBox_6.setMinimum(1) - self.band_set_comb_spinBox_6.setMaximum(100000) - self.band_set_comb_spinBox_6.setObjectName("band_set_comb_spinBox_6") - self.gridLayout_41.addWidget(self.band_set_comb_spinBox_6, 0, 1, 1, 1) - spacerItem98 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_41.addItem(spacerItem98, 1, 2, 1, 1) - self.gridLayout_149.addLayout(self.gridLayout_41, 1, 0, 1, 4) - self.gridLayout_154.addLayout(self.gridLayout_149, 0, 0, 1, 1) - self.gridLayout_233 = QtWidgets.QGridLayout() - self.gridLayout_233.setObjectName("gridLayout_233") - self.label_183 = QtWidgets.QLabel(self.tab_spectral_dist) - self.label_183.setStyleSheet("background-color : #656565; color : white") - self.label_183.setFrameShape(QtWidgets.QFrame.Panel) - self.label_183.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_183.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_183.setObjectName("label_183") - self.gridLayout_233.addWidget(self.label_183, 1, 0, 1, 4) - spacerItem99 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_233.addItem(spacerItem99, 2, 0, 1, 2) - spacerItem100 = QtWidgets.QSpacerItem(38, 37, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_233.addItem(spacerItem100, 0, 3, 1, 1) - self.spectral_distance_bandsets_toolButton = QtWidgets.QToolButton(self.tab_spectral_dist) + sizePolicy.setHeightForWidth(self.label_252.sizePolicy().hasHeightForWidth()) + self.label_252.setSizePolicy(sizePolicy) + self.label_252.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_252.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_252.setObjectName("label_252") + self.gridLayout_23.addWidget(self.label_252, 1, 0, 1, 1) + self.band_set_comb_spinBox_3 = QtWidgets.QSpinBox(self.tab_stack_bands) + self.band_set_comb_spinBox_3.setMinimum(1) + self.band_set_comb_spinBox_3.setMaximum(100000) + self.band_set_comb_spinBox_3.setObjectName("band_set_comb_spinBox_3") + self.gridLayout_23.addWidget(self.band_set_comb_spinBox_3, 1, 1, 1, 1) + spacerItem48 = QtWidgets.QSpacerItem(647, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_23.addItem(spacerItem48, 1, 3, 1, 1) + spacerItem49 = QtWidgets.QSpacerItem(20, 339, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_23.addItem(spacerItem49, 2, 0, 1, 1) + self.horizontalLayout_53 = QtWidgets.QHBoxLayout() + self.horizontalLayout_53.setObjectName("horizontalLayout_53") + spacerItem50 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_53.addItem(spacerItem50) + self.stack_raster_bands = QtWidgets.QToolButton(self.tab_stack_bands) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.spectral_distance_bandsets_toolButton.setFont(font) - self.spectral_distance_bandsets_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.spectral_distance_bandsets_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.spectral_distance_bandsets_toolButton.setIcon(icon64) - self.spectral_distance_bandsets_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.spectral_distance_bandsets_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.spectral_distance_bandsets_toolButton.setObjectName("spectral_distance_bandsets_toolButton") - self.gridLayout_233.addWidget(self.spectral_distance_bandsets_toolButton, 2, 3, 1, 1) - self.spectral_distance = QtWidgets.QToolButton(self.tab_spectral_dist) + self.stack_raster_bands.setFont(font) + self.stack_raster_bands.setLayoutDirection(QtCore.Qt.RightToLeft) + self.stack_raster_bands.setStyleSheet("margin: 0px;padding: 0px;") + self.stack_raster_bands.setIcon(icon33) + self.stack_raster_bands.setIconSize(QtCore.QSize(34, 34)) + self.stack_raster_bands.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.stack_raster_bands.setObjectName("stack_raster_bands") + self.horizontalLayout_53.addWidget(self.stack_raster_bands) + self.stack_Button = QtWidgets.QToolButton(self.tab_stack_bands) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.spectral_distance.setFont(font) - self.spectral_distance.setLayoutDirection(QtCore.Qt.RightToLeft) - self.spectral_distance.setStyleSheet("margin: 0px;padding: 0px;") - self.spectral_distance.setIcon(icon48) - self.spectral_distance.setIconSize(QtCore.QSize(34, 34)) - self.spectral_distance.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.spectral_distance.setObjectName("spectral_distance") - self.gridLayout_233.addWidget(self.spectral_distance, 2, 2, 1, 1) - self.gridLayout_154.addLayout(self.gridLayout_233, 1, 0, 1, 1) - self.tabWidget_4.addTab(self.tab_spectral_dist, "") - self.tab_classification = QtWidgets.QWidget() - self.tab_classification.setObjectName("tab_classification") - self.gridLayout_260 = QtWidgets.QGridLayout(self.tab_classification) - self.gridLayout_260.setObjectName("gridLayout_260") - self.gridLayout_218 = QtWidgets.QGridLayout() - self.gridLayout_218.setObjectName("gridLayout_218") - self.horizontalLayout_55 = QtWidgets.QHBoxLayout() - self.horizontalLayout_55.setObjectName("horizontalLayout_55") - self.label_32 = QtWidgets.QLabel(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_32.sizePolicy().hasHeightForWidth()) - self.label_32.setSizePolicy(sizePolicy) - self.label_32.setObjectName("label_32") - self.horizontalLayout_55.addWidget(self.label_32) - self.macroclass_checkBox = QtWidgets.QCheckBox(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.macroclass_checkBox.sizePolicy().hasHeightForWidth()) - self.macroclass_checkBox.setSizePolicy(sizePolicy) - self.macroclass_checkBox.setObjectName("macroclass_checkBox") - self.horizontalLayout_55.addWidget(self.macroclass_checkBox) - self.class_checkBox = QtWidgets.QCheckBox(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_checkBox.sizePolicy().hasHeightForWidth()) - self.class_checkBox.setSizePolicy(sizePolicy) - self.class_checkBox.setObjectName("class_checkBox") - self.horizontalLayout_55.addWidget(self.class_checkBox) - spacerItem101 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_55.addItem(spacerItem101) - self.algorithm_weight_button = QtWidgets.QToolButton(self.tab_classification) - self.algorithm_weight_button.setStyleSheet("margin: 0px;padding: 0px;") - self.algorithm_weight_button.setIcon(icon3) - self.algorithm_weight_button.setIconSize(QtCore.QSize(22, 22)) - self.algorithm_weight_button.setObjectName("algorithm_weight_button") - self.horizontalLayout_55.addWidget(self.algorithm_weight_button) - self.gridLayout_218.addLayout(self.horizontalLayout_55, 2, 0, 1, 4) - self.algorithm_combo = QtWidgets.QComboBox(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.algorithm_combo.sizePolicy().hasHeightForWidth()) - self.algorithm_combo.setSizePolicy(sizePolicy) - self.algorithm_combo.setMinimumSize(QtCore.QSize(100, 0)) - self.algorithm_combo.setObjectName("algorithm_combo") - self.algorithm_combo.addItem("") - self.algorithm_combo.addItem("") - self.algorithm_combo.addItem("") - self.gridLayout_218.addWidget(self.algorithm_combo, 4, 0, 1, 3) - self.band_set_comb_spinBox_12 = QtWidgets.QSpinBox(self.tab_classification) - self.band_set_comb_spinBox_12.setMinimum(1) - self.band_set_comb_spinBox_12.setMaximum(100000) - self.band_set_comb_spinBox_12.setObjectName("band_set_comb_spinBox_12") - self.gridLayout_218.addWidget(self.band_set_comb_spinBox_12, 1, 1, 1, 1) - self.label_261 = QtWidgets.QLabel(self.tab_classification) + self.stack_Button.setFont(font) + self.stack_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.stack_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.stack_Button.setIcon(icon44) + self.stack_Button.setIconSize(QtCore.QSize(34, 34)) + self.stack_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.stack_Button.setObjectName("stack_Button") + self.horizontalLayout_53.addWidget(self.stack_Button) + self.gridLayout_23.addLayout(self.horizontalLayout_53, 4, 0, 1, 4) + self.label_223 = QtWidgets.QLabel(self.tab_stack_bands) + self.label_223.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_223.setFrameShape(QtWidgets.QFrame.Panel) + self.label_223.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_223.setObjectName("label_223") + self.gridLayout_23.addWidget(self.label_223, 0, 0, 1, 4) + self.label_226 = QtWidgets.QLabel(self.tab_stack_bands) + self.label_226.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_226.setFrameShape(QtWidgets.QFrame.Panel) + self.label_226.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_226.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_226.setObjectName("label_226") + self.gridLayout_23.addWidget(self.label_226, 3, 0, 1, 4) + self.tabWidget_preprocessing.addTab(self.tab_stack_bands, "") + self.tab_mosaic_band_sets = QtWidgets.QWidget() + self.tab_mosaic_band_sets.setObjectName("tab_mosaic_band_sets") + self.gridLayout_69 = QtWidgets.QGridLayout(self.tab_mosaic_band_sets) + self.gridLayout_69.setObjectName("gridLayout_69") + self.horizontalLayout_28 = QtWidgets.QHBoxLayout() + self.horizontalLayout_28.setObjectName("horizontalLayout_28") + self.label_134 = QtWidgets.QLabel(self.tab_mosaic_band_sets) + self.label_134.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_134.setFrameShape(QtWidgets.QFrame.Panel) + self.label_134.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_134.setObjectName("label_134") + self.horizontalLayout_28.addWidget(self.label_134) + self.gridLayout_69.addLayout(self.horizontalLayout_28, 0, 0, 1, 1) + self.gridLayout_66 = QtWidgets.QGridLayout() + self.gridLayout_66.setObjectName("gridLayout_66") + self.nodata_checkBox_9 = QtWidgets.QCheckBox(self.tab_mosaic_band_sets) + self.nodata_checkBox_9.setObjectName("nodata_checkBox_9") + self.gridLayout_66.addWidget(self.nodata_checkBox_9, 1, 0, 1, 1) + spacerItem51 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_66.addItem(spacerItem51, 1, 2, 1, 1) + self.mosaic_virtual_checkBox = QtWidgets.QCheckBox(self.tab_mosaic_band_sets) + self.mosaic_virtual_checkBox.setObjectName("mosaic_virtual_checkBox") + self.gridLayout_66.addWidget(self.mosaic_virtual_checkBox, 2, 0, 1, 1) + self.mosaic_output_prefix = QtWidgets.QLineEdit(self.tab_mosaic_band_sets) + self.mosaic_output_prefix.setMaxLength(10) + self.mosaic_output_prefix.setObjectName("mosaic_output_prefix") + self.gridLayout_66.addWidget(self.mosaic_output_prefix, 3, 1, 1, 1) + self.nodata_spinBox_10 = QtWidgets.QSpinBox(self.tab_mosaic_band_sets) + self.nodata_spinBox_10.setMinimum(-2147483647) + self.nodata_spinBox_10.setMaximum(2147483647) + self.nodata_spinBox_10.setObjectName("nodata_spinBox_10") + self.gridLayout_66.addWidget(self.nodata_spinBox_10, 1, 1, 1, 1) + self.mosaic_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_mosaic_band_sets) + self.mosaic_output_name_lineEdit.setMaxLength(10) + self.mosaic_output_name_lineEdit.setObjectName("mosaic_output_name_lineEdit") + self.gridLayout_66.addWidget(self.mosaic_output_name_lineEdit, 4, 1, 1, 1) + self.label_135 = QtWidgets.QLabel(self.tab_mosaic_band_sets) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_261.sizePolicy().hasHeightForWidth()) - self.label_261.setSizePolicy(sizePolicy) - self.label_261.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_261.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_261.setObjectName("label_261") - self.gridLayout_218.addWidget(self.label_261, 1, 0, 1, 1) - self.label_240 = QtWidgets.QLabel(self.tab_classification) - self.label_240.setStyleSheet("background-color : #656565; color : white") - self.label_240.setFrameShape(QtWidgets.QFrame.Panel) - self.label_240.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_240.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_240.setObjectName("label_240") - self.gridLayout_218.addWidget(self.label_240, 3, 0, 1, 4) - self.gridLayout_255 = QtWidgets.QGridLayout() - self.gridLayout_255.setObjectName("gridLayout_255") - self.alg_threshold_SpinBox = QtWidgets.QDoubleSpinBox(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.alg_threshold_SpinBox.sizePolicy().hasHeightForWidth()) - self.alg_threshold_SpinBox.setSizePolicy(sizePolicy) - self.alg_threshold_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.alg_threshold_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.alg_threshold_SpinBox.setDecimals(4) - self.alg_threshold_SpinBox.setMaximum(10000.0) - self.alg_threshold_SpinBox.setObjectName("alg_threshold_SpinBox") - self.gridLayout_255.addWidget(self.alg_threshold_SpinBox, 0, 1, 1, 1) - self.algorithm_threshold_button = QtWidgets.QToolButton(self.tab_classification) - self.algorithm_threshold_button.setStyleSheet("margin: 0px;padding: 0px;") - self.algorithm_threshold_button.setIcon(icon9) - self.algorithm_threshold_button.setIconSize(QtCore.QSize(22, 22)) - self.algorithm_threshold_button.setObjectName("algorithm_threshold_button") - self.gridLayout_255.addWidget(self.algorithm_threshold_button, 0, 3, 1, 1) - self.label_234 = QtWidgets.QLabel(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_234.sizePolicy().hasHeightForWidth()) - self.label_234.setSizePolicy(sizePolicy) - self.label_234.setMaximumSize(QtCore.QSize(100, 16777215)) - self.label_234.setObjectName("label_234") - self.gridLayout_255.addWidget(self.label_234, 0, 0, 1, 1) - spacerItem102 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_255.addItem(spacerItem102, 0, 2, 1, 1) - self.gridLayout_218.addLayout(self.gridLayout_255, 4, 3, 1, 1) - self.label_243 = QtWidgets.QLabel(self.tab_classification) - self.label_243.setStyleSheet("background-color : #656565; color : white") - self.label_243.setFrameShape(QtWidgets.QFrame.Panel) - self.label_243.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_243.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_243.setObjectName("label_243") - self.gridLayout_218.addWidget(self.label_243, 0, 0, 1, 4) - spacerItem103 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_218.addItem(spacerItem103, 1, 3, 1, 1) - self.gridLayout_260.addLayout(self.gridLayout_218, 0, 0, 1, 1) - self.verticalLayout_4 = QtWidgets.QVBoxLayout() - self.verticalLayout_4.setObjectName("verticalLayout_4") - self.gridLayout_225 = QtWidgets.QGridLayout() - self.gridLayout_225.setObjectName("gridLayout_225") - self.LC_signature_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.LC_signature_checkBox.setObjectName("LC_signature_checkBox") - self.gridLayout_225.addWidget(self.LC_signature_checkBox, 1, 1, 1, 1) - self.label_235 = QtWidgets.QLabel(self.tab_classification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_135.sizePolicy().hasHeightForWidth()) + self.label_135.setSizePolicy(sizePolicy) + self.label_135.setMinimumSize(QtCore.QSize(229, 0)) + self.label_135.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_135.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_135.setObjectName("label_135") + self.gridLayout_66.addWidget(self.label_135, 4, 0, 1, 1) + self.label_137 = QtWidgets.QLabel(self.tab_mosaic_band_sets) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_235.sizePolicy().hasHeightForWidth()) - self.label_235.setSizePolicy(sizePolicy) - self.label_235.setObjectName("label_235") - self.gridLayout_225.addWidget(self.label_235, 1, 0, 1, 1) - self.LC_signature_button = QtWidgets.QToolButton(self.tab_classification) - self.LC_signature_button.setStyleSheet("margin: 0px;padding: 0px;") - self.LC_signature_button.setText("") - self.LC_signature_button.setIcon(icon6) - self.LC_signature_button.setIconSize(QtCore.QSize(22, 22)) - self.LC_signature_button.setObjectName("LC_signature_button") - self.gridLayout_225.addWidget(self.LC_signature_button, 1, 5, 1, 1) - self.LCS_leave_unclassified_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.LCS_leave_unclassified_checkBox.setObjectName("LCS_leave_unclassified_checkBox") - self.gridLayout_225.addWidget(self.LCS_leave_unclassified_checkBox, 1, 3, 1, 1) - self.label_241 = QtWidgets.QLabel(self.tab_classification) - self.label_241.setStyleSheet("background-color : #656565; color : white") - self.label_241.setFrameShape(QtWidgets.QFrame.Panel) - self.label_241.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_241.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_241.setObjectName("label_241") - self.gridLayout_225.addWidget(self.label_241, 0, 0, 1, 6) - self.LCS_class_algorithm_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.LCS_class_algorithm_checkBox.setObjectName("LCS_class_algorithm_checkBox") - self.gridLayout_225.addWidget(self.LCS_class_algorithm_checkBox, 1, 2, 1, 1) - self.verticalLayout_4.addLayout(self.gridLayout_225) - self.label_242 = QtWidgets.QLabel(self.tab_classification) - self.label_242.setStyleSheet("background-color : #656565; color : white") - self.label_242.setFrameShape(QtWidgets.QFrame.Panel) - self.label_242.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_242.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_242.setObjectName("label_242") - self.verticalLayout_4.addWidget(self.label_242) - self.gridLayout_239 = QtWidgets.QGridLayout() - self.gridLayout_239.setSpacing(4) - self.gridLayout_239.setObjectName("gridLayout_239") - self.resetQmlButton = QtWidgets.QToolButton(self.tab_classification) - self.resetQmlButton.setStyleSheet("margin: 0px;padding: 0px;") - self.resetQmlButton.setIcon(icon59) - self.resetQmlButton.setIconSize(QtCore.QSize(22, 22)) - self.resetQmlButton.setObjectName("resetQmlButton") - self.gridLayout_239.addWidget(self.resetQmlButton, 0, 3, 1, 1) - self.label_238 = QtWidgets.QLabel(self.tab_classification) + sizePolicy.setHeightForWidth(self.label_137.sizePolicy().hasHeightForWidth()) + self.label_137.setSizePolicy(sizePolicy) + self.label_137.setMinimumSize(QtCore.QSize(229, 0)) + self.label_137.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_137.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_137.setObjectName("label_137") + self.gridLayout_66.addWidget(self.label_137, 3, 0, 1, 1) + self.mosaic_band_sets_lineEdit = QtWidgets.QLineEdit(self.tab_mosaic_band_sets) + self.mosaic_band_sets_lineEdit.setObjectName("mosaic_band_sets_lineEdit") + self.gridLayout_66.addWidget(self.mosaic_band_sets_lineEdit, 0, 1, 1, 2) + self.label_144 = QtWidgets.QLabel(self.tab_mosaic_band_sets) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_238.sizePolicy().hasHeightForWidth()) - self.label_238.setSizePolicy(sizePolicy) - self.label_238.setObjectName("label_238") - self.gridLayout_239.addWidget(self.label_238, 0, 0, 1, 1) - self.qml_Button = QtWidgets.QToolButton(self.tab_classification) - self.qml_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.qml_Button.setIcon(icon65) - self.qml_Button.setIconSize(QtCore.QSize(22, 22)) - self.qml_Button.setObjectName("qml_Button") - self.gridLayout_239.addWidget(self.qml_Button, 0, 2, 1, 1) - self.qml_lineEdit = QtWidgets.QLineEdit(self.tab_classification) - self.qml_lineEdit.setEnabled(False) - self.qml_lineEdit.setObjectName("qml_lineEdit") - self.gridLayout_239.addWidget(self.qml_lineEdit, 0, 1, 1, 1) - self.verticalLayout_4.addLayout(self.gridLayout_239) - self.gridLayout_241 = QtWidgets.QGridLayout() - self.gridLayout_241.setObjectName("gridLayout_241") - self.mask_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.mask_checkBox.setObjectName("mask_checkBox") - self.gridLayout_241.addWidget(self.mask_checkBox, 0, 0, 1, 1) - self.resetMaskButton = QtWidgets.QToolButton(self.tab_classification) - self.resetMaskButton.setStyleSheet("margin: 0px;padding: 0px;") - self.resetMaskButton.setIcon(icon59) - self.resetMaskButton.setIconSize(QtCore.QSize(22, 22)) - self.resetMaskButton.setObjectName("resetMaskButton") - self.gridLayout_241.addWidget(self.resetMaskButton, 0, 3, 1, 1) - self.mask_lineEdit = QtWidgets.QLineEdit(self.tab_classification) - self.mask_lineEdit.setEnabled(False) - self.mask_lineEdit.setInputMethodHints(QtCore.Qt.ImhUrlCharactersOnly) - self.mask_lineEdit.setText("") - self.mask_lineEdit.setObjectName("mask_lineEdit") - self.gridLayout_241.addWidget(self.mask_lineEdit, 0, 1, 1, 2) - self.verticalLayout_4.addLayout(self.gridLayout_241) - self.horizontalLayout_56 = QtWidgets.QHBoxLayout() - self.horizontalLayout_56.setObjectName("horizontalLayout_56") - self.vector_output_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.vector_output_checkBox.setObjectName("vector_output_checkBox") - self.horizontalLayout_56.addWidget(self.vector_output_checkBox) - self.report_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.report_checkBox.setObjectName("report_checkBox") - self.horizontalLayout_56.addWidget(self.report_checkBox) - self.alg_files_checkBox = QtWidgets.QCheckBox(self.tab_classification) - self.alg_files_checkBox.setObjectName("alg_files_checkBox") - self.horizontalLayout_56.addWidget(self.alg_files_checkBox) - self.verticalLayout_4.addLayout(self.horizontalLayout_56) - self.gridLayout_249 = QtWidgets.QGridLayout() - self.gridLayout_249.setObjectName("gridLayout_249") - self.button_classification = QtWidgets.QToolButton(self.tab_classification) + sizePolicy.setHeightForWidth(self.label_144.sizePolicy().hasHeightForWidth()) + self.label_144.setSizePolicy(sizePolicy) + self.label_144.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_144.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_144.setObjectName("label_144") + self.gridLayout_66.addWidget(self.label_144, 0, 0, 1, 1) + self.gridLayout_69.addLayout(self.gridLayout_66, 1, 0, 1, 1) + spacerItem52 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_69.addItem(spacerItem52, 2, 0, 1, 1) + self.gridLayout_228 = QtWidgets.QGridLayout() + self.gridLayout_228.setObjectName("gridLayout_228") + spacerItem53 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_228.addItem(spacerItem53, 1, 0, 1, 1) + self.mosaic_bandsets_toolButton = QtWidgets.QToolButton(self.tab_mosaic_band_sets) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.button_classification.setFont(font) - self.button_classification.setLayoutDirection(QtCore.Qt.RightToLeft) - self.button_classification.setStyleSheet("margin: 0px;padding: 0px;") - self.button_classification.setIcon(icon64) - self.button_classification.setIconSize(QtCore.QSize(34, 34)) - self.button_classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.button_classification.setObjectName("button_classification") - self.gridLayout_249.addWidget(self.button_classification, 2, 2, 1, 1) - self.label_239 = QtWidgets.QLabel(self.tab_classification) - self.label_239.setStyleSheet("background-color : #656565; color : white") - self.label_239.setFrameShape(QtWidgets.QFrame.Panel) - self.label_239.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_239.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_239.setObjectName("label_239") - self.gridLayout_249.addWidget(self.label_239, 1, 0, 1, 3) - spacerItem104 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_249.addItem(spacerItem104, 0, 2, 1, 1) - spacerItem105 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_249.addItem(spacerItem105, 2, 0, 1, 1) - self.classification = QtWidgets.QToolButton(self.tab_classification) + self.mosaic_bandsets_toolButton.setFont(font) + self.mosaic_bandsets_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.mosaic_bandsets_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.mosaic_bandsets_toolButton.setIcon(icon44) + self.mosaic_bandsets_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.mosaic_bandsets_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.mosaic_bandsets_toolButton.setObjectName("mosaic_bandsets_toolButton") + self.gridLayout_228.addWidget(self.mosaic_bandsets_toolButton, 1, 2, 1, 1) + self.mosaic_bandsets = QtWidgets.QToolButton(self.tab_mosaic_band_sets) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.classification.setFont(font) - self.classification.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification.setStyleSheet("margin: 0px;padding: 0px;") - self.classification.setIcon(icon48) - self.classification.setIconSize(QtCore.QSize(34, 34)) - self.classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification.setObjectName("classification") - self.gridLayout_249.addWidget(self.classification, 2, 1, 1, 1) - self.verticalLayout_4.addLayout(self.gridLayout_249) - self.gridLayout_260.addLayout(self.verticalLayout_4, 1, 0, 1, 1) - self.tabWidget_4.addTab(self.tab_classification, "") - self.tab_random_forest = QtWidgets.QWidget() - self.tab_random_forest.setObjectName("tab_random_forest") - self.gridLayout_288 = QtWidgets.QGridLayout(self.tab_random_forest) - self.gridLayout_288.setObjectName("gridLayout_288") - self.toolBox_random_forest = QtWidgets.QToolBox(self.tab_random_forest) - self.toolBox_random_forest.setStyleSheet("") - self.toolBox_random_forest.setObjectName("toolBox_random_forest") - self.page_21 = QtWidgets.QWidget() - self.page_21.setGeometry(QtCore.QRect(0, 0, 634, 327)) - self.page_21.setObjectName("page_21") - self.gridLayout_287 = QtWidgets.QGridLayout(self.page_21) - self.gridLayout_287.setObjectName("gridLayout_287") - self.gridLayout_280 = QtWidgets.QGridLayout() - self.gridLayout_280.setObjectName("gridLayout_280") - self.horizontalLayout_58 = QtWidgets.QHBoxLayout() - self.horizontalLayout_58.setObjectName("horizontalLayout_58") - self.label_233 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_233.sizePolicy().hasHeightForWidth()) - self.label_233.setSizePolicy(sizePolicy) - self.label_233.setObjectName("label_233") - self.horizontalLayout_58.addWidget(self.label_233) - self.macroclass_checkBox_rf = QtWidgets.QCheckBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.macroclass_checkBox_rf.sizePolicy().hasHeightForWidth()) - self.macroclass_checkBox_rf.setSizePolicy(sizePolicy) - self.macroclass_checkBox_rf.setChecked(True) - self.macroclass_checkBox_rf.setObjectName("macroclass_checkBox_rf") - self.horizontalLayout_58.addWidget(self.macroclass_checkBox_rf) - self.class_checkBox_rf = QtWidgets.QCheckBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_checkBox_rf.sizePolicy().hasHeightForWidth()) - self.class_checkBox_rf.setSizePolicy(sizePolicy) - self.class_checkBox_rf.setObjectName("class_checkBox_rf") - self.horizontalLayout_58.addWidget(self.class_checkBox_rf) - spacerItem106 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_58.addItem(spacerItem106) - self.gridLayout_280.addLayout(self.horizontalLayout_58, 2, 0, 1, 3) - self.band_set_comb_spinBox_13 = QtWidgets.QSpinBox(self.page_21) - self.band_set_comb_spinBox_13.setMinimum(1) - self.band_set_comb_spinBox_13.setMaximum(100000) - self.band_set_comb_spinBox_13.setObjectName("band_set_comb_spinBox_13") - self.gridLayout_280.addWidget(self.band_set_comb_spinBox_13, 1, 1, 1, 1) - self.label_262 = QtWidgets.QLabel(self.page_21) + self.mosaic_bandsets.setFont(font) + self.mosaic_bandsets.setLayoutDirection(QtCore.Qt.RightToLeft) + self.mosaic_bandsets.setStyleSheet("margin: 0px;padding: 0px;") + self.mosaic_bandsets.setIcon(icon33) + self.mosaic_bandsets.setIconSize(QtCore.QSize(34, 34)) + self.mosaic_bandsets.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.mosaic_bandsets.setObjectName("mosaic_bandsets") + self.gridLayout_228.addWidget(self.mosaic_bandsets, 1, 1, 1, 1) + self.label_182 = QtWidgets.QLabel(self.tab_mosaic_band_sets) + self.label_182.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_182.setFrameShape(QtWidgets.QFrame.Panel) + self.label_182.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_182.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_182.setObjectName("label_182") + self.gridLayout_228.addWidget(self.label_182, 0, 0, 1, 3) + self.gridLayout_69.addLayout(self.gridLayout_228, 3, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_mosaic_band_sets, "") + self.tab_cloud_mask = QtWidgets.QWidget() + self.tab_cloud_mask.setObjectName("tab_cloud_mask") + self.gridLayout_76 = QtWidgets.QGridLayout(self.tab_cloud_mask) + self.gridLayout_76.setObjectName("gridLayout_76") + self.horizontalLayout_33 = QtWidgets.QHBoxLayout() + self.horizontalLayout_33.setObjectName("horizontalLayout_33") + self.label_138 = QtWidgets.QLabel(self.tab_cloud_mask) + self.label_138.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_138.setFrameShape(QtWidgets.QFrame.Panel) + self.label_138.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_138.setObjectName("label_138") + self.horizontalLayout_33.addWidget(self.label_138) + self.gridLayout_76.addLayout(self.horizontalLayout_33, 0, 0, 1, 1) + self.gridLayout_261 = QtWidgets.QGridLayout() + self.gridLayout_261.setObjectName("gridLayout_261") + self.label_260 = QtWidgets.QLabel(self.tab_cloud_mask) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_262.sizePolicy().hasHeightForWidth()) - self.label_262.setSizePolicy(sizePolicy) - self.label_262.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_262.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_262.setObjectName("label_262") - self.gridLayout_280.addWidget(self.label_262, 1, 0, 1, 1) - self.label_245 = QtWidgets.QLabel(self.page_21) - self.label_245.setStyleSheet("background-color : #656565; color : white") - self.label_245.setFrameShape(QtWidgets.QFrame.Panel) - self.label_245.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_245.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_245.setObjectName("label_245") - self.gridLayout_280.addWidget(self.label_245, 0, 0, 1, 3) - self.gridLayout_284 = QtWidgets.QGridLayout() - self.gridLayout_284.setObjectName("gridLayout_284") - self.number_trees_SpinBox = QtWidgets.QDoubleSpinBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.number_trees_SpinBox.sizePolicy().hasHeightForWidth()) - self.number_trees_SpinBox.setSizePolicy(sizePolicy) - self.number_trees_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.number_trees_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.number_trees_SpinBox.setDecimals(0) - self.number_trees_SpinBox.setMinimum(1.0) - self.number_trees_SpinBox.setMaximum(1000000.0) - self.number_trees_SpinBox.setSingleStep(1.0) - self.number_trees_SpinBox.setProperty("value", 10.0) - self.number_trees_SpinBox.setObjectName("number_trees_SpinBox") - self.gridLayout_284.addWidget(self.number_trees_SpinBox, 0, 1, 1, 1) - self.label_237 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_237.sizePolicy().hasHeightForWidth()) - self.label_237.setSizePolicy(sizePolicy) - self.label_237.setMaximumSize(QtCore.QSize(150, 16777215)) - self.label_237.setObjectName("label_237") - self.gridLayout_284.addWidget(self.label_237, 0, 0, 1, 1) - spacerItem107 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_284.addItem(spacerItem107, 0, 2, 1, 1) - self.gridLayout_280.addLayout(self.gridLayout_284, 4, 0, 1, 3) - self.gridLayout_282 = QtWidgets.QGridLayout() - self.gridLayout_282.setObjectName("gridLayout_282") - self.number_training_samples_SpinBox = QtWidgets.QDoubleSpinBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.number_training_samples_SpinBox.sizePolicy().hasHeightForWidth()) - self.number_training_samples_SpinBox.setSizePolicy(sizePolicy) - self.number_training_samples_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.number_training_samples_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.number_training_samples_SpinBox.setDecimals(0) - self.number_training_samples_SpinBox.setMinimum(1.0) - self.number_training_samples_SpinBox.setMaximum(1000000.0) - self.number_training_samples_SpinBox.setSingleStep(100.0) - self.number_training_samples_SpinBox.setProperty("value", 5000.0) - self.number_training_samples_SpinBox.setObjectName("number_training_samples_SpinBox") - self.gridLayout_282.addWidget(self.number_training_samples_SpinBox, 0, 1, 1, 1) - self.label_236 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_236.sizePolicy().hasHeightForWidth()) - self.label_236.setSizePolicy(sizePolicy) - self.label_236.setMaximumSize(QtCore.QSize(208, 16777215)) - self.label_236.setObjectName("label_236") - self.gridLayout_282.addWidget(self.label_236, 0, 0, 1, 1) - spacerItem108 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_282.addItem(spacerItem108, 0, 2, 1, 1) - self.gridLayout_280.addLayout(self.gridLayout_282, 3, 0, 1, 3) - spacerItem109 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_280.addItem(spacerItem109, 1, 2, 1, 1) - self.gridLayout_287.addLayout(self.gridLayout_280, 0, 0, 1, 1) - self.gridLayout_285 = QtWidgets.QGridLayout() - self.gridLayout_285.setObjectName("gridLayout_285") - self.evaluate_classifier_checkBox = QtWidgets.QCheckBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.evaluate_classifier_checkBox.sizePolicy().hasHeightForWidth()) - self.evaluate_classifier_checkBox.setSizePolicy(sizePolicy) - self.evaluate_classifier_checkBox.setObjectName("evaluate_classifier_checkBox") - self.gridLayout_285.addWidget(self.evaluate_classifier_checkBox, 0, 0, 1, 1) - self.evaluate_feature_power_set_checkBox = QtWidgets.QCheckBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) + sizePolicy.setHeightForWidth(self.label_260.sizePolicy().hasHeightForWidth()) + self.label_260.setSizePolicy(sizePolicy) + self.label_260.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_260.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_260.setObjectName("label_260") + self.gridLayout_261.addWidget(self.label_260, 0, 0, 1, 1) + spacerItem54 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_261.addItem(spacerItem54, 0, 2, 1, 1) + self.band_set_comb_spinBox_9 = QtWidgets.QSpinBox(self.tab_cloud_mask) + self.band_set_comb_spinBox_9.setMinimum(1) + self.band_set_comb_spinBox_9.setMaximum(100000) + self.band_set_comb_spinBox_9.setObjectName("band_set_comb_spinBox_9") + self.gridLayout_261.addWidget(self.band_set_comb_spinBox_9, 0, 1, 1, 1) + self.gridLayout_76.addLayout(self.gridLayout_261, 1, 0, 1, 1) + self.gridLayout_106 = QtWidgets.QGridLayout() + self.gridLayout_106.setObjectName("gridLayout_106") + self.classification_name_combo_4 = QtWidgets.QComboBox(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.evaluate_feature_power_set_checkBox.sizePolicy().hasHeightForWidth()) - self.evaluate_feature_power_set_checkBox.setSizePolicy(sizePolicy) - self.evaluate_feature_power_set_checkBox.setObjectName("evaluate_feature_power_set_checkBox") - self.gridLayout_285.addWidget(self.evaluate_feature_power_set_checkBox, 0, 1, 1, 1) - spacerItem110 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_285.addItem(spacerItem110, 0, 6, 1, 1) - self.label_248 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHeightForWidth(self.classification_name_combo_4.sizePolicy().hasHeightForWidth()) + self.classification_name_combo_4.setSizePolicy(sizePolicy) + self.classification_name_combo_4.setObjectName("classification_name_combo_4") + self.gridLayout_106.addWidget(self.classification_name_combo_4, 0, 1, 1, 1) + self.cloud_mask_classes_lineEdit = QtWidgets.QLineEdit(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_248.sizePolicy().hasHeightForWidth()) - self.label_248.setSizePolicy(sizePolicy) - self.label_248.setMaximumSize(QtCore.QSize(100, 16777215)) - self.label_248.setObjectName("label_248") - self.gridLayout_285.addWidget(self.label_248, 0, 4, 1, 1) - self.rf_power_min_SpinBox = QtWidgets.QDoubleSpinBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.cloud_mask_classes_lineEdit.sizePolicy().hasHeightForWidth()) + self.cloud_mask_classes_lineEdit.setSizePolicy(sizePolicy) + self.cloud_mask_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) + self.cloud_mask_classes_lineEdit.setText("") + self.cloud_mask_classes_lineEdit.setMaxLength(10000) + self.cloud_mask_classes_lineEdit.setObjectName("cloud_mask_classes_lineEdit") + self.gridLayout_106.addWidget(self.cloud_mask_classes_lineEdit, 1, 1, 1, 1) + self.label_203 = QtWidgets.QLabel(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rf_power_min_SpinBox.sizePolicy().hasHeightForWidth()) - self.rf_power_min_SpinBox.setSizePolicy(sizePolicy) - self.rf_power_min_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.rf_power_min_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.rf_power_min_SpinBox.setDecimals(0) - self.rf_power_min_SpinBox.setMinimum(1.0) - self.rf_power_min_SpinBox.setMaximum(1000000.0) - self.rf_power_min_SpinBox.setSingleStep(1.0) - self.rf_power_min_SpinBox.setProperty("value", 2.0) - self.rf_power_min_SpinBox.setObjectName("rf_power_min_SpinBox") - self.gridLayout_285.addWidget(self.rf_power_min_SpinBox, 0, 3, 1, 1) - self.label_247 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHeightForWidth(self.label_203.sizePolicy().hasHeightForWidth()) + self.label_203.setSizePolicy(sizePolicy) + self.label_203.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_203.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_203.setObjectName("label_203") + self.gridLayout_106.addWidget(self.label_203, 1, 0, 1, 1) + self.label_186 = QtWidgets.QLabel(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_247.sizePolicy().hasHeightForWidth()) - self.label_247.setSizePolicy(sizePolicy) - self.label_247.setMaximumSize(QtCore.QSize(100, 16777215)) - self.label_247.setObjectName("label_247") - self.gridLayout_285.addWidget(self.label_247, 0, 2, 1, 1) - self.rf_power_max_SpinBox = QtWidgets.QDoubleSpinBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.label_186.sizePolicy().hasHeightForWidth()) + self.label_186.setSizePolicy(sizePolicy) + self.label_186.setMinimumSize(QtCore.QSize(229, 0)) + self.label_186.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_186.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_186.setObjectName("label_186") + self.gridLayout_106.addWidget(self.label_186, 0, 0, 1, 1) + self.toolButton_reload_23 = QtWidgets.QToolButton(self.tab_cloud_mask) + self.toolButton_reload_23.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_23.setIcon(icon60) + self.toolButton_reload_23.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_23.setObjectName("toolButton_reload_23") + self.gridLayout_106.addWidget(self.toolButton_reload_23, 0, 2, 1, 1) + self.gridLayout_76.addLayout(self.gridLayout_106, 2, 0, 1, 1) + self.gridLayout_143 = QtWidgets.QGridLayout() + self.gridLayout_143.setObjectName("gridLayout_143") + self.mask_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_cloud_mask) + self.mask_output_name_lineEdit.setMaxLength(10) + self.mask_output_name_lineEdit.setObjectName("mask_output_name_lineEdit") + self.gridLayout_143.addWidget(self.mask_output_name_lineEdit, 2, 1, 1, 1) + self.gridLayout_145 = QtWidgets.QGridLayout() + self.gridLayout_145.setObjectName("gridLayout_145") + spacerItem55 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_145.addItem(spacerItem55, 0, 2, 1, 1) + self.cloud_buffer_checkBox = QtWidgets.QCheckBox(self.tab_cloud_mask) + self.cloud_buffer_checkBox.setEnabled(True) + self.cloud_buffer_checkBox.setObjectName("cloud_buffer_checkBox") + self.gridLayout_145.addWidget(self.cloud_buffer_checkBox, 0, 0, 1, 1) + self.nodata_spinBox_11 = QtWidgets.QSpinBox(self.tab_cloud_mask) + self.nodata_spinBox_11.setMinimum(-2147483647) + self.nodata_spinBox_11.setMaximum(2147483647) + self.nodata_spinBox_11.setProperty("value", -32768) + self.nodata_spinBox_11.setObjectName("nodata_spinBox_11") + self.gridLayout_145.addWidget(self.nodata_spinBox_11, 1, 1, 1, 1) + self.label_141 = QtWidgets.QLabel(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rf_power_max_SpinBox.sizePolicy().hasHeightForWidth()) - self.rf_power_max_SpinBox.setSizePolicy(sizePolicy) - self.rf_power_max_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.rf_power_max_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.rf_power_max_SpinBox.setDecimals(0) - self.rf_power_max_SpinBox.setMinimum(1.0) - self.rf_power_max_SpinBox.setMaximum(1000000.0) - self.rf_power_max_SpinBox.setSingleStep(1.0) - self.rf_power_max_SpinBox.setProperty("value", 7.0) - self.rf_power_max_SpinBox.setObjectName("rf_power_max_SpinBox") - self.gridLayout_285.addWidget(self.rf_power_max_SpinBox, 0, 5, 1, 1) - self.save_classifier_checkBox = QtWidgets.QCheckBox(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.label_141.sizePolicy().hasHeightForWidth()) + self.label_141.setSizePolicy(sizePolicy) + self.label_141.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_141.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_141.setObjectName("label_141") + self.gridLayout_145.addWidget(self.label_141, 1, 0, 1, 1) + self.cloud_buffer_spinBox = QtWidgets.QSpinBox(self.tab_cloud_mask) + self.cloud_buffer_spinBox.setMinimum(1) + self.cloud_buffer_spinBox.setMaximum(1000) + self.cloud_buffer_spinBox.setProperty("value", 1) + self.cloud_buffer_spinBox.setObjectName("cloud_buffer_spinBox") + self.gridLayout_145.addWidget(self.cloud_buffer_spinBox, 0, 1, 1, 1) + self.gridLayout_143.addLayout(self.gridLayout_145, 0, 0, 1, 2) + self.label_140 = QtWidgets.QLabel(self.tab_cloud_mask) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.save_classifier_checkBox.sizePolicy().hasHeightForWidth()) - self.save_classifier_checkBox.setSizePolicy(sizePolicy) - self.save_classifier_checkBox.setObjectName("save_classifier_checkBox") - self.gridLayout_285.addWidget(self.save_classifier_checkBox, 1, 0, 1, 1) - self.gridLayout_287.addLayout(self.gridLayout_285, 1, 0, 1, 1) - self.gridLayout_286 = QtWidgets.QGridLayout() - self.gridLayout_286.setObjectName("gridLayout_286") - self.label_244 = QtWidgets.QLabel(self.page_21) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_140.sizePolicy().hasHeightForWidth()) + self.label_140.setSizePolicy(sizePolicy) + self.label_140.setMinimumSize(QtCore.QSize(229, 0)) + self.label_140.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_140.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_140.setObjectName("label_140") + self.gridLayout_143.addWidget(self.label_140, 2, 0, 1, 1) + self.mask_virtual_checkBox = QtWidgets.QCheckBox(self.tab_cloud_mask) + self.mask_virtual_checkBox.setObjectName("mask_virtual_checkBox") + self.gridLayout_143.addWidget(self.mask_virtual_checkBox, 1, 0, 1, 1) + self.gridLayout_76.addLayout(self.gridLayout_143, 3, 0, 1, 1) + spacerItem56 = QtWidgets.QSpacerItem(20, 173, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_76.addItem(spacerItem56, 4, 0, 1, 1) + self.gridLayout_257 = QtWidgets.QGridLayout() + self.gridLayout_257.setObjectName("gridLayout_257") + self.cloud_mask_toolButton = QtWidgets.QToolButton(self.tab_cloud_mask) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.cloud_mask_toolButton.setFont(font) + self.cloud_mask_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.cloud_mask_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.cloud_mask_toolButton.setIcon(icon44) + self.cloud_mask_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.cloud_mask_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.cloud_mask_toolButton.setObjectName("cloud_mask_toolButton") + self.gridLayout_257.addWidget(self.cloud_mask_toolButton, 1, 2, 1, 1) + self.cloud_masking = QtWidgets.QToolButton(self.tab_cloud_mask) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.cloud_masking.setFont(font) + self.cloud_masking.setLayoutDirection(QtCore.Qt.RightToLeft) + self.cloud_masking.setStyleSheet("margin: 0px;padding: 0px;") + self.cloud_masking.setIcon(icon33) + self.cloud_masking.setIconSize(QtCore.QSize(34, 34)) + self.cloud_masking.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.cloud_masking.setObjectName("cloud_masking") + self.gridLayout_257.addWidget(self.cloud_masking, 1, 1, 1, 1) + spacerItem57 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_257.addItem(spacerItem57, 1, 0, 1, 1) + self.label_185 = QtWidgets.QLabel(self.tab_cloud_mask) + self.label_185.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_185.setFrameShape(QtWidgets.QFrame.Panel) + self.label_185.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_185.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_185.setObjectName("label_185") + self.gridLayout_257.addWidget(self.label_185, 0, 0, 1, 3) + self.gridLayout_76.addLayout(self.gridLayout_257, 5, 0, 1, 1) + self.tabWidget_preprocessing.addTab(self.tab_cloud_mask, "") + self.gridLayout_6.addWidget(self.tabWidget_preprocessing, 0, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_preprocessing, "") + self.tab_band_processing = QtWidgets.QWidget() + self.tab_band_processing.setObjectName("tab_band_processing") + self.gridLayout_62 = QtWidgets.QGridLayout(self.tab_band_processing) + self.gridLayout_62.setObjectName("gridLayout_62") + self.tabWidget_4 = QtWidgets.QTabWidget(self.tab_band_processing) + self.tabWidget_4.setStyleSheet("") + self.tabWidget_4.setIconSize(QtCore.QSize(20, 20)) + self.tabWidget_4.setDocumentMode(True) + self.tabWidget_4.setObjectName("tabWidget_4") + self.tab_bandset_combination_2 = QtWidgets.QWidget() + self.tab_bandset_combination_2.setObjectName("tab_bandset_combination_2") + self.gridLayout_44 = QtWidgets.QGridLayout(self.tab_bandset_combination_2) + self.gridLayout_44.setObjectName("gridLayout_44") + self.toolBox_band_set_combination = QtWidgets.QToolBox(self.tab_bandset_combination_2) + self.toolBox_band_set_combination.setObjectName("toolBox_band_set_combination") + self.page_29 = QtWidgets.QWidget() + self.page_29.setGeometry(QtCore.QRect(0, 0, 336, 221)) + self.page_29.setObjectName("page_29") + self.gridLayout_45 = QtWidgets.QGridLayout(self.page_29) + self.gridLayout_45.setObjectName("gridLayout_45") + self.horizontalLayout_34 = QtWidgets.QHBoxLayout() + self.horizontalLayout_34.setObjectName("horizontalLayout_34") + self.label_72 = QtWidgets.QLabel(self.page_29) + self.label_72.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_72.setFrameShape(QtWidgets.QFrame.Panel) + self.label_72.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_72.setObjectName("label_72") + self.horizontalLayout_34.addWidget(self.label_72) + self.gridLayout_45.addLayout(self.horizontalLayout_34, 0, 0, 1, 1) + self.gridLayout_331 = QtWidgets.QGridLayout() + self.gridLayout_331.setObjectName("gridLayout_331") + spacerItem58 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_331.addItem(spacerItem58, 1, 3, 1, 1) + self.band_set_comb_spinBox = QtWidgets.QSpinBox(self.page_29) + self.band_set_comb_spinBox.setMinimum(1) + self.band_set_comb_spinBox.setMaximum(100000) + self.band_set_comb_spinBox.setObjectName("band_set_comb_spinBox") + self.gridLayout_331.addWidget(self.band_set_comb_spinBox, 1, 2, 1, 1) + self.label_250 = QtWidgets.QLabel(self.page_29) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_244.sizePolicy().hasHeightForWidth()) - self.label_244.setSizePolicy(sizePolicy) - self.label_244.setObjectName("label_244") - self.gridLayout_286.addWidget(self.label_244, 0, 0, 1, 1) - self.classifier_Button = QtWidgets.QToolButton(self.page_21) - self.classifier_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.classifier_Button.setIcon(icon65) - self.classifier_Button.setIconSize(QtCore.QSize(22, 22)) - self.classifier_Button.setObjectName("classifier_Button") - self.gridLayout_286.addWidget(self.classifier_Button, 0, 2, 1, 1) - self.classifier_lineEdit_ = QtWidgets.QLineEdit(self.page_21) - self.classifier_lineEdit_.setEnabled(False) - self.classifier_lineEdit_.setObjectName("classifier_lineEdit_") - self.gridLayout_286.addWidget(self.classifier_lineEdit_, 0, 1, 1, 1) - self.resetClassifierButton = QtWidgets.QToolButton(self.page_21) - self.resetClassifierButton.setStyleSheet("margin: 0px;padding: 0px;") - self.resetClassifierButton.setIcon(icon59) - self.resetClassifierButton.setIconSize(QtCore.QSize(22, 22)) - self.resetClassifierButton.setObjectName("resetClassifierButton") - self.gridLayout_286.addWidget(self.resetClassifierButton, 0, 3, 1, 1) - self.gridLayout_287.addLayout(self.gridLayout_286, 2, 0, 1, 1) - self.gridLayout_283 = QtWidgets.QGridLayout() - self.gridLayout_283.setObjectName("gridLayout_283") - self.button_random_forest = QtWidgets.QToolButton(self.page_21) + sizePolicy.setHeightForWidth(self.label_250.sizePolicy().hasHeightForWidth()) + self.label_250.setSizePolicy(sizePolicy) + self.label_250.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_250.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_250.setWordWrap(True) + self.label_250.setObjectName("label_250") + self.gridLayout_331.addWidget(self.label_250, 1, 0, 1, 2) + self.horizontalLayout_17 = QtWidgets.QHBoxLayout() + self.horizontalLayout_17.setObjectName("horizontalLayout_17") + self.nodata_checkBox_12 = QtWidgets.QCheckBox(self.page_29) + self.nodata_checkBox_12.setObjectName("nodata_checkBox_12") + self.horizontalLayout_17.addWidget(self.nodata_checkBox_12) + self.nodata_spinBox_16 = QtWidgets.QSpinBox(self.page_29) + self.nodata_spinBox_16.setMinimum(-999999999) + self.nodata_spinBox_16.setMaximum(999999999) + self.nodata_spinBox_16.setProperty("value", 0) + self.nodata_spinBox_16.setObjectName("nodata_spinBox_16") + self.horizontalLayout_17.addWidget(self.nodata_spinBox_16) + spacerItem59 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_17.addItem(spacerItem59) + self.gridLayout_331.addLayout(self.horizontalLayout_17, 2, 0, 1, 4) + self.gridLayout_45.addLayout(self.gridLayout_331, 1, 0, 1, 1) + self.gridLayout_333 = QtWidgets.QGridLayout() + self.gridLayout_333.setObjectName("gridLayout_333") + self.band_combination = QtWidgets.QToolButton(self.page_29) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.button_random_forest.setFont(font) - self.button_random_forest.setLayoutDirection(QtCore.Qt.RightToLeft) - self.button_random_forest.setStyleSheet("margin: 0px;padding: 0px;") - self.button_random_forest.setIcon(icon64) - self.button_random_forest.setIconSize(QtCore.QSize(34, 34)) - self.button_random_forest.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.button_random_forest.setObjectName("button_random_forest") - self.gridLayout_283.addWidget(self.button_random_forest, 2, 2, 1, 1) - self.label_246 = QtWidgets.QLabel(self.page_21) - self.label_246.setStyleSheet("background-color : #656565; color : white") - self.label_246.setFrameShape(QtWidgets.QFrame.Panel) - self.label_246.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_246.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_246.setObjectName("label_246") - self.gridLayout_283.addWidget(self.label_246, 1, 0, 1, 3) - spacerItem111 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_283.addItem(spacerItem111, 0, 2, 1, 1) - spacerItem112 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_283.addItem(spacerItem112, 2, 0, 1, 1) - self.random_forest = QtWidgets.QToolButton(self.page_21) + self.band_combination.setFont(font) + self.band_combination.setLayoutDirection(QtCore.Qt.RightToLeft) + self.band_combination.setStyleSheet("margin: 0px;padding: 0px;") + self.band_combination.setIcon(icon33) + self.band_combination.setIconSize(QtCore.QSize(34, 34)) + self.band_combination.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.band_combination.setObjectName("band_combination") + self.gridLayout_333.addWidget(self.band_combination, 2, 1, 1, 1) + self.label_253 = QtWidgets.QLabel(self.page_29) + self.label_253.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_253.setFrameShape(QtWidgets.QFrame.Panel) + self.label_253.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_253.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_253.setObjectName("label_253") + self.gridLayout_333.addWidget(self.label_253, 1, 0, 1, 3) + self.calculateBandSetComb_toolButton = QtWidgets.QToolButton(self.page_29) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.random_forest.setFont(font) - self.random_forest.setLayoutDirection(QtCore.Qt.RightToLeft) - self.random_forest.setStyleSheet("margin: 0px;padding: 0px;") - self.random_forest.setIcon(icon48) - self.random_forest.setIconSize(QtCore.QSize(34, 34)) - self.random_forest.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.random_forest.setObjectName("random_forest") - self.gridLayout_283.addWidget(self.random_forest, 2, 1, 1, 1) - self.gridLayout_287.addLayout(self.gridLayout_283, 3, 0, 1, 1) - self.toolBox_random_forest.addItem(self.page_21, "") - self.page_25 = QtWidgets.QWidget() - self.page_25.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_25.setObjectName("page_25") - self.gridLayout_293 = QtWidgets.QGridLayout(self.page_25) - self.gridLayout_293.setObjectName("gridLayout_293") - self.gridLayout_294 = QtWidgets.QGridLayout() - self.gridLayout_294.setObjectName("gridLayout_294") - self.report_textBrowser_5 = QtWidgets.QTextBrowser(self.page_25) + self.calculateBandSetComb_toolButton.setFont(font) + self.calculateBandSetComb_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.calculateBandSetComb_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.calculateBandSetComb_toolButton.setIcon(icon44) + self.calculateBandSetComb_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.calculateBandSetComb_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.calculateBandSetComb_toolButton.setObjectName("calculateBandSetComb_toolButton") + self.gridLayout_333.addWidget(self.calculateBandSetComb_toolButton, 2, 2, 1, 1) + spacerItem60 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_333.addItem(spacerItem60, 0, 2, 1, 1) + spacerItem61 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_333.addItem(spacerItem61, 2, 0, 1, 1) + self.gridLayout_45.addLayout(self.gridLayout_333, 2, 0, 1, 1) + self.toolBox_band_set_combination.addItem(self.page_29, "") + self.page_30 = QtWidgets.QWidget() + self.page_30.setGeometry(QtCore.QRect(0, 0, 98, 90)) + self.page_30.setObjectName("page_30") + self.gridLayout_334 = QtWidgets.QGridLayout(self.page_30) + self.gridLayout_334.setObjectName("gridLayout_334") + self.gridLayout_335 = QtWidgets.QGridLayout() + self.gridLayout_335.setObjectName("gridLayout_335") + self.band_set_comb_textBrowser = QtWidgets.QTextBrowser(self.page_30) font = QtGui.QFont() font.setFamily("Courier 10 Pitch") - self.report_textBrowser_5.setFont(font) - self.report_textBrowser_5.setTabChangesFocus(True) - self.report_textBrowser_5.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.report_textBrowser_5.setTabStopWidth(160) - self.report_textBrowser_5.setOpenLinks(False) - self.report_textBrowser_5.setObjectName("report_textBrowser_5") - self.gridLayout_294.addWidget(self.report_textBrowser_5, 0, 0, 1, 1) - self.gridLayout_293.addLayout(self.gridLayout_294, 0, 0, 1, 1) - self.toolBox_random_forest.addItem(self.page_25, "") - self.gridLayout_288.addWidget(self.toolBox_random_forest, 0, 0, 1, 1) - self.tabWidget_4.addTab(self.tab_random_forest, "") - self.gridLayout_163.addWidget(self.tabWidget_4, 0, 0, 1, 1) - self.SCP_tabs.addTab(self.tab_band_processing, "") - self.tab_postProcessing = QtWidgets.QWidget() - self.tab_postProcessing.setObjectName("tab_postProcessing") - self.gridLayout_552 = QtWidgets.QGridLayout(self.tab_postProcessing) - self.gridLayout_552.setObjectName("gridLayout_552") - self.tabWidget_2 = QtWidgets.QTabWidget(self.tab_postProcessing) - self.tabWidget_2.setStyleSheet("") - self.tabWidget_2.setIconSize(QtCore.QSize(20, 20)) - self.tabWidget_2.setDocumentMode(True) - self.tabWidget_2.setObjectName("tabWidget_2") - self.tab_accuracy = QtWidgets.QWidget() - self.tab_accuracy.setObjectName("tab_accuracy") - self.gridLayout_184 = QtWidgets.QGridLayout(self.tab_accuracy) - self.gridLayout_184.setObjectName("gridLayout_184") - self.toolBox_accuracy = QtWidgets.QToolBox(self.tab_accuracy) - self.toolBox_accuracy.setObjectName("toolBox_accuracy") - self.page_10 = QtWidgets.QWidget() - self.page_10.setGeometry(QtCore.QRect(0, 0, 723, 351)) - self.page_10.setObjectName("page_10") - self.gridLayout_36 = QtWidgets.QGridLayout(self.page_10) - self.gridLayout_36.setObjectName("gridLayout_36") - self.gridLayout_33 = QtWidgets.QGridLayout() - self.gridLayout_33.setObjectName("gridLayout_33") - self.label_33 = QtWidgets.QLabel(self.page_10) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_33.sizePolicy().hasHeightForWidth()) - self.label_33.setSizePolicy(sizePolicy) - self.label_33.setMinimumSize(QtCore.QSize(229, 0)) - self.label_33.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_33.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_33.setObjectName("label_33") - self.gridLayout_33.addWidget(self.label_33, 1, 0, 1, 1) - self.label_34 = QtWidgets.QLabel(self.page_10) + self.band_set_comb_textBrowser.setFont(font) + self.band_set_comb_textBrowser.setTabChangesFocus(True) + self.band_set_comb_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.band_set_comb_textBrowser.setTabStopWidth(120) + self.band_set_comb_textBrowser.setOpenLinks(False) + self.band_set_comb_textBrowser.setObjectName("band_set_comb_textBrowser") + self.gridLayout_335.addWidget(self.band_set_comb_textBrowser, 0, 0, 1, 1) + self.gridLayout_334.addLayout(self.gridLayout_335, 0, 0, 1, 1) + self.toolBox_band_set_combination.addItem(self.page_30, "") + self.gridLayout_44.addWidget(self.toolBox_band_set_combination, 0, 0, 1, 1) + self.tabWidget_4.addTab(self.tab_bandset_combination_2, "") + self.band_dilation_tab = QtWidgets.QWidget() + self.band_dilation_tab.setObjectName("band_dilation_tab") + self.gridLayout_52 = QtWidgets.QGridLayout(self.band_dilation_tab) + self.gridLayout_52.setObjectName("gridLayout_52") + self.gridLayout_214 = QtWidgets.QGridLayout() + self.gridLayout_214.setObjectName("gridLayout_214") + self.label_292 = QtWidgets.QLabel(self.band_dilation_tab) + self.label_292.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_292.setFrameShape(QtWidgets.QFrame.Panel) + self.label_292.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_292.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_292.setObjectName("label_292") + self.gridLayout_214.addWidget(self.label_292, 5, 0, 1, 3) + self.horizontalLayout_62 = QtWidgets.QHBoxLayout() + self.horizontalLayout_62.setObjectName("horizontalLayout_62") + self.label_294 = QtWidgets.QLabel(self.band_dilation_tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_34.sizePolicy().hasHeightForWidth()) - self.label_34.setSizePolicy(sizePolicy) - self.label_34.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_34.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_34.setObjectName("label_34") - self.gridLayout_33.addWidget(self.label_34, 2, 0, 1, 1) - self.classification_name_combo = QtWidgets.QComboBox(self.page_10) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_name_combo.sizePolicy().hasHeightForWidth()) - self.classification_name_combo.setSizePolicy(sizePolicy) - self.classification_name_combo.setObjectName("classification_name_combo") - self.gridLayout_33.addWidget(self.classification_name_combo, 1, 1, 1, 3) - self.buttonReload_shape_4 = QtWidgets.QToolButton(self.page_10) - self.buttonReload_shape_4.setStyleSheet("margin: 0px;padding: 0px;") - self.buttonReload_shape_4.setIcon(icon55) - self.buttonReload_shape_4.setIconSize(QtCore.QSize(22, 22)) - self.buttonReload_shape_4.setObjectName("buttonReload_shape_4") - self.gridLayout_33.addWidget(self.buttonReload_shape_4, 2, 4, 1, 1) - self.toolButton_reload_4 = QtWidgets.QToolButton(self.page_10) - self.toolButton_reload_4.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_4.setIcon(icon55) - self.toolButton_reload_4.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_4.setObjectName("toolButton_reload_4") - self.gridLayout_33.addWidget(self.toolButton_reload_4, 1, 4, 1, 1) - self.reference_name_combo = QtWidgets.QComboBox(self.page_10) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reference_name_combo.sizePolicy().hasHeightForWidth()) - self.reference_name_combo.setSizePolicy(sizePolicy) - self.reference_name_combo.setObjectName("reference_name_combo") - self.gridLayout_33.addWidget(self.reference_name_combo, 2, 1, 1, 3) - self.horizontalLayout_36 = QtWidgets.QHBoxLayout() - self.horizontalLayout_36.setObjectName("horizontalLayout_36") - self.label_145 = QtWidgets.QLabel(self.page_10) - self.label_145.setStyleSheet("background-color : #656565; color : white") - self.label_145.setFrameShape(QtWidgets.QFrame.Panel) - self.label_145.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_145.setObjectName("label_145") - self.horizontalLayout_36.addWidget(self.label_145) - self.gridLayout_33.addLayout(self.horizontalLayout_36, 0, 0, 1, 5) - self.label_82 = QtWidgets.QLabel(self.page_10) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_82.sizePolicy().hasHeightForWidth()) - self.label_82.setSizePolicy(sizePolicy) - self.label_82.setMinimumSize(QtCore.QSize(6, 0)) - self.label_82.setMaximumSize(QtCore.QSize(100, 200)) - self.label_82.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_82.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_82.setObjectName("label_82") - self.gridLayout_33.addWidget(self.label_82, 3, 1, 1, 1) - self.class_field_comboBox = QtWidgets.QComboBox(self.page_10) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_field_comboBox.sizePolicy().hasHeightForWidth()) - self.class_field_comboBox.setSizePolicy(sizePolicy) - self.class_field_comboBox.setObjectName("class_field_comboBox") - self.gridLayout_33.addWidget(self.class_field_comboBox, 3, 2, 1, 2) - self.horizontalLayout_67 = QtWidgets.QHBoxLayout() - self.horizontalLayout_67.setObjectName("horizontalLayout_67") - self.nodata_checkBox_11 = QtWidgets.QCheckBox(self.page_10) - self.nodata_checkBox_11.setObjectName("nodata_checkBox_11") - self.horizontalLayout_67.addWidget(self.nodata_checkBox_11) - self.nodata_spinBox_15 = QtWidgets.QSpinBox(self.page_10) - self.nodata_spinBox_15.setMinimum(-2147483647) - self.nodata_spinBox_15.setMaximum(2147483647) - self.nodata_spinBox_15.setProperty("value", 0) - self.nodata_spinBox_15.setObjectName("nodata_spinBox_15") - self.horizontalLayout_67.addWidget(self.nodata_spinBox_15) - spacerItem113 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_67.addItem(spacerItem113) - self.gridLayout_33.addLayout(self.horizontalLayout_67, 4, 0, 1, 5) - self.gridLayout_36.addLayout(self.gridLayout_33, 0, 0, 1, 1) - self.gridLayout_25 = QtWidgets.QGridLayout() - self.gridLayout_25.setObjectName("gridLayout_25") - spacerItem114 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_25.addItem(spacerItem114, 0, 2, 1, 1) - spacerItem115 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_25.addItem(spacerItem115, 2, 0, 1, 1) - self.label_168 = QtWidgets.QLabel(self.page_10) - self.label_168.setStyleSheet("background-color : #656565; color : white") - self.label_168.setFrameShape(QtWidgets.QFrame.Panel) - self.label_168.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_168.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_168.setObjectName("label_168") - self.gridLayout_25.addWidget(self.label_168, 1, 0, 1, 3) - self.calculateMatrix_toolButton = QtWidgets.QToolButton(self.page_10) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_294.sizePolicy().hasHeightForWidth()) + self.label_294.setSizePolicy(sizePolicy) + self.label_294.setMinimumSize(QtCore.QSize(229, 0)) + self.label_294.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_294.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_294.setWordWrap(True) + self.label_294.setObjectName("label_294") + self.horizontalLayout_62.addWidget(self.label_294) + self.band_set_comb_spinBox_16 = QtWidgets.QSpinBox(self.band_dilation_tab) + self.band_set_comb_spinBox_16.setMinimum(1) + self.band_set_comb_spinBox_16.setMaximum(100000) + self.band_set_comb_spinBox_16.setObjectName("band_set_comb_spinBox_16") + self.horizontalLayout_62.addWidget(self.band_set_comb_spinBox_16) + spacerItem62 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_62.addItem(spacerItem62) + self.gridLayout_214.addLayout(self.horizontalLayout_62, 0, 0, 1, 3) + self.horizontalLayout_16 = QtWidgets.QHBoxLayout() + self.horizontalLayout_16.setObjectName("horizontalLayout_16") + self.label_295 = QtWidgets.QLabel(self.band_dilation_tab) + self.label_295.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_295.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_295.setObjectName("label_295") + self.horizontalLayout_16.addWidget(self.label_295) + self.output_name_lineEdit_2 = QtWidgets.QLineEdit(self.band_dilation_tab) + self.output_name_lineEdit_2.setMaxLength(10000) + self.output_name_lineEdit_2.setObjectName("output_name_lineEdit_2") + self.horizontalLayout_16.addWidget(self.output_name_lineEdit_2) + self.virtual_output_checkBox_1 = QtWidgets.QCheckBox(self.band_dilation_tab) + self.virtual_output_checkBox_1.setObjectName("virtual_output_checkBox_1") + self.horizontalLayout_16.addWidget(self.virtual_output_checkBox_1) + self.gridLayout_214.addLayout(self.horizontalLayout_16, 3, 0, 1, 3) + self.horizontalLayout_75 = QtWidgets.QHBoxLayout() + self.horizontalLayout_75.setObjectName("horizontalLayout_75") + self.label_291 = QtWidgets.QLabel(self.band_dilation_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_291.sizePolicy().hasHeightForWidth()) + self.label_291.setSizePolicy(sizePolicy) + self.label_291.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_291.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_291.setObjectName("label_291") + self.horizontalLayout_75.addWidget(self.label_291) + self.dilation_classes_lineEdit = QtWidgets.QLineEdit(self.band_dilation_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.dilation_classes_lineEdit.sizePolicy().hasHeightForWidth()) + self.dilation_classes_lineEdit.setSizePolicy(sizePolicy) + self.dilation_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) + self.dilation_classes_lineEdit.setText("") + self.dilation_classes_lineEdit.setMaxLength(10000) + self.dilation_classes_lineEdit.setObjectName("dilation_classes_lineEdit") + self.horizontalLayout_75.addWidget(self.dilation_classes_lineEdit) + self.gridLayout_214.addLayout(self.horizontalLayout_75, 1, 0, 1, 3) + spacerItem63 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_214.addItem(spacerItem63, 6, 0, 1, 1) + spacerItem64 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_214.addItem(spacerItem64, 4, 2, 1, 1) + self.band_dilation_toolButton = QtWidgets.QToolButton(self.band_dilation_tab) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.calculateMatrix_toolButton.setFont(font) - self.calculateMatrix_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.calculateMatrix_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculateMatrix_toolButton.setIcon(icon64) - self.calculateMatrix_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.calculateMatrix_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.calculateMatrix_toolButton.setObjectName("calculateMatrix_toolButton") - self.gridLayout_25.addWidget(self.calculateMatrix_toolButton, 2, 2, 1, 1) - self.accuracy = QtWidgets.QToolButton(self.page_10) + self.band_dilation_toolButton.setFont(font) + self.band_dilation_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.band_dilation_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.band_dilation_toolButton.setIcon(icon44) + self.band_dilation_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.band_dilation_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.band_dilation_toolButton.setObjectName("band_dilation_toolButton") + self.gridLayout_214.addWidget(self.band_dilation_toolButton, 6, 2, 1, 1) + self.horizontalLayout_74 = QtWidgets.QHBoxLayout() + self.horizontalLayout_74.setObjectName("horizontalLayout_74") + self.label_290 = QtWidgets.QLabel(self.band_dilation_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_290.sizePolicy().hasHeightForWidth()) + self.label_290.setSizePolicy(sizePolicy) + self.label_290.setMinimumSize(QtCore.QSize(229, 0)) + self.label_290.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_290.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_290.setObjectName("label_290") + self.horizontalLayout_74.addWidget(self.label_290) + self.dilation_threshold_spinBox = QtWidgets.QSpinBox(self.band_dilation_tab) + self.dilation_threshold_spinBox.setMinimum(1) + self.dilation_threshold_spinBox.setMaximum(1000) + self.dilation_threshold_spinBox.setProperty("value", 1) + self.dilation_threshold_spinBox.setObjectName("dilation_threshold_spinBox") + self.horizontalLayout_74.addWidget(self.dilation_threshold_spinBox) + self.circular_structure_checkBox_2 = QtWidgets.QCheckBox(self.band_dilation_tab) + self.circular_structure_checkBox_2.setObjectName("circular_structure_checkBox_2") + self.horizontalLayout_74.addWidget(self.circular_structure_checkBox_2) + spacerItem65 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_74.addItem(spacerItem65) + self.gridLayout_214.addLayout(self.horizontalLayout_74, 2, 0, 1, 3) + self.band_dilation = QtWidgets.QToolButton(self.band_dilation_tab) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.accuracy.setFont(font) - self.accuracy.setLayoutDirection(QtCore.Qt.RightToLeft) - self.accuracy.setStyleSheet("margin: 0px;padding: 0px;") - self.accuracy.setIcon(icon48) - self.accuracy.setIconSize(QtCore.QSize(34, 34)) - self.accuracy.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.accuracy.setObjectName("accuracy") - self.gridLayout_25.addWidget(self.accuracy, 2, 1, 1, 1) - self.gridLayout_36.addLayout(self.gridLayout_25, 1, 0, 1, 1) - self.toolBox_accuracy.addItem(self.page_10, "") - self.page_11 = QtWidgets.QWidget() - self.page_11.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_11.setObjectName("page_11") - self.gridLayout_35 = QtWidgets.QGridLayout(self.page_11) - self.gridLayout_35.setObjectName("gridLayout_35") - self.gridLayout_34 = QtWidgets.QGridLayout() - self.gridLayout_34.setObjectName("gridLayout_34") - self.error_matrix_textBrowser = QtWidgets.QTextBrowser(self.page_11) + self.band_dilation.setFont(font) + self.band_dilation.setLayoutDirection(QtCore.Qt.RightToLeft) + self.band_dilation.setStyleSheet("margin: 0px;padding: 0px;") + self.band_dilation.setIcon(icon33) + self.band_dilation.setIconSize(QtCore.QSize(34, 34)) + self.band_dilation.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.band_dilation.setObjectName("band_dilation") + self.gridLayout_214.addWidget(self.band_dilation, 6, 1, 1, 1) + self.gridLayout_52.addLayout(self.gridLayout_214, 1, 0, 1, 1) + self.horizontalLayout_76 = QtWidgets.QHBoxLayout() + self.horizontalLayout_76.setObjectName("horizontalLayout_76") + self.label_293 = QtWidgets.QLabel(self.band_dilation_tab) + self.label_293.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_293.setFrameShape(QtWidgets.QFrame.Panel) + self.label_293.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_293.setObjectName("label_293") + self.horizontalLayout_76.addWidget(self.label_293) + self.gridLayout_52.addLayout(self.horizontalLayout_76, 0, 0, 1, 1) + self.tabWidget_4.addTab(self.band_dilation_tab, "") + self.band_erosion_tab = QtWidgets.QWidget() + self.band_erosion_tab.setObjectName("band_erosion_tab") + self.gridLayout_46 = QtWidgets.QGridLayout(self.band_erosion_tab) + self.gridLayout_46.setObjectName("gridLayout_46") + self.horizontalLayout_44 = QtWidgets.QHBoxLayout() + self.horizontalLayout_44.setObjectName("horizontalLayout_44") + self.label_202 = QtWidgets.QLabel(self.band_erosion_tab) + self.label_202.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_202.setFrameShape(QtWidgets.QFrame.Panel) + self.label_202.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_202.setObjectName("label_202") + self.horizontalLayout_44.addWidget(self.label_202) + self.gridLayout_46.addLayout(self.horizontalLayout_44, 0, 0, 1, 1) + self.gridLayout_204 = QtWidgets.QGridLayout() + self.gridLayout_204.setObjectName("gridLayout_204") + self.classification_erosion = QtWidgets.QToolButton(self.band_erosion_tab) font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.error_matrix_textBrowser.setFont(font) - self.error_matrix_textBrowser.setTabChangesFocus(True) - self.error_matrix_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.error_matrix_textBrowser.setTabStopWidth(120) - self.error_matrix_textBrowser.setOpenLinks(False) - self.error_matrix_textBrowser.setObjectName("error_matrix_textBrowser") - self.gridLayout_34.addWidget(self.error_matrix_textBrowser, 0, 0, 1, 1) - self.gridLayout_35.addLayout(self.gridLayout_34, 0, 0, 1, 1) - self.toolBox_accuracy.addItem(self.page_11, "") - self.gridLayout_184.addWidget(self.toolBox_accuracy, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_accuracy, "") - self.tab_landCoverChange = QtWidgets.QWidget() - self.tab_landCoverChange.setObjectName("tab_landCoverChange") - self.gridLayout_187 = QtWidgets.QGridLayout(self.tab_landCoverChange) - self.gridLayout_187.setObjectName("gridLayout_187") - self.toolBox_landCoverChange = QtWidgets.QToolBox(self.tab_landCoverChange) - self.toolBox_landCoverChange.setObjectName("toolBox_landCoverChange") - self.page_12 = QtWidgets.QWidget() - self.page_12.setGeometry(QtCore.QRect(0, 0, 723, 351)) - self.page_12.setObjectName("page_12") - self.gridLayout_186 = QtWidgets.QGridLayout(self.page_12) - self.gridLayout_186.setObjectName("gridLayout_186") - self.gridLayout_44 = QtWidgets.QGridLayout() - self.gridLayout_44.setObjectName("gridLayout_44") - self.mask_unchanged_checkBox = QtWidgets.QCheckBox(self.page_12) - self.mask_unchanged_checkBox.setChecked(True) - self.mask_unchanged_checkBox.setObjectName("mask_unchanged_checkBox") - self.gridLayout_44.addWidget(self.mask_unchanged_checkBox, 3, 0, 1, 1) - self.classification_reference_name_combo = QtWidgets.QComboBox(self.page_12) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + font.setBold(True) + font.setWeight(75) + self.classification_erosion.setFont(font) + self.classification_erosion.setLayoutDirection(QtCore.Qt.RightToLeft) + self.classification_erosion.setStyleSheet("margin: 0px;padding: 0px;") + self.classification_erosion.setIcon(icon33) + self.classification_erosion.setIconSize(QtCore.QSize(34, 34)) + self.classification_erosion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.classification_erosion.setObjectName("classification_erosion") + self.gridLayout_204.addWidget(self.classification_erosion, 6, 1, 1, 1) + self.horizontalLayout_15 = QtWidgets.QHBoxLayout() + self.horizontalLayout_15.setObjectName("horizontalLayout_15") + self.label_151 = QtWidgets.QLabel(self.band_erosion_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_151.sizePolicy().hasHeightForWidth()) + self.label_151.setSizePolicy(sizePolicy) + self.label_151.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_151.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_151.setObjectName("label_151") + self.horizontalLayout_15.addWidget(self.label_151) + self.erosion_classes_lineEdit = QtWidgets.QLineEdit(self.band_erosion_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_reference_name_combo.sizePolicy().hasHeightForWidth()) - self.classification_reference_name_combo.setSizePolicy(sizePolicy) - self.classification_reference_name_combo.setObjectName("classification_reference_name_combo") - self.gridLayout_44.addWidget(self.classification_reference_name_combo, 1, 1, 1, 1) - self.label_40 = QtWidgets.QLabel(self.page_12) + sizePolicy.setHeightForWidth(self.erosion_classes_lineEdit.sizePolicy().hasHeightForWidth()) + self.erosion_classes_lineEdit.setSizePolicy(sizePolicy) + self.erosion_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) + self.erosion_classes_lineEdit.setText("") + self.erosion_classes_lineEdit.setMaxLength(10000) + self.erosion_classes_lineEdit.setObjectName("erosion_classes_lineEdit") + self.horizontalLayout_15.addWidget(self.erosion_classes_lineEdit) + self.gridLayout_204.addLayout(self.horizontalLayout_15, 1, 0, 1, 3) + self.horizontalLayout_78 = QtWidgets.QHBoxLayout() + self.horizontalLayout_78.setObjectName("horizontalLayout_78") + self.label_296 = QtWidgets.QLabel(self.band_erosion_tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_40.sizePolicy().hasHeightForWidth()) - self.label_40.setSizePolicy(sizePolicy) - self.label_40.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_40.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_40.setObjectName("label_40") - self.gridLayout_44.addWidget(self.label_40, 2, 0, 1, 1) - self.label_38 = QtWidgets.QLabel(self.page_12) + sizePolicy.setHeightForWidth(self.label_296.sizePolicy().hasHeightForWidth()) + self.label_296.setSizePolicy(sizePolicy) + self.label_296.setMinimumSize(QtCore.QSize(229, 0)) + self.label_296.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_296.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_296.setWordWrap(True) + self.label_296.setObjectName("label_296") + self.horizontalLayout_78.addWidget(self.label_296) + self.band_set_comb_spinBox_17 = QtWidgets.QSpinBox(self.band_erosion_tab) + self.band_set_comb_spinBox_17.setMinimum(1) + self.band_set_comb_spinBox_17.setMaximum(100000) + self.band_set_comb_spinBox_17.setObjectName("band_set_comb_spinBox_17") + self.horizontalLayout_78.addWidget(self.band_set_comb_spinBox_17) + spacerItem66 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_78.addItem(spacerItem66) + self.gridLayout_204.addLayout(self.horizontalLayout_78, 0, 0, 1, 3) + spacerItem67 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_204.addItem(spacerItem67, 6, 0, 1, 1) + self.class_erosion_toolButton = QtWidgets.QToolButton(self.band_erosion_tab) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.class_erosion_toolButton.setFont(font) + self.class_erosion_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.class_erosion_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.class_erosion_toolButton.setIcon(icon44) + self.class_erosion_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.class_erosion_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.class_erosion_toolButton.setObjectName("class_erosion_toolButton") + self.gridLayout_204.addWidget(self.class_erosion_toolButton, 6, 2, 1, 1) + spacerItem68 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_204.addItem(spacerItem68, 4, 2, 1, 1) + self.label_175 = QtWidgets.QLabel(self.band_erosion_tab) + self.label_175.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_175.setFrameShape(QtWidgets.QFrame.Panel) + self.label_175.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_175.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_175.setObjectName("label_175") + self.gridLayout_204.addWidget(self.label_175, 5, 0, 1, 3) + self.horizontalLayout_14 = QtWidgets.QHBoxLayout() + self.horizontalLayout_14.setObjectName("horizontalLayout_14") + self.label_149 = QtWidgets.QLabel(self.band_erosion_tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_38.sizePolicy().hasHeightForWidth()) - self.label_38.setSizePolicy(sizePolicy) - self.label_38.setMinimumSize(QtCore.QSize(229, 0)) - self.label_38.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_38.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_38.setObjectName("label_38") - self.gridLayout_44.addWidget(self.label_38, 1, 0, 1, 1) - self.new_classification_name_combo = QtWidgets.QComboBox(self.page_12) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.label_149.sizePolicy().hasHeightForWidth()) + self.label_149.setSizePolicy(sizePolicy) + self.label_149.setMinimumSize(QtCore.QSize(229, 0)) + self.label_149.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_149.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_149.setObjectName("label_149") + self.horizontalLayout_14.addWidget(self.label_149) + self.erosion_threshold_spinBox = QtWidgets.QSpinBox(self.band_erosion_tab) + self.erosion_threshold_spinBox.setMinimum(1) + self.erosion_threshold_spinBox.setMaximum(1000) + self.erosion_threshold_spinBox.setProperty("value", 1) + self.erosion_threshold_spinBox.setObjectName("erosion_threshold_spinBox") + self.horizontalLayout_14.addWidget(self.erosion_threshold_spinBox) + self.circular_structure_checkBox_3 = QtWidgets.QCheckBox(self.band_erosion_tab) + self.circular_structure_checkBox_3.setObjectName("circular_structure_checkBox_3") + self.horizontalLayout_14.addWidget(self.circular_structure_checkBox_3) + spacerItem69 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_14.addItem(spacerItem69) + self.gridLayout_204.addLayout(self.horizontalLayout_14, 2, 0, 1, 3) + self.horizontalLayout_18 = QtWidgets.QHBoxLayout() + self.horizontalLayout_18.setObjectName("horizontalLayout_18") + self.label_297 = QtWidgets.QLabel(self.band_erosion_tab) + self.label_297.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_297.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_297.setObjectName("label_297") + self.horizontalLayout_18.addWidget(self.label_297) + self.output_name_lineEdit_3 = QtWidgets.QLineEdit(self.band_erosion_tab) + self.output_name_lineEdit_3.setMaxLength(10000) + self.output_name_lineEdit_3.setObjectName("output_name_lineEdit_3") + self.horizontalLayout_18.addWidget(self.output_name_lineEdit_3) + self.virtual_output_checkBox_2 = QtWidgets.QCheckBox(self.band_erosion_tab) + self.virtual_output_checkBox_2.setObjectName("virtual_output_checkBox_2") + self.horizontalLayout_18.addWidget(self.virtual_output_checkBox_2) + self.gridLayout_204.addLayout(self.horizontalLayout_18, 3, 0, 1, 3) + self.gridLayout_46.addLayout(self.gridLayout_204, 1, 0, 1, 1) + self.tabWidget_4.addTab(self.band_erosion_tab, "") + self.band_sieve_tab = QtWidgets.QWidget() + self.band_sieve_tab.setObjectName("band_sieve_tab") + self.gridLayout_53 = QtWidgets.QGridLayout(self.band_sieve_tab) + self.gridLayout_53.setObjectName("gridLayout_53") + self.horizontalLayout_43 = QtWidgets.QHBoxLayout() + self.horizontalLayout_43.setObjectName("horizontalLayout_43") + self.label_195 = QtWidgets.QLabel(self.band_sieve_tab) + self.label_195.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_195.setFrameShape(QtWidgets.QFrame.Panel) + self.label_195.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_195.setObjectName("label_195") + self.horizontalLayout_43.addWidget(self.label_195) + self.gridLayout_53.addLayout(self.horizontalLayout_43, 0, 0, 1, 1) + self.gridLayout_64 = QtWidgets.QGridLayout() + self.gridLayout_64.setObjectName("gridLayout_64") + self.horizontalLayout_79 = QtWidgets.QHBoxLayout() + self.horizontalLayout_79.setObjectName("horizontalLayout_79") + self.label_298 = QtWidgets.QLabel(self.band_sieve_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.new_classification_name_combo.sizePolicy().hasHeightForWidth()) - self.new_classification_name_combo.setSizePolicy(sizePolicy) - self.new_classification_name_combo.setObjectName("new_classification_name_combo") - self.gridLayout_44.addWidget(self.new_classification_name_combo, 2, 1, 1, 1) - self.toolButton_reload_5 = QtWidgets.QToolButton(self.page_12) - self.toolButton_reload_5.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_5.setIcon(icon55) - self.toolButton_reload_5.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_5.setObjectName("toolButton_reload_5") - self.gridLayout_44.addWidget(self.toolButton_reload_5, 1, 2, 1, 1) - self.toolButton_reload_6 = QtWidgets.QToolButton(self.page_12) - self.toolButton_reload_6.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_6.setIcon(icon55) - self.toolButton_reload_6.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_6.setObjectName("toolButton_reload_6") - self.gridLayout_44.addWidget(self.toolButton_reload_6, 2, 2, 1, 1) - self.horizontalLayout_35 = QtWidgets.QHBoxLayout() - self.horizontalLayout_35.setObjectName("horizontalLayout_35") - self.label_116 = QtWidgets.QLabel(self.page_12) - self.label_116.setStyleSheet("background-color : #656565; color : white") - self.label_116.setFrameShape(QtWidgets.QFrame.Panel) - self.label_116.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_116.setObjectName("label_116") - self.horizontalLayout_35.addWidget(self.label_116) - self.gridLayout_44.addLayout(self.horizontalLayout_35, 0, 0, 1, 3) - self.gridLayout_186.addLayout(self.gridLayout_44, 0, 0, 1, 1) - self.gridLayout_45 = QtWidgets.QGridLayout() - self.gridLayout_45.setObjectName("gridLayout_45") - spacerItem116 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_45.addItem(spacerItem116, 2, 0, 1, 1) - spacerItem117 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_45.addItem(spacerItem117, 0, 2, 1, 1) - self.label_169 = QtWidgets.QLabel(self.page_12) - self.label_169.setStyleSheet("background-color : #656565; color : white") - self.label_169.setFrameShape(QtWidgets.QFrame.Panel) - self.label_169.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_169.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_169.setObjectName("label_169") - self.gridLayout_45.addWidget(self.label_169, 1, 0, 1, 3) - self.calculateLandCoverChange_toolButton = QtWidgets.QToolButton(self.page_12) + sizePolicy.setHeightForWidth(self.label_298.sizePolicy().hasHeightForWidth()) + self.label_298.setSizePolicy(sizePolicy) + self.label_298.setMinimumSize(QtCore.QSize(229, 0)) + self.label_298.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_298.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_298.setWordWrap(True) + self.label_298.setObjectName("label_298") + self.horizontalLayout_79.addWidget(self.label_298) + self.band_set_comb_spinBox_18 = QtWidgets.QSpinBox(self.band_sieve_tab) + self.band_set_comb_spinBox_18.setMinimum(1) + self.band_set_comb_spinBox_18.setMaximum(100000) + self.band_set_comb_spinBox_18.setObjectName("band_set_comb_spinBox_18") + self.horizontalLayout_79.addWidget(self.band_set_comb_spinBox_18) + spacerItem70 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_79.addItem(spacerItem70) + self.gridLayout_64.addLayout(self.horizontalLayout_79, 0, 0, 1, 3) + self.label_174 = QtWidgets.QLabel(self.band_sieve_tab) + self.label_174.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_174.setFrameShape(QtWidgets.QFrame.Panel) + self.label_174.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_174.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_174.setObjectName("label_174") + self.gridLayout_64.addWidget(self.label_174, 4, 0, 1, 3) + self.sieve_toolButton = QtWidgets.QToolButton(self.band_sieve_tab) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.calculateLandCoverChange_toolButton.setFont(font) - self.calculateLandCoverChange_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.calculateLandCoverChange_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculateLandCoverChange_toolButton.setIcon(icon64) - self.calculateLandCoverChange_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.calculateLandCoverChange_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.calculateLandCoverChange_toolButton.setObjectName("calculateLandCoverChange_toolButton") - self.gridLayout_45.addWidget(self.calculateLandCoverChange_toolButton, 2, 2, 1, 1) - self.land_cover_change = QtWidgets.QToolButton(self.page_12) + self.sieve_toolButton.setFont(font) + self.sieve_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.sieve_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.sieve_toolButton.setIcon(icon44) + self.sieve_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.sieve_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.sieve_toolButton.setObjectName("sieve_toolButton") + self.gridLayout_64.addWidget(self.sieve_toolButton, 5, 2, 1, 1) + spacerItem71 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_64.addItem(spacerItem71, 3, 2, 1, 1) + self.classification_sieve = QtWidgets.QToolButton(self.band_sieve_tab) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.land_cover_change.setFont(font) - self.land_cover_change.setLayoutDirection(QtCore.Qt.RightToLeft) - self.land_cover_change.setStyleSheet("margin: 0px;padding: 0px;") - self.land_cover_change.setIcon(icon48) - self.land_cover_change.setIconSize(QtCore.QSize(34, 34)) - self.land_cover_change.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.land_cover_change.setObjectName("land_cover_change") - self.gridLayout_45.addWidget(self.land_cover_change, 2, 1, 1, 1) - self.gridLayout_186.addLayout(self.gridLayout_45, 1, 0, 1, 1) - self.toolBox_landCoverChange.addItem(self.page_12, "") - self.page_13 = QtWidgets.QWidget() - self.page_13.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_13.setObjectName("page_13") - self.gridLayout_185 = QtWidgets.QGridLayout(self.page_13) - self.gridLayout_185.setObjectName("gridLayout_185") - self.gridLayout_46 = QtWidgets.QGridLayout() - self.gridLayout_46.setObjectName("gridLayout_46") - self.change_textBrowser = QtWidgets.QTextBrowser(self.page_13) - font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.change_textBrowser.setFont(font) - self.change_textBrowser.setTabChangesFocus(True) - self.change_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.change_textBrowser.setTabStopWidth(160) - self.change_textBrowser.setOpenLinks(False) - self.change_textBrowser.setObjectName("change_textBrowser") - self.gridLayout_46.addWidget(self.change_textBrowser, 0, 0, 1, 1) - self.gridLayout_185.addLayout(self.gridLayout_46, 0, 0, 1, 1) - self.toolBox_landCoverChange.addItem(self.page_13, "") - self.gridLayout_187.addWidget(self.toolBox_landCoverChange, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_landCoverChange, "") - self.tab_class_report = QtWidgets.QWidget() - self.tab_class_report.setObjectName("tab_class_report") - self.gridLayout_27 = QtWidgets.QGridLayout(self.tab_class_report) - self.gridLayout_27.setObjectName("gridLayout_27") - self.toolBox_class_report = QtWidgets.QToolBox(self.tab_class_report) - self.toolBox_class_report.setStyleSheet("") - self.toolBox_class_report.setObjectName("toolBox_class_report") - self.page_14 = QtWidgets.QWidget() - self.page_14.setGeometry(QtCore.QRect(0, 0, 723, 351)) - self.page_14.setObjectName("page_14") - self.gridLayout_48 = QtWidgets.QGridLayout(self.page_14) - self.gridLayout_48.setObjectName("gridLayout_48") - self.gridLayout_47 = QtWidgets.QGridLayout() - self.gridLayout_47.setObjectName("gridLayout_47") - self.classification_report_name_combo = QtWidgets.QComboBox(self.page_14) + self.classification_sieve.setFont(font) + self.classification_sieve.setLayoutDirection(QtCore.Qt.RightToLeft) + self.classification_sieve.setStyleSheet("margin: 0px;padding: 0px;") + self.classification_sieve.setIcon(icon33) + self.classification_sieve.setIconSize(QtCore.QSize(34, 34)) + self.classification_sieve.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.classification_sieve.setObjectName("classification_sieve") + self.gridLayout_64.addWidget(self.classification_sieve, 5, 1, 1, 1) + spacerItem72 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_64.addItem(spacerItem72, 5, 0, 1, 1) + self.horizontalLayout_12 = QtWidgets.QHBoxLayout() + self.horizontalLayout_12.setObjectName("horizontalLayout_12") + self.label_133 = QtWidgets.QLabel(self.band_sieve_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_133.sizePolicy().hasHeightForWidth()) + self.label_133.setSizePolicy(sizePolicy) + self.label_133.setMinimumSize(QtCore.QSize(229, 0)) + self.label_133.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_133.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_133.setObjectName("label_133") + self.horizontalLayout_12.addWidget(self.label_133) + self.sieve_threshold_spinBox = QtWidgets.QSpinBox(self.band_sieve_tab) + self.sieve_threshold_spinBox.setMinimum(2) + self.sieve_threshold_spinBox.setMaximum(10000) + self.sieve_threshold_spinBox.setProperty("value", 2) + self.sieve_threshold_spinBox.setObjectName("sieve_threshold_spinBox") + self.horizontalLayout_12.addWidget(self.sieve_threshold_spinBox) + spacerItem73 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_12.addItem(spacerItem73) + self.label_136 = QtWidgets.QLabel(self.band_sieve_tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_136.sizePolicy().hasHeightForWidth()) + self.label_136.setSizePolicy(sizePolicy) + self.label_136.setMinimumSize(QtCore.QSize(229, 0)) + self.label_136.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_136.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_136.setObjectName("label_136") + self.horizontalLayout_12.addWidget(self.label_136) + self.sieve_connection_combo = QtWidgets.QComboBox(self.band_sieve_tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_report_name_combo.sizePolicy().hasHeightForWidth()) - self.classification_report_name_combo.setSizePolicy(sizePolicy) - self.classification_report_name_combo.setObjectName("classification_report_name_combo") - self.gridLayout_47.addWidget(self.classification_report_name_combo, 1, 1, 1, 1) - self.label_44 = QtWidgets.QLabel(self.page_14) + sizePolicy.setHeightForWidth(self.sieve_connection_combo.sizePolicy().hasHeightForWidth()) + self.sieve_connection_combo.setSizePolicy(sizePolicy) + self.sieve_connection_combo.setMaximumSize(QtCore.QSize(80, 16777215)) + self.sieve_connection_combo.setObjectName("sieve_connection_combo") + self.sieve_connection_combo.addItem("") + self.sieve_connection_combo.addItem("") + self.horizontalLayout_12.addWidget(self.sieve_connection_combo) + self.gridLayout_64.addLayout(self.horizontalLayout_12, 1, 0, 1, 3) + self.horizontalLayout_35 = QtWidgets.QHBoxLayout() + self.horizontalLayout_35.setObjectName("horizontalLayout_35") + self.label_299 = QtWidgets.QLabel(self.band_sieve_tab) + self.label_299.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_299.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_299.setObjectName("label_299") + self.horizontalLayout_35.addWidget(self.label_299) + self.output_name_lineEdit_4 = QtWidgets.QLineEdit(self.band_sieve_tab) + self.output_name_lineEdit_4.setMaxLength(10000) + self.output_name_lineEdit_4.setObjectName("output_name_lineEdit_4") + self.horizontalLayout_35.addWidget(self.output_name_lineEdit_4) + self.virtual_output_checkBox_3 = QtWidgets.QCheckBox(self.band_sieve_tab) + self.virtual_output_checkBox_3.setObjectName("virtual_output_checkBox_3") + self.horizontalLayout_35.addWidget(self.virtual_output_checkBox_3) + self.gridLayout_64.addLayout(self.horizontalLayout_35, 2, 0, 1, 3) + self.gridLayout_53.addLayout(self.gridLayout_64, 1, 0, 1, 1) + self.tabWidget_4.addTab(self.band_sieve_tab, "") + self.PCA_tab = QtWidgets.QWidget() + self.PCA_tab.setObjectName("PCA_tab") + self.gridLayout_41 = QtWidgets.QGridLayout(self.PCA_tab) + self.gridLayout_41.setObjectName("gridLayout_41") + self.toolBox_PCA = QtWidgets.QToolBox(self.PCA_tab) + self.toolBox_PCA.setStyleSheet("") + self.toolBox_PCA.setObjectName("toolBox_PCA") + self.page_16 = QtWidgets.QWidget() + self.page_16.setGeometry(QtCore.QRect(0, 0, 493, 202)) + self.page_16.setObjectName("page_16") + self.gridLayout_182 = QtWidgets.QGridLayout(self.page_16) + self.gridLayout_182.setObjectName("gridLayout_182") + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.label_58 = QtWidgets.QLabel(self.page_16) + self.label_58.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_58.setFrameShape(QtWidgets.QFrame.Panel) + self.label_58.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_58.setObjectName("label_58") + self.horizontalLayout_5.addWidget(self.label_58) + self.gridLayout_182.addLayout(self.horizontalLayout_5, 0, 0, 1, 1) + self.gridLayout_173 = QtWidgets.QGridLayout() + self.gridLayout_173.setObjectName("gridLayout_173") + self.band_set_comb_spinBox_4 = QtWidgets.QSpinBox(self.page_16) + self.band_set_comb_spinBox_4.setMinimum(1) + self.band_set_comb_spinBox_4.setMaximum(100000) + self.band_set_comb_spinBox_4.setObjectName("band_set_comb_spinBox_4") + self.gridLayout_173.addWidget(self.band_set_comb_spinBox_4, 0, 1, 1, 1) + self.pca_Button = QtWidgets.QToolButton(self.page_16) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.pca_Button.setFont(font) + self.pca_Button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.pca_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.pca_Button.setIcon(icon44) + self.pca_Button.setIconSize(QtCore.QSize(34, 34)) + self.pca_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.pca_Button.setObjectName("pca_Button") + self.gridLayout_173.addWidget(self.pca_Button, 5, 3, 1, 1) + spacerItem74 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_173.addItem(spacerItem74, 2, 2, 1, 1) + self.nodata_spinBox_5 = QtWidgets.QSpinBox(self.page_16) + self.nodata_spinBox_5.setMinimum(-999999999) + self.nodata_spinBox_5.setMaximum(999999999) + self.nodata_spinBox_5.setProperty("value", 0) + self.nodata_spinBox_5.setObjectName("nodata_spinBox_5") + self.gridLayout_173.addWidget(self.nodata_spinBox_5, 2, 1, 1, 1) + spacerItem75 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_173.addItem(spacerItem75, 3, 3, 1, 1) + self.nodata_checkBox_4 = QtWidgets.QCheckBox(self.page_16) + self.nodata_checkBox_4.setObjectName("nodata_checkBox_4") + self.gridLayout_173.addWidget(self.nodata_checkBox_4, 2, 0, 1, 1) + self.pca_components_spinBox = QtWidgets.QSpinBox(self.page_16) + self.pca_components_spinBox.setMinimum(2) + self.pca_components_spinBox.setMaximum(1000) + self.pca_components_spinBox.setObjectName("pca_components_spinBox") + self.gridLayout_173.addWidget(self.pca_components_spinBox, 1, 1, 1, 1) + self.num_comp_checkBox = QtWidgets.QCheckBox(self.page_16) + self.num_comp_checkBox.setObjectName("num_comp_checkBox") + self.gridLayout_173.addWidget(self.num_comp_checkBox, 1, 0, 1, 1) + self.label_254 = QtWidgets.QLabel(self.page_16) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_44.sizePolicy().hasHeightForWidth()) - self.label_44.setSizePolicy(sizePolicy) - self.label_44.setMinimumSize(QtCore.QSize(229, 0)) - self.label_44.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_44.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_44.setObjectName("label_44") - self.gridLayout_47.addWidget(self.label_44, 1, 0, 1, 1) - self.gridLayout_26 = QtWidgets.QGridLayout() - self.gridLayout_26.setObjectName("gridLayout_26") - self.nodata_checkBox = QtWidgets.QCheckBox(self.page_14) - self.nodata_checkBox.setObjectName("nodata_checkBox") - self.gridLayout_26.addWidget(self.nodata_checkBox, 0, 0, 1, 1) - self.nodata_spinBox_2 = QtWidgets.QSpinBox(self.page_14) - self.nodata_spinBox_2.setMinimum(-2147483647) - self.nodata_spinBox_2.setMaximum(2147483647) - self.nodata_spinBox_2.setProperty("value", 0) - self.nodata_spinBox_2.setObjectName("nodata_spinBox_2") - self.gridLayout_26.addWidget(self.nodata_spinBox_2, 0, 1, 1, 1) - self.gridLayout_47.addLayout(self.gridLayout_26, 2, 0, 1, 1) - self.toolButton_reload_10 = QtWidgets.QToolButton(self.page_14) - self.toolButton_reload_10.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_10.setIcon(icon55) - self.toolButton_reload_10.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_10.setObjectName("toolButton_reload_10") - self.gridLayout_47.addWidget(self.toolButton_reload_10, 1, 2, 1, 1) - self.gridLayout_48.addLayout(self.gridLayout_47, 1, 1, 1, 1) - self.gridLayout_189 = QtWidgets.QGridLayout() - self.gridLayout_189.setObjectName("gridLayout_189") - spacerItem118 = QtWidgets.QSpacerItem(358, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_189.addItem(spacerItem118, 2, 1, 1, 1) - self.label_170 = QtWidgets.QLabel(self.page_14) - self.label_170.setStyleSheet("background-color : #656565; color : white") - self.label_170.setFrameShape(QtWidgets.QFrame.Panel) - self.label_170.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_170.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_170.setObjectName("label_170") - self.gridLayout_189.addWidget(self.label_170, 1, 0, 1, 4) - self.calculateReport_toolButton = QtWidgets.QToolButton(self.page_14) + sizePolicy.setHeightForWidth(self.label_254.sizePolicy().hasHeightForWidth()) + self.label_254.setSizePolicy(sizePolicy) + self.label_254.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_254.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_254.setObjectName("label_254") + self.gridLayout_173.addWidget(self.label_254, 0, 0, 1, 1) + self.label_166 = QtWidgets.QLabel(self.page_16) + self.label_166.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_166.setFrameShape(QtWidgets.QFrame.Panel) + self.label_166.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_166.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_166.setObjectName("label_166") + self.gridLayout_173.addWidget(self.label_166, 4, 0, 1, 4) + self.pca = QtWidgets.QToolButton(self.page_16) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.calculateReport_toolButton.setFont(font) - self.calculateReport_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.calculateReport_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculateReport_toolButton.setIcon(icon64) - self.calculateReport_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.calculateReport_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.calculateReport_toolButton.setObjectName("calculateReport_toolButton") - self.gridLayout_189.addWidget(self.calculateReport_toolButton, 2, 3, 1, 1) - spacerItem119 = QtWidgets.QSpacerItem(20, 82, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_189.addItem(spacerItem119, 0, 0, 1, 2) - self.classification_report = QtWidgets.QToolButton(self.page_14) + self.pca.setFont(font) + self.pca.setLayoutDirection(QtCore.Qt.RightToLeft) + self.pca.setStyleSheet("margin: 0px;padding: 0px;") + self.pca.setIcon(icon33) + self.pca.setIconSize(QtCore.QSize(34, 34)) + self.pca.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.pca.setObjectName("pca") + self.gridLayout_173.addWidget(self.pca, 5, 2, 1, 1) + self.gridLayout_182.addLayout(self.gridLayout_173, 1, 0, 1, 1) + self.toolBox_PCA.addItem(self.page_16, "") + self.page_17 = QtWidgets.QWidget() + self.page_17.setGeometry(QtCore.QRect(0, 0, 98, 90)) + self.page_17.setObjectName("page_17") + self.gridLayout_200 = QtWidgets.QGridLayout(self.page_17) + self.gridLayout_200.setObjectName("gridLayout_200") + self.gridLayout_201 = QtWidgets.QGridLayout() + self.gridLayout_201.setObjectName("gridLayout_201") + self.report_textBrowser_2 = QtWidgets.QTextBrowser(self.page_17) + font = QtGui.QFont() + font.setFamily("Courier 10 Pitch") + self.report_textBrowser_2.setFont(font) + self.report_textBrowser_2.setTabChangesFocus(True) + self.report_textBrowser_2.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.report_textBrowser_2.setTabStopWidth(160) + self.report_textBrowser_2.setOpenLinks(False) + self.report_textBrowser_2.setObjectName("report_textBrowser_2") + self.gridLayout_201.addWidget(self.report_textBrowser_2, 0, 0, 1, 1) + self.gridLayout_200.addLayout(self.gridLayout_201, 0, 0, 1, 1) + self.toolBox_PCA.addItem(self.page_17, "") + self.gridLayout_41.addWidget(self.toolBox_PCA, 0, 0, 1, 1) + self.tabWidget_4.addTab(self.PCA_tab, "") + self.tab_classification = QtWidgets.QWidget() + self.tab_classification.setObjectName("tab_classification") + self.gridLayout_151 = QtWidgets.QGridLayout(self.tab_classification) + self.gridLayout_151.setObjectName("gridLayout_151") + self.label_240 = QtWidgets.QLabel(self.tab_classification) font = QtGui.QFont() font.setBold(True) + font.setItalic(False) font.setWeight(75) - self.classification_report.setFont(font) - self.classification_report.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification_report.setStyleSheet("margin: 0px;padding: 0px;") - self.classification_report.setIcon(icon48) - self.classification_report.setIconSize(QtCore.QSize(34, 34)) - self.classification_report.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification_report.setObjectName("classification_report") - self.gridLayout_189.addWidget(self.classification_report, 2, 2, 1, 1) - self.gridLayout_48.addLayout(self.gridLayout_189, 2, 1, 1, 1) - self.horizontalLayout_37 = QtWidgets.QHBoxLayout() - self.horizontalLayout_37.setObjectName("horizontalLayout_37") - self.label_148 = QtWidgets.QLabel(self.page_14) - self.label_148.setStyleSheet("background-color : #656565; color : white") - self.label_148.setFrameShape(QtWidgets.QFrame.Panel) - self.label_148.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_148.setObjectName("label_148") - self.horizontalLayout_37.addWidget(self.label_148) - self.gridLayout_48.addLayout(self.horizontalLayout_37, 0, 1, 1, 1) - self.toolBox_class_report.addItem(self.page_14, "") - self.page_15 = QtWidgets.QWidget() - self.page_15.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_15.setObjectName("page_15") - self.gridLayout_188 = QtWidgets.QGridLayout(self.page_15) - self.gridLayout_188.setObjectName("gridLayout_188") - self.gridLayout_43 = QtWidgets.QGridLayout() - self.gridLayout_43.setObjectName("gridLayout_43") - self.report_textBrowser = QtWidgets.QTextBrowser(self.page_15) - font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.report_textBrowser.setFont(font) - self.report_textBrowser.setTabChangesFocus(True) - self.report_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.report_textBrowser.setTabStopWidth(160) - self.report_textBrowser.setOpenLinks(False) - self.report_textBrowser.setObjectName("report_textBrowser") - self.gridLayout_43.addWidget(self.report_textBrowser, 0, 0, 1, 1) - self.gridLayout_188.addLayout(self.gridLayout_43, 0, 0, 1, 1) - self.toolBox_class_report.addItem(self.page_15, "") - self.gridLayout_27.addWidget(self.toolBox_class_report, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_class_report, "") - self.tab_cross_classification = QtWidgets.QWidget() - self.tab_cross_classification.setObjectName("tab_cross_classification") - self.gridLayout_254 = QtWidgets.QGridLayout(self.tab_cross_classification) - self.gridLayout_254.setObjectName("gridLayout_254") - self.toolBox_cross_classification = QtWidgets.QToolBox(self.tab_cross_classification) - self.toolBox_cross_classification.setObjectName("toolBox_cross_classification") - self.page_19 = QtWidgets.QWidget() - self.page_19.setGeometry(QtCore.QRect(0, 0, 723, 351)) - self.page_19.setObjectName("page_19") - self.gridLayout_192 = QtWidgets.QGridLayout(self.page_19) - self.gridLayout_192.setObjectName("gridLayout_192") - self.horizontalLayout_38 = QtWidgets.QHBoxLayout() - self.horizontalLayout_38.setObjectName("horizontalLayout_38") - self.label_187 = QtWidgets.QLabel(self.page_19) - self.label_187.setStyleSheet("background-color : #656565; color : white") - self.label_187.setFrameShape(QtWidgets.QFrame.Panel) - self.label_187.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_187.setObjectName("label_187") - self.horizontalLayout_38.addWidget(self.label_187) - self.gridLayout_192.addLayout(self.horizontalLayout_38, 0, 0, 1, 1) - self.gridLayout_250 = QtWidgets.QGridLayout() - self.gridLayout_250.setObjectName("gridLayout_250") - self.gridLayout_248 = QtWidgets.QGridLayout() - self.gridLayout_248.setObjectName("gridLayout_248") - self.nodata_checkBox_6 = QtWidgets.QCheckBox(self.page_19) - self.nodata_checkBox_6.setObjectName("nodata_checkBox_6") - self.gridLayout_248.addWidget(self.nodata_checkBox_6, 0, 0, 1, 1) - self.nodata_spinBox_7 = QtWidgets.QSpinBox(self.page_19) - self.nodata_spinBox_7.setMinimum(-2147483647) - self.nodata_spinBox_7.setMaximum(2147483647) - self.nodata_spinBox_7.setObjectName("nodata_spinBox_7") - self.gridLayout_248.addWidget(self.nodata_spinBox_7, 0, 1, 1, 1) - self.gridLayout_250.addLayout(self.gridLayout_248, 2, 0, 1, 1) - self.label_197 = QtWidgets.QLabel(self.page_19) + self.label_240.setFont(font) + self.label_240.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_240.setFrameShape(QtWidgets.QFrame.Panel) + self.label_240.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_240.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_240.setObjectName("label_240") + self.gridLayout_151.addWidget(self.label_240, 1, 0, 1, 1) + self.gridLayout_218 = QtWidgets.QGridLayout() + self.gridLayout_218.setObjectName("gridLayout_218") + self.label_261 = QtWidgets.QLabel(self.tab_classification) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_197.sizePolicy().hasHeightForWidth()) - self.label_197.setSizePolicy(sizePolicy) - self.label_197.setMinimumSize(QtCore.QSize(229, 0)) - self.label_197.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_197.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_197.setObjectName("label_197") - self.gridLayout_250.addWidget(self.label_197, 1, 0, 1, 1) - self.label_199 = QtWidgets.QLabel(self.page_19) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_261.sizePolicy().hasHeightForWidth()) + self.label_261.setSizePolicy(sizePolicy) + self.label_261.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_261.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_261.setObjectName("label_261") + self.gridLayout_218.addWidget(self.label_261, 1, 0, 1, 1) + self.label_243 = QtWidgets.QLabel(self.tab_classification) + self.label_243.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_243.setFrameShape(QtWidgets.QFrame.Panel) + self.label_243.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_243.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_243.setObjectName("label_243") + self.gridLayout_218.addWidget(self.label_243, 0, 0, 1, 3) + self.band_set_comb_spinBox_12 = QtWidgets.QSpinBox(self.tab_classification) + self.band_set_comb_spinBox_12.setMinimum(1) + self.band_set_comb_spinBox_12.setMaximum(100000) + self.band_set_comb_spinBox_12.setObjectName("band_set_comb_spinBox_12") + self.gridLayout_218.addWidget(self.band_set_comb_spinBox_12, 1, 1, 1, 1) + self.gridLayout_70 = QtWidgets.QGridLayout() + self.gridLayout_70.setObjectName("gridLayout_70") + self.linear_scaling_radioButton = QtWidgets.QRadioButton(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_199.sizePolicy().hasHeightForWidth()) - self.label_199.setSizePolicy(sizePolicy) - self.label_199.setMinimumSize(QtCore.QSize(6, 0)) - self.label_199.setMaximumSize(QtCore.QSize(100, 200)) - self.label_199.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_199.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_199.setObjectName("label_199") - self.gridLayout_250.addWidget(self.label_199, 4, 1, 1, 1) - self.class_field_comboBox_2 = QtWidgets.QComboBox(self.page_19) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.linear_scaling_radioButton.sizePolicy().hasHeightForWidth()) + self.linear_scaling_radioButton.setSizePolicy(sizePolicy) + self.linear_scaling_radioButton.setAutoExclusive(False) + self.linear_scaling_radioButton.setObjectName("linear_scaling_radioButton") + self.gridLayout_70.addWidget(self.linear_scaling_radioButton, 0, 2, 1, 1) + self.z_score_radioButton = QtWidgets.QRadioButton(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_field_comboBox_2.sizePolicy().hasHeightForWidth()) - self.class_field_comboBox_2.setSizePolicy(sizePolicy) - self.class_field_comboBox_2.setObjectName("class_field_comboBox_2") - self.gridLayout_250.addWidget(self.class_field_comboBox_2, 4, 2, 1, 2) - self.toolButton_reload_21 = QtWidgets.QToolButton(self.page_19) - self.toolButton_reload_21.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_21.setIcon(icon55) - self.toolButton_reload_21.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_21.setObjectName("toolButton_reload_21") - self.gridLayout_250.addWidget(self.toolButton_reload_21, 1, 4, 1, 1) - self.classification_name_combo_2 = QtWidgets.QComboBox(self.page_19) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.z_score_radioButton.sizePolicy().hasHeightForWidth()) + self.z_score_radioButton.setSizePolicy(sizePolicy) + self.z_score_radioButton.setChecked(True) + self.z_score_radioButton.setAutoExclusive(False) + self.z_score_radioButton.setObjectName("z_score_radioButton") + self.gridLayout_70.addWidget(self.z_score_radioButton, 0, 1, 1, 1) + spacerItem76 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_70.addItem(spacerItem76, 0, 3, 1, 1) + self.input_normalization_checkBox = QtWidgets.QCheckBox(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.input_normalization_checkBox.sizePolicy().hasHeightForWidth()) + self.input_normalization_checkBox.setSizePolicy(sizePolicy) + self.input_normalization_checkBox.setChecked(False) + self.input_normalization_checkBox.setObjectName("input_normalization_checkBox") + self.gridLayout_70.addWidget(self.input_normalization_checkBox, 0, 0, 1, 1) + self.gridLayout_218.addLayout(self.gridLayout_70, 1, 2, 1, 1) + self.horizontalLayout_55 = QtWidgets.QHBoxLayout() + self.horizontalLayout_55.setObjectName("horizontalLayout_55") + self.label_32 = QtWidgets.QLabel(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_name_combo_2.sizePolicy().hasHeightForWidth()) - self.classification_name_combo_2.setSizePolicy(sizePolicy) - self.classification_name_combo_2.setObjectName("classification_name_combo_2") - self.gridLayout_250.addWidget(self.classification_name_combo_2, 1, 1, 1, 3) - self.buttonReload_shape_5 = QtWidgets.QToolButton(self.page_19) - self.buttonReload_shape_5.setStyleSheet("margin: 0px;padding: 0px;") - self.buttonReload_shape_5.setIcon(icon55) - self.buttonReload_shape_5.setIconSize(QtCore.QSize(22, 22)) - self.buttonReload_shape_5.setObjectName("buttonReload_shape_5") - self.gridLayout_250.addWidget(self.buttonReload_shape_5, 3, 4, 1, 1) - self.reference_name_combo_2 = QtWidgets.QComboBox(self.page_19) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.label_32.sizePolicy().hasHeightForWidth()) + self.label_32.setSizePolicy(sizePolicy) + self.label_32.setObjectName("label_32") + self.horizontalLayout_55.addWidget(self.label_32) + self.macroclass_radioButton = QtWidgets.QRadioButton(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reference_name_combo_2.sizePolicy().hasHeightForWidth()) - self.reference_name_combo_2.setSizePolicy(sizePolicy) - self.reference_name_combo_2.setObjectName("reference_name_combo_2") - self.gridLayout_250.addWidget(self.reference_name_combo_2, 3, 1, 1, 3) - self.label_198 = QtWidgets.QLabel(self.page_19) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.macroclass_radioButton.sizePolicy().hasHeightForWidth()) + self.macroclass_radioButton.setSizePolicy(sizePolicy) + self.macroclass_radioButton.setChecked(True) + self.macroclass_radioButton.setAutoExclusive(False) + self.macroclass_radioButton.setObjectName("macroclass_radioButton") + self.horizontalLayout_55.addWidget(self.macroclass_radioButton) + self.class_radioButton = QtWidgets.QRadioButton(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_198.sizePolicy().hasHeightForWidth()) - self.label_198.setSizePolicy(sizePolicy) - self.label_198.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_198.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_198.setObjectName("label_198") - self.gridLayout_250.addWidget(self.label_198, 3, 0, 1, 1) - self.regression_raster_checkBox = QtWidgets.QCheckBox(self.page_19) - self.regression_raster_checkBox.setObjectName("regression_raster_checkBox") - self.gridLayout_250.addWidget(self.regression_raster_checkBox, 5, 0, 1, 1) - self.gridLayout_192.addLayout(self.gridLayout_250, 1, 0, 1, 1) - self.gridLayout_251 = QtWidgets.QGridLayout() - self.gridLayout_251.setObjectName("gridLayout_251") - spacerItem120 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_251.addItem(spacerItem120, 0, 2, 1, 1) - spacerItem121 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_251.addItem(spacerItem121, 2, 0, 1, 1) - self.label_200 = QtWidgets.QLabel(self.page_19) - self.label_200.setStyleSheet("background-color : #656565; color : white") - self.label_200.setFrameShape(QtWidgets.QFrame.Panel) - self.label_200.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_200.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_200.setObjectName("label_200") - self.gridLayout_251.addWidget(self.label_200, 1, 0, 1, 3) - self.calculatecrossClass_toolButton = QtWidgets.QToolButton(self.page_19) + sizePolicy.setHeightForWidth(self.class_radioButton.sizePolicy().hasHeightForWidth()) + self.class_radioButton.setSizePolicy(sizePolicy) + self.class_radioButton.setAutoExclusive(False) + self.class_radioButton.setObjectName("class_radioButton") + self.horizontalLayout_55.addWidget(self.class_radioButton) + spacerItem77 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_55.addItem(spacerItem77) + self.gridLayout_218.addLayout(self.horizontalLayout_55, 2, 0, 1, 3) + self.gridLayout_151.addLayout(self.gridLayout_218, 0, 0, 1, 1) + self.gridLayout_249 = QtWidgets.QGridLayout() + self.gridLayout_249.setObjectName("gridLayout_249") + self.name_classifier = QtWidgets.QLabel(self.tab_classification) + self.name_classifier.setFrameShape(QtWidgets.QFrame.Panel) + self.name_classifier.setFrameShadow(QtWidgets.QFrame.Sunken) + self.name_classifier.setText("") + self.name_classifier.setObjectName("name_classifier") + self.gridLayout_249.addWidget(self.name_classifier, 1, 3, 1, 1) + self.label_classifier = QtWidgets.QLabel(self.tab_classification) + self.label_classifier.setFrameShape(QtWidgets.QFrame.Panel) + self.label_classifier.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_classifier.setText("") + self.label_classifier.setObjectName("label_classifier") + self.gridLayout_249.addWidget(self.label_classifier, 1, 1, 1, 2) + self.classification = QtWidgets.QToolButton(self.tab_classification) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.calculatecrossClass_toolButton.setFont(font) - self.calculatecrossClass_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.calculatecrossClass_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculatecrossClass_toolButton.setIcon(icon64) - self.calculatecrossClass_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.calculatecrossClass_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.calculatecrossClass_toolButton.setObjectName("calculatecrossClass_toolButton") - self.gridLayout_251.addWidget(self.calculatecrossClass_toolButton, 2, 2, 1, 1) - self.cross_classification = QtWidgets.QToolButton(self.page_19) + self.classification.setFont(font) + self.classification.setLayoutDirection(QtCore.Qt.RightToLeft) + self.classification.setStyleSheet("margin: 0px;padding: 0px;") + self.classification.setIcon(icon33) + self.classification.setIconSize(QtCore.QSize(34, 34)) + self.classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.classification.setObjectName("classification") + self.gridLayout_249.addWidget(self.classification, 1, 6, 1, 1) + self.label_239 = QtWidgets.QLabel(self.tab_classification) + self.label_239.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_239.setFrameShape(QtWidgets.QFrame.Panel) + self.label_239.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_239.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_239.setObjectName("label_239") + self.gridLayout_249.addWidget(self.label_239, 0, 0, 1, 8) + self.save_classifier_button = QtWidgets.QToolButton(self.tab_classification) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.cross_classification.setFont(font) - self.cross_classification.setLayoutDirection(QtCore.Qt.RightToLeft) - self.cross_classification.setStyleSheet("margin: 0px;padding: 0px;") - self.cross_classification.setIcon(icon48) - self.cross_classification.setIconSize(QtCore.QSize(34, 34)) - self.cross_classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.cross_classification.setObjectName("cross_classification") - self.gridLayout_251.addWidget(self.cross_classification, 2, 1, 1, 1) - self.gridLayout_192.addLayout(self.gridLayout_251, 2, 0, 1, 1) - self.toolBox_cross_classification.addItem(self.page_19, "") - self.page_22 = QtWidgets.QWidget() - self.page_22.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_22.setObjectName("page_22") - self.gridLayout_252 = QtWidgets.QGridLayout(self.page_22) - self.gridLayout_252.setObjectName("gridLayout_252") - self.gridLayout_253 = QtWidgets.QGridLayout() - self.gridLayout_253.setObjectName("gridLayout_253") - self.cross_matrix_textBrowser = QtWidgets.QTextBrowser(self.page_22) + self.save_classifier_button.setFont(font) + self.save_classifier_button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.save_classifier_button.setStyleSheet("margin: 0px;padding: 0px;") + self.save_classifier_button.setIcon(icon47) + self.save_classifier_button.setIconSize(QtCore.QSize(34, 34)) + self.save_classifier_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.save_classifier_button.setObjectName("save_classifier_button") + self.gridLayout_249.addWidget(self.save_classifier_button, 1, 5, 1, 1) + self.load_classifier_Button = QtWidgets.QToolButton(self.tab_classification) + self.load_classifier_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.load_classifier_Button.setIcon(icon43) + self.load_classifier_Button.setIconSize(QtCore.QSize(22, 22)) + self.load_classifier_Button.setObjectName("load_classifier_Button") + self.gridLayout_249.addWidget(self.load_classifier_Button, 1, 4, 1, 1) + self.button_classification = QtWidgets.QToolButton(self.tab_classification) font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.cross_matrix_textBrowser.setFont(font) - self.cross_matrix_textBrowser.setTabChangesFocus(True) - self.cross_matrix_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.cross_matrix_textBrowser.setTabStopWidth(120) - self.cross_matrix_textBrowser.setOpenLinks(False) - self.cross_matrix_textBrowser.setObjectName("cross_matrix_textBrowser") - self.gridLayout_253.addWidget(self.cross_matrix_textBrowser, 0, 0, 1, 1) - self.gridLayout_252.addLayout(self.gridLayout_253, 0, 0, 1, 1) - self.toolBox_cross_classification.addItem(self.page_22, "") - self.gridLayout_254.addWidget(self.toolBox_cross_classification, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_cross_classification, "") - self.tab_class_signature = QtWidgets.QWidget() - self.tab_class_signature.setObjectName("tab_class_signature") - self.gridLayout_123 = QtWidgets.QGridLayout(self.tab_class_signature) - self.gridLayout_123.setObjectName("gridLayout_123") - self.toolBox_class_signature = QtWidgets.QToolBox(self.tab_class_signature) - self.toolBox_class_signature.setStyleSheet("") - self.toolBox_class_signature.setObjectName("toolBox_class_signature") - self.page_20 = QtWidgets.QWidget() - self.page_20.setGeometry(QtCore.QRect(0, 0, 387, 196)) - self.page_20.setObjectName("page_20") - self.gridLayout_209 = QtWidgets.QGridLayout(self.page_20) - self.gridLayout_209.setObjectName("gridLayout_209") - self.horizontalLayout_39 = QtWidgets.QHBoxLayout() - self.horizontalLayout_39.setObjectName("horizontalLayout_39") - self.label_188 = QtWidgets.QLabel(self.page_20) - self.label_188.setStyleSheet("background-color : #656565; color : white") - self.label_188.setFrameShape(QtWidgets.QFrame.Panel) - self.label_188.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_188.setObjectName("label_188") - self.horizontalLayout_39.addWidget(self.label_188) - self.gridLayout_209.addLayout(self.horizontalLayout_39, 0, 0, 1, 1) - self.gridLayout_211 = QtWidgets.QGridLayout() - self.gridLayout_211.setObjectName("gridLayout_211") - self.gridLayout_112 = QtWidgets.QGridLayout() - self.gridLayout_112.setObjectName("gridLayout_112") - self.classification_name_combo_3 = QtWidgets.QComboBox(self.page_20) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + font.setBold(True) + font.setWeight(75) + self.button_classification.setFont(font) + self.button_classification.setLayoutDirection(QtCore.Qt.RightToLeft) + self.button_classification.setStyleSheet("margin: 0px;padding: 0px;") + self.button_classification.setIcon(icon44) + self.button_classification.setIconSize(QtCore.QSize(34, 34)) + self.button_classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.button_classification.setObjectName("button_classification") + self.gridLayout_249.addWidget(self.button_classification, 1, 7, 1, 1) + self.label_255 = QtWidgets.QLabel(self.tab_classification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_name_combo_3.sizePolicy().hasHeightForWidth()) - self.classification_name_combo_3.setSizePolicy(sizePolicy) - self.classification_name_combo_3.setObjectName("classification_name_combo_3") - self.gridLayout_112.addWidget(self.classification_name_combo_3, 0, 1, 1, 1) - self.label_201 = QtWidgets.QLabel(self.page_20) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_255.sizePolicy().hasHeightForWidth()) + self.label_255.setSizePolicy(sizePolicy) + self.label_255.setObjectName("label_255") + self.gridLayout_249.addWidget(self.label_255, 1, 0, 1, 1) + self.gridLayout_151.addLayout(self.gridLayout_249, 3, 0, 1, 1) + self.toolBox_classification = QtWidgets.QToolBox(self.tab_classification) + self.toolBox_classification.setObjectName("toolBox_classification") + self.page_max_like = QtWidgets.QWidget() + self.page_max_like.setGeometry(QtCore.QRect(0, 0, 705, 113)) + self.page_max_like.setObjectName("page_max_like") + self.gridLayout_92 = QtWidgets.QGridLayout(self.page_max_like) + self.gridLayout_92.setObjectName("gridLayout_92") + self.gridLayout_226 = QtWidgets.QGridLayout() + self.gridLayout_226.setObjectName("gridLayout_226") + self.confidence_raster_checkBox = QtWidgets.QCheckBox(self.page_max_like) + self.confidence_raster_checkBox.setObjectName("confidence_raster_checkBox") + self.gridLayout_226.addWidget(self.confidence_raster_checkBox, 2, 0, 1, 5) + self.label_235 = QtWidgets.QLabel(self.page_max_like) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_235.sizePolicy().hasHeightForWidth()) + self.label_235.setSizePolicy(sizePolicy) + self.label_235.setMaximumSize(QtCore.QSize(100, 16777215)) + self.label_235.setObjectName("label_235") + self.gridLayout_226.addWidget(self.label_235, 0, 0, 1, 1) + self.signature_raster_checkBox_3 = QtWidgets.QCheckBox(self.page_max_like) + self.signature_raster_checkBox_3.setObjectName("signature_raster_checkBox_3") + self.gridLayout_226.addWidget(self.signature_raster_checkBox_3, 1, 0, 1, 2) + self.single_threshold_checkBox_2 = QtWidgets.QCheckBox(self.page_max_like) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox_2.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox_2.setSizePolicy(sizePolicy) + self.single_threshold_checkBox_2.setObjectName("single_threshold_checkBox_2") + self.gridLayout_226.addWidget(self.single_threshold_checkBox_2, 0, 3, 1, 1) + self.signature_threshold_button_2 = QtWidgets.QToolButton(self.page_max_like) + self.signature_threshold_button_2.setStyleSheet("margin: 0px;padding: 0px;") + self.signature_threshold_button_2.setIcon(icon8) + self.signature_threshold_button_2.setIconSize(QtCore.QSize(22, 22)) + self.signature_threshold_button_2.setObjectName("signature_threshold_button_2") + self.gridLayout_226.addWidget(self.signature_threshold_button_2, 0, 4, 1, 1) + self.alg_threshold_SpinBox_2 = QtWidgets.QDoubleSpinBox(self.page_max_like) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.alg_threshold_SpinBox_2.sizePolicy().hasHeightForWidth()) + self.alg_threshold_SpinBox_2.setSizePolicy(sizePolicy) + self.alg_threshold_SpinBox_2.setMaximumSize(QtCore.QSize(100, 16777215)) + self.alg_threshold_SpinBox_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.alg_threshold_SpinBox_2.setDecimals(4) + self.alg_threshold_SpinBox_2.setMaximum(100.0) + self.alg_threshold_SpinBox_2.setObjectName("alg_threshold_SpinBox_2") + self.gridLayout_226.addWidget(self.alg_threshold_SpinBox_2, 0, 2, 1, 1) + self.single_threshold_checkBox = QtWidgets.QCheckBox(self.page_max_like) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox.setSizePolicy(sizePolicy) + self.single_threshold_checkBox.setChecked(False) + self.single_threshold_checkBox.setObjectName("single_threshold_checkBox") + self.gridLayout_226.addWidget(self.single_threshold_checkBox, 0, 1, 1, 1) + spacerItem78 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_226.addItem(spacerItem78, 0, 5, 1, 1) + spacerItem79 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_226.addItem(spacerItem79, 3, 5, 1, 1) + self.gridLayout_92.addLayout(self.gridLayout_226, 0, 0, 1, 1) + icon61 = QtGui.QIcon() + icon61.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_options.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.toolBox_classification.addItem(self.page_max_like, icon61, "") + self.page_mindist = QtWidgets.QWidget() + self.page_mindist.setGeometry(QtCore.QRect(0, 0, 555, 113)) + self.page_mindist.setObjectName("page_mindist") + self.gridLayout_10 = QtWidgets.QGridLayout(self.page_mindist) + self.gridLayout_10.setObjectName("gridLayout_10") + self.gridLayout_229 = QtWidgets.QGridLayout() + self.gridLayout_229.setObjectName("gridLayout_229") + self.signature_raster_checkBox_2 = QtWidgets.QCheckBox(self.page_mindist) + self.signature_raster_checkBox_2.setObjectName("signature_raster_checkBox_2") + self.gridLayout_229.addWidget(self.signature_raster_checkBox_2, 1, 0, 1, 2) + self.label_237 = QtWidgets.QLabel(self.page_mindist) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_237.sizePolicy().hasHeightForWidth()) + self.label_237.setSizePolicy(sizePolicy) + self.label_237.setMaximumSize(QtCore.QSize(100, 16777215)) + self.label_237.setObjectName("label_237") + self.gridLayout_229.addWidget(self.label_237, 0, 0, 1, 1) + self.single_threshold_checkBox_4 = QtWidgets.QCheckBox(self.page_mindist) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox_4.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox_4.setSizePolicy(sizePolicy) + self.single_threshold_checkBox_4.setChecked(False) + self.single_threshold_checkBox_4.setObjectName("single_threshold_checkBox_4") + self.gridLayout_229.addWidget(self.single_threshold_checkBox_4, 0, 1, 1, 1) + self.alg_threshold_SpinBox_4 = QtWidgets.QDoubleSpinBox(self.page_mindist) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.alg_threshold_SpinBox_4.sizePolicy().hasHeightForWidth()) + self.alg_threshold_SpinBox_4.setSizePolicy(sizePolicy) + self.alg_threshold_SpinBox_4.setMaximumSize(QtCore.QSize(100, 16777215)) + self.alg_threshold_SpinBox_4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.alg_threshold_SpinBox_4.setDecimals(4) + self.alg_threshold_SpinBox_4.setMaximum(100.0) + self.alg_threshold_SpinBox_4.setObjectName("alg_threshold_SpinBox_4") + self.gridLayout_229.addWidget(self.alg_threshold_SpinBox_4, 0, 2, 1, 1) + self.single_threshold_checkBox_3 = QtWidgets.QCheckBox(self.page_mindist) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox_3.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox_3.setSizePolicy(sizePolicy) + self.single_threshold_checkBox_3.setObjectName("single_threshold_checkBox_3") + self.gridLayout_229.addWidget(self.single_threshold_checkBox_3, 0, 3, 1, 1) + spacerItem80 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_229.addItem(spacerItem80, 3, 5, 1, 1) + spacerItem81 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_229.addItem(spacerItem81, 0, 5, 1, 1) + self.signature_threshold_button_4 = QtWidgets.QToolButton(self.page_mindist) + self.signature_threshold_button_4.setStyleSheet("margin: 0px;padding: 0px;") + self.signature_threshold_button_4.setIcon(icon8) + self.signature_threshold_button_4.setIconSize(QtCore.QSize(22, 22)) + self.signature_threshold_button_4.setObjectName("signature_threshold_button_4") + self.gridLayout_229.addWidget(self.signature_threshold_button_4, 0, 4, 1, 1) + self.confidence_raster_checkBox_2 = QtWidgets.QCheckBox(self.page_mindist) + self.confidence_raster_checkBox_2.setObjectName("confidence_raster_checkBox_2") + self.gridLayout_229.addWidget(self.confidence_raster_checkBox_2, 2, 0, 1, 5) + self.gridLayout_10.addLayout(self.gridLayout_229, 0, 0, 1, 1) + self.toolBox_classification.addItem(self.page_mindist, "") + self.page_mlp = QtWidgets.QWidget() + self.page_mlp.setGeometry(QtCore.QRect(0, 0, 732, 243)) + self.page_mlp.setObjectName("page_mlp") + self.gridLayout_91 = QtWidgets.QGridLayout(self.page_mlp) + self.gridLayout_91.setObjectName("gridLayout_91") + self.gridLayout_90 = QtWidgets.QGridLayout() + self.gridLayout_90.setObjectName("gridLayout_90") + self.label_329 = QtWidgets.QLabel(self.page_mlp) + self.label_329.setObjectName("label_329") + self.gridLayout_90.addWidget(self.label_329, 2, 2, 1, 1) + self.alpha_SpinBox = QtWidgets.QDoubleSpinBox(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.alpha_SpinBox.sizePolicy().hasHeightForWidth()) + self.alpha_SpinBox.setSizePolicy(sizePolicy) + self.alpha_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.alpha_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.alpha_SpinBox.setDecimals(5) + self.alpha_SpinBox.setMinimum(1e-05) + self.alpha_SpinBox.setMaximum(1000.0) + self.alpha_SpinBox.setSingleStep(0.0001) + self.alpha_SpinBox.setProperty("value", 0.01) + self.alpha_SpinBox.setObjectName("alpha_SpinBox") + self.gridLayout_90.addWidget(self.alpha_SpinBox, 2, 5, 1, 1) + self.batch_size_lineEdit = QtWidgets.QLineEdit(self.page_mlp) + self.batch_size_lineEdit.setMaxLength(10000) + self.batch_size_lineEdit.setObjectName("batch_size_lineEdit") + self.gridLayout_90.addWidget(self.batch_size_lineEdit, 3, 3, 1, 1) + spacerItem82 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_90.addItem(spacerItem82, 3, 7, 1, 1) + self.label_238 = QtWidgets.QLabel(self.page_mlp) + self.label_238.setObjectName("label_238") + self.gridLayout_90.addWidget(self.label_238, 3, 0, 1, 1) + self.label_328 = QtWidgets.QLabel(self.page_mlp) + self.label_328.setObjectName("label_328") + self.gridLayout_90.addWidget(self.label_328, 3, 2, 1, 1) + self.horizontalLayout_6 = QtWidgets.QHBoxLayout() + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.label_256 = QtWidgets.QLabel(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_256.sizePolicy().hasHeightForWidth()) + self.label_256.setSizePolicy(sizePolicy) + self.label_256.setObjectName("label_256") + self.horizontalLayout_6.addWidget(self.label_256) + self.scikit_radioButton = QtWidgets.QRadioButton(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.scikit_radioButton.sizePolicy().hasHeightForWidth()) + self.scikit_radioButton.setSizePolicy(sizePolicy) + self.scikit_radioButton.setChecked(True) + self.scikit_radioButton.setObjectName("scikit_radioButton") + self.horizontalLayout_6.addWidget(self.scikit_radioButton) + self.pytorch_radioButton = QtWidgets.QRadioButton(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pytorch_radioButton.sizePolicy().hasHeightForWidth()) + self.pytorch_radioButton.setSizePolicy(sizePolicy) + self.pytorch_radioButton.setObjectName("pytorch_radioButton") + self.horizontalLayout_6.addWidget(self.pytorch_radioButton) + spacerItem83 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_6.addItem(spacerItem83) + self.gridLayout_90.addLayout(self.horizontalLayout_6, 0, 0, 1, 8) + self.max_iterations_SpinBox = QtWidgets.QDoubleSpinBox(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.max_iterations_SpinBox.sizePolicy().hasHeightForWidth()) + self.max_iterations_SpinBox.setSizePolicy(sizePolicy) + self.max_iterations_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.max_iterations_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.max_iterations_SpinBox.setDecimals(0) + self.max_iterations_SpinBox.setMinimum(1.0) + self.max_iterations_SpinBox.setMaximum(100000.0) + self.max_iterations_SpinBox.setSingleStep(10.0) + self.max_iterations_SpinBox.setProperty("value", 200.0) + self.max_iterations_SpinBox.setObjectName("max_iterations_SpinBox") + self.gridLayout_90.addWidget(self.max_iterations_SpinBox, 2, 1, 1, 1) + self.label_262 = QtWidgets.QLabel(self.page_mlp) + self.label_262.setObjectName("label_262") + self.gridLayout_90.addWidget(self.label_262, 2, 0, 1, 1) + self.activation_lineEdit = QtWidgets.QLineEdit(self.page_mlp) + self.activation_lineEdit.setMaxLength(10000) + self.activation_lineEdit.setObjectName("activation_lineEdit") + self.gridLayout_90.addWidget(self.activation_lineEdit, 2, 3, 1, 1) + self.label_242 = QtWidgets.QLabel(self.page_mlp) + self.label_242.setObjectName("label_242") + self.gridLayout_90.addWidget(self.label_242, 2, 4, 1, 1) + self.learning_rate_SpinBox = QtWidgets.QDoubleSpinBox(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.learning_rate_SpinBox.sizePolicy().hasHeightForWidth()) + self.learning_rate_SpinBox.setSizePolicy(sizePolicy) + self.learning_rate_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.learning_rate_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.learning_rate_SpinBox.setDecimals(4) + self.learning_rate_SpinBox.setMinimum(0.0001) + self.learning_rate_SpinBox.setMaximum(1000.0) + self.learning_rate_SpinBox.setSingleStep(0.01) + self.learning_rate_SpinBox.setProperty("value", 0.001) + self.learning_rate_SpinBox.setObjectName("learning_rate_SpinBox") + self.gridLayout_90.addWidget(self.learning_rate_SpinBox, 3, 5, 1, 1) + self.training_proportion_SpinBox = QtWidgets.QDoubleSpinBox(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.training_proportion_SpinBox.sizePolicy().hasHeightForWidth()) + self.training_proportion_SpinBox.setSizePolicy(sizePolicy) + self.training_proportion_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.training_proportion_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.training_proportion_SpinBox.setDecimals(2) + self.training_proportion_SpinBox.setMinimum(0.01) + self.training_proportion_SpinBox.setMaximum(1.0) + self.training_proportion_SpinBox.setSingleStep(0.1) + self.training_proportion_SpinBox.setProperty("value", 0.9) + self.training_proportion_SpinBox.setObjectName("training_proportion_SpinBox") + self.gridLayout_90.addWidget(self.training_proportion_SpinBox, 3, 1, 1, 1) + self.label_330 = QtWidgets.QLabel(self.page_mlp) + self.label_330.setObjectName("label_330") + self.gridLayout_90.addWidget(self.label_330, 1, 0, 1, 1) + self.hidden_layers_lineEdit = QtWidgets.QLineEdit(self.page_mlp) + self.hidden_layers_lineEdit.setMaxLength(10000) + self.hidden_layers_lineEdit.setObjectName("hidden_layers_lineEdit") + self.gridLayout_90.addWidget(self.hidden_layers_lineEdit, 1, 1, 1, 6) + self.label_241 = QtWidgets.QLabel(self.page_mlp) + self.label_241.setObjectName("label_241") + self.gridLayout_90.addWidget(self.label_241, 3, 4, 1, 1) + self.cross_validation_checkBox_3 = QtWidgets.QCheckBox(self.page_mlp) + self.cross_validation_checkBox_3.setChecked(True) + self.cross_validation_checkBox_3.setObjectName("cross_validation_checkBox_3") + self.gridLayout_90.addWidget(self.cross_validation_checkBox_3, 4, 0, 1, 7) + spacerItem84 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_90.addItem(spacerItem84, 7, 5, 1, 1) + self.best_estimator_checkBox_2 = QtWidgets.QCheckBox(self.page_mlp) + self.best_estimator_checkBox_2.setObjectName("best_estimator_checkBox_2") + self.gridLayout_90.addWidget(self.best_estimator_checkBox_2, 5, 0, 1, 1) + self.steps_SpinBox_2 = QtWidgets.QDoubleSpinBox(self.page_mlp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_201.sizePolicy().hasHeightForWidth()) - self.label_201.setSizePolicy(sizePolicy) - self.label_201.setMinimumSize(QtCore.QSize(229, 0)) - self.label_201.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_201.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_201.setObjectName("label_201") - self.gridLayout_112.addWidget(self.label_201, 0, 0, 1, 1) - self.toolButton_reload_22 = QtWidgets.QToolButton(self.page_20) - self.toolButton_reload_22.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_22.setIcon(icon55) - self.toolButton_reload_22.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_22.setObjectName("toolButton_reload_22") - self.gridLayout_112.addWidget(self.toolButton_reload_22, 0, 2, 1, 1) - self.gridLayout_211.addLayout(self.gridLayout_112, 0, 0, 1, 3) - self.label_259 = QtWidgets.QLabel(self.page_20) + sizePolicy.setHeightForWidth(self.steps_SpinBox_2.sizePolicy().hasHeightForWidth()) + self.steps_SpinBox_2.setSizePolicy(sizePolicy) + self.steps_SpinBox_2.setMaximumSize(QtCore.QSize(100, 16777215)) + self.steps_SpinBox_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.steps_SpinBox_2.setDecimals(0) + self.steps_SpinBox_2.setMinimum(1.0) + self.steps_SpinBox_2.setMaximum(100.0) + self.steps_SpinBox_2.setSingleStep(1.0) + self.steps_SpinBox_2.setProperty("value", 5.0) + self.steps_SpinBox_2.setObjectName("steps_SpinBox_2") + self.gridLayout_90.addWidget(self.steps_SpinBox_2, 5, 1, 1, 1) + self.confidence_raster_checkBox_3 = QtWidgets.QCheckBox(self.page_mlp) + self.confidence_raster_checkBox_3.setObjectName("confidence_raster_checkBox_3") + self.gridLayout_90.addWidget(self.confidence_raster_checkBox_3, 6, 0, 1, 2) + self.gridLayout_91.addLayout(self.gridLayout_90, 0, 0, 1, 1) + self.toolBox_classification.addItem(self.page_mlp, "") + self.page_random_forest = QtWidgets.QWidget() + self.page_random_forest.setGeometry(QtCore.QRect(0, 0, 644, 206)) + self.page_random_forest.setObjectName("page_random_forest") + self.gridLayout_89 = QtWidgets.QGridLayout(self.page_random_forest) + self.gridLayout_89.setObjectName("gridLayout_89") + self.gridLayout_88 = QtWidgets.QGridLayout() + self.gridLayout_88.setObjectName("gridLayout_88") + self.label_155 = QtWidgets.QLabel(self.page_random_forest) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_259.sizePolicy().hasHeightForWidth()) - self.label_259.setSizePolicy(sizePolicy) - self.label_259.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_259.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_259.setObjectName("label_259") - self.gridLayout_211.addWidget(self.label_259, 1, 0, 1, 1) - self.band_set_comb_spinBox_8 = QtWidgets.QSpinBox(self.page_20) - self.band_set_comb_spinBox_8.setMinimum(1) - self.band_set_comb_spinBox_8.setMaximum(100000) - self.band_set_comb_spinBox_8.setObjectName("band_set_comb_spinBox_8") - self.gridLayout_211.addWidget(self.band_set_comb_spinBox_8, 1, 1, 1, 1) - spacerItem122 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_211.addItem(spacerItem122, 1, 2, 1, 1) - self.gridLayout_209.addLayout(self.gridLayout_211, 1, 0, 1, 1) - self.gridLayout_256 = QtWidgets.QGridLayout() - self.gridLayout_256.setObjectName("gridLayout_256") - self.label_184 = QtWidgets.QLabel(self.page_20) - self.label_184.setStyleSheet("background-color : #656565; color : white") - self.label_184.setFrameShape(QtWidgets.QFrame.Panel) - self.label_184.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_184.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_184.setObjectName("label_184") - self.gridLayout_256.addWidget(self.label_184, 2, 0, 1, 4) - self.class_signature_Button = QtWidgets.QToolButton(self.page_20) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.class_signature_Button.setFont(font) - self.class_signature_Button.setLayoutDirection(QtCore.Qt.RightToLeft) - self.class_signature_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.class_signature_Button.setIcon(icon64) - self.class_signature_Button.setIconSize(QtCore.QSize(34, 34)) - self.class_signature_Button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.class_signature_Button.setObjectName("class_signature_Button") - self.gridLayout_256.addWidget(self.class_signature_Button, 3, 3, 1, 1) - spacerItem123 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_256.addItem(spacerItem123, 3, 0, 1, 2) - spacerItem124 = QtWidgets.QSpacerItem(38, 37, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_256.addItem(spacerItem124, 1, 0, 1, 1) - self.class_signature_save_siglist_checkBox = QtWidgets.QCheckBox(self.page_20) - self.class_signature_save_siglist_checkBox.setChecked(True) - self.class_signature_save_siglist_checkBox.setObjectName("class_signature_save_siglist_checkBox") - self.gridLayout_256.addWidget(self.class_signature_save_siglist_checkBox, 0, 0, 1, 4) - self.class_signature = QtWidgets.QToolButton(self.page_20) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.class_signature.setFont(font) - self.class_signature.setLayoutDirection(QtCore.Qt.RightToLeft) - self.class_signature.setStyleSheet("margin: 0px;padding: 0px;") - self.class_signature.setIcon(icon48) - self.class_signature.setIconSize(QtCore.QSize(34, 34)) - self.class_signature.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.class_signature.setObjectName("class_signature") - self.gridLayout_256.addWidget(self.class_signature, 3, 2, 1, 1) - self.gridLayout_209.addLayout(self.gridLayout_256, 2, 0, 1, 1) - self.toolBox_class_signature.addItem(self.page_20, "") - self.page_24 = QtWidgets.QWidget() - self.page_24.setGeometry(QtCore.QRect(0, 0, 98, 90)) - self.page_24.setObjectName("page_24") - self.gridLayout_258 = QtWidgets.QGridLayout(self.page_24) - self.gridLayout_258.setObjectName("gridLayout_258") - self.gridLayout_259 = QtWidgets.QGridLayout() - self.gridLayout_259.setObjectName("gridLayout_259") - self.report_textBrowser_4 = QtWidgets.QTextBrowser(self.page_24) - font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - self.report_textBrowser_4.setFont(font) - self.report_textBrowser_4.setTabChangesFocus(True) - self.report_textBrowser_4.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) - self.report_textBrowser_4.setTabStopWidth(160) - self.report_textBrowser_4.setOpenLinks(False) - self.report_textBrowser_4.setObjectName("report_textBrowser_4") - self.gridLayout_259.addWidget(self.report_textBrowser_4, 0, 0, 1, 1) - self.gridLayout_258.addLayout(self.gridLayout_259, 0, 0, 1, 1) - self.toolBox_class_signature.addItem(self.page_24, "") - self.gridLayout_123.addWidget(self.toolBox_class_signature, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_class_signature, "") - self.tab_class_to_vector = QtWidgets.QWidget() - self.tab_class_to_vector.setObjectName("tab_class_to_vector") - self.gridLayout_49 = QtWidgets.QGridLayout(self.tab_class_to_vector) - self.gridLayout_49.setObjectName("gridLayout_49") - self.horizontalLayout_40 = QtWidgets.QHBoxLayout() - self.horizontalLayout_40.setObjectName("horizontalLayout_40") - self.label_189 = QtWidgets.QLabel(self.tab_class_to_vector) - self.label_189.setStyleSheet("background-color : #656565; color : white") - self.label_189.setFrameShape(QtWidgets.QFrame.Panel) - self.label_189.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_189.setObjectName("label_189") - self.horizontalLayout_40.addWidget(self.label_189) - self.gridLayout_49.addLayout(self.horizontalLayout_40, 0, 0, 1, 1) - self.gridLayout_71 = QtWidgets.QGridLayout() - self.gridLayout_71.setObjectName("gridLayout_71") - self.label_63 = QtWidgets.QLabel(self.tab_class_to_vector) + sizePolicy.setHeightForWidth(self.label_155.sizePolicy().hasHeightForWidth()) + self.label_155.setSizePolicy(sizePolicy) + self.label_155.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_155.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_155.setObjectName("label_155") + self.gridLayout_88.addWidget(self.label_155, 0, 0, 1, 1) + self.max_features_lineEdit = QtWidgets.QLineEdit(self.page_random_forest) + self.max_features_lineEdit.setText("") + self.max_features_lineEdit.setMaxLength(10000) + self.max_features_lineEdit.setObjectName("max_features_lineEdit") + self.gridLayout_88.addWidget(self.max_features_lineEdit, 0, 6, 1, 1) + self.best_estimator_checkBox = QtWidgets.QCheckBox(self.page_random_forest) + self.best_estimator_checkBox.setObjectName("best_estimator_checkBox") + self.gridLayout_88.addWidget(self.best_estimator_checkBox, 4, 0, 1, 3) + self.class_weight_checkBox = QtWidgets.QCheckBox(self.page_random_forest) + self.class_weight_checkBox.setObjectName("class_weight_checkBox") + self.gridLayout_88.addWidget(self.class_weight_checkBox, 3, 0, 1, 2) + spacerItem85 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_88.addItem(spacerItem85, 6, 0, 1, 1) + self.label_153 = QtWidgets.QLabel(self.page_random_forest) + self.label_153.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_153.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_153.setObjectName("label_153") + self.gridLayout_88.addWidget(self.label_153, 0, 5, 1, 1) + spacerItem86 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_88.addItem(spacerItem86, 0, 7, 1, 1) + self.min_split_SpinBox = QtWidgets.QDoubleSpinBox(self.page_random_forest) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.min_split_SpinBox.sizePolicy().hasHeightForWidth()) + self.min_split_SpinBox.setSizePolicy(sizePolicy) + self.min_split_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.min_split_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.min_split_SpinBox.setDecimals(0) + self.min_split_SpinBox.setMinimum(1.0) + self.min_split_SpinBox.setMaximum(10000.0) + self.min_split_SpinBox.setSingleStep(1.0) + self.min_split_SpinBox.setProperty("value", 2.0) + self.min_split_SpinBox.setObjectName("min_split_SpinBox") + self.gridLayout_88.addWidget(self.min_split_SpinBox, 0, 4, 1, 1) + self.cross_validation_checkBox_2 = QtWidgets.QCheckBox(self.page_random_forest) + self.cross_validation_checkBox_2.setChecked(True) + self.cross_validation_checkBox_2.setObjectName("cross_validation_checkBox_2") + self.gridLayout_88.addWidget(self.cross_validation_checkBox_2, 2, 0, 1, 2) + self.label_160 = QtWidgets.QLabel(self.page_random_forest) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_63.sizePolicy().hasHeightForWidth()) - self.label_63.setSizePolicy(sizePolicy) - self.label_63.setMinimumSize(QtCore.QSize(229, 0)) - self.label_63.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_63.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_63.setObjectName("label_63") - self.gridLayout_71.addWidget(self.label_63, 0, 0, 1, 1) - self.classification_vector_name_combo = QtWidgets.QComboBox(self.tab_class_to_vector) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.label_160.sizePolicy().hasHeightForWidth()) + self.label_160.setSizePolicy(sizePolicy) + self.label_160.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_160.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_160.setObjectName("label_160") + self.gridLayout_88.addWidget(self.label_160, 0, 2, 1, 2) + self.ovr_checkBox = QtWidgets.QCheckBox(self.page_random_forest) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.ovr_checkBox.sizePolicy().hasHeightForWidth()) + self.ovr_checkBox.setSizePolicy(sizePolicy) + self.ovr_checkBox.setObjectName("ovr_checkBox") + self.gridLayout_88.addWidget(self.ovr_checkBox, 1, 0, 1, 1) + self.number_trees_SpinBox = QtWidgets.QDoubleSpinBox(self.page_random_forest) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.number_trees_SpinBox.sizePolicy().hasHeightForWidth()) + self.number_trees_SpinBox.setSizePolicy(sizePolicy) + self.number_trees_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.number_trees_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.number_trees_SpinBox.setDecimals(0) + self.number_trees_SpinBox.setMinimum(2.0) + self.number_trees_SpinBox.setMaximum(10000.0) + self.number_trees_SpinBox.setSingleStep(10.0) + self.number_trees_SpinBox.setProperty("value", 10.0) + self.number_trees_SpinBox.setObjectName("number_trees_SpinBox") + self.gridLayout_88.addWidget(self.number_trees_SpinBox, 0, 1, 1, 1) + self.confidence_raster_checkBox_4 = QtWidgets.QCheckBox(self.page_random_forest) + self.confidence_raster_checkBox_4.setObjectName("confidence_raster_checkBox_4") + self.gridLayout_88.addWidget(self.confidence_raster_checkBox_4, 5, 0, 1, 4) + self.steps_SpinBox = QtWidgets.QDoubleSpinBox(self.page_random_forest) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.steps_SpinBox.sizePolicy().hasHeightForWidth()) + self.steps_SpinBox.setSizePolicy(sizePolicy) + self.steps_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.steps_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.steps_SpinBox.setDecimals(0) + self.steps_SpinBox.setMinimum(1.0) + self.steps_SpinBox.setMaximum(100.0) + self.steps_SpinBox.setSingleStep(1.0) + self.steps_SpinBox.setProperty("value", 5.0) + self.steps_SpinBox.setObjectName("steps_SpinBox") + self.gridLayout_88.addWidget(self.steps_SpinBox, 4, 3, 1, 1) + self.gridLayout_89.addLayout(self.gridLayout_88, 0, 0, 1, 1) + self.toolBox_classification.addItem(self.page_random_forest, "") + self.page_sam = QtWidgets.QWidget() + self.page_sam.setGeometry(QtCore.QRect(0, 0, 548, 113)) + self.page_sam.setObjectName("page_sam") + self.gridLayout_93 = QtWidgets.QGridLayout(self.page_sam) + self.gridLayout_93.setObjectName("gridLayout_93") + self.gridLayout_227 = QtWidgets.QGridLayout() + self.gridLayout_227.setObjectName("gridLayout_227") + self.signature_threshold_button_3 = QtWidgets.QToolButton(self.page_sam) + self.signature_threshold_button_3.setStyleSheet("margin: 0px;padding: 0px;") + self.signature_threshold_button_3.setIcon(icon8) + self.signature_threshold_button_3.setIconSize(QtCore.QSize(22, 22)) + self.signature_threshold_button_3.setObjectName("signature_threshold_button_3") + self.gridLayout_227.addWidget(self.signature_threshold_button_3, 0, 4, 1, 1) + spacerItem87 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_227.addItem(spacerItem87, 0, 5, 1, 1) + self.alg_threshold_SpinBox_3 = QtWidgets.QDoubleSpinBox(self.page_sam) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.alg_threshold_SpinBox_3.sizePolicy().hasHeightForWidth()) + self.alg_threshold_SpinBox_3.setSizePolicy(sizePolicy) + self.alg_threshold_SpinBox_3.setMaximumSize(QtCore.QSize(100, 16777215)) + self.alg_threshold_SpinBox_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.alg_threshold_SpinBox_3.setDecimals(4) + self.alg_threshold_SpinBox_3.setMaximum(100.0) + self.alg_threshold_SpinBox_3.setObjectName("alg_threshold_SpinBox_3") + self.gridLayout_227.addWidget(self.alg_threshold_SpinBox_3, 0, 2, 1, 1) + spacerItem88 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_227.addItem(spacerItem88, 3, 5, 1, 1) + self.label_236 = QtWidgets.QLabel(self.page_sam) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_236.sizePolicy().hasHeightForWidth()) + self.label_236.setSizePolicy(sizePolicy) + self.label_236.setMaximumSize(QtCore.QSize(100, 16777215)) + self.label_236.setObjectName("label_236") + self.gridLayout_227.addWidget(self.label_236, 0, 0, 1, 1) + self.single_threshold_checkBox_6 = QtWidgets.QCheckBox(self.page_sam) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_vector_name_combo.sizePolicy().hasHeightForWidth()) - self.classification_vector_name_combo.setSizePolicy(sizePolicy) - self.classification_vector_name_combo.setObjectName("classification_vector_name_combo") - self.gridLayout_71.addWidget(self.classification_vector_name_combo, 0, 1, 1, 1) - self.toolButton_reload_11 = QtWidgets.QToolButton(self.tab_class_to_vector) - self.toolButton_reload_11.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_11.setIcon(icon55) - self.toolButton_reload_11.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_11.setObjectName("toolButton_reload_11") - self.gridLayout_71.addWidget(self.toolButton_reload_11, 0, 2, 1, 1) - self.gridLayout_49.addLayout(self.gridLayout_71, 1, 0, 1, 1) - self.gridLayout_74 = QtWidgets.QGridLayout() - self.gridLayout_74.setObjectName("gridLayout_74") - self.class_macroclass_comboBox = QtWidgets.QComboBox(self.tab_class_to_vector) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox_6.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox_6.setSizePolicy(sizePolicy) + self.single_threshold_checkBox_6.setChecked(False) + self.single_threshold_checkBox_6.setObjectName("single_threshold_checkBox_6") + self.gridLayout_227.addWidget(self.single_threshold_checkBox_6, 0, 1, 1, 1) + self.single_threshold_checkBox_5 = QtWidgets.QCheckBox(self.page_sam) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_macroclass_comboBox.sizePolicy().hasHeightForWidth()) - self.class_macroclass_comboBox.setSizePolicy(sizePolicy) - self.class_macroclass_comboBox.setObjectName("class_macroclass_comboBox") - self.class_macroclass_comboBox.addItem("") - self.class_macroclass_comboBox.addItem("") - self.gridLayout_74.addWidget(self.class_macroclass_comboBox, 1, 1, 1, 1) - self.use_class_code_checkBox = QtWidgets.QCheckBox(self.tab_class_to_vector) - self.use_class_code_checkBox.setObjectName("use_class_code_checkBox") - self.gridLayout_74.addWidget(self.use_class_code_checkBox, 1, 0, 1, 1) - self.label_49 = QtWidgets.QLabel(self.tab_class_to_vector) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.single_threshold_checkBox_5.sizePolicy().hasHeightForWidth()) + self.single_threshold_checkBox_5.setSizePolicy(sizePolicy) + self.single_threshold_checkBox_5.setObjectName("single_threshold_checkBox_5") + self.gridLayout_227.addWidget(self.single_threshold_checkBox_5, 0, 3, 1, 1) + self.confidence_raster_checkBox_5 = QtWidgets.QCheckBox(self.page_sam) + self.confidence_raster_checkBox_5.setObjectName("confidence_raster_checkBox_5") + self.gridLayout_227.addWidget(self.confidence_raster_checkBox_5, 2, 0, 1, 5) + self.signature_raster_checkBox = QtWidgets.QCheckBox(self.page_sam) + self.signature_raster_checkBox.setObjectName("signature_raster_checkBox") + self.gridLayout_227.addWidget(self.signature_raster_checkBox, 1, 0, 1, 4) + self.gridLayout_93.addLayout(self.gridLayout_227, 0, 0, 1, 1) + self.toolBox_classification.addItem(self.page_sam, "") + self.page_svm = QtWidgets.QWidget() + self.page_svm.setGeometry(QtCore.QRect(0, 0, 523, 176)) + self.page_svm.setObjectName("page_svm") + self.gridLayout_96 = QtWidgets.QGridLayout(self.page_svm) + self.gridLayout_96.setObjectName("gridLayout_96") + self.gridLayout_67 = QtWidgets.QGridLayout() + self.gridLayout_67.setObjectName("gridLayout_67") + self.param_c_SpinBox = QtWidgets.QDoubleSpinBox(self.page_svm) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_49.sizePolicy().hasHeightForWidth()) - self.label_49.setSizePolicy(sizePolicy) - self.label_49.setStyleSheet("background-color : #656565; color : white") - self.label_49.setFrameShape(QtWidgets.QFrame.Panel) - self.label_49.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_49.setObjectName("label_49") - self.gridLayout_74.addWidget(self.label_49, 0, 0, 1, 2) - self.dissolve_output_checkBox = QtWidgets.QCheckBox(self.tab_class_to_vector) - self.dissolve_output_checkBox.setObjectName("dissolve_output_checkBox") - self.gridLayout_74.addWidget(self.dissolve_output_checkBox, 2, 0, 1, 1) - self.gridLayout_49.addLayout(self.gridLayout_74, 2, 0, 1, 1) - self.gridLayout_75 = QtWidgets.QGridLayout() - self.gridLayout_75.setObjectName("gridLayout_75") - spacerItem125 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_75.addItem(spacerItem125, 0, 1, 1, 1) - spacerItem126 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_75.addItem(spacerItem126, 0, 0, 1, 1) - self.convert_toolButton = QtWidgets.QToolButton(self.tab_class_to_vector) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.convert_toolButton.setFont(font) - self.convert_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.convert_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.convert_toolButton.setIcon(icon64) - self.convert_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.convert_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.convert_toolButton.setObjectName("convert_toolButton") - self.gridLayout_75.addWidget(self.convert_toolButton, 2, 2, 1, 1) - self.label_171 = QtWidgets.QLabel(self.tab_class_to_vector) - self.label_171.setStyleSheet("background-color : #656565; color : white") - self.label_171.setFrameShape(QtWidgets.QFrame.Panel) - self.label_171.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_171.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_171.setObjectName("label_171") - self.gridLayout_75.addWidget(self.label_171, 1, 0, 1, 3) - self.classification_to_vector = QtWidgets.QToolButton(self.tab_class_to_vector) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.classification_to_vector.setFont(font) - self.classification_to_vector.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification_to_vector.setStyleSheet("margin: 0px;padding: 0px;") - self.classification_to_vector.setIcon(icon48) - self.classification_to_vector.setIconSize(QtCore.QSize(34, 34)) - self.classification_to_vector.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification_to_vector.setObjectName("classification_to_vector") - self.gridLayout_75.addWidget(self.classification_to_vector, 2, 1, 1, 1) - self.gridLayout_49.addLayout(self.gridLayout_75, 3, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_class_to_vector, "") - self.tab_reclassification = QtWidgets.QWidget() - self.tab_reclassification.setObjectName("tab_reclassification") - self.gridLayout_191 = QtWidgets.QGridLayout(self.tab_reclassification) - self.gridLayout_191.setObjectName("gridLayout_191") - self.gridLayout_78 = QtWidgets.QGridLayout() - self.gridLayout_78.setObjectName("gridLayout_78") - self.label_65 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy.setHeightForWidth(self.param_c_SpinBox.sizePolicy().hasHeightForWidth()) + self.param_c_SpinBox.setSizePolicy(sizePolicy) + self.param_c_SpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.param_c_SpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.param_c_SpinBox.setDecimals(4) + self.param_c_SpinBox.setMinimum(1.0) + self.param_c_SpinBox.setMaximum(10000.0) + self.param_c_SpinBox.setSingleStep(1.0) + self.param_c_SpinBox.setProperty("value", 1.0) + self.param_c_SpinBox.setObjectName("param_c_SpinBox") + self.gridLayout_67.addWidget(self.param_c_SpinBox, 0, 1, 1, 1) + self.label_173 = QtWidgets.QLabel(self.page_svm) + self.label_173.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_173.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_173.setObjectName("label_173") + self.gridLayout_67.addWidget(self.label_173, 0, 2, 1, 1) + spacerItem89 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_67.addItem(spacerItem89, 0, 6, 1, 1) + self.gamma_lineEdit = QtWidgets.QLineEdit(self.page_svm) + self.gamma_lineEdit.setMaxLength(10000) + self.gamma_lineEdit.setObjectName("gamma_lineEdit") + self.gridLayout_67.addWidget(self.gamma_lineEdit, 0, 5, 1, 1) + self.cross_validation_checkBox = QtWidgets.QCheckBox(self.page_svm) + self.cross_validation_checkBox.setChecked(True) + self.cross_validation_checkBox.setObjectName("cross_validation_checkBox") + self.gridLayout_67.addWidget(self.cross_validation_checkBox, 1, 0, 1, 1) + self.kernel_lineEdit = QtWidgets.QLineEdit(self.page_svm) + self.kernel_lineEdit.setMaxLength(10000) + self.kernel_lineEdit.setObjectName("kernel_lineEdit") + self.gridLayout_67.addWidget(self.kernel_lineEdit, 0, 3, 1, 1) + self.label_163 = QtWidgets.QLabel(self.page_svm) + self.label_163.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_163.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_163.setObjectName("label_163") + self.gridLayout_67.addWidget(self.label_163, 0, 4, 1, 1) + self.label_162 = QtWidgets.QLabel(self.page_svm) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_65.sizePolicy().hasHeightForWidth()) - self.label_65.setSizePolicy(sizePolicy) - self.label_65.setMinimumSize(QtCore.QSize(229, 0)) - self.label_65.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_65.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_65.setObjectName("label_65") - self.gridLayout_78.addWidget(self.label_65, 1, 0, 1, 1) - self.reclassification_name_combo = QtWidgets.QComboBox(self.tab_reclassification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reclassification_name_combo.sizePolicy().hasHeightForWidth()) - self.reclassification_name_combo.setSizePolicy(sizePolicy) - self.reclassification_name_combo.setObjectName("reclassification_name_combo") - self.gridLayout_78.addWidget(self.reclassification_name_combo, 1, 1, 1, 1) - self.toolButton_reload_12 = QtWidgets.QToolButton(self.tab_reclassification) - self.toolButton_reload_12.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_12.setIcon(icon55) - self.toolButton_reload_12.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_12.setObjectName("toolButton_reload_12") - self.gridLayout_78.addWidget(self.toolButton_reload_12, 1, 2, 1, 1) - self.horizontalLayout_41 = QtWidgets.QHBoxLayout() - self.horizontalLayout_41.setObjectName("horizontalLayout_41") - self.label_190 = QtWidgets.QLabel(self.tab_reclassification) - self.label_190.setStyleSheet("background-color : #656565; color : white") - self.label_190.setFrameShape(QtWidgets.QFrame.Panel) - self.label_190.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_190.setObjectName("label_190") - self.horizontalLayout_41.addWidget(self.label_190) - self.gridLayout_78.addLayout(self.horizontalLayout_41, 0, 0, 1, 3) - self.gridLayout_191.addLayout(self.gridLayout_78, 0, 0, 1, 1) - self.gridLayout_79 = QtWidgets.QGridLayout() - self.gridLayout_79.setObjectName("gridLayout_79") - self.calculate_unique_values_toolButton = QtWidgets.QToolButton(self.tab_reclassification) - self.calculate_unique_values_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.calculate_unique_values_toolButton.setIcon(icon67) - self.calculate_unique_values_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.calculate_unique_values_toolButton.setObjectName("calculate_unique_values_toolButton") - self.gridLayout_79.addWidget(self.calculate_unique_values_toolButton, 1, 4, 1, 1) - self.CID_MCID_code_checkBox = QtWidgets.QCheckBox(self.tab_reclassification) - self.CID_MCID_code_checkBox.setObjectName("CID_MCID_code_checkBox") - self.gridLayout_79.addWidget(self.CID_MCID_code_checkBox, 1, 2, 1, 1) - self.label_98 = QtWidgets.QLabel(self.tab_reclassification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_162.sizePolicy().hasHeightForWidth()) + self.label_162.setSizePolicy(sizePolicy) + self.label_162.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_162.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_162.setObjectName("label_162") + self.gridLayout_67.addWidget(self.label_162, 0, 0, 1, 1) + spacerItem90 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_67.addItem(spacerItem90, 5, 1, 1, 1) + self.best_estimator_checkBox_3 = QtWidgets.QCheckBox(self.page_svm) + self.best_estimator_checkBox_3.setObjectName("best_estimator_checkBox_3") + self.gridLayout_67.addWidget(self.best_estimator_checkBox_3, 3, 0, 1, 2) + self.class_weight_checkBox_2 = QtWidgets.QCheckBox(self.page_svm) + self.class_weight_checkBox_2.setObjectName("class_weight_checkBox_2") + self.gridLayout_67.addWidget(self.class_weight_checkBox_2, 2, 0, 1, 2) + self.steps_SpinBox_3 = QtWidgets.QDoubleSpinBox(self.page_svm) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_98.sizePolicy().hasHeightForWidth()) - self.label_98.setSizePolicy(sizePolicy) - self.label_98.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_98.setObjectName("label_98") - self.gridLayout_79.addWidget(self.label_98, 1, 3, 1, 1) - self.label_54 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy.setHeightForWidth(self.steps_SpinBox_3.sizePolicy().hasHeightForWidth()) + self.steps_SpinBox_3.setSizePolicy(sizePolicy) + self.steps_SpinBox_3.setMaximumSize(QtCore.QSize(100, 16777215)) + self.steps_SpinBox_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.steps_SpinBox_3.setDecimals(0) + self.steps_SpinBox_3.setMinimum(1.0) + self.steps_SpinBox_3.setMaximum(100.0) + self.steps_SpinBox_3.setSingleStep(1.0) + self.steps_SpinBox_3.setProperty("value", 5.0) + self.steps_SpinBox_3.setObjectName("steps_SpinBox_3") + self.gridLayout_67.addWidget(self.steps_SpinBox_3, 3, 2, 1, 2) + self.confidence_raster_checkBox_6 = QtWidgets.QCheckBox(self.page_svm) + self.confidence_raster_checkBox_6.setObjectName("confidence_raster_checkBox_6") + self.gridLayout_67.addWidget(self.confidence_raster_checkBox_6, 4, 0, 1, 4) + self.gridLayout_96.addLayout(self.gridLayout_67, 0, 0, 1, 1) + self.toolBox_classification.addItem(self.page_svm, "") + self.gridLayout_151.addWidget(self.toolBox_classification, 2, 0, 1, 1) + self.tabWidget_4.addTab(self.tab_classification, "") + self.tab_neighbor_pixels = QtWidgets.QWidget() + self.tab_neighbor_pixels.setObjectName("tab_neighbor_pixels") + self.gridLayout_2 = QtWidgets.QGridLayout(self.tab_neighbor_pixels) + self.gridLayout_2.setObjectName("gridLayout_2") + self.gridLayout_240 = QtWidgets.QGridLayout() + self.gridLayout_240.setObjectName("gridLayout_240") + self.label_283 = QtWidgets.QLabel(self.tab_neighbor_pixels) + self.label_283.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_283.setFrameShape(QtWidgets.QFrame.Panel) + self.label_283.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_283.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_283.setObjectName("label_283") + self.gridLayout_240.addWidget(self.label_283, 8, 0, 1, 3) + self.gridLayout_309 = QtWidgets.QGridLayout() + self.gridLayout_309.setObjectName("gridLayout_309") + self.label_287 = QtWidgets.QLabel(self.tab_neighbor_pixels) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_54.sizePolicy().hasHeightForWidth()) - self.label_54.setSizePolicy(sizePolicy) - self.label_54.setStyleSheet("background-color : #656565; color : white") - self.label_54.setFrameShape(QtWidgets.QFrame.Panel) - self.label_54.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_54.setObjectName("label_54") - self.gridLayout_79.addWidget(self.label_54, 0, 2, 1, 3) - self.incremental_new_values_toolButton = QtWidgets.QToolButton(self.tab_reclassification) - self.incremental_new_values_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.incremental_new_values_toolButton.setIcon(icon67) - self.incremental_new_values_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.incremental_new_values_toolButton.setObjectName("incremental_new_values_toolButton") - self.gridLayout_79.addWidget(self.incremental_new_values_toolButton, 2, 4, 1, 1) - self.label_271 = QtWidgets.QLabel(self.tab_reclassification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_287.sizePolicy().hasHeightForWidth()) + self.label_287.setSizePolicy(sizePolicy) + self.label_287.setFrameShape(QtWidgets.QFrame.Panel) + self.label_287.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_287.setText("") + self.label_287.setObjectName("label_287") + self.gridLayout_309.addWidget(self.label_287, 0, 1, 1, 1) + self.label_281 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_271.sizePolicy().hasHeightForWidth()) - self.label_271.setSizePolicy(sizePolicy) - self.label_271.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_271.setObjectName("label_271") - self.gridLayout_79.addWidget(self.label_271, 2, 3, 1, 1) - self.gridLayout_191.addLayout(self.gridLayout_79, 1, 0, 1, 1) - self.gridLayout_77 = QtWidgets.QGridLayout() - self.gridLayout_77.setObjectName("gridLayout_77") - self.reclass_values_tableWidget = QtWidgets.QTableWidget(self.tab_reclassification) - self.reclass_values_tableWidget.setAlternatingRowColors(True) - self.reclass_values_tableWidget.setObjectName("reclass_values_tableWidget") - self.reclass_values_tableWidget.setColumnCount(2) - self.reclass_values_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.reclass_values_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.reclass_values_tableWidget.setHorizontalHeaderItem(1, item) - self.reclass_values_tableWidget.horizontalHeader().setStretchLastSection(True) - self.reclass_values_tableWidget.verticalHeader().setDefaultSectionSize(24) - self.gridLayout_77.addWidget(self.reclass_values_tableWidget, 0, 0, 1, 1) - self.gridLayout_81 = QtWidgets.QGridLayout() - self.gridLayout_81.setObjectName("gridLayout_81") - self.add_value_pushButton = QtWidgets.QToolButton(self.tab_reclassification) - self.add_value_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.add_value_pushButton.setIcon(icon66) - self.add_value_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_value_pushButton.setObjectName("add_value_pushButton") - self.gridLayout_81.addWidget(self.add_value_pushButton, 1, 0, 1, 1) - self.remove_row_pushButton = QtWidgets.QToolButton(self.tab_reclassification) - self.remove_row_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.remove_row_pushButton.setIcon(icon58) - self.remove_row_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_row_pushButton.setObjectName("remove_row_pushButton") - self.gridLayout_81.addWidget(self.remove_row_pushButton, 2, 0, 1, 1) - spacerItem127 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_81.addItem(spacerItem127, 0, 0, 1, 1) - spacerItem128 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_81.addItem(spacerItem128, 6, 0, 1, 1) - self.import_reclass_toolButton = QtWidgets.QToolButton(self.tab_reclassification) - self.import_reclass_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_reclass_toolButton.setIcon(icon54) - self.import_reclass_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_reclass_toolButton.setObjectName("import_reclass_toolButton") - self.gridLayout_81.addWidget(self.import_reclass_toolButton, 4, 0, 1, 1) - self.export_reclass_toolButton = QtWidgets.QToolButton(self.tab_reclassification) - self.export_reclass_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_reclass_toolButton.setIcon(icon53) - self.export_reclass_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_reclass_toolButton.setObjectName("export_reclass_toolButton") - self.gridLayout_81.addWidget(self.export_reclass_toolButton, 5, 0, 1, 1) - spacerItem129 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_81.addItem(spacerItem129, 3, 0, 1, 1) - self.gridLayout_77.addLayout(self.gridLayout_81, 0, 1, 1, 1) - self.gridLayout_191.addLayout(self.gridLayout_77, 2, 0, 1, 1) - self.gridLayout_80 = QtWidgets.QGridLayout() - self.gridLayout_80.setObjectName("gridLayout_80") - self.gridLayout_82 = QtWidgets.QGridLayout() - self.gridLayout_82.setObjectName("gridLayout_82") - self.apply_symbology_checkBox = QtWidgets.QCheckBox(self.tab_reclassification) - self.apply_symbology_checkBox.setChecked(False) - self.apply_symbology_checkBox.setObjectName("apply_symbology_checkBox") - self.gridLayout_82.addWidget(self.apply_symbology_checkBox, 1, 0, 1, 1) - self.class_macroclass_comboBox_2 = QtWidgets.QComboBox(self.tab_reclassification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_macroclass_comboBox_2.sizePolicy().hasHeightForWidth()) - self.class_macroclass_comboBox_2.setSizePolicy(sizePolicy) - self.class_macroclass_comboBox_2.setObjectName("class_macroclass_comboBox_2") - self.class_macroclass_comboBox_2.addItem("") - self.class_macroclass_comboBox_2.addItem("") - self.gridLayout_82.addWidget(self.class_macroclass_comboBox_2, 1, 1, 1, 1) - self.label_51 = QtWidgets.QLabel(self.tab_reclassification) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_281.sizePolicy().hasHeightForWidth()) + self.label_281.setSizePolicy(sizePolicy) + self.label_281.setMinimumSize(QtCore.QSize(229, 0)) + font = QtGui.QFont() + font.setBold(False) + font.setWeight(50) + self.label_281.setFont(font) + self.label_281.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_281.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_281.setObjectName("label_281") + self.gridLayout_309.addWidget(self.label_281, 0, 0, 1, 1) + self.toolButton_input_matrix = QtWidgets.QToolButton(self.tab_neighbor_pixels) + self.toolButton_input_matrix.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_input_matrix.setIcon(icon43) + self.toolButton_input_matrix.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_input_matrix.setObjectName("toolButton_input_matrix") + self.gridLayout_309.addWidget(self.toolButton_input_matrix, 0, 2, 1, 1) + self.horizontalLayout_71 = QtWidgets.QHBoxLayout() + self.horizontalLayout_71.setObjectName("horizontalLayout_71") + self.label_279 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_51.sizePolicy().hasHeightForWidth()) - self.label_51.setSizePolicy(sizePolicy) - self.label_51.setStyleSheet("background-color : #656565; color : white") - self.label_51.setFrameShape(QtWidgets.QFrame.Panel) - self.label_51.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_51.setObjectName("label_51") - self.gridLayout_82.addWidget(self.label_51, 0, 0, 1, 2) - self.gridLayout_80.addLayout(self.gridLayout_82, 0, 0, 1, 1) - self.gridLayout_191.addLayout(self.gridLayout_80, 3, 0, 1, 1) - self.gridLayout_83 = QtWidgets.QGridLayout() - self.gridLayout_83.setObjectName("gridLayout_83") - spacerItem130 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_83.addItem(spacerItem130, 1, 0, 1, 1) - self.label_172 = QtWidgets.QLabel(self.tab_reclassification) - self.label_172.setStyleSheet("background-color : #656565; color : white") - self.label_172.setFrameShape(QtWidgets.QFrame.Panel) - self.label_172.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_172.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_172.setObjectName("label_172") - self.gridLayout_83.addWidget(self.label_172, 0, 0, 1, 3) - self.reclassify_toolButton = QtWidgets.QToolButton(self.tab_reclassification) + sizePolicy.setHeightForWidth(self.label_279.sizePolicy().hasHeightForWidth()) + self.label_279.setSizePolicy(sizePolicy) + self.label_279.setMinimumSize(QtCore.QSize(229, 0)) + self.label_279.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_279.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_279.setObjectName("label_279") + self.horizontalLayout_71.addWidget(self.label_279) + self.neighbor_output_name_lineEdit = QtWidgets.QLineEdit(self.tab_neighbor_pixels) + self.neighbor_output_name_lineEdit.setMaxLength(10) + self.neighbor_output_name_lineEdit.setObjectName("neighbor_output_name_lineEdit") + self.horizontalLayout_71.addWidget(self.neighbor_output_name_lineEdit) + self.neighbor_virtual_checkBox = QtWidgets.QCheckBox(self.tab_neighbor_pixels) + self.neighbor_virtual_checkBox.setObjectName("neighbor_virtual_checkBox") + self.horizontalLayout_71.addWidget(self.neighbor_virtual_checkBox) + self.gridLayout_309.addLayout(self.horizontalLayout_71, 2, 0, 1, 3) + self.gridLayout_240.addLayout(self.gridLayout_309, 2, 0, 1, 3) + self.neighbor_pixels = QtWidgets.QToolButton(self.tab_neighbor_pixels) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.reclassify_toolButton.setFont(font) - self.reclassify_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.reclassify_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.reclassify_toolButton.setIcon(icon64) - self.reclassify_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.reclassify_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.reclassify_toolButton.setObjectName("reclassify_toolButton") - self.gridLayout_83.addWidget(self.reclassify_toolButton, 1, 2, 1, 1) - self.reclassification = QtWidgets.QToolButton(self.tab_reclassification) + self.neighbor_pixels.setFont(font) + self.neighbor_pixels.setLayoutDirection(QtCore.Qt.RightToLeft) + self.neighbor_pixels.setStyleSheet("margin: 0px;padding: 0px;") + self.neighbor_pixels.setIcon(icon33) + self.neighbor_pixels.setIconSize(QtCore.QSize(34, 34)) + self.neighbor_pixels.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.neighbor_pixels.setObjectName("neighbor_pixels") + self.gridLayout_240.addWidget(self.neighbor_pixels, 9, 1, 1, 1) + spacerItem91 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_240.addItem(spacerItem91, 9, 0, 1, 1) + self.class_neighbor_toolButton = QtWidgets.QToolButton(self.tab_neighbor_pixels) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.reclassification.setFont(font) - self.reclassification.setLayoutDirection(QtCore.Qt.RightToLeft) - self.reclassification.setStyleSheet("margin: 0px;padding: 0px;") - self.reclassification.setIcon(icon48) - self.reclassification.setIconSize(QtCore.QSize(34, 34)) - self.reclassification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.reclassification.setObjectName("reclassification") - self.gridLayout_83.addWidget(self.reclassification, 1, 1, 1, 1) - self.gridLayout_191.addLayout(self.gridLayout_83, 4, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_reclassification, "") - self.tab = QtWidgets.QWidget() - self.tab.setObjectName("tab") - self.gridLayout_359 = QtWidgets.QGridLayout(self.tab) - self.gridLayout_359.setObjectName("gridLayout_359") - self.horizontalLayout_42 = QtWidgets.QHBoxLayout() - self.horizontalLayout_42.setObjectName("horizontalLayout_42") - self.label_193 = QtWidgets.QLabel(self.tab) - self.label_193.setStyleSheet("background-color : #656565; color : white") - self.label_193.setFrameShape(QtWidgets.QFrame.Panel) - self.label_193.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_193.setObjectName("label_193") - self.horizontalLayout_42.addWidget(self.label_193) - self.gridLayout_359.addLayout(self.horizontalLayout_42, 0, 0, 1, 1) - self.gridLayout_196 = QtWidgets.QGridLayout() - self.gridLayout_196.setObjectName("gridLayout_196") - self.undo_edit_Button = QtWidgets.QToolButton(self.tab) - self.undo_edit_Button.setEnabled(False) - self.undo_edit_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon81 = QtGui.QIcon() - icon81.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_edit_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.undo_edit_Button.setIcon(icon81) - self.undo_edit_Button.setIconSize(QtCore.QSize(22, 22)) - self.undo_edit_Button.setObjectName("undo_edit_Button") - self.gridLayout_196.addWidget(self.undo_edit_Button, 10, 0, 1, 1) - self.label_173 = QtWidgets.QLabel(self.tab) - self.label_173.setStyleSheet("background-color : #656565; color : white") - self.label_173.setFrameShape(QtWidgets.QFrame.Panel) - self.label_173.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_173.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_173.setObjectName("label_173") - self.gridLayout_196.addWidget(self.label_173, 9, 0, 1, 4) - self.horizontalLayout_8 = QtWidgets.QHBoxLayout() - self.horizontalLayout_8.setObjectName("horizontalLayout_8") - self.label_66 = QtWidgets.QLabel(self.tab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + self.class_neighbor_toolButton.setFont(font) + self.class_neighbor_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.class_neighbor_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.class_neighbor_toolButton.setIcon(icon44) + self.class_neighbor_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.class_neighbor_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.class_neighbor_toolButton.setObjectName("class_neighbor_toolButton") + self.gridLayout_240.addWidget(self.class_neighbor_toolButton, 9, 2, 1, 1) + spacerItem92 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_240.addItem(spacerItem92, 7, 2, 1, 1) + self.horizontalLayout_70 = QtWidgets.QHBoxLayout() + self.horizontalLayout_70.setObjectName("horizontalLayout_70") + self.label_286 = QtWidgets.QLabel(self.tab_neighbor_pixels) + self.label_286.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_286.setFrameShape(QtWidgets.QFrame.Panel) + self.label_286.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_286.setObjectName("label_286") + self.horizontalLayout_70.addWidget(self.label_286) + self.gridLayout_240.addLayout(self.horizontalLayout_70, 0, 0, 1, 3) + self.gridLayout_277 = QtWidgets.QGridLayout() + self.gridLayout_277.setObjectName("gridLayout_277") + self.statistic_lineEdit_2 = QtWidgets.QLineEdit(self.tab_neighbor_pixels) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_66.sizePolicy().hasHeightForWidth()) - self.label_66.setSizePolicy(sizePolicy) - self.label_66.setMinimumSize(QtCore.QSize(229, 0)) - self.label_66.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_66.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_66.setObjectName("label_66") - self.horizontalLayout_8.addWidget(self.label_66) - self.edit_raster_name_combo = QtWidgets.QComboBox(self.tab) + sizePolicy.setHeightForWidth(self.statistic_lineEdit_2.sizePolicy().hasHeightForWidth()) + self.statistic_lineEdit_2.setSizePolicy(sizePolicy) + self.statistic_lineEdit_2.setMaximumSize(QtCore.QSize(200, 16777215)) + self.statistic_lineEdit_2.setText("") + self.statistic_lineEdit_2.setMaxLength(10000) + self.statistic_lineEdit_2.setObjectName("statistic_lineEdit_2") + self.gridLayout_277.addWidget(self.statistic_lineEdit_2, 1, 2, 1, 1) + self.statistic_name_combobox_2 = QtWidgets.QComboBox(self.tab_neighbor_pixels) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.edit_raster_name_combo.sizePolicy().hasHeightForWidth()) - self.edit_raster_name_combo.setSizePolicy(sizePolicy) - self.edit_raster_name_combo.setObjectName("edit_raster_name_combo") - self.horizontalLayout_8.addWidget(self.edit_raster_name_combo) - self.toolButton_reload_14 = QtWidgets.QToolButton(self.tab) - self.toolButton_reload_14.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_14.setIcon(icon55) - self.toolButton_reload_14.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_14.setObjectName("toolButton_reload_14") - self.horizontalLayout_8.addWidget(self.toolButton_reload_14) - self.gridLayout_196.addLayout(self.horizontalLayout_8, 0, 0, 1, 4) - self.horizontalLayout_6 = QtWidgets.QHBoxLayout() - self.horizontalLayout_6.setObjectName("horizontalLayout_6") - self.use_constant_val_checkBox = QtWidgets.QCheckBox(self.tab) - self.use_constant_val_checkBox.setChecked(True) - self.use_constant_val_checkBox.setObjectName("use_constant_val_checkBox") - self.horizontalLayout_6.addWidget(self.use_constant_val_checkBox) - self.value_spinBox = QtWidgets.QSpinBox(self.tab) - self.value_spinBox.setMinimum(-2147483647) - self.value_spinBox.setMaximum(2147483647) - self.value_spinBox.setObjectName("value_spinBox") - self.horizontalLayout_6.addWidget(self.value_spinBox) - spacerItem131 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_6.addItem(spacerItem131) - self.gridLayout_196.addLayout(self.horizontalLayout_6, 6, 0, 1, 4) - self.horizontalLayout_7 = QtWidgets.QHBoxLayout() - self.horizontalLayout_7.setObjectName("horizontalLayout_7") - self.use_expression_checkBox = QtWidgets.QCheckBox(self.tab) - self.use_expression_checkBox.setObjectName("use_expression_checkBox") - self.horizontalLayout_7.addWidget(self.use_expression_checkBox) - self.expression_lineEdit = QtWidgets.QLineEdit(self.tab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.statistic_name_combobox_2.sizePolicy().hasHeightForWidth()) + self.statistic_name_combobox_2.setSizePolicy(sizePolicy) + self.statistic_name_combobox_2.setMaximumSize(QtCore.QSize(200, 16777215)) + self.statistic_name_combobox_2.setObjectName("statistic_name_combobox_2") + self.gridLayout_277.addWidget(self.statistic_name_combobox_2, 1, 1, 1, 1) + self.label_284 = QtWidgets.QLabel(self.tab_neighbor_pixels) + self.label_284.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_284.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_284.setObjectName("label_284") + self.gridLayout_277.addWidget(self.label_284, 1, 0, 1, 1) + spacerItem93 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_277.addItem(spacerItem93, 1, 3, 1, 1) + self.label_285 = QtWidgets.QLabel(self.tab_neighbor_pixels) + self.label_285.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_285.setFrameShape(QtWidgets.QFrame.Panel) + self.label_285.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_285.setObjectName("label_285") + self.gridLayout_277.addWidget(self.label_285, 0, 0, 1, 4) + self.gridLayout_240.addLayout(self.gridLayout_277, 6, 0, 1, 3) + self.gridLayout_300 = QtWidgets.QGridLayout() + self.gridLayout_300.setObjectName("gridLayout_300") + self.label_282 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_282.sizePolicy().hasHeightForWidth()) + self.label_282.setSizePolicy(sizePolicy) + self.label_282.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_282.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_282.setObjectName("label_282") + self.gridLayout_300.addWidget(self.label_282, 0, 0, 1, 1) + self.label_280 = QtWidgets.QLabel(self.tab_neighbor_pixels) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_280.sizePolicy().hasHeightForWidth()) + self.label_280.setSizePolicy(sizePolicy) + self.label_280.setMinimumSize(QtCore.QSize(229, 0)) + self.label_280.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_280.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_280.setObjectName("label_280") + self.gridLayout_300.addWidget(self.label_280, 1, 0, 1, 1) + self.band_set_comb_spinBox_15 = QtWidgets.QSpinBox(self.tab_neighbor_pixels) + self.band_set_comb_spinBox_15.setMinimum(1) + self.band_set_comb_spinBox_15.setMaximum(100000) + self.band_set_comb_spinBox_15.setObjectName("band_set_comb_spinBox_15") + self.gridLayout_300.addWidget(self.band_set_comb_spinBox_15, 0, 1, 1, 1) + self.class_neighbor_threshold_spinBox = QtWidgets.QSpinBox(self.tab_neighbor_pixels) + self.class_neighbor_threshold_spinBox.setMinimum(1) + self.class_neighbor_threshold_spinBox.setMaximum(1000) + self.class_neighbor_threshold_spinBox.setProperty("value", 1) + self.class_neighbor_threshold_spinBox.setObjectName("class_neighbor_threshold_spinBox") + self.gridLayout_300.addWidget(self.class_neighbor_threshold_spinBox, 1, 1, 1, 1) + spacerItem94 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_300.addItem(spacerItem94, 1, 3, 1, 1) + self.circular_structure_checkBox = QtWidgets.QCheckBox(self.tab_neighbor_pixels) + self.circular_structure_checkBox.setObjectName("circular_structure_checkBox") + self.gridLayout_300.addWidget(self.circular_structure_checkBox, 1, 2, 1, 1) + self.gridLayout_240.addLayout(self.gridLayout_300, 1, 0, 1, 3) + self.horizontalLayout_72 = QtWidgets.QHBoxLayout() + self.horizontalLayout_72.setObjectName("horizontalLayout_72") + spacerItem95 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_72.addItem(spacerItem95) + self.gridLayout_240.addLayout(self.horizontalLayout_72, 3, 0, 1, 3) + self.gridLayout_2.addLayout(self.gridLayout_240, 0, 0, 1, 1) + self.tabWidget_4.addTab(self.tab_neighbor_pixels, "") + self.gridLayout_62.addWidget(self.tabWidget_4, 0, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_band_processing, "") + self.tab_postProcessing = QtWidgets.QWidget() + self.tab_postProcessing.setObjectName("tab_postProcessing") + self.gridLayout_552 = QtWidgets.QGridLayout(self.tab_postProcessing) + self.gridLayout_552.setContentsMargins(3, 3, 3, 3) + self.gridLayout_552.setObjectName("gridLayout_552") + self.tabWidget_2 = QtWidgets.QTabWidget(self.tab_postProcessing) + self.tabWidget_2.setStyleSheet("") + self.tabWidget_2.setIconSize(QtCore.QSize(20, 20)) + self.tabWidget_2.setDocumentMode(True) + self.tabWidget_2.setObjectName("tabWidget_2") + self.tab_accuracy = QtWidgets.QWidget() + self.tab_accuracy.setObjectName("tab_accuracy") + self.gridLayout_184 = QtWidgets.QGridLayout(self.tab_accuracy) + self.gridLayout_184.setObjectName("gridLayout_184") + self.toolBox_accuracy = QtWidgets.QToolBox(self.tab_accuracy) + self.toolBox_accuracy.setObjectName("toolBox_accuracy") + self.page_10 = QtWidgets.QWidget() + self.page_10.setGeometry(QtCore.QRect(0, 0, 731, 388)) + self.page_10.setObjectName("page_10") + self.gridLayout_36 = QtWidgets.QGridLayout(self.page_10) + self.gridLayout_36.setObjectName("gridLayout_36") + self.gridLayout_33 = QtWidgets.QGridLayout() + self.gridLayout_33.setObjectName("gridLayout_33") + self.label_33 = QtWidgets.QLabel(self.page_10) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_33.sizePolicy().hasHeightForWidth()) + self.label_33.setSizePolicy(sizePolicy) + self.label_33.setMinimumSize(QtCore.QSize(229, 0)) + self.label_33.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_33.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_33.setObjectName("label_33") + self.gridLayout_33.addWidget(self.label_33, 1, 0, 1, 1) + self.label_34 = QtWidgets.QLabel(self.page_10) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.expression_lineEdit.sizePolicy().hasHeightForWidth()) - self.expression_lineEdit.setSizePolicy(sizePolicy) - self.expression_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) - self.expression_lineEdit.setMaxLength(10000) - self.expression_lineEdit.setObjectName("expression_lineEdit") - self.horizontalLayout_7.addWidget(self.expression_lineEdit) - self.gridLayout_196.addLayout(self.horizontalLayout_7, 7, 0, 1, 4) - spacerItem132 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_196.addItem(spacerItem132, 10, 1, 1, 1) - spacerItem133 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_196.addItem(spacerItem133, 8, 3, 1, 1) - self.horizontalLayout_9 = QtWidgets.QHBoxLayout() - self.horizontalLayout_9.setObjectName("horizontalLayout_9") - self.label_81 = QtWidgets.QLabel(self.tab) - self.label_81.setStyleSheet("background-color : #656565; color : white") - self.label_81.setFrameShape(QtWidgets.QFrame.Panel) - self.label_81.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_81.setObjectName("label_81") - self.horizontalLayout_9.addWidget(self.label_81) - self.gridLayout_196.addLayout(self.horizontalLayout_9, 1, 0, 1, 4) - self.horizontalLayout_24 = QtWidgets.QHBoxLayout() - self.horizontalLayout_24.setObjectName("horizontalLayout_24") - self.use_field_vector_checkBox = QtWidgets.QCheckBox(self.tab) - self.use_field_vector_checkBox.setObjectName("use_field_vector_checkBox") - self.horizontalLayout_24.addWidget(self.use_field_vector_checkBox) - self.field_comboBox_2 = QtWidgets.QComboBox(self.tab) + sizePolicy.setHeightForWidth(self.label_34.sizePolicy().hasHeightForWidth()) + self.label_34.setSizePolicy(sizePolicy) + self.label_34.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_34.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_34.setObjectName("label_34") + self.gridLayout_33.addWidget(self.label_34, 2, 0, 1, 1) + self.classification_name_combo = QtWidgets.QComboBox(self.page_10) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.field_comboBox_2.sizePolicy().hasHeightForWidth()) - self.field_comboBox_2.setSizePolicy(sizePolicy) - self.field_comboBox_2.setObjectName("field_comboBox_2") - self.horizontalLayout_24.addWidget(self.field_comboBox_2) - self.gridLayout_196.addLayout(self.horizontalLayout_24, 5, 0, 1, 4) - self.horizontalLayout_21 = QtWidgets.QHBoxLayout() - self.horizontalLayout_21.setObjectName("horizontalLayout_21") - self.edit_val_use_vector_radioButton = QtWidgets.QRadioButton(self.tab) - self.edit_val_use_vector_radioButton.setObjectName("edit_val_use_vector_radioButton") - self.horizontalLayout_21.addWidget(self.edit_val_use_vector_radioButton) - self.vector_name_combo_2 = QtWidgets.QComboBox(self.tab) + sizePolicy.setHeightForWidth(self.classification_name_combo.sizePolicy().hasHeightForWidth()) + self.classification_name_combo.setSizePolicy(sizePolicy) + self.classification_name_combo.setObjectName("classification_name_combo") + self.gridLayout_33.addWidget(self.classification_name_combo, 1, 1, 1, 3) + self.buttonReload_shape_4 = QtWidgets.QToolButton(self.page_10) + self.buttonReload_shape_4.setStyleSheet("margin: 0px;padding: 0px;") + self.buttonReload_shape_4.setIcon(icon60) + self.buttonReload_shape_4.setIconSize(QtCore.QSize(22, 22)) + self.buttonReload_shape_4.setObjectName("buttonReload_shape_4") + self.gridLayout_33.addWidget(self.buttonReload_shape_4, 2, 4, 1, 1) + self.toolButton_reload_4 = QtWidgets.QToolButton(self.page_10) + self.toolButton_reload_4.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_4.setIcon(icon60) + self.toolButton_reload_4.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_4.setObjectName("toolButton_reload_4") + self.gridLayout_33.addWidget(self.toolButton_reload_4, 1, 4, 1, 1) + self.reference_name_combo = QtWidgets.QComboBox(self.page_10) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.vector_name_combo_2.sizePolicy().hasHeightForWidth()) - self.vector_name_combo_2.setSizePolicy(sizePolicy) - self.vector_name_combo_2.setObjectName("vector_name_combo_2") - self.horizontalLayout_21.addWidget(self.vector_name_combo_2) - self.toolButton_reload_20 = QtWidgets.QToolButton(self.tab) - self.toolButton_reload_20.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_20.setIcon(icon55) - self.toolButton_reload_20.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_20.setObjectName("toolButton_reload_20") - self.horizontalLayout_21.addWidget(self.toolButton_reload_20) - self.gridLayout_196.addLayout(self.horizontalLayout_21, 3, 0, 1, 4) - self.horizontalLayout_23 = QtWidgets.QHBoxLayout() - self.horizontalLayout_23.setObjectName("horizontalLayout_23") - self.edit_val_use_ROI_radioButton = QtWidgets.QRadioButton(self.tab) - self.edit_val_use_ROI_radioButton.setChecked(True) - self.edit_val_use_ROI_radioButton.setObjectName("edit_val_use_ROI_radioButton") - self.horizontalLayout_23.addWidget(self.edit_val_use_ROI_radioButton) - self.gridLayout_196.addLayout(self.horizontalLayout_23, 2, 0, 1, 4) - self.horizontalLayout_26 = QtWidgets.QHBoxLayout() - self.horizontalLayout_26.setObjectName("horizontalLayout_26") - self.label_158 = QtWidgets.QLabel(self.tab) - self.label_158.setStyleSheet("background-color : #656565; color : white") - self.label_158.setFrameShape(QtWidgets.QFrame.Panel) - self.label_158.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_158.setObjectName("label_158") - self.horizontalLayout_26.addWidget(self.label_158) - self.gridLayout_196.addLayout(self.horizontalLayout_26, 4, 0, 1, 4) - self.raster_set_value_toolButton = QtWidgets.QToolButton(self.tab) + sizePolicy.setHeightForWidth(self.reference_name_combo.sizePolicy().hasHeightForWidth()) + self.reference_name_combo.setSizePolicy(sizePolicy) + self.reference_name_combo.setObjectName("reference_name_combo") + self.gridLayout_33.addWidget(self.reference_name_combo, 2, 1, 1, 3) + self.horizontalLayout_36 = QtWidgets.QHBoxLayout() + self.horizontalLayout_36.setObjectName("horizontalLayout_36") + self.label_145 = QtWidgets.QLabel(self.page_10) + self.label_145.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_145.setFrameShape(QtWidgets.QFrame.Panel) + self.label_145.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_145.setObjectName("label_145") + self.horizontalLayout_36.addWidget(self.label_145) + self.gridLayout_33.addLayout(self.horizontalLayout_36, 0, 0, 1, 5) + self.label_82 = QtWidgets.QLabel(self.page_10) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_82.sizePolicy().hasHeightForWidth()) + self.label_82.setSizePolicy(sizePolicy) + self.label_82.setMinimumSize(QtCore.QSize(6, 0)) + self.label_82.setMaximumSize(QtCore.QSize(100, 200)) + self.label_82.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_82.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_82.setObjectName("label_82") + self.gridLayout_33.addWidget(self.label_82, 3, 1, 1, 1) + self.class_field_comboBox = QtWidgets.QComboBox(self.page_10) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.class_field_comboBox.sizePolicy().hasHeightForWidth()) + self.class_field_comboBox.setSizePolicy(sizePolicy) + self.class_field_comboBox.setObjectName("class_field_comboBox") + self.gridLayout_33.addWidget(self.class_field_comboBox, 3, 2, 1, 2) + self.horizontalLayout_67 = QtWidgets.QHBoxLayout() + self.horizontalLayout_67.setObjectName("horizontalLayout_67") + self.nodata_checkBox_11 = QtWidgets.QCheckBox(self.page_10) + self.nodata_checkBox_11.setObjectName("nodata_checkBox_11") + self.horizontalLayout_67.addWidget(self.nodata_checkBox_11) + self.nodata_spinBox_15 = QtWidgets.QSpinBox(self.page_10) + self.nodata_spinBox_15.setMinimum(-2147483647) + self.nodata_spinBox_15.setMaximum(2147483647) + self.nodata_spinBox_15.setProperty("value", 0) + self.nodata_spinBox_15.setObjectName("nodata_spinBox_15") + self.horizontalLayout_67.addWidget(self.nodata_spinBox_15) + spacerItem96 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_67.addItem(spacerItem96) + self.gridLayout_33.addLayout(self.horizontalLayout_67, 4, 0, 1, 5) + self.gridLayout_36.addLayout(self.gridLayout_33, 0, 0, 1, 1) + self.gridLayout_25 = QtWidgets.QGridLayout() + self.gridLayout_25.setObjectName("gridLayout_25") + spacerItem97 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_25.addItem(spacerItem97, 0, 2, 1, 1) + spacerItem98 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_25.addItem(spacerItem98, 2, 0, 1, 1) + self.label_168 = QtWidgets.QLabel(self.page_10) + self.label_168.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_168.setFrameShape(QtWidgets.QFrame.Panel) + self.label_168.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_168.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_168.setObjectName("label_168") + self.gridLayout_25.addWidget(self.label_168, 1, 0, 1, 3) + self.calculateMatrix_toolButton = QtWidgets.QToolButton(self.page_10) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.raster_set_value_toolButton.setFont(font) - self.raster_set_value_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.raster_set_value_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.raster_set_value_toolButton.setIcon(icon64) - self.raster_set_value_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.raster_set_value_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.raster_set_value_toolButton.setObjectName("raster_set_value_toolButton") - self.gridLayout_196.addWidget(self.raster_set_value_toolButton, 10, 3, 1, 1) - self.edit_raster_using_vector = QtWidgets.QToolButton(self.tab) + self.calculateMatrix_toolButton.setFont(font) + self.calculateMatrix_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.calculateMatrix_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.calculateMatrix_toolButton.setIcon(icon44) + self.calculateMatrix_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.calculateMatrix_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.calculateMatrix_toolButton.setObjectName("calculateMatrix_toolButton") + self.gridLayout_25.addWidget(self.calculateMatrix_toolButton, 2, 2, 1, 1) + self.accuracy = QtWidgets.QToolButton(self.page_10) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.edit_raster_using_vector.setFont(font) - self.edit_raster_using_vector.setLayoutDirection(QtCore.Qt.RightToLeft) - self.edit_raster_using_vector.setStyleSheet("margin: 0px;padding: 0px;") - self.edit_raster_using_vector.setIcon(icon48) - self.edit_raster_using_vector.setIconSize(QtCore.QSize(34, 34)) - self.edit_raster_using_vector.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.edit_raster_using_vector.setObjectName("edit_raster_using_vector") - self.gridLayout_196.addWidget(self.edit_raster_using_vector, 10, 2, 1, 1) - self.gridLayout_359.addLayout(self.gridLayout_196, 1, 0, 1, 1) - self.tabWidget_2.addTab(self.tab, "") - self.tab_sieve = QtWidgets.QWidget() - self.tab_sieve.setObjectName("tab_sieve") - self.gridLayout_202 = QtWidgets.QGridLayout(self.tab_sieve) - self.gridLayout_202.setObjectName("gridLayout_202") - self.gridLayout_64 = QtWidgets.QGridLayout() - self.gridLayout_64.setObjectName("gridLayout_64") - spacerItem134 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_64.addItem(spacerItem134, 2, 2, 1, 1) - spacerItem135 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_64.addItem(spacerItem135, 4, 0, 1, 1) - self.horizontalLayout_11 = QtWidgets.QHBoxLayout() - self.horizontalLayout_11.setObjectName("horizontalLayout_11") - self.label_70 = QtWidgets.QLabel(self.tab_sieve) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_70.sizePolicy().hasHeightForWidth()) - self.label_70.setSizePolicy(sizePolicy) - self.label_70.setMinimumSize(QtCore.QSize(229, 0)) - self.label_70.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_70.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_70.setObjectName("label_70") - self.horizontalLayout_11.addWidget(self.label_70) - self.sieve_raster_name_combo = QtWidgets.QComboBox(self.tab_sieve) + self.accuracy.setFont(font) + self.accuracy.setLayoutDirection(QtCore.Qt.RightToLeft) + self.accuracy.setStyleSheet("margin: 0px;padding: 0px;") + self.accuracy.setIcon(icon33) + self.accuracy.setIconSize(QtCore.QSize(34, 34)) + self.accuracy.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.accuracy.setObjectName("accuracy") + self.gridLayout_25.addWidget(self.accuracy, 2, 1, 1, 1) + self.gridLayout_36.addLayout(self.gridLayout_25, 1, 0, 1, 1) + self.toolBox_accuracy.addItem(self.page_10, "") + self.page_11 = QtWidgets.QWidget() + self.page_11.setGeometry(QtCore.QRect(0, 0, 98, 90)) + self.page_11.setObjectName("page_11") + self.gridLayout_35 = QtWidgets.QGridLayout(self.page_11) + self.gridLayout_35.setObjectName("gridLayout_35") + self.gridLayout_34 = QtWidgets.QGridLayout() + self.gridLayout_34.setObjectName("gridLayout_34") + self.error_matrix_textBrowser = QtWidgets.QTextBrowser(self.page_11) + font = QtGui.QFont() + font.setFamily("Courier 10 Pitch") + self.error_matrix_textBrowser.setFont(font) + self.error_matrix_textBrowser.setTabChangesFocus(True) + self.error_matrix_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.error_matrix_textBrowser.setTabStopWidth(120) + self.error_matrix_textBrowser.setOpenLinks(False) + self.error_matrix_textBrowser.setObjectName("error_matrix_textBrowser") + self.gridLayout_34.addWidget(self.error_matrix_textBrowser, 0, 0, 1, 1) + self.gridLayout_35.addLayout(self.gridLayout_34, 0, 0, 1, 1) + self.toolBox_accuracy.addItem(self.page_11, "") + self.gridLayout_184.addWidget(self.toolBox_accuracy, 0, 0, 1, 1) + self.tabWidget_2.addTab(self.tab_accuracy, "") + self.tab_class_report = QtWidgets.QWidget() + self.tab_class_report.setObjectName("tab_class_report") + self.gridLayout_27 = QtWidgets.QGridLayout(self.tab_class_report) + self.gridLayout_27.setObjectName("gridLayout_27") + self.toolBox_class_report = QtWidgets.QToolBox(self.tab_class_report) + self.toolBox_class_report.setStyleSheet("") + self.toolBox_class_report.setObjectName("toolBox_class_report") + self.page_14 = QtWidgets.QWidget() + self.page_14.setGeometry(QtCore.QRect(0, 0, 488, 172)) + self.page_14.setObjectName("page_14") + self.gridLayout_48 = QtWidgets.QGridLayout(self.page_14) + self.gridLayout_48.setObjectName("gridLayout_48") + self.gridLayout_47 = QtWidgets.QGridLayout() + self.gridLayout_47.setObjectName("gridLayout_47") + self.classification_report_name_combo = QtWidgets.QComboBox(self.page_14) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sieve_raster_name_combo.sizePolicy().hasHeightForWidth()) - self.sieve_raster_name_combo.setSizePolicy(sizePolicy) - self.sieve_raster_name_combo.setObjectName("sieve_raster_name_combo") - self.horizontalLayout_11.addWidget(self.sieve_raster_name_combo) - self.toolButton_reload_15 = QtWidgets.QToolButton(self.tab_sieve) - self.toolButton_reload_15.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_15.setIcon(icon55) - self.toolButton_reload_15.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_15.setObjectName("toolButton_reload_15") - self.horizontalLayout_11.addWidget(self.toolButton_reload_15) - self.gridLayout_64.addLayout(self.horizontalLayout_11, 0, 0, 1, 3) - self.horizontalLayout_12 = QtWidgets.QHBoxLayout() - self.horizontalLayout_12.setObjectName("horizontalLayout_12") - self.label_133 = QtWidgets.QLabel(self.tab_sieve) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_133.sizePolicy().hasHeightForWidth()) - self.label_133.setSizePolicy(sizePolicy) - self.label_133.setMinimumSize(QtCore.QSize(229, 0)) - self.label_133.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_133.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_133.setObjectName("label_133") - self.horizontalLayout_12.addWidget(self.label_133) - self.sieve_threshold_spinBox = QtWidgets.QSpinBox(self.tab_sieve) - self.sieve_threshold_spinBox.setMinimum(2) - self.sieve_threshold_spinBox.setMaximum(10000) - self.sieve_threshold_spinBox.setObjectName("sieve_threshold_spinBox") - self.horizontalLayout_12.addWidget(self.sieve_threshold_spinBox) - spacerItem136 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_12.addItem(spacerItem136) - self.label_136 = QtWidgets.QLabel(self.tab_sieve) + sizePolicy.setHeightForWidth(self.classification_report_name_combo.sizePolicy().hasHeightForWidth()) + self.classification_report_name_combo.setSizePolicy(sizePolicy) + self.classification_report_name_combo.setObjectName("classification_report_name_combo") + self.gridLayout_47.addWidget(self.classification_report_name_combo, 1, 1, 1, 1) + self.label_44 = QtWidgets.QLabel(self.page_14) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_136.sizePolicy().hasHeightForWidth()) - self.label_136.setSizePolicy(sizePolicy) - self.label_136.setMinimumSize(QtCore.QSize(229, 0)) - self.label_136.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_136.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_136.setObjectName("label_136") - self.horizontalLayout_12.addWidget(self.label_136) - self.sieve_connection_combo = QtWidgets.QComboBox(self.tab_sieve) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sieve_connection_combo.sizePolicy().hasHeightForWidth()) - self.sieve_connection_combo.setSizePolicy(sizePolicy) - self.sieve_connection_combo.setMaximumSize(QtCore.QSize(80, 16777215)) - self.sieve_connection_combo.setObjectName("sieve_connection_combo") - self.sieve_connection_combo.addItem("") - self.sieve_connection_combo.addItem("") - self.horizontalLayout_12.addWidget(self.sieve_connection_combo) - self.gridLayout_64.addLayout(self.horizontalLayout_12, 1, 0, 1, 3) - self.label_174 = QtWidgets.QLabel(self.tab_sieve) - self.label_174.setStyleSheet("background-color : #656565; color : white") - self.label_174.setFrameShape(QtWidgets.QFrame.Panel) - self.label_174.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_174.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_174.setObjectName("label_174") - self.gridLayout_64.addWidget(self.label_174, 3, 0, 1, 3) - self.sieve_toolButton = QtWidgets.QToolButton(self.tab_sieve) + sizePolicy.setHeightForWidth(self.label_44.sizePolicy().hasHeightForWidth()) + self.label_44.setSizePolicy(sizePolicy) + self.label_44.setMinimumSize(QtCore.QSize(229, 0)) + self.label_44.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_44.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_44.setObjectName("label_44") + self.gridLayout_47.addWidget(self.label_44, 1, 0, 1, 1) + self.gridLayout_26 = QtWidgets.QGridLayout() + self.gridLayout_26.setObjectName("gridLayout_26") + self.nodata_checkBox = QtWidgets.QCheckBox(self.page_14) + self.nodata_checkBox.setObjectName("nodata_checkBox") + self.gridLayout_26.addWidget(self.nodata_checkBox, 0, 0, 1, 1) + self.nodata_spinBox_2 = QtWidgets.QSpinBox(self.page_14) + self.nodata_spinBox_2.setMinimum(-2147483647) + self.nodata_spinBox_2.setMaximum(2147483647) + self.nodata_spinBox_2.setProperty("value", 0) + self.nodata_spinBox_2.setObjectName("nodata_spinBox_2") + self.gridLayout_26.addWidget(self.nodata_spinBox_2, 0, 1, 1, 1) + self.gridLayout_47.addLayout(self.gridLayout_26, 2, 0, 1, 1) + self.toolButton_reload_10 = QtWidgets.QToolButton(self.page_14) + self.toolButton_reload_10.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_10.setIcon(icon60) + self.toolButton_reload_10.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_10.setObjectName("toolButton_reload_10") + self.gridLayout_47.addWidget(self.toolButton_reload_10, 1, 2, 1, 1) + self.gridLayout_48.addLayout(self.gridLayout_47, 1, 1, 1, 1) + self.gridLayout_189 = QtWidgets.QGridLayout() + self.gridLayout_189.setObjectName("gridLayout_189") + spacerItem99 = QtWidgets.QSpacerItem(358, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_189.addItem(spacerItem99, 2, 1, 1, 1) + self.label_170 = QtWidgets.QLabel(self.page_14) + self.label_170.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_170.setFrameShape(QtWidgets.QFrame.Panel) + self.label_170.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_170.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_170.setObjectName("label_170") + self.gridLayout_189.addWidget(self.label_170, 1, 0, 1, 4) + self.calculateReport_toolButton = QtWidgets.QToolButton(self.page_14) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.sieve_toolButton.setFont(font) - self.sieve_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.sieve_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.sieve_toolButton.setIcon(icon64) - self.sieve_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.sieve_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.sieve_toolButton.setObjectName("sieve_toolButton") - self.gridLayout_64.addWidget(self.sieve_toolButton, 4, 2, 1, 1) - self.classification_sieve = QtWidgets.QToolButton(self.tab_sieve) + self.calculateReport_toolButton.setFont(font) + self.calculateReport_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.calculateReport_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.calculateReport_toolButton.setIcon(icon44) + self.calculateReport_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.calculateReport_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.calculateReport_toolButton.setObjectName("calculateReport_toolButton") + self.gridLayout_189.addWidget(self.calculateReport_toolButton, 2, 3, 1, 1) + spacerItem100 = QtWidgets.QSpacerItem(20, 82, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_189.addItem(spacerItem100, 0, 0, 1, 2) + self.classification_report = QtWidgets.QToolButton(self.page_14) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.classification_sieve.setFont(font) - self.classification_sieve.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification_sieve.setStyleSheet("margin: 0px;padding: 0px;") - self.classification_sieve.setIcon(icon48) - self.classification_sieve.setIconSize(QtCore.QSize(34, 34)) - self.classification_sieve.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification_sieve.setObjectName("classification_sieve") - self.gridLayout_64.addWidget(self.classification_sieve, 4, 1, 1, 1) - self.gridLayout_202.addLayout(self.gridLayout_64, 1, 0, 1, 1) - self.horizontalLayout_43 = QtWidgets.QHBoxLayout() - self.horizontalLayout_43.setObjectName("horizontalLayout_43") - self.label_195 = QtWidgets.QLabel(self.tab_sieve) - self.label_195.setStyleSheet("background-color : #656565; color : white") - self.label_195.setFrameShape(QtWidgets.QFrame.Panel) - self.label_195.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_195.setObjectName("label_195") - self.horizontalLayout_43.addWidget(self.label_195) - self.gridLayout_202.addLayout(self.horizontalLayout_43, 0, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_sieve, "") - self.tab_erosion = QtWidgets.QWidget() - self.tab_erosion.setObjectName("tab_erosion") - self.gridLayout_205 = QtWidgets.QGridLayout(self.tab_erosion) - self.gridLayout_205.setObjectName("gridLayout_205") - self.horizontalLayout_44 = QtWidgets.QHBoxLayout() - self.horizontalLayout_44.setObjectName("horizontalLayout_44") - self.label_202 = QtWidgets.QLabel(self.tab_erosion) - self.label_202.setStyleSheet("background-color : #656565; color : white") - self.label_202.setFrameShape(QtWidgets.QFrame.Panel) - self.label_202.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_202.setObjectName("label_202") - self.horizontalLayout_44.addWidget(self.label_202) - self.gridLayout_205.addLayout(self.horizontalLayout_44, 0, 0, 1, 1) - self.gridLayout_204 = QtWidgets.QGridLayout() - self.gridLayout_204.setObjectName("gridLayout_204") - spacerItem137 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_204.addItem(spacerItem137, 3, 2, 1, 1) - spacerItem138 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_204.addItem(spacerItem138, 5, 0, 1, 1) - self.horizontalLayout_13 = QtWidgets.QHBoxLayout() - self.horizontalLayout_13.setObjectName("horizontalLayout_13") - self.label_146 = QtWidgets.QLabel(self.tab_erosion) + self.classification_report.setFont(font) + self.classification_report.setLayoutDirection(QtCore.Qt.RightToLeft) + self.classification_report.setStyleSheet("margin: 0px;padding: 0px;") + self.classification_report.setIcon(icon33) + self.classification_report.setIconSize(QtCore.QSize(34, 34)) + self.classification_report.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.classification_report.setObjectName("classification_report") + self.gridLayout_189.addWidget(self.classification_report, 2, 2, 1, 1) + self.gridLayout_48.addLayout(self.gridLayout_189, 2, 1, 1, 1) + self.horizontalLayout_37 = QtWidgets.QHBoxLayout() + self.horizontalLayout_37.setObjectName("horizontalLayout_37") + self.label_148 = QtWidgets.QLabel(self.page_14) + self.label_148.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_148.setFrameShape(QtWidgets.QFrame.Panel) + self.label_148.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_148.setObjectName("label_148") + self.horizontalLayout_37.addWidget(self.label_148) + self.gridLayout_48.addLayout(self.horizontalLayout_37, 0, 1, 1, 1) + self.toolBox_class_report.addItem(self.page_14, "") + self.page_15 = QtWidgets.QWidget() + self.page_15.setGeometry(QtCore.QRect(0, 0, 98, 90)) + self.page_15.setObjectName("page_15") + self.gridLayout_188 = QtWidgets.QGridLayout(self.page_15) + self.gridLayout_188.setObjectName("gridLayout_188") + self.gridLayout_43 = QtWidgets.QGridLayout() + self.gridLayout_43.setObjectName("gridLayout_43") + self.report_textBrowser = QtWidgets.QTextBrowser(self.page_15) + font = QtGui.QFont() + font.setFamily("Courier 10 Pitch") + self.report_textBrowser.setFont(font) + self.report_textBrowser.setTabChangesFocus(True) + self.report_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.report_textBrowser.setTabStopWidth(160) + self.report_textBrowser.setOpenLinks(False) + self.report_textBrowser.setObjectName("report_textBrowser") + self.gridLayout_43.addWidget(self.report_textBrowser, 0, 0, 1, 1) + self.gridLayout_188.addLayout(self.gridLayout_43, 0, 0, 1, 1) + self.toolBox_class_report.addItem(self.page_15, "") + self.gridLayout_27.addWidget(self.toolBox_class_report, 0, 0, 1, 1) + self.tabWidget_2.addTab(self.tab_class_report, "") + self.tab_cross_classification = QtWidgets.QWidget() + self.tab_cross_classification.setObjectName("tab_cross_classification") + self.gridLayout_254 = QtWidgets.QGridLayout(self.tab_cross_classification) + self.gridLayout_254.setObjectName("gridLayout_254") + self.toolBox_cross_classification = QtWidgets.QToolBox(self.tab_cross_classification) + self.toolBox_cross_classification.setObjectName("toolBox_cross_classification") + self.page_19 = QtWidgets.QWidget() + self.page_19.setGeometry(QtCore.QRect(0, 0, 500, 266)) + self.page_19.setObjectName("page_19") + self.gridLayout_192 = QtWidgets.QGridLayout(self.page_19) + self.gridLayout_192.setObjectName("gridLayout_192") + self.horizontalLayout_38 = QtWidgets.QHBoxLayout() + self.horizontalLayout_38.setObjectName("horizontalLayout_38") + self.label_187 = QtWidgets.QLabel(self.page_19) + self.label_187.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_187.setFrameShape(QtWidgets.QFrame.Panel) + self.label_187.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_187.setObjectName("label_187") + self.horizontalLayout_38.addWidget(self.label_187) + self.gridLayout_192.addLayout(self.horizontalLayout_38, 0, 0, 1, 1) + self.gridLayout_250 = QtWidgets.QGridLayout() + self.gridLayout_250.setObjectName("gridLayout_250") + self.gridLayout_248 = QtWidgets.QGridLayout() + self.gridLayout_248.setObjectName("gridLayout_248") + self.nodata_checkBox_6 = QtWidgets.QCheckBox(self.page_19) + self.nodata_checkBox_6.setObjectName("nodata_checkBox_6") + self.gridLayout_248.addWidget(self.nodata_checkBox_6, 0, 0, 1, 1) + self.nodata_spinBox_7 = QtWidgets.QSpinBox(self.page_19) + self.nodata_spinBox_7.setMinimum(-2147483647) + self.nodata_spinBox_7.setMaximum(2147483647) + self.nodata_spinBox_7.setObjectName("nodata_spinBox_7") + self.gridLayout_248.addWidget(self.nodata_spinBox_7, 0, 1, 1, 1) + self.gridLayout_250.addLayout(self.gridLayout_248, 2, 0, 1, 1) + self.label_197 = QtWidgets.QLabel(self.page_19) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_146.sizePolicy().hasHeightForWidth()) - self.label_146.setSizePolicy(sizePolicy) - self.label_146.setMinimumSize(QtCore.QSize(229, 0)) - self.label_146.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_146.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_146.setObjectName("label_146") - self.horizontalLayout_13.addWidget(self.label_146) - self.erosion_raster_name_combo = QtWidgets.QComboBox(self.tab_erosion) + sizePolicy.setHeightForWidth(self.label_197.sizePolicy().hasHeightForWidth()) + self.label_197.setSizePolicy(sizePolicy) + self.label_197.setMinimumSize(QtCore.QSize(229, 0)) + self.label_197.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_197.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_197.setObjectName("label_197") + self.gridLayout_250.addWidget(self.label_197, 1, 0, 1, 1) + self.label_199 = QtWidgets.QLabel(self.page_19) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_199.sizePolicy().hasHeightForWidth()) + self.label_199.setSizePolicy(sizePolicy) + self.label_199.setMinimumSize(QtCore.QSize(6, 0)) + self.label_199.setMaximumSize(QtCore.QSize(100, 200)) + self.label_199.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_199.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_199.setObjectName("label_199") + self.gridLayout_250.addWidget(self.label_199, 4, 1, 1, 1) + self.class_field_comboBox_2 = QtWidgets.QComboBox(self.page_19) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.class_field_comboBox_2.sizePolicy().hasHeightForWidth()) + self.class_field_comboBox_2.setSizePolicy(sizePolicy) + self.class_field_comboBox_2.setObjectName("class_field_comboBox_2") + self.gridLayout_250.addWidget(self.class_field_comboBox_2, 4, 2, 1, 2) + self.toolButton_reload_21 = QtWidgets.QToolButton(self.page_19) + self.toolButton_reload_21.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_21.setIcon(icon60) + self.toolButton_reload_21.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_21.setObjectName("toolButton_reload_21") + self.gridLayout_250.addWidget(self.toolButton_reload_21, 1, 4, 1, 1) + self.classification_name_combo_2 = QtWidgets.QComboBox(self.page_19) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.erosion_raster_name_combo.sizePolicy().hasHeightForWidth()) - self.erosion_raster_name_combo.setSizePolicy(sizePolicy) - self.erosion_raster_name_combo.setObjectName("erosion_raster_name_combo") - self.horizontalLayout_13.addWidget(self.erosion_raster_name_combo) - self.toolButton_reload_18 = QtWidgets.QToolButton(self.tab_erosion) - self.toolButton_reload_18.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_18.setIcon(icon55) - self.toolButton_reload_18.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_18.setObjectName("toolButton_reload_18") - self.horizontalLayout_13.addWidget(self.toolButton_reload_18) - self.gridLayout_204.addLayout(self.horizontalLayout_13, 0, 0, 1, 3) - self.horizontalLayout_14 = QtWidgets.QHBoxLayout() - self.horizontalLayout_14.setObjectName("horizontalLayout_14") - self.label_149 = QtWidgets.QLabel(self.tab_erosion) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) + sizePolicy.setHeightForWidth(self.classification_name_combo_2.sizePolicy().hasHeightForWidth()) + self.classification_name_combo_2.setSizePolicy(sizePolicy) + self.classification_name_combo_2.setObjectName("classification_name_combo_2") + self.gridLayout_250.addWidget(self.classification_name_combo_2, 1, 1, 1, 3) + self.buttonReload_shape_5 = QtWidgets.QToolButton(self.page_19) + self.buttonReload_shape_5.setStyleSheet("margin: 0px;padding: 0px;") + self.buttonReload_shape_5.setIcon(icon60) + self.buttonReload_shape_5.setIconSize(QtCore.QSize(22, 22)) + self.buttonReload_shape_5.setObjectName("buttonReload_shape_5") + self.gridLayout_250.addWidget(self.buttonReload_shape_5, 3, 4, 1, 1) + self.reference_name_combo_2 = QtWidgets.QComboBox(self.page_19) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_149.sizePolicy().hasHeightForWidth()) - self.label_149.setSizePolicy(sizePolicy) - self.label_149.setMinimumSize(QtCore.QSize(229, 0)) - self.label_149.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_149.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_149.setObjectName("label_149") - self.horizontalLayout_14.addWidget(self.label_149) - self.erosion_threshold_spinBox = QtWidgets.QSpinBox(self.tab_erosion) - self.erosion_threshold_spinBox.setMinimum(1) - self.erosion_threshold_spinBox.setMaximum(1000) - self.erosion_threshold_spinBox.setProperty("value", 1) - self.erosion_threshold_spinBox.setObjectName("erosion_threshold_spinBox") - self.horizontalLayout_14.addWidget(self.erosion_threshold_spinBox) - self.circular_structure_checkBox_3 = QtWidgets.QCheckBox(self.tab_erosion) - self.circular_structure_checkBox_3.setObjectName("circular_structure_checkBox_3") - self.horizontalLayout_14.addWidget(self.circular_structure_checkBox_3) - spacerItem139 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_14.addItem(spacerItem139) - self.gridLayout_204.addLayout(self.horizontalLayout_14, 2, 0, 1, 3) - self.horizontalLayout_15 = QtWidgets.QHBoxLayout() - self.horizontalLayout_15.setObjectName("horizontalLayout_15") - self.label_151 = QtWidgets.QLabel(self.tab_erosion) + sizePolicy.setHeightForWidth(self.reference_name_combo_2.sizePolicy().hasHeightForWidth()) + self.reference_name_combo_2.setSizePolicy(sizePolicy) + self.reference_name_combo_2.setObjectName("reference_name_combo_2") + self.gridLayout_250.addWidget(self.reference_name_combo_2, 3, 1, 1, 3) + self.label_198 = QtWidgets.QLabel(self.page_19) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_151.sizePolicy().hasHeightForWidth()) - self.label_151.setSizePolicy(sizePolicy) - self.label_151.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_151.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_151.setObjectName("label_151") - self.horizontalLayout_15.addWidget(self.label_151) - self.erosion_classes_lineEdit = QtWidgets.QLineEdit(self.tab_erosion) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.erosion_classes_lineEdit.sizePolicy().hasHeightForWidth()) - self.erosion_classes_lineEdit.setSizePolicy(sizePolicy) - self.erosion_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) - self.erosion_classes_lineEdit.setText("") - self.erosion_classes_lineEdit.setMaxLength(10000) - self.erosion_classes_lineEdit.setObjectName("erosion_classes_lineEdit") - self.horizontalLayout_15.addWidget(self.erosion_classes_lineEdit) - self.gridLayout_204.addLayout(self.horizontalLayout_15, 1, 0, 1, 3) - self.label_175 = QtWidgets.QLabel(self.tab_erosion) - self.label_175.setStyleSheet("background-color : #656565; color : white") - self.label_175.setFrameShape(QtWidgets.QFrame.Panel) - self.label_175.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_175.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_175.setObjectName("label_175") - self.gridLayout_204.addWidget(self.label_175, 4, 0, 1, 3) - self.class_erosion_toolButton = QtWidgets.QToolButton(self.tab_erosion) + sizePolicy.setHeightForWidth(self.label_198.sizePolicy().hasHeightForWidth()) + self.label_198.setSizePolicy(sizePolicy) + self.label_198.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_198.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_198.setObjectName("label_198") + self.gridLayout_250.addWidget(self.label_198, 3, 0, 1, 1) + self.regression_raster_checkBox = QtWidgets.QCheckBox(self.page_19) + self.regression_raster_checkBox.setObjectName("regression_raster_checkBox") + self.gridLayout_250.addWidget(self.regression_raster_checkBox, 5, 0, 1, 1) + self.gridLayout_192.addLayout(self.gridLayout_250, 1, 0, 1, 1) + self.gridLayout_251 = QtWidgets.QGridLayout() + self.gridLayout_251.setObjectName("gridLayout_251") + spacerItem101 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_251.addItem(spacerItem101, 0, 2, 1, 1) + spacerItem102 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_251.addItem(spacerItem102, 2, 0, 1, 1) + self.label_200 = QtWidgets.QLabel(self.page_19) + self.label_200.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_200.setFrameShape(QtWidgets.QFrame.Panel) + self.label_200.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_200.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_200.setObjectName("label_200") + self.gridLayout_251.addWidget(self.label_200, 1, 0, 1, 3) + self.calculatecrossClass_toolButton = QtWidgets.QToolButton(self.page_19) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.class_erosion_toolButton.setFont(font) - self.class_erosion_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.class_erosion_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.class_erosion_toolButton.setIcon(icon64) - self.class_erosion_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.class_erosion_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.class_erosion_toolButton.setObjectName("class_erosion_toolButton") - self.gridLayout_204.addWidget(self.class_erosion_toolButton, 5, 2, 1, 1) - self.classification_erosion = QtWidgets.QToolButton(self.tab_erosion) + self.calculatecrossClass_toolButton.setFont(font) + self.calculatecrossClass_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.calculatecrossClass_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.calculatecrossClass_toolButton.setIcon(icon44) + self.calculatecrossClass_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.calculatecrossClass_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.calculatecrossClass_toolButton.setObjectName("calculatecrossClass_toolButton") + self.gridLayout_251.addWidget(self.calculatecrossClass_toolButton, 2, 2, 1, 1) + self.cross_classification = QtWidgets.QToolButton(self.page_19) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.classification_erosion.setFont(font) - self.classification_erosion.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification_erosion.setStyleSheet("margin: 0px;padding: 0px;") - self.classification_erosion.setIcon(icon48) - self.classification_erosion.setIconSize(QtCore.QSize(34, 34)) - self.classification_erosion.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification_erosion.setObjectName("classification_erosion") - self.gridLayout_204.addWidget(self.classification_erosion, 5, 1, 1, 1) - self.gridLayout_205.addLayout(self.gridLayout_204, 1, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_erosion, "") - self.tab_dilation = QtWidgets.QWidget() - self.tab_dilation.setObjectName("tab_dilation") - self.gridLayout_207 = QtWidgets.QGridLayout(self.tab_dilation) - self.gridLayout_207.setObjectName("gridLayout_207") - self.horizontalLayout_45 = QtWidgets.QHBoxLayout() - self.horizontalLayout_45.setObjectName("horizontalLayout_45") - self.label_204 = QtWidgets.QLabel(self.tab_dilation) - self.label_204.setStyleSheet("background-color : #656565; color : white") - self.label_204.setFrameShape(QtWidgets.QFrame.Panel) - self.label_204.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_204.setObjectName("label_204") - self.horizontalLayout_45.addWidget(self.label_204) - self.gridLayout_207.addLayout(self.horizontalLayout_45, 0, 0, 1, 1) - self.gridLayout_206 = QtWidgets.QGridLayout() - self.gridLayout_206.setObjectName("gridLayout_206") - spacerItem140 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_206.addItem(spacerItem140, 3, 2, 1, 1) - spacerItem141 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_206.addItem(spacerItem141, 5, 0, 1, 1) - self.horizontalLayout_16 = QtWidgets.QHBoxLayout() - self.horizontalLayout_16.setObjectName("horizontalLayout_16") - self.label_152 = QtWidgets.QLabel(self.tab_dilation) + self.cross_classification.setFont(font) + self.cross_classification.setLayoutDirection(QtCore.Qt.RightToLeft) + self.cross_classification.setStyleSheet("margin: 0px;padding: 0px;") + self.cross_classification.setIcon(icon33) + self.cross_classification.setIconSize(QtCore.QSize(34, 34)) + self.cross_classification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.cross_classification.setObjectName("cross_classification") + self.gridLayout_251.addWidget(self.cross_classification, 2, 1, 1, 1) + self.gridLayout_192.addLayout(self.gridLayout_251, 2, 0, 1, 1) + self.toolBox_cross_classification.addItem(self.page_19, "") + self.page_22 = QtWidgets.QWidget() + self.page_22.setGeometry(QtCore.QRect(0, 0, 98, 90)) + self.page_22.setObjectName("page_22") + self.gridLayout_252 = QtWidgets.QGridLayout(self.page_22) + self.gridLayout_252.setObjectName("gridLayout_252") + self.gridLayout_253 = QtWidgets.QGridLayout() + self.gridLayout_253.setObjectName("gridLayout_253") + self.cross_matrix_textBrowser = QtWidgets.QTextBrowser(self.page_22) + font = QtGui.QFont() + font.setFamily("Courier 10 Pitch") + self.cross_matrix_textBrowser.setFont(font) + self.cross_matrix_textBrowser.setTabChangesFocus(True) + self.cross_matrix_textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.cross_matrix_textBrowser.setTabStopWidth(120) + self.cross_matrix_textBrowser.setOpenLinks(False) + self.cross_matrix_textBrowser.setObjectName("cross_matrix_textBrowser") + self.gridLayout_253.addWidget(self.cross_matrix_textBrowser, 0, 0, 1, 1) + self.gridLayout_252.addLayout(self.gridLayout_253, 0, 0, 1, 1) + self.toolBox_cross_classification.addItem(self.page_22, "") + self.gridLayout_254.addWidget(self.toolBox_cross_classification, 0, 0, 1, 1) + self.tabWidget_2.addTab(self.tab_cross_classification, "") + self.tab_class_to_vector = QtWidgets.QWidget() + self.tab_class_to_vector.setObjectName("tab_class_to_vector") + self.gridLayout_49 = QtWidgets.QGridLayout(self.tab_class_to_vector) + self.gridLayout_49.setObjectName("gridLayout_49") + self.horizontalLayout_40 = QtWidgets.QHBoxLayout() + self.horizontalLayout_40.setObjectName("horizontalLayout_40") + self.label_189 = QtWidgets.QLabel(self.tab_class_to_vector) + self.label_189.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_189.setFrameShape(QtWidgets.QFrame.Panel) + self.label_189.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_189.setObjectName("label_189") + self.horizontalLayout_40.addWidget(self.label_189) + self.gridLayout_49.addLayout(self.horizontalLayout_40, 0, 0, 1, 1) + self.gridLayout_71 = QtWidgets.QGridLayout() + self.gridLayout_71.setObjectName("gridLayout_71") + self.label_63 = QtWidgets.QLabel(self.tab_class_to_vector) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_152.sizePolicy().hasHeightForWidth()) - self.label_152.setSizePolicy(sizePolicy) - self.label_152.setMinimumSize(QtCore.QSize(229, 0)) - self.label_152.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_152.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_152.setObjectName("label_152") - self.horizontalLayout_16.addWidget(self.label_152) - self.dilation_raster_name_combo = QtWidgets.QComboBox(self.tab_dilation) + sizePolicy.setHeightForWidth(self.label_63.sizePolicy().hasHeightForWidth()) + self.label_63.setSizePolicy(sizePolicy) + self.label_63.setMinimumSize(QtCore.QSize(229, 0)) + self.label_63.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_63.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_63.setObjectName("label_63") + self.gridLayout_71.addWidget(self.label_63, 0, 0, 1, 1) + self.classification_vector_name_combo = QtWidgets.QComboBox(self.tab_class_to_vector) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.dilation_raster_name_combo.sizePolicy().hasHeightForWidth()) - self.dilation_raster_name_combo.setSizePolicy(sizePolicy) - self.dilation_raster_name_combo.setObjectName("dilation_raster_name_combo") - self.horizontalLayout_16.addWidget(self.dilation_raster_name_combo) - self.toolButton_reload_19 = QtWidgets.QToolButton(self.tab_dilation) - self.toolButton_reload_19.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_19.setIcon(icon55) - self.toolButton_reload_19.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_19.setObjectName("toolButton_reload_19") - self.horizontalLayout_16.addWidget(self.toolButton_reload_19) - self.gridLayout_206.addLayout(self.horizontalLayout_16, 0, 0, 1, 3) - self.horizontalLayout_17 = QtWidgets.QHBoxLayout() - self.horizontalLayout_17.setObjectName("horizontalLayout_17") - self.label_153 = QtWidgets.QLabel(self.tab_dilation) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_153.sizePolicy().hasHeightForWidth()) - self.label_153.setSizePolicy(sizePolicy) - self.label_153.setMinimumSize(QtCore.QSize(229, 0)) - self.label_153.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_153.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_153.setObjectName("label_153") - self.horizontalLayout_17.addWidget(self.label_153) - self.dilation_threshold_spinBox = QtWidgets.QSpinBox(self.tab_dilation) - self.dilation_threshold_spinBox.setMinimum(1) - self.dilation_threshold_spinBox.setMaximum(1000) - self.dilation_threshold_spinBox.setProperty("value", 1) - self.dilation_threshold_spinBox.setObjectName("dilation_threshold_spinBox") - self.horizontalLayout_17.addWidget(self.dilation_threshold_spinBox) - self.circular_structure_checkBox_2 = QtWidgets.QCheckBox(self.tab_dilation) - self.circular_structure_checkBox_2.setObjectName("circular_structure_checkBox_2") - self.horizontalLayout_17.addWidget(self.circular_structure_checkBox_2) - spacerItem142 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_17.addItem(spacerItem142) - self.gridLayout_206.addLayout(self.horizontalLayout_17, 2, 0, 1, 3) - self.horizontalLayout_18 = QtWidgets.QHBoxLayout() - self.horizontalLayout_18.setObjectName("horizontalLayout_18") - self.label_155 = QtWidgets.QLabel(self.tab_dilation) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) + sizePolicy.setHeightForWidth(self.classification_vector_name_combo.sizePolicy().hasHeightForWidth()) + self.classification_vector_name_combo.setSizePolicy(sizePolicy) + self.classification_vector_name_combo.setObjectName("classification_vector_name_combo") + self.gridLayout_71.addWidget(self.classification_vector_name_combo, 0, 1, 1, 1) + self.toolButton_reload_11 = QtWidgets.QToolButton(self.tab_class_to_vector) + self.toolButton_reload_11.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_11.setIcon(icon60) + self.toolButton_reload_11.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_11.setObjectName("toolButton_reload_11") + self.gridLayout_71.addWidget(self.toolButton_reload_11, 0, 2, 1, 1) + self.gridLayout_49.addLayout(self.gridLayout_71, 1, 0, 1, 1) + self.gridLayout_74 = QtWidgets.QGridLayout() + self.gridLayout_74.setObjectName("gridLayout_74") + self.class_macroclass_comboBox = QtWidgets.QComboBox(self.tab_class_to_vector) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_155.sizePolicy().hasHeightForWidth()) - self.label_155.setSizePolicy(sizePolicy) - self.label_155.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_155.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_155.setObjectName("label_155") - self.horizontalLayout_18.addWidget(self.label_155) - self.dilation_classes_lineEdit = QtWidgets.QLineEdit(self.tab_dilation) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.class_macroclass_comboBox.sizePolicy().hasHeightForWidth()) + self.class_macroclass_comboBox.setSizePolicy(sizePolicy) + self.class_macroclass_comboBox.setObjectName("class_macroclass_comboBox") + self.class_macroclass_comboBox.addItem("") + self.class_macroclass_comboBox.addItem("") + self.gridLayout_74.addWidget(self.class_macroclass_comboBox, 1, 1, 1, 1) + self.use_class_code_checkBox = QtWidgets.QCheckBox(self.tab_class_to_vector) + self.use_class_code_checkBox.setObjectName("use_class_code_checkBox") + self.gridLayout_74.addWidget(self.use_class_code_checkBox, 1, 0, 1, 1) + self.label_49 = QtWidgets.QLabel(self.tab_class_to_vector) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.dilation_classes_lineEdit.sizePolicy().hasHeightForWidth()) - self.dilation_classes_lineEdit.setSizePolicy(sizePolicy) - self.dilation_classes_lineEdit.setMinimumSize(QtCore.QSize(400, 26)) - self.dilation_classes_lineEdit.setText("") - self.dilation_classes_lineEdit.setMaxLength(10000) - self.dilation_classes_lineEdit.setObjectName("dilation_classes_lineEdit") - self.horizontalLayout_18.addWidget(self.dilation_classes_lineEdit) - self.gridLayout_206.addLayout(self.horizontalLayout_18, 1, 0, 1, 3) - self.label_176 = QtWidgets.QLabel(self.tab_dilation) - self.label_176.setStyleSheet("background-color : #656565; color : white") - self.label_176.setFrameShape(QtWidgets.QFrame.Panel) - self.label_176.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_176.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_176.setObjectName("label_176") - self.gridLayout_206.addWidget(self.label_176, 4, 0, 1, 3) - self.class_dilation_toolButton = QtWidgets.QToolButton(self.tab_dilation) + sizePolicy.setHeightForWidth(self.label_49.sizePolicy().hasHeightForWidth()) + self.label_49.setSizePolicy(sizePolicy) + self.label_49.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_49.setFrameShape(QtWidgets.QFrame.Panel) + self.label_49.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_49.setObjectName("label_49") + self.gridLayout_74.addWidget(self.label_49, 0, 0, 1, 2) + self.dissolve_output_checkBox = QtWidgets.QCheckBox(self.tab_class_to_vector) + self.dissolve_output_checkBox.setObjectName("dissolve_output_checkBox") + self.gridLayout_74.addWidget(self.dissolve_output_checkBox, 2, 0, 1, 1) + self.gridLayout_49.addLayout(self.gridLayout_74, 2, 0, 1, 1) + self.gridLayout_75 = QtWidgets.QGridLayout() + self.gridLayout_75.setObjectName("gridLayout_75") + spacerItem103 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_75.addItem(spacerItem103, 0, 1, 1, 1) + spacerItem104 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_75.addItem(spacerItem104, 0, 0, 1, 1) + self.convert_toolButton = QtWidgets.QToolButton(self.tab_class_to_vector) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.class_dilation_toolButton.setFont(font) - self.class_dilation_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.class_dilation_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.class_dilation_toolButton.setIcon(icon64) - self.class_dilation_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.class_dilation_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.class_dilation_toolButton.setObjectName("class_dilation_toolButton") - self.gridLayout_206.addWidget(self.class_dilation_toolButton, 5, 2, 1, 1) - self.classification_dilation = QtWidgets.QToolButton(self.tab_dilation) + self.convert_toolButton.setFont(font) + self.convert_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.convert_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.convert_toolButton.setIcon(icon44) + self.convert_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.convert_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.convert_toolButton.setObjectName("convert_toolButton") + self.gridLayout_75.addWidget(self.convert_toolButton, 2, 2, 1, 1) + self.label_171 = QtWidgets.QLabel(self.tab_class_to_vector) + self.label_171.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_171.setFrameShape(QtWidgets.QFrame.Panel) + self.label_171.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_171.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_171.setObjectName("label_171") + self.gridLayout_75.addWidget(self.label_171, 1, 0, 1, 3) + self.classification_to_vector = QtWidgets.QToolButton(self.tab_class_to_vector) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.classification_dilation.setFont(font) - self.classification_dilation.setLayoutDirection(QtCore.Qt.RightToLeft) - self.classification_dilation.setStyleSheet("margin: 0px;padding: 0px;") - self.classification_dilation.setIcon(icon48) - self.classification_dilation.setIconSize(QtCore.QSize(34, 34)) - self.classification_dilation.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.classification_dilation.setObjectName("classification_dilation") - self.gridLayout_206.addWidget(self.classification_dilation, 5, 1, 1, 1) - self.gridLayout_207.addLayout(self.gridLayout_206, 1, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_dilation, "") - self.tab_zonal_stats_rasters = QtWidgets.QWidget() - self.tab_zonal_stats_rasters.setObjectName("tab_zonal_stats_rasters") - self.gridLayout_281 = QtWidgets.QGridLayout(self.tab_zonal_stats_rasters) - self.gridLayout_281.setObjectName("gridLayout_281") - self.gridLayout_87 = QtWidgets.QGridLayout() - self.gridLayout_87.setObjectName("gridLayout_87") - self.horizontalLayout_50 = QtWidgets.QHBoxLayout() - self.horizontalLayout_50.setObjectName("horizontalLayout_50") - self.label_212 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - self.label_212.setStyleSheet("background-color : #656565; color : white") - self.label_212.setFrameShape(QtWidgets.QFrame.Panel) - self.label_212.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_212.setObjectName("label_212") - self.horizontalLayout_50.addWidget(self.label_212) - self.gridLayout_87.addLayout(self.horizontalLayout_50, 0, 0, 1, 1) - self.horizontalLayout_51 = QtWidgets.QHBoxLayout() - self.horizontalLayout_51.setObjectName("horizontalLayout_51") - self.label_77 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) + self.classification_to_vector.setFont(font) + self.classification_to_vector.setLayoutDirection(QtCore.Qt.RightToLeft) + self.classification_to_vector.setStyleSheet("margin: 0px;padding: 0px;") + self.classification_to_vector.setIcon(icon33) + self.classification_to_vector.setIconSize(QtCore.QSize(34, 34)) + self.classification_to_vector.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.classification_to_vector.setObjectName("classification_to_vector") + self.gridLayout_75.addWidget(self.classification_to_vector, 2, 1, 1, 1) + self.gridLayout_49.addLayout(self.gridLayout_75, 3, 0, 1, 1) + self.tabWidget_2.addTab(self.tab_class_to_vector, "") + self.tab_reclassification = QtWidgets.QWidget() + self.tab_reclassification.setObjectName("tab_reclassification") + self.gridLayout_191 = QtWidgets.QGridLayout(self.tab_reclassification) + self.gridLayout_191.setObjectName("gridLayout_191") + self.gridLayout_78 = QtWidgets.QGridLayout() + self.gridLayout_78.setObjectName("gridLayout_78") + self.label_65 = QtWidgets.QLabel(self.tab_reclassification) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_77.sizePolicy().hasHeightForWidth()) - self.label_77.setSizePolicy(sizePolicy) - self.label_77.setMinimumSize(QtCore.QSize(229, 0)) - self.label_77.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_77.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_77.setObjectName("label_77") - self.horizontalLayout_51.addWidget(self.label_77) - self.classification_name_combo_5 = QtWidgets.QComboBox(self.tab_zonal_stats_rasters) + sizePolicy.setHeightForWidth(self.label_65.sizePolicy().hasHeightForWidth()) + self.label_65.setSizePolicy(sizePolicy) + self.label_65.setMinimumSize(QtCore.QSize(229, 0)) + self.label_65.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_65.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_65.setObjectName("label_65") + self.gridLayout_78.addWidget(self.label_65, 1, 0, 1, 1) + self.reclassification_name_combo = QtWidgets.QComboBox(self.tab_reclassification) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.classification_name_combo_5.sizePolicy().hasHeightForWidth()) - self.classification_name_combo_5.setSizePolicy(sizePolicy) - self.classification_name_combo_5.setObjectName("classification_name_combo_5") - self.horizontalLayout_51.addWidget(self.classification_name_combo_5) - self.toolButton_reload_24 = QtWidgets.QToolButton(self.tab_zonal_stats_rasters) - self.toolButton_reload_24.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_reload_24.setIcon(icon55) - self.toolButton_reload_24.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_reload_24.setObjectName("toolButton_reload_24") - self.horizontalLayout_51.addWidget(self.toolButton_reload_24) - self.gridLayout_87.addLayout(self.horizontalLayout_51, 1, 0, 1, 1) - self.horizontalLayout_52 = QtWidgets.QHBoxLayout() - self.horizontalLayout_52.setObjectName("horizontalLayout_52") - self.nodata_checkBox_10 = QtWidgets.QCheckBox(self.tab_zonal_stats_rasters) - self.nodata_checkBox_10.setObjectName("nodata_checkBox_10") - self.horizontalLayout_52.addWidget(self.nodata_checkBox_10) - self.nodata_spinBox_12 = QtWidgets.QSpinBox(self.tab_zonal_stats_rasters) - self.nodata_spinBox_12.setMinimum(-2147483647) - self.nodata_spinBox_12.setMaximum(2147483647) - self.nodata_spinBox_12.setObjectName("nodata_spinBox_12") - self.horizontalLayout_52.addWidget(self.nodata_spinBox_12) - spacerItem143 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_52.addItem(spacerItem143) - self.gridLayout_87.addLayout(self.horizontalLayout_52, 2, 0, 1, 1) - self.gridLayout_281.addLayout(self.gridLayout_87, 0, 0, 1, 1) - self.gridLayout_91 = QtWidgets.QGridLayout() - self.gridLayout_91.setObjectName("gridLayout_91") - self.class_field_comboBox_4 = QtWidgets.QComboBox(self.tab_zonal_stats_rasters) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(1) + sizePolicy.setHeightForWidth(self.reclassification_name_combo.sizePolicy().hasHeightForWidth()) + self.reclassification_name_combo.setSizePolicy(sizePolicy) + self.reclassification_name_combo.setObjectName("reclassification_name_combo") + self.gridLayout_78.addWidget(self.reclassification_name_combo, 1, 1, 1, 1) + self.toolButton_reload_12 = QtWidgets.QToolButton(self.tab_reclassification) + self.toolButton_reload_12.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_reload_12.setIcon(icon60) + self.toolButton_reload_12.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_reload_12.setObjectName("toolButton_reload_12") + self.gridLayout_78.addWidget(self.toolButton_reload_12, 1, 2, 1, 1) + self.horizontalLayout_41 = QtWidgets.QHBoxLayout() + self.horizontalLayout_41.setObjectName("horizontalLayout_41") + self.label_190 = QtWidgets.QLabel(self.tab_reclassification) + self.label_190.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_190.setFrameShape(QtWidgets.QFrame.Panel) + self.label_190.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_190.setObjectName("label_190") + self.horizontalLayout_41.addWidget(self.label_190) + self.gridLayout_78.addLayout(self.horizontalLayout_41, 0, 0, 1, 3) + self.gridLayout_191.addLayout(self.gridLayout_78, 0, 0, 1, 1) + self.gridLayout_79 = QtWidgets.QGridLayout() + self.gridLayout_79.setObjectName("gridLayout_79") + self.calculate_unique_values_toolButton = QtWidgets.QToolButton(self.tab_reclassification) + self.calculate_unique_values_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.calculate_unique_values_toolButton.setIcon(icon57) + self.calculate_unique_values_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.calculate_unique_values_toolButton.setObjectName("calculate_unique_values_toolButton") + self.gridLayout_79.addWidget(self.calculate_unique_values_toolButton, 1, 4, 1, 1) + self.CID_MCID_code_checkBox = QtWidgets.QCheckBox(self.tab_reclassification) + self.CID_MCID_code_checkBox.setObjectName("CID_MCID_code_checkBox") + self.gridLayout_79.addWidget(self.CID_MCID_code_checkBox, 1, 2, 1, 1) + self.label_98 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.class_field_comboBox_4.sizePolicy().hasHeightForWidth()) - self.class_field_comboBox_4.setSizePolicy(sizePolicy) - self.class_field_comboBox_4.setObjectName("class_field_comboBox_4") - self.gridLayout_91.addWidget(self.class_field_comboBox_4, 1, 2, 1, 1) - self.label_214 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_98.sizePolicy().hasHeightForWidth()) + self.label_98.setSizePolicy(sizePolicy) + self.label_98.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_98.setObjectName("label_98") + self.gridLayout_79.addWidget(self.label_98, 1, 3, 1, 1) + self.label_54 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_214.sizePolicy().hasHeightForWidth()) - self.label_214.setSizePolicy(sizePolicy) - self.label_214.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_214.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_214.setObjectName("label_214") - self.gridLayout_91.addWidget(self.label_214, 0, 0, 1, 1) - self.buttonReload_shape_6 = QtWidgets.QToolButton(self.tab_zonal_stats_rasters) - self.buttonReload_shape_6.setStyleSheet("margin: 0px;padding: 0px;") - self.buttonReload_shape_6.setIcon(icon55) - self.buttonReload_shape_6.setIconSize(QtCore.QSize(22, 22)) - self.buttonReload_shape_6.setObjectName("buttonReload_shape_6") - self.gridLayout_91.addWidget(self.buttonReload_shape_6, 0, 3, 1, 1) - self.label_213 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.label_54.sizePolicy().hasHeightForWidth()) + self.label_54.setSizePolicy(sizePolicy) + self.label_54.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_54.setFrameShape(QtWidgets.QFrame.Panel) + self.label_54.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_54.setObjectName("label_54") + self.gridLayout_79.addWidget(self.label_54, 0, 2, 1, 3) + self.incremental_new_values_toolButton = QtWidgets.QToolButton(self.tab_reclassification) + self.incremental_new_values_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.incremental_new_values_toolButton.setIcon(icon57) + self.incremental_new_values_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.incremental_new_values_toolButton.setObjectName("incremental_new_values_toolButton") + self.gridLayout_79.addWidget(self.incremental_new_values_toolButton, 2, 4, 1, 1) + self.label_271 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_213.sizePolicy().hasHeightForWidth()) - self.label_213.setSizePolicy(sizePolicy) - self.label_213.setMinimumSize(QtCore.QSize(6, 0)) - self.label_213.setMaximumSize(QtCore.QSize(100, 200)) - self.label_213.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_213.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_213.setObjectName("label_213") - self.gridLayout_91.addWidget(self.label_213, 1, 1, 1, 1) - self.reference_name_combo_3 = QtWidgets.QComboBox(self.tab_zonal_stats_rasters) + sizePolicy.setHeightForWidth(self.label_271.sizePolicy().hasHeightForWidth()) + self.label_271.setSizePolicy(sizePolicy) + self.label_271.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_271.setObjectName("label_271") + self.gridLayout_79.addWidget(self.label_271, 2, 3, 1, 1) + self.gridLayout_191.addLayout(self.gridLayout_79, 1, 0, 1, 1) + self.gridLayout_77 = QtWidgets.QGridLayout() + self.gridLayout_77.setObjectName("gridLayout_77") + self.reclass_values_tableWidget = QtWidgets.QTableWidget(self.tab_reclassification) + self.reclass_values_tableWidget.setAlternatingRowColors(True) + self.reclass_values_tableWidget.setObjectName("reclass_values_tableWidget") + self.reclass_values_tableWidget.setColumnCount(2) + self.reclass_values_tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.reclass_values_tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.reclass_values_tableWidget.setHorizontalHeaderItem(1, item) + self.reclass_values_tableWidget.horizontalHeader().setStretchLastSection(True) + self.reclass_values_tableWidget.verticalHeader().setDefaultSectionSize(24) + self.gridLayout_77.addWidget(self.reclass_values_tableWidget, 0, 0, 1, 1) + self.gridLayout_81 = QtWidgets.QGridLayout() + self.gridLayout_81.setObjectName("gridLayout_81") + self.add_value_pushButton = QtWidgets.QToolButton(self.tab_reclassification) + self.add_value_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.add_value_pushButton.setIcon(icon49) + self.add_value_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.add_value_pushButton.setObjectName("add_value_pushButton") + self.gridLayout_81.addWidget(self.add_value_pushButton, 1, 0, 1, 1) + self.remove_row_pushButton = QtWidgets.QToolButton(self.tab_reclassification) + self.remove_row_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.remove_row_pushButton.setIcon(icon41) + self.remove_row_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.remove_row_pushButton.setObjectName("remove_row_pushButton") + self.gridLayout_81.addWidget(self.remove_row_pushButton, 2, 0, 1, 1) + spacerItem105 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_81.addItem(spacerItem105, 0, 0, 1, 1) + spacerItem106 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_81.addItem(spacerItem106, 6, 0, 1, 1) + self.import_reclass_toolButton = QtWidgets.QToolButton(self.tab_reclassification) + self.import_reclass_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.import_reclass_toolButton.setIcon(icon46) + self.import_reclass_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.import_reclass_toolButton.setObjectName("import_reclass_toolButton") + self.gridLayout_81.addWidget(self.import_reclass_toolButton, 4, 0, 1, 1) + self.export_reclass_toolButton = QtWidgets.QToolButton(self.tab_reclassification) + self.export_reclass_toolButton.setStyleSheet("margin: 0px;padding: 0px") + self.export_reclass_toolButton.setIcon(icon47) + self.export_reclass_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.export_reclass_toolButton.setObjectName("export_reclass_toolButton") + self.gridLayout_81.addWidget(self.export_reclass_toolButton, 5, 0, 1, 1) + spacerItem107 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_81.addItem(spacerItem107, 3, 0, 1, 1) + self.gridLayout_77.addLayout(self.gridLayout_81, 0, 1, 1, 1) + self.gridLayout_191.addLayout(self.gridLayout_77, 2, 0, 1, 1) + self.gridLayout_80 = QtWidgets.QGridLayout() + self.gridLayout_80.setObjectName("gridLayout_80") + self.gridLayout_82 = QtWidgets.QGridLayout() + self.gridLayout_82.setObjectName("gridLayout_82") + self.apply_symbology_checkBox = QtWidgets.QCheckBox(self.tab_reclassification) + self.apply_symbology_checkBox.setChecked(False) + self.apply_symbology_checkBox.setObjectName("apply_symbology_checkBox") + self.gridLayout_82.addWidget(self.apply_symbology_checkBox, 1, 0, 1, 1) + self.class_macroclass_comboBox_2 = QtWidgets.QComboBox(self.tab_reclassification) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reference_name_combo_3.sizePolicy().hasHeightForWidth()) - self.reference_name_combo_3.setSizePolicy(sizePolicy) - self.reference_name_combo_3.setObjectName("reference_name_combo_3") - self.gridLayout_91.addWidget(self.reference_name_combo_3, 0, 1, 1, 2) - self.gridLayout_281.addLayout(self.gridLayout_91, 1, 0, 1, 1) - self.gridLayout_131 = QtWidgets.QGridLayout() - self.gridLayout_131.setObjectName("gridLayout_131") - self.statistic_lineEdit = QtWidgets.QLineEdit(self.tab_zonal_stats_rasters) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHeightForWidth(self.class_macroclass_comboBox_2.sizePolicy().hasHeightForWidth()) + self.class_macroclass_comboBox_2.setSizePolicy(sizePolicy) + self.class_macroclass_comboBox_2.setObjectName("class_macroclass_comboBox_2") + self.class_macroclass_comboBox_2.addItem("") + self.class_macroclass_comboBox_2.addItem("") + self.gridLayout_82.addWidget(self.class_macroclass_comboBox_2, 1, 1, 1, 1) + self.label_51 = QtWidgets.QLabel(self.tab_reclassification) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.statistic_lineEdit.sizePolicy().hasHeightForWidth()) - self.statistic_lineEdit.setSizePolicy(sizePolicy) - self.statistic_lineEdit.setMaximumSize(QtCore.QSize(200, 16777215)) - self.statistic_lineEdit.setText("") - self.statistic_lineEdit.setMaxLength(10000) - self.statistic_lineEdit.setObjectName("statistic_lineEdit") - self.gridLayout_131.addWidget(self.statistic_lineEdit, 1, 2, 1, 1) - self.statistic_name_combobox = QtWidgets.QComboBox(self.tab_zonal_stats_rasters) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.statistic_name_combobox.sizePolicy().hasHeightForWidth()) - self.statistic_name_combobox.setSizePolicy(sizePolicy) - self.statistic_name_combobox.setMaximumSize(QtCore.QSize(200, 16777215)) - self.statistic_name_combobox.setObjectName("statistic_name_combobox") - self.gridLayout_131.addWidget(self.statistic_name_combobox, 1, 1, 1, 1) - self.label_232 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - self.label_232.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_232.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_232.setObjectName("label_232") - self.gridLayout_131.addWidget(self.label_232, 1, 0, 1, 1) - spacerItem144 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_131.addItem(spacerItem144, 1, 3, 1, 1) - self.label_216 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - self.label_216.setStyleSheet("background-color : #656565; color : white") - self.label_216.setFrameShape(QtWidgets.QFrame.Panel) - self.label_216.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_216.setObjectName("label_216") - self.gridLayout_131.addWidget(self.label_216, 0, 0, 1, 4) - self.gridLayout_281.addLayout(self.gridLayout_131, 2, 0, 1, 1) - self.gridLayout_128 = QtWidgets.QGridLayout() - self.gridLayout_128.setObjectName("gridLayout_128") - self.zonal_stat_raster_toolButton = QtWidgets.QToolButton(self.tab_zonal_stats_rasters) + sizePolicy.setHeightForWidth(self.label_51.sizePolicy().hasHeightForWidth()) + self.label_51.setSizePolicy(sizePolicy) + self.label_51.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_51.setFrameShape(QtWidgets.QFrame.Panel) + self.label_51.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_51.setObjectName("label_51") + self.gridLayout_82.addWidget(self.label_51, 0, 0, 1, 2) + self.gridLayout_80.addLayout(self.gridLayout_82, 0, 0, 1, 1) + self.gridLayout_191.addLayout(self.gridLayout_80, 3, 0, 1, 1) + self.gridLayout_83 = QtWidgets.QGridLayout() + self.gridLayout_83.setObjectName("gridLayout_83") + spacerItem108 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_83.addItem(spacerItem108, 1, 0, 1, 1) + self.label_172 = QtWidgets.QLabel(self.tab_reclassification) + self.label_172.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_172.setFrameShape(QtWidgets.QFrame.Panel) + self.label_172.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_172.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_172.setObjectName("label_172") + self.gridLayout_83.addWidget(self.label_172, 0, 0, 1, 3) + self.reclassify_toolButton = QtWidgets.QToolButton(self.tab_reclassification) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.zonal_stat_raster_toolButton.setFont(font) - self.zonal_stat_raster_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) - self.zonal_stat_raster_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.zonal_stat_raster_toolButton.setIcon(icon64) - self.zonal_stat_raster_toolButton.setIconSize(QtCore.QSize(34, 34)) - self.zonal_stat_raster_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.zonal_stat_raster_toolButton.setObjectName("zonal_stat_raster_toolButton") - self.gridLayout_128.addWidget(self.zonal_stat_raster_toolButton, 2, 2, 1, 1) - self.label_215 = QtWidgets.QLabel(self.tab_zonal_stats_rasters) - self.label_215.setStyleSheet("background-color : #656565; color : white") - self.label_215.setFrameShape(QtWidgets.QFrame.Panel) - self.label_215.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_215.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_215.setObjectName("label_215") - self.gridLayout_128.addWidget(self.label_215, 1, 0, 1, 3) - spacerItem145 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_128.addItem(spacerItem145, 2, 0, 1, 1) - spacerItem146 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_128.addItem(spacerItem146, 0, 0, 1, 1) - self.zonal_stat_raster = QtWidgets.QToolButton(self.tab_zonal_stats_rasters) + self.reclassify_toolButton.setFont(font) + self.reclassify_toolButton.setLayoutDirection(QtCore.Qt.RightToLeft) + self.reclassify_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.reclassify_toolButton.setIcon(icon44) + self.reclassify_toolButton.setIconSize(QtCore.QSize(34, 34)) + self.reclassify_toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.reclassify_toolButton.setObjectName("reclassify_toolButton") + self.gridLayout_83.addWidget(self.reclassify_toolButton, 1, 2, 1, 1) + self.reclassification = QtWidgets.QToolButton(self.tab_reclassification) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.zonal_stat_raster.setFont(font) - self.zonal_stat_raster.setLayoutDirection(QtCore.Qt.RightToLeft) - self.zonal_stat_raster.setStyleSheet("margin: 0px;padding: 0px;") - self.zonal_stat_raster.setIcon(icon48) - self.zonal_stat_raster.setIconSize(QtCore.QSize(34, 34)) - self.zonal_stat_raster.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.zonal_stat_raster.setObjectName("zonal_stat_raster") - self.gridLayout_128.addWidget(self.zonal_stat_raster, 2, 1, 1, 1) - self.gridLayout_281.addLayout(self.gridLayout_128, 3, 0, 1, 1) - self.tabWidget_2.addTab(self.tab_zonal_stats_rasters, "") + self.reclassification.setFont(font) + self.reclassification.setLayoutDirection(QtCore.Qt.RightToLeft) + self.reclassification.setStyleSheet("margin: 0px;padding: 0px;") + self.reclassification.setIcon(icon33) + self.reclassification.setIconSize(QtCore.QSize(34, 34)) + self.reclassification.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.reclassification.setObjectName("reclassification") + self.gridLayout_83.addWidget(self.reclassification, 1, 1, 1, 1) + self.gridLayout_191.addLayout(self.gridLayout_83, 4, 0, 1, 1) + self.tabWidget_2.addTab(self.tab_reclassification, "") self.gridLayout_552.addWidget(self.tabWidget_2, 0, 0, 1, 1) self.SCP_tabs.addTab(self.tab_postProcessing, "") self.tab_band_calc = QtWidgets.QWidget() self.tab_band_calc.setObjectName("tab_band_calc") - self.gridLayout_303 = QtWidgets.QGridLayout(self.tab_band_calc) - self.gridLayout_303.setObjectName("gridLayout_303") + self.gridLayout_38 = QtWidgets.QGridLayout(self.tab_band_calc) + self.gridLayout_38.setContentsMargins(3, 3, 3, 3) + self.gridLayout_38.setObjectName("gridLayout_38") self.splitter_band_calc = QtWidgets.QSplitter(self.tab_band_calc) self.splitter_band_calc.setOrientation(QtCore.Qt.Vertical) self.splitter_band_calc.setChildrenCollapsible(False) @@ -8192,17 +5520,13 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_171.setObjectName("gridLayout_171") self.toolButton_reload_13 = QtWidgets.QToolButton(self.widget_2) self.toolButton_reload_13.setStyleSheet("margin: 0px;padding: 0px") - self.toolButton_reload_13.setIcon(icon55) + self.toolButton_reload_13.setIcon(icon60) self.toolButton_reload_13.setIconSize(QtCore.QSize(22, 22)) self.toolButton_reload_13.setObjectName("toolButton_reload_13") self.gridLayout_171.addWidget(self.toolButton_reload_13, 0, 0, 1, 1) self.gridLayout_86.addLayout(self.gridLayout_171, 1, 1, 2, 1) self.tableWidget_band_calc = QtWidgets.QTableWidget(self.widget_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tableWidget_band_calc.sizePolicy().hasHeightForWidth()) - self.tableWidget_band_calc.setSizePolicy(sizePolicy) + self.tableWidget_band_calc.setMaximumSize(QtCore.QSize(16777215, 300)) self.tableWidget_band_calc.setFrameShape(QtWidgets.QFrame.WinPanel) self.tableWidget_band_calc.setFrameShadow(QtWidgets.QFrame.Sunken) self.tableWidget_band_calc.setAlternatingRowColors(True) @@ -8229,7 +5553,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.bandcalc_filter_lineEdit.setObjectName("bandcalc_filter_lineEdit") self.gridLayout_85.addWidget(self.bandcalc_filter_lineEdit, 0, 1, 1, 1) self.label_71 = QtWidgets.QLabel(self.widget_2) - self.label_71.setStyleSheet("background-color : #656565; color : white") + self.label_71.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_71.setFrameShape(QtWidgets.QFrame.Panel) self.label_71.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_71.setObjectName("label_71") @@ -8242,123 +5566,39 @@ def setupUi(self, SemiAutomaticClassificationPlugin): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widget_3.sizePolicy().hasHeightForWidth()) self.widget_3.setSizePolicy(sizePolicy) - self.widget_3.setMinimumSize(QtCore.QSize(0, 250)) + self.widget_3.setMinimumSize(QtCore.QSize(0, 100)) self.widget_3.setObjectName("widget_3") self.gridLayout_40 = QtWidgets.QGridLayout(self.widget_3) - self.gridLayout_40.setContentsMargins(0, 0, 0, 0) + self.gridLayout_40.setContentsMargins(1, 1, 1, 1) + self.gridLayout_40.setSpacing(2) self.gridLayout_40.setObjectName("gridLayout_40") - self.band_calc_tabWidget = QtWidgets.QTabWidget(self.widget_3) - self.band_calc_tabWidget.setStyleSheet("QTabBar::tab {\n" -"padding: 10px;\n" -"min-height: 18px;\n" -"}") - self.band_calc_tabWidget.setTabPosition(QtWidgets.QTabWidget.North) - self.band_calc_tabWidget.setObjectName("band_calc_tabWidget") - self.tab_expression = QtWidgets.QWidget() - self.tab_expression.setObjectName("tab_expression") - self.gridLayout_2 = QtWidgets.QGridLayout(self.tab_expression) - self.gridLayout_2.setObjectName("gridLayout_2") - self.splitter_2 = QtWidgets.QSplitter(self.tab_expression) + self.verticalLayout_9 = QtWidgets.QVBoxLayout() + self.verticalLayout_9.setObjectName("verticalLayout_9") + self.label_band_calc = QtWidgets.QLabel(self.widget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_band_calc.sizePolicy().hasHeightForWidth()) + self.label_band_calc.setSizePolicy(sizePolicy) + self.label_band_calc.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_band_calc.setFrameShape(QtWidgets.QFrame.Panel) + self.label_band_calc.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_band_calc.setWordWrap(True) + self.label_band_calc.setObjectName("label_band_calc") + self.verticalLayout_9.addWidget(self.label_band_calc) + self.splitter_2 = QtWidgets.QSplitter(self.widget_3) self.splitter_2.setOrientation(QtCore.Qt.Horizontal) self.splitter_2.setChildrenCollapsible(False) self.splitter_2.setObjectName("splitter_2") - self.plainTextEdit_calc = QtWidgets.QPlainTextEdit(self.splitter_2) - self.plainTextEdit_calc.setMinimumSize(QtCore.QSize(100, 0)) - self.plainTextEdit_calc.setMaximumSize(QtCore.QSize(16777215, 400)) - font = QtGui.QFont() - font.setPointSize(11) - self.plainTextEdit_calc.setFont(font) - self.plainTextEdit_calc.setPlainText("") - self.plainTextEdit_calc.setObjectName("plainTextEdit_calc") - self.frame = QtWidgets.QFrame(self.splitter_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) - self.frame.setSizePolicy(sizePolicy) - self.frame.setMinimumSize(QtCore.QSize(100, 0)) - self.frame.setMaximumSize(QtCore.QSize(300, 16777215)) - self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame.setFrameShadow(QtWidgets.QFrame.Raised) - self.frame.setObjectName("frame") - self.gridLayout_67 = QtWidgets.QGridLayout(self.frame) - self.gridLayout_67.setContentsMargins(2, 2, 2, 2) - self.gridLayout_67.setObjectName("gridLayout_67") - self.gridLayout_88 = QtWidgets.QGridLayout() - self.gridLayout_88.setObjectName("gridLayout_88") - self.gridLayout_90 = QtWidgets.QGridLayout() - self.gridLayout_90.setObjectName("gridLayout_90") - self.horizontalLayout_49 = QtWidgets.QHBoxLayout() - self.horizontalLayout_49.setObjectName("horizontalLayout_49") - self.toolButton_less = QtWidgets.QToolButton(self.frame) - self.toolButton_less.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_less.setObjectName("toolButton_less") - self.horizontalLayout_49.addWidget(self.toolButton_less) - self.toolButton_greater = QtWidgets.QToolButton(self.frame) - self.toolButton_greater.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_greater.setObjectName("toolButton_greater") - self.horizontalLayout_49.addWidget(self.toolButton_greater) - self.toolButton_lbracket = QtWidgets.QToolButton(self.frame) - self.toolButton_lbracket.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_lbracket.setObjectName("toolButton_lbracket") - self.horizontalLayout_49.addWidget(self.toolButton_lbracket) - self.toolButton_rbracket = QtWidgets.QToolButton(self.frame) - self.toolButton_rbracket.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_rbracket.setObjectName("toolButton_rbracket") - self.horizontalLayout_49.addWidget(self.toolButton_rbracket) - self.toolButton_power = QtWidgets.QToolButton(self.frame) - self.toolButton_power.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_power.setObjectName("toolButton_power") - self.horizontalLayout_49.addWidget(self.toolButton_power) - self.toolButton_sqrt = QtWidgets.QToolButton(self.frame) - self.toolButton_sqrt.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_sqrt.setObjectName("toolButton_sqrt") - self.horizontalLayout_49.addWidget(self.toolButton_sqrt) - self.gridLayout_90.addLayout(self.horizontalLayout_49, 1, 0, 1, 1) - self.horizontalLayout_4 = QtWidgets.QHBoxLayout() - self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.toolButton_plus = QtWidgets.QToolButton(self.frame) - self.toolButton_plus.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_plus.setObjectName("toolButton_plus") - self.horizontalLayout_4.addWidget(self.toolButton_plus) - self.toolButton_minus = QtWidgets.QToolButton(self.frame) - self.toolButton_minus.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_minus.setObjectName("toolButton_minus") - self.horizontalLayout_4.addWidget(self.toolButton_minus) - self.toolButton_product = QtWidgets.QToolButton(self.frame) - self.toolButton_product.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_product.setObjectName("toolButton_product") - self.horizontalLayout_4.addWidget(self.toolButton_product) - self.toolButton_ratio = QtWidgets.QToolButton(self.frame) - self.toolButton_ratio.setMinimumSize(QtCore.QSize(25, 25)) - self.toolButton_ratio.setObjectName("toolButton_ratio") - self.horizontalLayout_4.addWidget(self.toolButton_ratio) - self.toolButton_equal = QtWidgets.QToolButton(self.frame) - self.toolButton_equal.setMinimumSize(QtCore.QSize(45, 25)) - self.toolButton_equal.setObjectName("toolButton_equal") - self.horizontalLayout_4.addWidget(self.toolButton_equal) - self.toolButton_unequal = QtWidgets.QToolButton(self.frame) - self.toolButton_unequal.setMinimumSize(QtCore.QSize(45, 25)) - self.toolButton_unequal.setObjectName("toolButton_unequal") - self.horizontalLayout_4.addWidget(self.toolButton_unequal) - self.gridLayout_90.addLayout(self.horizontalLayout_4, 0, 0, 1, 2) - self.toolButton_import_expression = QtWidgets.QToolButton(self.frame) - self.toolButton_import_expression.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_import_expression.setIcon(icon65) - self.toolButton_import_expression.setIconSize(QtCore.QSize(22, 22)) - self.toolButton_import_expression.setObjectName("toolButton_import_expression") - self.gridLayout_90.addWidget(self.toolButton_import_expression, 1, 1, 1, 1) - self.gridLayout_88.addLayout(self.gridLayout_90, 0, 0, 2, 3) - self.gridLayout_93 = QtWidgets.QGridLayout() - self.gridLayout_93.setObjectName("gridLayout_93") - self.gridLayout_38 = QtWidgets.QGridLayout() - self.gridLayout_38.setObjectName("gridLayout_38") - self.band_calc_function_tableWidget = QtWidgets.QTableWidget(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.band_calc_function_tableWidget.sizePolicy().hasHeightForWidth()) - self.band_calc_function_tableWidget.setSizePolicy(sizePolicy) + self.plainTextEdit_calc = QtWidgets.QPlainTextEdit(self.splitter_2) + font = QtGui.QFont() + font.setPointSize(11) + self.plainTextEdit_calc.setFont(font) + self.plainTextEdit_calc.setPlainText("") + self.plainTextEdit_calc.setObjectName("plainTextEdit_calc") + self.band_calc_function_tableWidget = QtWidgets.QTableWidget(self.splitter_2) + self.band_calc_function_tableWidget.setMaximumSize(QtCore.QSize(250, 16777215)) + self.band_calc_function_tableWidget.setFrameShadow(QtWidgets.QFrame.Sunken) self.band_calc_function_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.band_calc_function_tableWidget.setAlternatingRowColors(True) self.band_calc_function_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) @@ -8369,162 +5609,32 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.band_calc_function_tableWidget.setHorizontalHeaderItem(0, item) self.band_calc_function_tableWidget.horizontalHeader().setStretchLastSection(True) self.band_calc_function_tableWidget.verticalHeader().setVisible(False) - self.gridLayout_38.addWidget(self.band_calc_function_tableWidget, 0, 0, 1, 1) - self.gridLayout_93.addLayout(self.gridLayout_38, 0, 0, 1, 2) - self.gridLayout_88.addLayout(self.gridLayout_93, 3, 0, 1, 3) - self.gridLayout_67.addLayout(self.gridLayout_88, 0, 0, 1, 1) - self.gridLayout_2.addWidget(self.splitter_2, 0, 0, 1, 1) - icon82 = QtGui.QIcon() - icon82.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_expression.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.band_calc_tabWidget.addTab(self.tab_expression, icon82, "") - self.tab_decision_rules = QtWidgets.QWidget() - self.tab_decision_rules.setObjectName("tab_decision_rules") - self.gridLayout_89 = QtWidgets.QGridLayout(self.tab_decision_rules) - self.gridLayout_89.setObjectName("gridLayout_89") - self.gridLayout_215 = QtWidgets.QGridLayout() - self.gridLayout_215.setObjectName("gridLayout_215") - self.decision_rules_tableWidget = QtWidgets.QTableWidget(self.tab_decision_rules) - font = QtGui.QFont() - font.setPointSize(10) - self.decision_rules_tableWidget.setFont(font) - self.decision_rules_tableWidget.setObjectName("decision_rules_tableWidget") - self.decision_rules_tableWidget.setColumnCount(2) - self.decision_rules_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.decision_rules_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.decision_rules_tableWidget.setHorizontalHeaderItem(1, item) - self.decision_rules_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_215.addWidget(self.decision_rules_tableWidget, 0, 0, 1, 1) - self.gridLayout_89.addLayout(self.gridLayout_215, 0, 0, 1, 1) - self.gridLayout_220 = QtWidgets.QGridLayout() - self.gridLayout_220.setObjectName("gridLayout_220") - spacerItem147 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_220.addItem(spacerItem147, 6, 0, 1, 1) - self.remove_rule_toolButton = QtWidgets.QToolButton(self.tab_decision_rules) - self.remove_rule_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.remove_rule_toolButton.setIcon(icon58) - self.remove_rule_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_rule_toolButton.setObjectName("remove_rule_toolButton") - self.gridLayout_220.addWidget(self.remove_rule_toolButton, 4, 0, 1, 1) - self.move_up_toolButton_2 = QtWidgets.QToolButton(self.tab_decision_rules) - self.move_up_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.move_up_toolButton_2.setIcon(icon61) - self.move_up_toolButton_2.setIconSize(QtCore.QSize(22, 22)) - self.move_up_toolButton_2.setObjectName("move_up_toolButton_2") - self.gridLayout_220.addWidget(self.move_up_toolButton_2, 0, 0, 1, 1) - self.import_rules_toolButton = QtWidgets.QToolButton(self.tab_decision_rules) - self.import_rules_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_rules_toolButton.setIcon(icon54) - self.import_rules_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_rules_toolButton.setObjectName("import_rules_toolButton") - self.gridLayout_220.addWidget(self.import_rules_toolButton, 7, 0, 1, 1) - self.clear_rules_toolButton = QtWidgets.QToolButton(self.tab_decision_rules) - self.clear_rules_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.clear_rules_toolButton.setIcon(icon59) - self.clear_rules_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.clear_rules_toolButton.setObjectName("clear_rules_toolButton") - self.gridLayout_220.addWidget(self.clear_rules_toolButton, 5, 0, 1, 1) - spacerItem148 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_220.addItem(spacerItem148, 9, 0, 1, 1) - self.add_rule_toolButton = QtWidgets.QToolButton(self.tab_decision_rules) - self.add_rule_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.add_rule_toolButton.setIcon(icon66) - self.add_rule_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.add_rule_toolButton.setObjectName("add_rule_toolButton") - self.gridLayout_220.addWidget(self.add_rule_toolButton, 3, 0, 1, 1) - spacerItem149 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_220.addItem(spacerItem149, 2, 0, 1, 1) - self.move_down_toolButton_2 = QtWidgets.QToolButton(self.tab_decision_rules) - self.move_down_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.move_down_toolButton_2.setIcon(icon62) - self.move_down_toolButton_2.setIconSize(QtCore.QSize(22, 22)) - self.move_down_toolButton_2.setObjectName("move_down_toolButton_2") - self.gridLayout_220.addWidget(self.move_down_toolButton_2, 1, 0, 1, 1) - self.export_rules_toolButton = QtWidgets.QToolButton(self.tab_decision_rules) - self.export_rules_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_rules_toolButton.setIcon(icon53) - self.export_rules_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_rules_toolButton.setObjectName("export_rules_toolButton") - self.gridLayout_220.addWidget(self.export_rules_toolButton, 8, 0, 1, 1) - self.gridLayout_89.addLayout(self.gridLayout_220, 0, 1, 1, 1) - icon83 = QtGui.QIcon() - icon83.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_rules.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.band_calc_tabWidget.addTab(self.tab_decision_rules, icon83, "") - self.gridLayout_40.addWidget(self.band_calc_tabWidget, 0, 0, 1, 1) - self.horizontalLayout_73 = QtWidgets.QHBoxLayout() - self.horizontalLayout_73.setObjectName("horizontalLayout_73") - self.nodata_as_value_checkBox = QtWidgets.QCheckBox(self.widget_3) - self.nodata_as_value_checkBox.setObjectName("nodata_as_value_checkBox") - self.horizontalLayout_73.addWidget(self.nodata_as_value_checkBox) - self.nodata_checkBox_3 = QtWidgets.QCheckBox(self.widget_3) - self.nodata_checkBox_3.setObjectName("nodata_checkBox_3") - self.horizontalLayout_73.addWidget(self.nodata_checkBox_3) - self.nodata_spinBox_13 = QtWidgets.QSpinBox(self.widget_3) - self.nodata_spinBox_13.setMinimum(-2147483647) - self.nodata_spinBox_13.setMaximum(2147483647) - self.nodata_spinBox_13.setObjectName("nodata_spinBox_13") - self.horizontalLayout_73.addWidget(self.nodata_spinBox_13) - self.label_4 = QtWidgets.QLabel(self.widget_3) - self.label_4.setObjectName("label_4") - self.horizontalLayout_73.addWidget(self.label_4) - self.calc_type_combo = QtWidgets.QComboBox(self.widget_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.calc_type_combo.sizePolicy().hasHeightForWidth()) - self.calc_type_combo.setSizePolicy(sizePolicy) - self.calc_type_combo.setObjectName("calc_type_combo") - self.calc_type_combo.addItem("") - self.calc_type_combo.addItem("") - self.calc_type_combo.addItem("") - self.calc_type_combo.addItem("") - self.calc_type_combo.addItem("") - self.calc_type_combo.addItem("") - self.horizontalLayout_73.addWidget(self.calc_type_combo) - spacerItem150 = QtWidgets.QSpacerItem(214, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_73.addItem(spacerItem150) - self.label_83 = QtWidgets.QLabel(self.widget_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_83.sizePolicy().hasHeightForWidth()) - self.label_83.setSizePolicy(sizePolicy) - self.label_83.setMinimumSize(QtCore.QSize(40, 0)) - self.label_83.setMaximumSize(QtCore.QSize(120, 16777215)) - self.label_83.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_83.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_83.setObjectName("label_83") - self.horizontalLayout_73.addWidget(self.label_83) - self.intersection_checkBox = QtWidgets.QCheckBox(self.widget_3) - self.intersection_checkBox.setChecked(True) - self.intersection_checkBox.setObjectName("intersection_checkBox") - self.horizontalLayout_73.addWidget(self.intersection_checkBox) - self.extent_checkBox = QtWidgets.QCheckBox(self.widget_3) - self.extent_checkBox.setObjectName("extent_checkBox") - self.horizontalLayout_73.addWidget(self.extent_checkBox) - self.raster_extent_combo = QtWidgets.QComboBox(self.widget_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.raster_extent_combo.sizePolicy().hasHeightForWidth()) - self.raster_extent_combo.setSizePolicy(sizePolicy) - self.raster_extent_combo.setObjectName("raster_extent_combo") - self.horizontalLayout_73.addWidget(self.raster_extent_combo) - self.align_radioButton = QtWidgets.QRadioButton(self.widget_3) - self.align_radioButton.setChecked(True) - self.align_radioButton.setObjectName("align_radioButton") - self.horizontalLayout_73.addWidget(self.align_radioButton) - self.gridLayout_40.addLayout(self.horizontalLayout_73, 1, 0, 1, 1) - self.label_84 = QtWidgets.QLabel(self.widget_3) - self.label_84.setStyleSheet("background-color : #656565; color : white") + self.verticalLayout_9.addWidget(self.splitter_2) + self.gridLayout_40.addLayout(self.verticalLayout_9, 0, 0, 1, 1) + self.horizontalLayout_11 = QtWidgets.QHBoxLayout() + self.horizontalLayout_11.setObjectName("horizontalLayout_11") + self.toolButton_import_expression = QtWidgets.QToolButton(self.widget_3) + self.toolButton_import_expression.setStyleSheet("margin: 0px;padding: 0px;") + self.toolButton_import_expression.setIcon(icon43) + self.toolButton_import_expression.setIconSize(QtCore.QSize(22, 22)) + self.toolButton_import_expression.setObjectName("toolButton_import_expression") + self.horizontalLayout_11.addWidget(self.toolButton_import_expression) + self.gridLayout_40.addLayout(self.horizontalLayout_11, 0, 1, 1, 1) + self.gridLayout_38.addWidget(self.splitter_band_calc, 0, 0, 1, 1) + self.verticalLayout_8 = QtWidgets.QVBoxLayout() + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.label_84 = QtWidgets.QLabel(self.tab_band_calc) + self.label_84.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_84.setFrameShape(QtWidgets.QFrame.Panel) self.label_84.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_84.setObjectName("label_84") - self.gridLayout_40.addWidget(self.label_84, 2, 0, 1, 1) - self.horizontalLayout_60 = QtWidgets.QHBoxLayout() - self.horizontalLayout_60.setObjectName("horizontalLayout_60") - self.raster_type_combo = QtWidgets.QComboBox(self.widget_3) + self.verticalLayout_8.addWidget(self.label_84) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.label_5 = QtWidgets.QLabel(self.tab_band_calc) + self.label_5.setObjectName("label_5") + self.horizontalLayout_4.addWidget(self.label_5) + self.raster_type_combo = QtWidgets.QComboBox(self.tab_band_calc) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) @@ -8537,8 +5647,8 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.raster_type_combo.addItem("") self.raster_type_combo.addItem("") self.raster_type_combo.addItem("") - self.horizontalLayout_60.addWidget(self.raster_type_combo) - self.label_268 = QtWidgets.QLabel(self.widget_3) + self.horizontalLayout_4.addWidget(self.raster_type_combo) + self.label_268 = QtWidgets.QLabel(self.tab_band_calc) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -8549,96 +5659,203 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.label_268.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_268.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) self.label_268.setObjectName("label_268") - self.horizontalLayout_60.addWidget(self.label_268) - self.nodata_spinBox_4 = QtWidgets.QSpinBox(self.widget_3) + self.horizontalLayout_4.addWidget(self.label_268) + self.nodata_spinBox_4 = QtWidgets.QSpinBox(self.tab_band_calc) self.nodata_spinBox_4.setMinimum(-2147483647) self.nodata_spinBox_4.setMaximum(2147483647) self.nodata_spinBox_4.setProperty("value", -32768) self.nodata_spinBox_4.setObjectName("nodata_spinBox_4") - self.horizontalLayout_60.addWidget(self.nodata_spinBox_4) - self.nodata_mask_checkBox = QtWidgets.QCheckBox(self.widget_3) - self.nodata_mask_checkBox.setChecked(True) - self.nodata_mask_checkBox.setObjectName("nodata_mask_checkBox") - self.horizontalLayout_60.addWidget(self.nodata_mask_checkBox) - self.set_scale_checkBox = QtWidgets.QCheckBox(self.widget_3) + self.horizontalLayout_4.addWidget(self.nodata_spinBox_4) + self.label_152 = QtWidgets.QLabel(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_152.sizePolicy().hasHeightForWidth()) + self.label_152.setSizePolicy(sizePolicy) + self.label_152.setMinimumSize(QtCore.QSize(40, 0)) + self.label_152.setMaximumSize(QtCore.QSize(120, 16777215)) + self.label_152.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_152.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_152.setObjectName("label_152") + self.horizontalLayout_4.addWidget(self.label_152) + self.nodata_mask_combo = QtWidgets.QComboBox(self.tab_band_calc) + self.nodata_mask_combo.setMaximumSize(QtCore.QSize(90, 16777215)) + self.nodata_mask_combo.setObjectName("nodata_mask_combo") + self.nodata_mask_combo.addItem("") + self.nodata_mask_combo.addItem("") + self.nodata_mask_combo.addItem("") + self.horizontalLayout_4.addWidget(self.nodata_mask_combo) + self.set_scale_checkBox = QtWidgets.QCheckBox(self.tab_band_calc) self.set_scale_checkBox.setObjectName("set_scale_checkBox") - self.horizontalLayout_60.addWidget(self.set_scale_checkBox) - self.scale_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.widget_3) + self.horizontalLayout_4.addWidget(self.set_scale_checkBox) + self.scale_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_band_calc) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.scale_doubleSpinBox.sizePolicy().hasHeightForWidth()) self.scale_doubleSpinBox.setSizePolicy(sizePolicy) self.scale_doubleSpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.scale_doubleSpinBox.setDecimals(7) + self.scale_doubleSpinBox.setDecimals(0) self.scale_doubleSpinBox.setMinimum(-1e+34) self.scale_doubleSpinBox.setMaximum(1e+34) self.scale_doubleSpinBox.setProperty("value", 1.0) self.scale_doubleSpinBox.setObjectName("scale_doubleSpinBox") - self.horizontalLayout_60.addWidget(self.scale_doubleSpinBox) - self.set_offset_checkBox = QtWidgets.QCheckBox(self.widget_3) + self.horizontalLayout_4.addWidget(self.scale_doubleSpinBox) + self.set_offset_checkBox = QtWidgets.QCheckBox(self.tab_band_calc) self.set_offset_checkBox.setObjectName("set_offset_checkBox") - self.horizontalLayout_60.addWidget(self.set_offset_checkBox) - self.offset_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.widget_3) + self.horizontalLayout_4.addWidget(self.set_offset_checkBox) + self.offset_doubleSpinBox = QtWidgets.QDoubleSpinBox(self.tab_band_calc) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.offset_doubleSpinBox.sizePolicy().hasHeightForWidth()) self.offset_doubleSpinBox.setSizePolicy(sizePolicy) self.offset_doubleSpinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.offset_doubleSpinBox.setDecimals(7) + self.offset_doubleSpinBox.setDecimals(0) self.offset_doubleSpinBox.setMinimum(-1e+34) self.offset_doubleSpinBox.setMaximum(1e+34) self.offset_doubleSpinBox.setProperty("value", 0.0) self.offset_doubleSpinBox.setObjectName("offset_doubleSpinBox") - self.horizontalLayout_60.addWidget(self.offset_doubleSpinBox) - spacerItem151 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_60.addItem(spacerItem151) - self.band_calc = QtWidgets.QToolButton(self.widget_3) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.band_calc.setFont(font) - self.band_calc.setLayoutDirection(QtCore.Qt.RightToLeft) - self.band_calc.setStyleSheet("margin: 0px;padding: 0px;") - self.band_calc.setIcon(icon48) - self.band_calc.setIconSize(QtCore.QSize(34, 34)) - self.band_calc.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.band_calc.setObjectName("band_calc") - self.horizontalLayout_60.addWidget(self.band_calc) - self.toolButton_calculate = QtWidgets.QToolButton(self.widget_3) + self.horizontalLayout_4.addWidget(self.offset_doubleSpinBox) + spacerItem109 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem109) + self.verticalLayout_8.addLayout(self.horizontalLayout_4) + self.horizontalLayout_60 = QtWidgets.QHBoxLayout() + self.horizontalLayout_60.setObjectName("horizontalLayout_60") + self.label_83 = QtWidgets.QLabel(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_83.sizePolicy().hasHeightForWidth()) + self.label_83.setSizePolicy(sizePolicy) + self.label_83.setMinimumSize(QtCore.QSize(40, 0)) + self.label_83.setMaximumSize(QtCore.QSize(120, 16777215)) + self.label_83.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_83.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_83.setObjectName("label_83") + self.horizontalLayout_60.addWidget(self.label_83) + self.raster_extent_combo = QtWidgets.QComboBox(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.raster_extent_combo.sizePolicy().hasHeightForWidth()) + self.raster_extent_combo.setSizePolicy(sizePolicy) + self.raster_extent_combo.setMinimumSize(QtCore.QSize(150, 0)) + self.raster_extent_combo.setObjectName("raster_extent_combo") + self.horizontalLayout_60.addWidget(self.raster_extent_combo) + self.UL_X_lineEdit = QtWidgets.QLineEdit(self.tab_band_calc) + self.UL_X_lineEdit.setMaximumSize(QtCore.QSize(200, 16777215)) + self.UL_X_lineEdit.setObjectName("UL_X_lineEdit") + self.horizontalLayout_60.addWidget(self.UL_X_lineEdit) + self.UL_Y_linedit = QtWidgets.QLineEdit(self.tab_band_calc) + self.UL_Y_linedit.setMaximumSize(QtCore.QSize(200, 16777215)) + self.UL_Y_linedit.setObjectName("UL_Y_linedit") + self.horizontalLayout_60.addWidget(self.UL_Y_linedit) + self.LR_X_lineEdit = QtWidgets.QLineEdit(self.tab_band_calc) + self.LR_X_lineEdit.setMaximumSize(QtCore.QSize(200, 16777215)) + self.LR_X_lineEdit.setObjectName("LR_X_lineEdit") + self.horizontalLayout_60.addWidget(self.LR_X_lineEdit) + self.LR_Y_lineEdit = QtWidgets.QLineEdit(self.tab_band_calc) + self.LR_Y_lineEdit.setMaximumSize(QtCore.QSize(200, 16777215)) + self.LR_Y_lineEdit.setObjectName("LR_Y_lineEdit") + self.horizontalLayout_60.addWidget(self.LR_Y_lineEdit) + self.label_116 = QtWidgets.QLabel(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_116.sizePolicy().hasHeightForWidth()) + self.label_116.setSizePolicy(sizePolicy) + self.label_116.setMinimumSize(QtCore.QSize(40, 0)) + self.label_116.setMaximumSize(QtCore.QSize(120, 16777215)) + self.label_116.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_116.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_116.setObjectName("label_116") + self.horizontalLayout_60.addWidget(self.label_116) + self.raster_extent_combo_2 = QtWidgets.QComboBox(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.raster_extent_combo_2.sizePolicy().hasHeightForWidth()) + self.raster_extent_combo_2.setSizePolicy(sizePolicy) + self.raster_extent_combo_2.setMinimumSize(QtCore.QSize(150, 0)) + self.raster_extent_combo_2.setObjectName("raster_extent_combo_2") + self.horizontalLayout_60.addWidget(self.raster_extent_combo_2) + self.label_146 = QtWidgets.QLabel(self.tab_band_calc) + self.label_146.setMinimumSize(QtCore.QSize(40, 0)) + self.label_146.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_146.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_146.setObjectName("label_146") + self.horizontalLayout_60.addWidget(self.label_146) + self.resolution_lineEdit = QtWidgets.QLineEdit(self.tab_band_calc) + self.resolution_lineEdit.setMaximumSize(QtCore.QSize(100, 16777215)) + self.resolution_lineEdit.setObjectName("resolution_lineEdit") + self.horizontalLayout_60.addWidget(self.resolution_lineEdit) + spacerItem110 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_60.addItem(spacerItem110) + self.toolButton_calculate = QtWidgets.QToolButton(self.tab_band_calc) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.toolButton_calculate.setFont(font) self.toolButton_calculate.setLayoutDirection(QtCore.Qt.RightToLeft) self.toolButton_calculate.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_calculate.setIcon(icon64) + self.toolButton_calculate.setIcon(icon44) self.toolButton_calculate.setIconSize(QtCore.QSize(34, 34)) self.toolButton_calculate.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.toolButton_calculate.setObjectName("toolButton_calculate") self.horizontalLayout_60.addWidget(self.toolButton_calculate) - self.gridLayout_40.addLayout(self.horizontalLayout_60, 3, 0, 1, 1) - self.gridLayout_303.addWidget(self.splitter_band_calc, 0, 0, 1, 1) + self.verticalLayout_8.addLayout(self.horizontalLayout_60) + self.gridLayout_38.addLayout(self.verticalLayout_8, 2, 0, 1, 1) + self.horizontalLayout_73 = QtWidgets.QHBoxLayout() + self.horizontalLayout_73.setObjectName("horizontalLayout_73") + self.nodata_as_value_checkBox = QtWidgets.QCheckBox(self.tab_band_calc) + self.nodata_as_value_checkBox.setObjectName("nodata_as_value_checkBox") + self.horizontalLayout_73.addWidget(self.nodata_as_value_checkBox) + self.nodata_checkBox_3 = QtWidgets.QCheckBox(self.tab_band_calc) + self.nodata_checkBox_3.setObjectName("nodata_checkBox_3") + self.horizontalLayout_73.addWidget(self.nodata_checkBox_3) + self.nodata_spinBox_13 = QtWidgets.QSpinBox(self.tab_band_calc) + self.nodata_spinBox_13.setMinimum(-2147483647) + self.nodata_spinBox_13.setMaximum(2147483647) + self.nodata_spinBox_13.setObjectName("nodata_spinBox_13") + self.horizontalLayout_73.addWidget(self.nodata_spinBox_13) + self.label_4 = QtWidgets.QLabel(self.tab_band_calc) + self.label_4.setObjectName("label_4") + self.horizontalLayout_73.addWidget(self.label_4) + self.calc_type_combo = QtWidgets.QComboBox(self.tab_band_calc) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.calc_type_combo.sizePolicy().hasHeightForWidth()) + self.calc_type_combo.setSizePolicy(sizePolicy) + self.calc_type_combo.setObjectName("calc_type_combo") + self.calc_type_combo.addItem("") + self.calc_type_combo.addItem("") + self.calc_type_combo.addItem("") + self.calc_type_combo.addItem("") + self.calc_type_combo.addItem("") + self.calc_type_combo.addItem("") + self.horizontalLayout_73.addWidget(self.calc_type_combo) + spacerItem111 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_73.addItem(spacerItem111) + self.gridLayout_38.addLayout(self.horizontalLayout_73, 1, 0, 1, 1) self.SCP_tabs.addTab(self.tab_band_calc, "") - self.tab_batch = QtWidgets.QWidget() - self.tab_batch.setObjectName("tab_batch") - self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.tab_batch) - self.verticalLayout_5.setObjectName("verticalLayout_5") - self.verticalLayout_3 = QtWidgets.QVBoxLayout() - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.label_73 = QtWidgets.QLabel(self.tab_batch) + self.tab_script = QtWidgets.QWidget() + self.tab_script.setObjectName("tab_script") + self.gridLayout_94 = QtWidgets.QGridLayout(self.tab_script) + self.gridLayout_94.setObjectName("gridLayout_94") + self.label_73 = QtWidgets.QLabel(self.tab_script) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label_73.sizePolicy().hasHeightForWidth()) self.label_73.setSizePolicy(sizePolicy) - self.label_73.setStyleSheet("background-color : #656565; color : white") + self.label_73.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_73.setFrameShape(QtWidgets.QFrame.Panel) self.label_73.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_73.setObjectName("label_73") - self.verticalLayout_3.addWidget(self.label_73) - self.splitter_batch = QtWidgets.QSplitter(self.tab_batch) + self.gridLayout_94.addWidget(self.label_73, 0, 0, 1, 1) + self.splitter_batch = QtWidgets.QSplitter(self.tab_script) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -8653,114 +5870,47 @@ def setupUi(self, SemiAutomaticClassificationPlugin): font = QtGui.QFont() font.setPointSize(11) self.plainTextEdit_batch.setFont(font) + self.plainTextEdit_batch.setStyleSheet("color:rgb(0, 225, 0); \n" +"background-color: rgb(27, 27, 27);") self.plainTextEdit_batch.setPlainText("") + self.plainTextEdit_batch.setBackgroundVisible(False) self.plainTextEdit_batch.setObjectName("plainTextEdit_batch") - self.widget_4 = QtWidgets.QWidget(self.splitter_batch) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Ignored) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.widget_4.sizePolicy().hasHeightForWidth()) - self.widget_4.setSizePolicy(sizePolicy) - self.widget_4.setMinimumSize(QtCore.QSize(100, 400)) - self.widget_4.setMaximumSize(QtCore.QSize(250, 16777215)) - self.widget_4.setObjectName("widget_4") - self.gridLayout_76 = QtWidgets.QGridLayout(self.widget_4) - self.gridLayout_76.setContentsMargins(1, 1, 1, 1) - self.gridLayout_76.setObjectName("gridLayout_76") - self.gridLayout_214 = QtWidgets.QGridLayout() - self.gridLayout_214.setObjectName("gridLayout_214") - self.export_batch_toolButton = QtWidgets.QToolButton(self.widget_4) - self.export_batch_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.export_batch_toolButton.setIcon(icon53) - self.export_batch_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.export_batch_toolButton.setObjectName("export_batch_toolButton") - self.gridLayout_214.addWidget(self.export_batch_toolButton, 0, 2, 1, 1) - self.clear_batch_toolButton = QtWidgets.QToolButton(self.widget_4) + self.gridLayout_94.addWidget(self.splitter_batch, 1, 0, 1, 1) + self.horizontalLayout_69 = QtWidgets.QHBoxLayout() + self.horizontalLayout_69.setObjectName("horizontalLayout_69") + self.clear_batch_toolButton = QtWidgets.QToolButton(self.tab_script) self.clear_batch_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - self.clear_batch_toolButton.setIcon(icon59) + self.clear_batch_toolButton.setIcon(icon45) self.clear_batch_toolButton.setIconSize(QtCore.QSize(22, 22)) self.clear_batch_toolButton.setObjectName("clear_batch_toolButton") - self.gridLayout_214.addWidget(self.clear_batch_toolButton, 0, 0, 1, 1) - self.import_batch_toolButton = QtWidgets.QToolButton(self.widget_4) - self.import_batch_toolButton.setStyleSheet("margin: 0px;padding: 0px") - self.import_batch_toolButton.setIcon(icon54) - self.import_batch_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.import_batch_toolButton.setObjectName("import_batch_toolButton") - self.gridLayout_214.addWidget(self.import_batch_toolButton, 0, 1, 1, 1) - self.gridLayout_76.addLayout(self.gridLayout_214, 1, 0, 1, 1) - self.batch_tableWidget = QtWidgets.QTableWidget(self.widget_4) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.batch_tableWidget.sizePolicy().hasHeightForWidth()) - self.batch_tableWidget.setSizePolicy(sizePolicy) - self.batch_tableWidget.setMaximumSize(QtCore.QSize(300, 16777215)) - self.batch_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.batch_tableWidget.setAlternatingRowColors(True) - self.batch_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.batch_tableWidget.setObjectName("batch_tableWidget") - self.batch_tableWidget.setColumnCount(1) - self.batch_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.batch_tableWidget.setHorizontalHeaderItem(0, item) - self.batch_tableWidget.horizontalHeader().setStretchLastSection(True) - self.batch_tableWidget.verticalHeader().setVisible(False) - self.gridLayout_76.addWidget(self.batch_tableWidget, 0, 0, 1, 1) - self.verticalLayout_3.addWidget(self.splitter_batch) - self.batch_label = QtWidgets.QLabel(self.tab_batch) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.batch_label.sizePolicy().hasHeightForWidth()) - self.batch_label.setSizePolicy(sizePolicy) - self.batch_label.setText("") - self.batch_label.setObjectName("batch_label") - self.verticalLayout_3.addWidget(self.batch_label) - self.label_177 = QtWidgets.QLabel(self.tab_batch) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_177.sizePolicy().hasHeightForWidth()) - self.label_177.setSizePolicy(sizePolicy) - self.label_177.setStyleSheet("background-color : #656565; color : white") - self.label_177.setFrameShape(QtWidgets.QFrame.Panel) - self.label_177.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_177.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_177.setObjectName("label_177") - self.verticalLayout_3.addWidget(self.label_177) - self.horizontalLayout_69 = QtWidgets.QHBoxLayout() - self.horizontalLayout_69.setObjectName("horizontalLayout_69") - spacerItem152 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_69.addItem(spacerItem152) - self.check_batch = QtWidgets.QToolButton(self.tab_batch) + self.horizontalLayout_69.addWidget(self.clear_batch_toolButton) + spacerItem112 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_69.addItem(spacerItem112) + self.copy_script = QtWidgets.QToolButton(self.tab_script) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.check_batch.setFont(font) - self.check_batch.setLayoutDirection(QtCore.Qt.RightToLeft) - self.check_batch.setStyleSheet("margin: 0px;padding: 0px;") - icon84 = QtGui.QIcon() - icon84.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch_check.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.check_batch.setIcon(icon84) - self.check_batch.setIconSize(QtCore.QSize(34, 34)) - self.check_batch.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.check_batch.setObjectName("check_batch") - self.horizontalLayout_69.addWidget(self.check_batch) - self.toolButton_run_batch = QtWidgets.QToolButton(self.tab_batch) + self.copy_script.setFont(font) + self.copy_script.setLayoutDirection(QtCore.Qt.RightToLeft) + self.copy_script.setStyleSheet("margin: 0px;padding: 0px;") + self.copy_script.setIconSize(QtCore.QSize(34, 34)) + self.copy_script.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.copy_script.setObjectName("copy_script") + self.horizontalLayout_69.addWidget(self.copy_script) + self.save_script_button = QtWidgets.QToolButton(self.tab_script) font = QtGui.QFont() font.setBold(True) font.setWeight(75) - self.toolButton_run_batch.setFont(font) - self.toolButton_run_batch.setLayoutDirection(QtCore.Qt.RightToLeft) - self.toolButton_run_batch.setStyleSheet("margin: 0px;padding: 0px;") - self.toolButton_run_batch.setIcon(icon64) - self.toolButton_run_batch.setIconSize(QtCore.QSize(34, 34)) - self.toolButton_run_batch.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.toolButton_run_batch.setObjectName("toolButton_run_batch") - self.horizontalLayout_69.addWidget(self.toolButton_run_batch) - self.verticalLayout_3.addLayout(self.horizontalLayout_69) - self.verticalLayout_5.addLayout(self.verticalLayout_3) - self.SCP_tabs.addTab(self.tab_batch, "") + self.save_script_button.setFont(font) + self.save_script_button.setLayoutDirection(QtCore.Qt.RightToLeft) + self.save_script_button.setStyleSheet("margin: 0px;padding: 0px;") + self.save_script_button.setIcon(icon47) + self.save_script_button.setIconSize(QtCore.QSize(24, 24)) + self.save_script_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.save_script_button.setObjectName("save_script_button") + self.horizontalLayout_69.addWidget(self.save_script_button) + self.gridLayout_94.addLayout(self.horizontalLayout_69, 2, 0, 1, 1) + self.SCP_tabs.addTab(self.tab_script, "") self.tab_Settings = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) @@ -8771,6 +5921,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.tab_Settings.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.tab_Settings.setObjectName("tab_Settings") self.gridLayout_134 = QtWidgets.QGridLayout(self.tab_Settings) + self.gridLayout_134.setContentsMargins(3, 3, 3, 3) self.gridLayout_134.setObjectName("gridLayout_134") self.settings_tabWidget = QtWidgets.QTabWidget(self.tab_Settings) self.settings_tabWidget.setDocumentMode(True) @@ -8782,7 +5933,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_3 = QtWidgets.QGridLayout() self.gridLayout_3.setObjectName("gridLayout_3") self.label_28 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_28.setStyleSheet("background-color : #656565; color : white") + self.label_28.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_28.setFrameShape(QtWidgets.QFrame.Panel) self.label_28.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_28.setObjectName("label_28") @@ -8850,7 +6001,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.smtp_checkBox.setObjectName("smtp_checkBox") self.gridLayout_237.addWidget(self.smtp_checkBox, 3, 1, 1, 1) self.label_117 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_117.setStyleSheet("background-color : #656565; color : white") + self.label_117.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_117.setFrameShape(QtWidgets.QFrame.Panel) self.label_117.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_117.setObjectName("label_117") @@ -8878,18 +6029,18 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_124.setObjectName("gridLayout_124") self.reset_temp_directory_Button = QtWidgets.QToolButton(self.tabWidgetProcessing) self.reset_temp_directory_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_temp_directory_Button.setIcon(icon59) + self.reset_temp_directory_Button.setIcon(icon45) self.reset_temp_directory_Button.setIconSize(QtCore.QSize(22, 22)) self.reset_temp_directory_Button.setObjectName("reset_temp_directory_Button") self.gridLayout_124.addWidget(self.reset_temp_directory_Button, 2, 3, 1, 1) self.temp_directory_Button = QtWidgets.QToolButton(self.tabWidgetProcessing) self.temp_directory_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.temp_directory_Button.setIcon(icon69) + self.temp_directory_Button.setIcon(icon59) self.temp_directory_Button.setIconSize(QtCore.QSize(22, 22)) self.temp_directory_Button.setObjectName("temp_directory_Button") self.gridLayout_124.addWidget(self.temp_directory_Button, 2, 0, 1, 1) self.label_87 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_87.setStyleSheet("background-color : #656565; color : white") + self.label_87.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_87.setFrameShape(QtWidgets.QFrame.Panel) self.label_87.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_87.setObjectName("label_87") @@ -8905,24 +6056,6 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_107.setObjectName("gridLayout_107") self.verticalLayout_6 = QtWidgets.QVBoxLayout() self.verticalLayout_6.setObjectName("verticalLayout_6") - self.SNAP_label = QtWidgets.QLabel(self.tabWidgetProcessing) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.SNAP_label.sizePolicy().hasHeightForWidth()) - self.SNAP_label.setSizePolicy(sizePolicy) - self.SNAP_label.setFrameShadow(QtWidgets.QFrame.Sunken) - self.SNAP_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.SNAP_label.setObjectName("SNAP_label") - self.verticalLayout_6.addWidget(self.SNAP_label) - self.label_276 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_276.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_276.setObjectName("label_276") - self.verticalLayout_6.addWidget(self.label_276) - self.label_288 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_288.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_288.setObjectName("label_288") - self.verticalLayout_6.addWidget(self.label_288) self.label_275 = QtWidgets.QLabel(self.tabWidgetProcessing) self.label_275.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_275.setObjectName("label_275") @@ -8930,21 +6063,12 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_107.addLayout(self.verticalLayout_6, 1, 0, 1, 1) self.verticalLayout_7 = QtWidgets.QVBoxLayout() self.verticalLayout_7.setObjectName("verticalLayout_7") - self.SNAP_GPT_lineEdit = QtWidgets.QLineEdit(self.tabWidgetProcessing) - self.SNAP_GPT_lineEdit.setObjectName("SNAP_GPT_lineEdit") - self.verticalLayout_7.addWidget(self.SNAP_GPT_lineEdit) - self.python_path_lineEdit = QtWidgets.QLineEdit(self.tabWidgetProcessing) - self.python_path_lineEdit.setObjectName("python_path_lineEdit") - self.verticalLayout_7.addWidget(self.python_path_lineEdit) - self.python_path_lineEdit_2 = QtWidgets.QLineEdit(self.tabWidgetProcessing) - self.python_path_lineEdit_2.setObjectName("python_path_lineEdit_2") - self.verticalLayout_7.addWidget(self.python_path_lineEdit_2) self.gdal_path_lineEdit = QtWidgets.QLineEdit(self.tabWidgetProcessing) self.gdal_path_lineEdit.setObjectName("gdal_path_lineEdit") self.verticalLayout_7.addWidget(self.gdal_path_lineEdit) self.gridLayout_107.addLayout(self.verticalLayout_7, 1, 1, 1, 1) self.label_211 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_211.setStyleSheet("background-color : #656565; color : white") + self.label_211.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_211.setFrameShape(QtWidgets.QFrame.Panel) self.label_211.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_211.setObjectName("label_211") @@ -8957,90 +6081,31 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.sound_checkBox.setTristate(False) self.sound_checkBox.setObjectName("sound_checkBox") self.gridLayout_30.addWidget(self.sound_checkBox, 1, 0, 1, 1) - self.virtual_raster_checkBox = QtWidgets.QCheckBox(self.tabWidgetProcessing) - self.virtual_raster_checkBox.setChecked(True) - self.virtual_raster_checkBox.setObjectName("virtual_raster_checkBox") - self.gridLayout_30.addWidget(self.virtual_raster_checkBox, 1, 1, 1, 1) self.label_45 = QtWidgets.QLabel(self.tabWidgetProcessing) - self.label_45.setStyleSheet("background-color : #656565; color : white") + self.label_45.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_45.setFrameShape(QtWidgets.QFrame.Panel) self.label_45.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_45.setObjectName("label_45") - self.gridLayout_30.addWidget(self.label_45, 0, 0, 1, 3) + self.gridLayout_30.addWidget(self.label_45, 0, 0, 1, 2) self.raster_compression_checkBox = QtWidgets.QCheckBox(self.tabWidgetProcessing) self.raster_compression_checkBox.setChecked(True) self.raster_compression_checkBox.setObjectName("raster_compression_checkBox") - self.gridLayout_30.addWidget(self.raster_compression_checkBox, 1, 2, 1, 1) + self.gridLayout_30.addWidget(self.raster_compression_checkBox, 1, 1, 1, 1) self.horizontalLayout_65 = QtWidgets.QHBoxLayout() self.horizontalLayout_65.setObjectName("horizontalLayout_65") - self.parallel_writing_checkBox = QtWidgets.QCheckBox(self.tabWidgetProcessing) - self.parallel_writing_checkBox.setObjectName("parallel_writing_checkBox") - self.horizontalLayout_65.addWidget(self.parallel_writing_checkBox) - self.gridLayout_30.addLayout(self.horizontalLayout_65, 2, 0, 1, 3) + self.gridLayout_30.addLayout(self.horizontalLayout_65, 2, 0, 1, 2) self.gridLayout_195.addLayout(self.gridLayout_30, 1, 0, 1, 1) - spacerItem153 = QtWidgets.QSpacerItem(17, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_195.addItem(spacerItem153, 5, 0, 1, 1) + spacerItem113 = QtWidgets.QSpacerItem(17, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_195.addItem(spacerItem113, 5, 0, 1, 1) self.settings_tabWidget.addTab(self.tabWidgetProcessing, "") self.tabWidgetInterface = QtWidgets.QWidget() self.tabWidgetInterface.setObjectName("tabWidgetInterface") self.gridLayout_63 = QtWidgets.QGridLayout(self.tabWidgetInterface) self.gridLayout_63.setObjectName("gridLayout_63") - self.gridLayout_13 = QtWidgets.QGridLayout() - self.gridLayout_13.setObjectName("gridLayout_13") - self.label_31 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_31.setFrameShape(QtWidgets.QFrame.Panel) - self.label_31.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_31.setObjectName("label_31") - self.gridLayout_13.addWidget(self.label_31, 1, 3, 1, 1) - self.Info_field_name_lineEdit = QtWidgets.QLineEdit(self.tabWidgetInterface) - self.Info_field_name_lineEdit.setMaxLength(10) - self.Info_field_name_lineEdit.setObjectName("Info_field_name_lineEdit") - self.gridLayout_13.addWidget(self.Info_field_name_lineEdit, 2, 3, 1, 1) - self.label_24 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_24.setStyleSheet("background-color : #656565; color : white") - self.label_24.setFrameShape(QtWidgets.QFrame.Panel) - self.label_24.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_24.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_24.setObjectName("label_24") - self.gridLayout_13.addWidget(self.label_24, 0, 0, 1, 5) - self.ID_field_name_lineEdit = QtWidgets.QLineEdit(self.tabWidgetInterface) - self.ID_field_name_lineEdit.setMaxLength(10) - self.ID_field_name_lineEdit.setObjectName("ID_field_name_lineEdit") - self.gridLayout_13.addWidget(self.ID_field_name_lineEdit, 2, 2, 1, 1) - self.MID_field_name_lineEdit = QtWidgets.QLineEdit(self.tabWidgetInterface) - self.MID_field_name_lineEdit.setMaxLength(10) - self.MID_field_name_lineEdit.setObjectName("MID_field_name_lineEdit") - self.gridLayout_13.addWidget(self.MID_field_name_lineEdit, 2, 0, 1, 1) - self.label_10 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_10.setFrameShape(QtWidgets.QFrame.Panel) - self.label_10.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_10.setObjectName("label_10") - self.gridLayout_13.addWidget(self.label_10, 1, 2, 1, 1) - self.MCInfo_field_name_lineEdit = QtWidgets.QLineEdit(self.tabWidgetInterface) - self.MCInfo_field_name_lineEdit.setMaxLength(10) - self.MCInfo_field_name_lineEdit.setObjectName("MCInfo_field_name_lineEdit") - self.gridLayout_13.addWidget(self.MCInfo_field_name_lineEdit, 2, 1, 1, 1) - self.label_17 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_17.setFrameShape(QtWidgets.QFrame.Panel) - self.label_17.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_17.setObjectName("label_17") - self.gridLayout_13.addWidget(self.label_17, 1, 0, 1, 1) - self.label_46 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_46.setFrameShape(QtWidgets.QFrame.Panel) - self.label_46.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_46.setObjectName("label_46") - self.gridLayout_13.addWidget(self.label_46, 1, 1, 1, 1) - self.reset_field_names_Button = QtWidgets.QToolButton(self.tabWidgetInterface) - self.reset_field_names_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_field_names_Button.setIcon(icon59) - self.reset_field_names_Button.setIconSize(QtCore.QSize(22, 22)) - self.reset_field_names_Button.setObjectName("reset_field_names_Button") - self.gridLayout_13.addWidget(self.reset_field_names_Button, 2, 4, 1, 1) - self.gridLayout_63.addLayout(self.gridLayout_13, 0, 0, 1, 1) self.gridLayout_21 = QtWidgets.QGridLayout() self.gridLayout_21.setObjectName("gridLayout_21") self.label_21 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_21.setStyleSheet("background-color : #656565; color : white") + self.label_21.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_21.setFrameShape(QtWidgets.QFrame.Panel) self.label_21.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_21.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -9084,11 +6149,27 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_21.addLayout(self.gridLayout_172, 2, 1, 1, 1) self.reset_color_Button = QtWidgets.QToolButton(self.tabWidgetInterface) self.reset_color_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_color_Button.setIcon(icon59) + self.reset_color_Button.setIcon(icon45) self.reset_color_Button.setIconSize(QtCore.QSize(22, 22)) self.reset_color_Button.setObjectName("reset_color_Button") self.gridLayout_21.addWidget(self.reset_color_Button, 2, 2, 1, 1) - self.gridLayout_63.addLayout(self.gridLayout_21, 1, 0, 1, 1) + self.gridLayout_63.addLayout(self.gridLayout_21, 0, 0, 1, 1) + self.gridLayout_17 = QtWidgets.QGridLayout() + self.gridLayout_17.setObjectName("gridLayout_17") + self.label_95 = QtWidgets.QLabel(self.tabWidgetInterface) + self.label_95.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_95.setFrameShape(QtWidgets.QFrame.Panel) + self.label_95.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_95.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_95.setObjectName("label_95") + self.gridLayout_17.addWidget(self.label_95, 0, 0, 1, 1) + spacerItem114 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_17.addItem(spacerItem114, 2, 0, 1, 1) + self.download_news_checkBox = QtWidgets.QCheckBox(self.tabWidgetInterface) + self.download_news_checkBox.setChecked(True) + self.download_news_checkBox.setObjectName("download_news_checkBox") + self.gridLayout_17.addWidget(self.download_news_checkBox, 1, 0, 1, 1) + self.gridLayout_63.addLayout(self.gridLayout_17, 3, 0, 1, 1) self.gridLayout_84 = QtWidgets.QGridLayout() self.gridLayout_84.setObjectName("gridLayout_84") self.label_68 = QtWidgets.QLabel(self.tabWidgetInterface) @@ -9111,7 +6192,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.variable_name_lineEdit.setObjectName("variable_name_lineEdit") self.gridLayout_84.addWidget(self.variable_name_lineEdit, 1, 1, 1, 1) self.label_69 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_69.setStyleSheet("background-color : #656565; color : white") + self.label_69.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_69.setFrameShape(QtWidgets.QFrame.Panel) self.label_69.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_69.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -9119,31 +6200,15 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_84.addWidget(self.label_69, 0, 0, 1, 3) self.reset_variable_name_Button = QtWidgets.QToolButton(self.tabWidgetInterface) self.reset_variable_name_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_variable_name_Button.setIcon(icon59) + self.reset_variable_name_Button.setIcon(icon45) self.reset_variable_name_Button.setIconSize(QtCore.QSize(22, 22)) self.reset_variable_name_Button.setObjectName("reset_variable_name_Button") self.gridLayout_84.addWidget(self.reset_variable_name_Button, 1, 2, 1, 1) - self.gridLayout_63.addLayout(self.gridLayout_84, 2, 0, 1, 1) - self.gridLayout_17 = QtWidgets.QGridLayout() - self.gridLayout_17.setObjectName("gridLayout_17") - self.label_95 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_95.setStyleSheet("background-color : #656565; color : white") - self.label_95.setFrameShape(QtWidgets.QFrame.Panel) - self.label_95.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_95.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_95.setObjectName("label_95") - self.gridLayout_17.addWidget(self.label_95, 0, 0, 1, 1) - spacerItem154 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_17.addItem(spacerItem154, 2, 0, 1, 1) - self.download_news_checkBox = QtWidgets.QCheckBox(self.tabWidgetInterface) - self.download_news_checkBox.setChecked(True) - self.download_news_checkBox.setObjectName("download_news_checkBox") - self.gridLayout_17.addWidget(self.download_news_checkBox, 1, 0, 1, 1) - self.gridLayout_63.addLayout(self.gridLayout_17, 4, 0, 1, 1) + self.gridLayout_63.addLayout(self.gridLayout_84, 1, 0, 1, 1) self.gridLayout_99 = QtWidgets.QGridLayout() self.gridLayout_99.setObjectName("gridLayout_99") self.label_76 = QtWidgets.QLabel(self.tabWidgetInterface) - self.label_76.setStyleSheet("background-color : #656565; color : white") + self.label_76.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_76.setFrameShape(QtWidgets.QFrame.Panel) self.label_76.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_76.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -9151,7 +6216,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_99.addWidget(self.label_76, 0, 0, 1, 3) self.reset_group_name_Button = QtWidgets.QToolButton(self.tabWidgetInterface) self.reset_group_name_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.reset_group_name_Button.setIcon(icon59) + self.reset_group_name_Button.setIcon(icon45) self.reset_group_name_Button.setIconSize(QtCore.QSize(22, 22)) self.reset_group_name_Button.setObjectName("reset_group_name_Button") self.gridLayout_99.addWidget(self.reset_group_name_Button, 1, 2, 1, 1) @@ -9180,71 +6245,63 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.group_name_lineEdit.setObjectName("group_name_lineEdit") self.horizontalLayout_61.addWidget(self.group_name_lineEdit) self.gridLayout_99.addLayout(self.horizontalLayout_61, 1, 0, 1, 2) - self.gridLayout_63.addLayout(self.gridLayout_99, 3, 0, 1, 1) + self.gridLayout_63.addLayout(self.gridLayout_99, 2, 0, 1, 1) self.settings_tabWidget.addTab(self.tabWidgetInterface, "") self.tabWidgetDebug = QtWidgets.QWidget() self.tabWidgetDebug.setObjectName("tabWidgetDebug") - self.gridLayout_56 = QtWidgets.QGridLayout(self.tabWidgetDebug) - self.gridLayout_56.setObjectName("gridLayout_56") - self.gridLayout_7 = QtWidgets.QGridLayout() - self.gridLayout_7.setObjectName("gridLayout_7") - self.log_checkBox = QtWidgets.QCheckBox(self.tabWidgetDebug) - self.log_checkBox.setChecked(False) - self.log_checkBox.setTristate(False) - self.log_checkBox.setObjectName("log_checkBox") - self.gridLayout_7.addWidget(self.log_checkBox, 1, 0, 1, 1) - self.exportLog_Button = QtWidgets.QToolButton(self.tabWidgetDebug) - self.exportLog_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.exportLog_Button.setIcon(icon53) - self.exportLog_Button.setIconSize(QtCore.QSize(22, 22)) - self.exportLog_Button.setObjectName("exportLog_Button") - self.gridLayout_7.addWidget(self.exportLog_Button, 1, 1, 1, 1) - self.clearLog_Button = QtWidgets.QToolButton(self.tabWidgetDebug) - self.clearLog_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.clearLog_Button.setIcon(icon59) - self.clearLog_Button.setIconSize(QtCore.QSize(22, 22)) - self.clearLog_Button.setObjectName("clearLog_Button") - self.gridLayout_7.addWidget(self.clearLog_Button, 1, 2, 1, 1) - self.label_30 = QtWidgets.QLabel(self.tabWidgetDebug) - self.label_30.setStyleSheet("background-color : #656565; color : white") - self.label_30.setFrameShape(QtWidgets.QFrame.Panel) - self.label_30.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_30.setObjectName("label_30") - self.gridLayout_7.addWidget(self.label_30, 0, 0, 1, 3) - self.log_tableWidget = QtWidgets.QTableWidget(self.tabWidgetDebug) - self.log_tableWidget.setObjectName("log_tableWidget") - self.log_tableWidget.setColumnCount(3) - self.log_tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.log_tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.log_tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.log_tableWidget.setHorizontalHeaderItem(2, item) - self.log_tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_7.addWidget(self.log_tableWidget, 2, 0, 1, 3) - self.gridLayout_56.addLayout(self.gridLayout_7, 0, 0, 1, 1) + self.gridLayout_13 = QtWidgets.QGridLayout(self.tabWidgetDebug) + self.gridLayout_13.setObjectName("gridLayout_13") self.gridLayout_55 = QtWidgets.QGridLayout() self.gridLayout_55.setObjectName("gridLayout_55") self.test_dependencies_Button = QtWidgets.QToolButton(self.tabWidgetDebug) self.test_dependencies_Button.setStyleSheet("margin: 0px;padding: 0px;") - self.test_dependencies_Button.setIcon(icon67) + self.test_dependencies_Button.setIcon(icon57) self.test_dependencies_Button.setIconSize(QtCore.QSize(22, 22)) self.test_dependencies_Button.setObjectName("test_dependencies_Button") self.gridLayout_55.addWidget(self.test_dependencies_Button, 2, 2, 1, 1) - self.label_42 = QtWidgets.QLabel(self.tabWidgetDebug) - self.label_42.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_42.setObjectName("label_42") - self.gridLayout_55.addWidget(self.label_42, 2, 1, 1, 1) - spacerItem155 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_55.addItem(spacerItem155, 2, 3, 1, 1) self.label_43 = QtWidgets.QLabel(self.tabWidgetDebug) - self.label_43.setStyleSheet("background-color : #656565; color : white") + self.label_43.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_43.setFrameShape(QtWidgets.QFrame.Panel) self.label_43.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_43.setObjectName("label_43") self.gridLayout_55.addWidget(self.label_43, 0, 0, 1, 4) - self.gridLayout_56.addLayout(self.gridLayout_55, 1, 0, 1, 1) + spacerItem115 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_55.addItem(spacerItem115, 2, 3, 1, 1) + self.label_42 = QtWidgets.QLabel(self.tabWidgetDebug) + self.label_42.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.label_42.setObjectName("label_42") + self.gridLayout_55.addWidget(self.label_42, 2, 1, 1, 1) + spacerItem116 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_55.addItem(spacerItem116, 4, 1, 1, 1) + self.test_textBrowser = QtWidgets.QTextBrowser(self.tabWidgetDebug) + self.test_textBrowser.setFrameShape(QtWidgets.QFrame.Panel) + self.test_textBrowser.setFrameShadow(QtWidgets.QFrame.Sunken) + self.test_textBrowser.setOpenExternalLinks(True) + self.test_textBrowser.setObjectName("test_textBrowser") + self.gridLayout_55.addWidget(self.test_textBrowser, 3, 1, 1, 3) + self.gridLayout_13.addLayout(self.gridLayout_55, 1, 0, 1, 1) + self.gridLayout_7 = QtWidgets.QGridLayout() + self.gridLayout_7.setObjectName("gridLayout_7") + self.exportLog_Button = QtWidgets.QToolButton(self.tabWidgetDebug) + self.exportLog_Button.setStyleSheet("margin: 0px;padding: 0px;") + self.exportLog_Button.setIcon(icon47) + self.exportLog_Button.setIconSize(QtCore.QSize(22, 22)) + self.exportLog_Button.setObjectName("exportLog_Button") + self.gridLayout_7.addWidget(self.exportLog_Button, 1, 2, 1, 1) + self.log_checkBox = QtWidgets.QCheckBox(self.tabWidgetDebug) + self.log_checkBox.setChecked(False) + self.log_checkBox.setTristate(False) + self.log_checkBox.setObjectName("log_checkBox") + self.gridLayout_7.addWidget(self.log_checkBox, 1, 0, 1, 1) + self.label_30 = QtWidgets.QLabel(self.tabWidgetDebug) + self.label_30.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_30.setFrameShape(QtWidgets.QFrame.Panel) + self.label_30.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_30.setObjectName("label_30") + self.gridLayout_7.addWidget(self.label_30, 0, 0, 1, 4) + spacerItem117 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_7.addItem(spacerItem117, 1, 1, 1, 1) + self.gridLayout_13.addLayout(self.gridLayout_7, 0, 0, 1, 1) self.settings_tabWidget.addTab(self.tabWidgetDebug, "") self.gridLayout_134.addWidget(self.settings_tabWidget, 0, 0, 1, 1) self.SCP_tabs.addTab(self.tab_Settings, "") @@ -9257,9 +6314,15 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.tab_About.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.tab_About.setObjectName("tab_About") self.gridLayout_16 = QtWidgets.QGridLayout(self.tab_About) + self.gridLayout_16.setContentsMargins(3, 3, 3, 3) self.gridLayout_16.setObjectName("gridLayout_16") self.gridLayout_5 = QtWidgets.QGridLayout() self.gridLayout_5.setObjectName("gridLayout_5") + self.label_7 = QtWidgets.QLabel(self.tab_About) + self.label_7.setText("") + self.label_7.setPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg")) + self.label_7.setObjectName("label_7") + self.gridLayout_5.addWidget(self.label_7, 0, 1, 1, 1) self.plugin_version_label = QtWidgets.QLabel(self.tab_About) self.plugin_version_label.setFrameShape(QtWidgets.QFrame.NoFrame) self.plugin_version_label.setFrameShadow(QtWidgets.QFrame.Raised) @@ -9267,14 +6330,19 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.plugin_version_label.setTextFormat(QtCore.Qt.PlainText) self.plugin_version_label.setAlignment(QtCore.Qt.AlignCenter) self.plugin_version_label.setObjectName("plugin_version_label") - self.gridLayout_5.addWidget(self.plugin_version_label, 1, 0, 1, 1) + self.gridLayout_5.addWidget(self.plugin_version_label, 1, 2, 1, 1) + spacerItem118 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_5.addItem(spacerItem118, 0, 0, 1, 1) self.plugin_label = QtWidgets.QLabel(self.tab_About) + self.plugin_label.setStyleSheet("font: bold") self.plugin_label.setFrameShape(QtWidgets.QFrame.NoFrame) self.plugin_label.setFrameShadow(QtWidgets.QFrame.Raised) self.plugin_label.setTextFormat(QtCore.Qt.PlainText) self.plugin_label.setAlignment(QtCore.Qt.AlignCenter) self.plugin_label.setObjectName("plugin_label") - self.gridLayout_5.addWidget(self.plugin_label, 0, 0, 1, 1) + self.gridLayout_5.addWidget(self.plugin_label, 0, 2, 1, 1) + spacerItem119 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_5.addItem(spacerItem119, 0, 3, 1, 1) self.gridLayout_16.addLayout(self.gridLayout_5, 0, 0, 1, 1) self.gridLayout_9 = QtWidgets.QGridLayout() self.gridLayout_9.setObjectName("gridLayout_9") @@ -9286,7 +6354,7 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.gridLayout_9.addWidget(self.textBrowser, 0, 0, 1, 1) self.gridLayout_16.addLayout(self.gridLayout_9, 1, 0, 1, 1) self.SCP_tabs.addTab(self.tab_About, "") - self.gridLayout_262.addWidget(self.SCP_tabs, 0, 0, 1, 1) + self.gridLayout_60.addWidget(self.SCP_tabs, 0, 0, 1, 1) self.main_tabWidget.addTab(self.tool_tab, icon, "") self.help_tab = QtWidgets.QWidget() self.help_tab.setObjectName("help_tab") @@ -9297,30 +6365,25 @@ def setupUi(self, SemiAutomaticClassificationPlugin): self.help_textBrowser.setOpenLinks(False) self.help_textBrowser.setObjectName("help_textBrowser") self.gridLayout_263.addWidget(self.help_textBrowser, 1, 0, 1, 1) - self.main_tabWidget.addTab(self.help_tab, icon51, "") + self.main_tabWidget.addTab(self.help_tab, icon36, "") self.gridLayout_301.addWidget(self.splitter, 0, 0, 1, 1) self.retranslateUi(SemiAutomaticClassificationPlugin) self.main_tabWidget.setCurrentIndex(0) self.SCP_tabs.setCurrentIndex(0) self.Band_set_tabWidget.setCurrentIndex(-1) + self.tabWidget_3.setCurrentIndex(0) self.tabWidget_5.setCurrentIndex(0) - self.alg_band_weight_tabWidget.setCurrentIndex(-1) self.toolBox_4.setCurrentIndex(2) - self.tabWidget_3.setCurrentIndex(1) self.tabWidget_preprocessing.setCurrentIndex(0) - self.tabWidget_4.setCurrentIndex(0) + self.tabWidget_4.setCurrentIndex(5) self.toolBox_band_set_combination.setCurrentIndex(0) self.toolBox_PCA.setCurrentIndex(0) - self.toolBox_kmeans.setCurrentIndex(0) - self.toolBox_random_forest.setCurrentIndex(0) + self.toolBox_classification.layout().setSpacing(2) self.tabWidget_2.setCurrentIndex(0) self.toolBox_accuracy.setCurrentIndex(0) - self.toolBox_landCoverChange.setCurrentIndex(0) self.toolBox_class_report.setCurrentIndex(0) self.toolBox_cross_classification.setCurrentIndex(0) - self.toolBox_class_signature.setCurrentIndex(0) - self.band_calc_tabWidget.setCurrentIndex(0) self.settings_tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(SemiAutomaticClassificationPlugin) @@ -9331,54 +6394,38 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): __sortingEnabled = self.menu_treeWidget.isSortingEnabled() self.menu_treeWidget.setSortingEnabled(False) self.menu_treeWidget.topLevelItem(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Band set")) - self.menu_treeWidget.topLevelItem(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Basic tools")) - self.menu_treeWidget.topLevelItem(1).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Algorithm band weight")) - self.menu_treeWidget.topLevelItem(1).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Band set list")) - self.menu_treeWidget.topLevelItem(1).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Export signatures")) - self.menu_treeWidget.topLevelItem(1).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Import signatures")) - self.menu_treeWidget.topLevelItem(1).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "LCS threshold")) - self.menu_treeWidget.topLevelItem(1).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Multiple ROI creation")) - self.menu_treeWidget.topLevelItem(1).child(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "RGB list")) - self.menu_treeWidget.topLevelItem(1).child(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Signature threshold")) - self.menu_treeWidget.topLevelItem(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Download products")) + self.menu_treeWidget.topLevelItem(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Download products")) + self.menu_treeWidget.topLevelItem(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Basic tools")) + self.menu_treeWidget.topLevelItem(2).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Export signatures")) + self.menu_treeWidget.topLevelItem(2).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Import signatures")) + self.menu_treeWidget.topLevelItem(2).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Multiple ROI creation")) + self.menu_treeWidget.topLevelItem(2).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "RGB composite")) + self.menu_treeWidget.topLevelItem(2).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Signature threshold")) self.menu_treeWidget.topLevelItem(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Preprocessing")) - self.menu_treeWidget.topLevelItem(3).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "ASTER")) - self.menu_treeWidget.topLevelItem(3).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "GOES")) - self.menu_treeWidget.topLevelItem(3).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Landsat")) - self.menu_treeWidget.topLevelItem(3).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "MODIS")) - self.menu_treeWidget.topLevelItem(3).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Sentinel-1")) - self.menu_treeWidget.topLevelItem(3).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Sentinel-2")) - self.menu_treeWidget.topLevelItem(3).child(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "Sentinel-3")) - self.menu_treeWidget.topLevelItem(3).child(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Clip multiple rasters")) - self.menu_treeWidget.topLevelItem(3).child(8).setText(0, _translate("SemiAutomaticClassificationPlugin", "Cloud masking")) - self.menu_treeWidget.topLevelItem(3).child(9).setText(0, _translate("SemiAutomaticClassificationPlugin", "Mosaic band sets")) - self.menu_treeWidget.topLevelItem(3).child(10).setText(0, _translate("SemiAutomaticClassificationPlugin", "Neighbor pixels")) - self.menu_treeWidget.topLevelItem(3).child(11).setText(0, _translate("SemiAutomaticClassificationPlugin", "Reproject raster bands")) - self.menu_treeWidget.topLevelItem(3).child(12).setText(0, _translate("SemiAutomaticClassificationPlugin", "Split raster bands")) - self.menu_treeWidget.topLevelItem(3).child(13).setText(0, _translate("SemiAutomaticClassificationPlugin", "Stack raster bands")) - self.menu_treeWidget.topLevelItem(3).child(14).setText(0, _translate("SemiAutomaticClassificationPlugin", "Vector to raster")) + self.menu_treeWidget.topLevelItem(3).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Clip raster bands")) + self.menu_treeWidget.topLevelItem(3).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Image conversion")) + self.menu_treeWidget.topLevelItem(3).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Masking bands")) + self.menu_treeWidget.topLevelItem(3).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Mosaic band sets")) + self.menu_treeWidget.topLevelItem(3).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Reproject raster bands")) + self.menu_treeWidget.topLevelItem(3).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Split raster bands")) + self.menu_treeWidget.topLevelItem(3).child(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "Stack raster bands")) + self.menu_treeWidget.topLevelItem(3).child(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Vector to raster")) self.menu_treeWidget.topLevelItem(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Band processing")) - self.menu_treeWidget.topLevelItem(4).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Band combination")) - self.menu_treeWidget.topLevelItem(4).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification")) - self.menu_treeWidget.topLevelItem(4).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Clustering")) - self.menu_treeWidget.topLevelItem(4).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "PCA")) - self.menu_treeWidget.topLevelItem(4).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Random forest")) - self.menu_treeWidget.topLevelItem(4).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Spectral distance")) + self.menu_treeWidget.topLevelItem(4).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification")) + self.menu_treeWidget.topLevelItem(4).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Combination")) + self.menu_treeWidget.topLevelItem(4).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Dilation")) + self.menu_treeWidget.topLevelItem(4).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Erosion")) + self.menu_treeWidget.topLevelItem(4).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Sieve")) + self.menu_treeWidget.topLevelItem(4).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Neighbor")) + self.menu_treeWidget.topLevelItem(4).child(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "PCA")) self.menu_treeWidget.topLevelItem(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Postprocessing")) self.menu_treeWidget.topLevelItem(5).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Accuracy")) - self.menu_treeWidget.topLevelItem(5).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification dilation")) - self.menu_treeWidget.topLevelItem(5).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification erosion")) - self.menu_treeWidget.topLevelItem(5).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification report")) - self.menu_treeWidget.topLevelItem(5).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification to vector")) - self.menu_treeWidget.topLevelItem(5).child(5).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification sieve")) - self.menu_treeWidget.topLevelItem(5).child(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "Class signature")) - self.menu_treeWidget.topLevelItem(5).child(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Cross classification")) - self.menu_treeWidget.topLevelItem(5).child(8).setText(0, _translate("SemiAutomaticClassificationPlugin", "Edit raster")) - self.menu_treeWidget.topLevelItem(5).child(9).setText(0, _translate("SemiAutomaticClassificationPlugin", "Land cover change")) - self.menu_treeWidget.topLevelItem(5).child(10).setText(0, _translate("SemiAutomaticClassificationPlugin", "Reclassification")) - self.menu_treeWidget.topLevelItem(5).child(11).setText(0, _translate("SemiAutomaticClassificationPlugin", "Zonal stat raster")) + self.menu_treeWidget.topLevelItem(5).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification report")) + self.menu_treeWidget.topLevelItem(5).child(2).setText(0, _translate("SemiAutomaticClassificationPlugin", "Classification to vector")) + self.menu_treeWidget.topLevelItem(5).child(3).setText(0, _translate("SemiAutomaticClassificationPlugin", "Cross classification")) + self.menu_treeWidget.topLevelItem(5).child(4).setText(0, _translate("SemiAutomaticClassificationPlugin", "Reclassification")) self.menu_treeWidget.topLevelItem(6).setText(0, _translate("SemiAutomaticClassificationPlugin", "Band calc")) - self.menu_treeWidget.topLevelItem(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Batch")) + self.menu_treeWidget.topLevelItem(7).setText(0, _translate("SemiAutomaticClassificationPlugin", "Script")) self.menu_treeWidget.topLevelItem(8).setText(0, _translate("SemiAutomaticClassificationPlugin", "Settings")) self.menu_treeWidget.topLevelItem(8).child(0).setText(0, _translate("SemiAutomaticClassificationPlugin", "Debug")) self.menu_treeWidget.topLevelItem(8).child(1).setText(0, _translate("SemiAutomaticClassificationPlugin", "Interface")) @@ -9386,46 +6433,34 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.menu_treeWidget.topLevelItem(9).setText(0, _translate("SemiAutomaticClassificationPlugin", "User manual")) self.menu_treeWidget.topLevelItem(10).setText(0, _translate("SemiAutomaticClassificationPlugin", "Help")) self.menu_treeWidget.topLevelItem(11).setText(0, _translate("SemiAutomaticClassificationPlugin", "About")) - self.menu_treeWidget.topLevelItem(12).setText(0, _translate("SemiAutomaticClassificationPlugin", "Support the SCP")) self.menu_treeWidget.setSortingEnabled(__sortingEnabled) - self.label_59.setText(_translate("SemiAutomaticClassificationPlugin", "Wavelength\n" -"quick settings")) - self.wavelength_sat_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a configuration for setting band center wavelengths

")) - self.label_60.setText(_translate("SemiAutomaticClassificationPlugin", "Wavelength \n" -"unit")) - self.unit_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Wavelength unit

")) - self.export_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export band set to text file

")) - self.export_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.import_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import band set from text file

")) - self.import_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.bandset_dateEdit.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) - self.label_3.setText(_translate("SemiAutomaticClassificationPlugin", "Date")) - self.label_52.setText(_translate("SemiAutomaticClassificationPlugin", " Single band list")) - self.bands_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) - self.bands_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) - item = self.bands_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - self.toolButton_reload_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_3.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.select_all_bands_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all / Unselect all

")) - self.select_all_bands_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.add_raster_bands_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add band to Band set

")) - self.add_raster_bands_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_53.setText(_translate("SemiAutomaticClassificationPlugin", " Band set definition")) - self.remove_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.remove_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.clear_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.clear_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.sort_by_name_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sort bands by name (priority to ending number)

")) - self.sort_by_name_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.move_up_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band up

")) - self.move_up_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.move_down_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band down

")) - self.move_down_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.band_set_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) + self.band_set_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) + item = self.bandset_tableWidget.horizontalHeaderItem(0) + item.setText(_translate("SemiAutomaticClassificationPlugin", "Band set table")) + self.move_up_toolButton_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band sets up

")) + self.move_up_toolButton_4.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.add_band_set_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add a new band set

")) self.add_band_set_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.move_down_toolButton_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band sets down

")) + self.move_down_toolButton_4.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.remove_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Remove selected band sets

")) + self.remove_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.sort_by_date.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sort band sets by date

")) + self.sort_by_date.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.rgb_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Display RGB composite in map of selected band sets

")) + self.rgb_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.label_154.setText(_translate("SemiAutomaticClassificationPlugin", " Band quick settings")) + self.bandset_dateEdit.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) + self.unit_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Wavelength unit

")) + self.label_94.setText(_translate("SemiAutomaticClassificationPlugin", "Wavelength unit")) + self.label_6.setText(_translate("SemiAutomaticClassificationPlugin", "Date")) + self.toolButton_custom_wavelength.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a csv file of wavelength values

")) + self.wavelength_sat_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a configuration for setting band center wavelengths

")) + self.label_150.setText(_translate("SemiAutomaticClassificationPlugin", "Wavelength")) self.virtual_raster_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a virtual raster of active band set

")) - self.virtual_raster_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster of band set")) + self.virtual_raster_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster \n" +"of band set")) self.band_calc_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Calculate expression in Band calc

")) self.band_calc_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Band calc expressions")) self.stack_raster_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a .tif raster stacking the bands of the active band set

")) @@ -9433,16 +6468,164 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): "(stack bands)")) self.overview_raster_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Build band overviews (external pyramids) of active band set for faster visualization

")) self.overview_raster_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Build band overviews")) - self.label_94.setText(_translate("SemiAutomaticClassificationPlugin", " Band set tools")) + self.label_208.setText(_translate("SemiAutomaticClassificationPlugin", " Band set tools")) self.band_set_process_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.band_set_process_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.toolButton_reload.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_39.setText(_translate("SemiAutomaticClassificationPlugin", " Multiband image list")) + self.label_59.setText(_translate("SemiAutomaticClassificationPlugin", " Band set definition")) + self.bandset_number_spinBox.setPrefix(_translate("SemiAutomaticClassificationPlugin", "Active band set ")) + self.label_bandset_date_4.setText(_translate("SemiAutomaticClassificationPlugin", "Date")) + self.bandset_date_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter images

")) + self.label_289.setText(_translate("SemiAutomaticClassificationPlugin", "Root directory")) + self.root_dir_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter images

")) + self.remove_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) + self.remove_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.clear_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) + self.clear_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.import_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import band set from text file

")) + self.import_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.export_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export band set to text file

")) + self.export_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.sort_by_name_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sort bands by name (priority to ending number)

")) + self.sort_by_name_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.toolButton_input_raster.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.image_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a multiband image

")) + self.move_down_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band down

")) + self.move_down_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.add_loaded_bands_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add bands loaded in QGIS

")) + self.add_loaded_bands_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.move_up_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted band up

")) + self.move_up_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_band_set), _translate("SemiAutomaticClassificationPlugin", "Band set")) - self.label_126.setText(_translate("SemiAutomaticClassificationPlugin", "RGB list")) + self.toolButton_OSM.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add OpenStreetMap to the map

")) + self.toolButton_OSM.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.label_205.setText(_translate("SemiAutomaticClassificationPlugin", "

Add OpenStreetMap to the map

")) + self.label_206.setText(_translate("SemiAutomaticClassificationPlugin", "

OpenStreetMap contributors. The cartography is licensed as CC BY-SA. Tile Usage Policy)

")) + self.label_103.setText(_translate("SemiAutomaticClassificationPlugin", " Search parameters")) + self.selectUL_toolButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set area in the map

")) + self.LX_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right X

")) + self.LX_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X (Lon)")) + self.UX_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left X

")) + self.UX_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X (Lon)")) + self.label_105.setText(_translate("SemiAutomaticClassificationPlugin", "LR")) + self.label_107.setText(_translate("SemiAutomaticClassificationPlugin", "UL")) + self.LY_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right Y

")) + self.LY_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y (Lat)")) + self.UY_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left Y

")) + self.UY_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y (Lat)")) + self.show_area_radioButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Show / hide area

")) + self.show_area_radioButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Show")) + self.find_images_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Find images

")) + self.label_35.setText(_translate("SemiAutomaticClassificationPlugin", "Find")) + self.landsat_satellite_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a product

")) + self.dateEdit_from.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) + self.label_110.setText(_translate("SemiAutomaticClassificationPlugin", "Max cloud cover (%)")) + self.dateEdit_to.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) + self.label_112.setText(_translate("SemiAutomaticClassificationPlugin", "to")) + self.label_111.setText(_translate("SemiAutomaticClassificationPlugin", "Date from")) + self.cloud_cover_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Maximum cloud cover percentage

")) + self.label_114.setText(_translate("SemiAutomaticClassificationPlugin", "Products")) + self.label_194.setText(_translate("SemiAutomaticClassificationPlugin", "Results")) + self.label_113.setText(_translate("SemiAutomaticClassificationPlugin", "Advanced search")) + self.imageID_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter images

")) + self.result_number_spinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Maximum number of results (images)

")) + self.remove_image_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) + self.remove_image_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.toolButton_display.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Display preview of highlighted images in map

")) + self.toolButton_display.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.clear_table_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) + self.clear_table_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.export_table_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export table to text file

")) + self.export_table_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.import_table_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import table from text file

")) + self.import_table_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.image_preview_label.setText(_translate("SemiAutomaticClassificationPlugin", "Preview")) + self.download_images_tableWidget.setSortingEnabled(True) + item = self.download_images_tableWidget.horizontalHeaderItem(0) + item.setText(_translate("SemiAutomaticClassificationPlugin", "product")) + item = self.download_images_tableWidget.horizontalHeaderItem(1) + item.setText(_translate("SemiAutomaticClassificationPlugin", "image")) + item = self.download_images_tableWidget.horizontalHeaderItem(2) + item.setText(_translate("SemiAutomaticClassificationPlugin", "product_id")) + item = self.download_images_tableWidget.horizontalHeaderItem(3) + item.setText(_translate("SemiAutomaticClassificationPlugin", "acquisition_date")) + item = self.download_images_tableWidget.horizontalHeaderItem(4) + item.setText(_translate("SemiAutomaticClassificationPlugin", "cloud_cover")) + item = self.download_images_tableWidget.horizontalHeaderItem(5) + item.setText(_translate("SemiAutomaticClassificationPlugin", "zone_path")) + item = self.download_images_tableWidget.horizontalHeaderItem(6) + item.setText(_translate("SemiAutomaticClassificationPlugin", "row")) + item = self.download_images_tableWidget.horizontalHeaderItem(7) + item.setText(_translate("SemiAutomaticClassificationPlugin", "min_lat")) + item = self.download_images_tableWidget.horizontalHeaderItem(8) + item.setText(_translate("SemiAutomaticClassificationPlugin", "min_lon")) + item = self.download_images_tableWidget.horizontalHeaderItem(9) + item.setText(_translate("SemiAutomaticClassificationPlugin", "max_lat")) + item = self.download_images_tableWidget.horizontalHeaderItem(10) + item.setText(_translate("SemiAutomaticClassificationPlugin", "max_lon")) + item = self.download_images_tableWidget.horizontalHeaderItem(11) + item.setText(_translate("SemiAutomaticClassificationPlugin", "collection")) + item = self.download_images_tableWidget.horizontalHeaderItem(12) + item.setText(_translate("SemiAutomaticClassificationPlugin", "size")) + item = self.download_images_tableWidget.horizontalHeaderItem(13) + item.setText(_translate("SemiAutomaticClassificationPlugin", "preview")) + item = self.download_images_tableWidget.horizontalHeaderItem(14) + item.setText(_translate("SemiAutomaticClassificationPlugin", "uid")) + self.label_100.setText(_translate("SemiAutomaticClassificationPlugin", " Product list")) + self.products_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) + self.products_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_search), _translate("SemiAutomaticClassificationPlugin", "Search")) + self.remember_user_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)

")) + self.remember_user_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "remember")) + self.password_earthdata_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Password

")) + self.password_scihub_label_4.setText(_translate("SemiAutomaticClassificationPlugin", "Password")) + self.label_191.setText(_translate("SemiAutomaticClassificationPlugin", "

Login Harmonized Landsat Sentinel-2 (https://urs.earthdata.nasa.gov)

")) + self.user_earthdata_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

User name

")) + self.user_scihub_label_3.setText(_translate("SemiAutomaticClassificationPlugin", "User")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_login), _translate("SemiAutomaticClassificationPlugin", "Login data")) + self.label_258.setText(_translate("SemiAutomaticClassificationPlugin", "

Download

")) + self.load_in_QGIS_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Load images in QGIS after download

")) + self.load_in_QGIS_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Load bands in QGIS")) + self.download_if_preview_in_legend_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Download images from list only if the corresponding previews are loaded in QGIS

")) + self.download_if_preview_in_legend_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Only if preview in Layers")) + self.export_links_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export download links to a text file

")) + self.export_links_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.virtual_download_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)

")) + self.virtual_download_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual download")) + self.preprocess_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Preprocess images

")) + self.preprocess_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Preprocess images")) + self.download_images_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.download_images_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.checkBoxs_band_1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_1.setText(_translate("SemiAutomaticClassificationPlugin", "1")) + self.checkBoxs_band_8A.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sentinel

")) + self.checkBoxs_band_8A.setText(_translate("SemiAutomaticClassificationPlugin", "8A")) + self.checkBoxs_band_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_4.setText(_translate("SemiAutomaticClassificationPlugin", "4")) + self.checkBoxs_band_11.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_11.setText(_translate("SemiAutomaticClassificationPlugin", "11")) + self.checkBoxs_band_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_5.setText(_translate("SemiAutomaticClassificationPlugin", "5")) + self.checkBoxs_band_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_6.setText(_translate("SemiAutomaticClassificationPlugin", "6")) + self.checkBoxs_band_7.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_7.setText(_translate("SemiAutomaticClassificationPlugin", "7")) + self.checkBoxs_band_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "2")) + self.checkBoxs_band_9.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_9.setText(_translate("SemiAutomaticClassificationPlugin", "9")) + self.check_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all

")) + self.check_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.ancillary_data_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Ancillary data")) + self.checkBoxs_band_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "3")) + self.checkBoxs_band_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_8.setText(_translate("SemiAutomaticClassificationPlugin", "8")) + self.checkBoxs_band_10.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Landsat / Sentinel

")) + self.checkBoxs_band_10.setText(_translate("SemiAutomaticClassificationPlugin", "10")) + self.checkBoxs_band_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sentinel

")) + self.checkBoxs_band_12.setText(_translate("SemiAutomaticClassificationPlugin", "12")) + self.label_3.setText(_translate("SemiAutomaticClassificationPlugin", "Bands")) + self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_download_products), _translate("SemiAutomaticClassificationPlugin", "Download products")) + self.label_126.setText(_translate("SemiAutomaticClassificationPlugin", "RGB composite")) self.sort_by_name_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sort RGB automatically

")) self.sort_by_name_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.move_down_toolButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted RGB down

")) @@ -9465,42 +6648,7 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_192.setText(_translate("SemiAutomaticClassificationPlugin", "Band combinations")) self.all_RGB_list_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add all combinations of bands

")) self.all_RGB_list_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_RGB), _translate("SemiAutomaticClassificationPlugin", "RGB list")) - self.label_208.setText(_translate("SemiAutomaticClassificationPlugin", "Band set list")) - self.band_set_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) - self.band_set_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) - item = self.band_set_list_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Number")) - item = self.band_set_list_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Bands")) - item = self.band_set_list_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Date")) - self.move_down_toolButton_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted Band sets down

")) - self.move_down_toolButton_4.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.move_up_toolButton_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted Band sets up

")) - self.move_up_toolButton_4.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.rgb_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add row

")) - self.rgb_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.add_bandset_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add row

")) - self.add_bandset_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.export_bandset_List_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export Band set list to file

")) - self.export_bandset_List_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.import_bandset_List_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import Band set list from file

")) - self.import_bandset_List_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.remove_bandset_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.remove_bandset_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.sort_by_date.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sort band sets by date

")) - self.sort_by_date.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_band_set_list), _translate("SemiAutomaticClassificationPlugin", "Band set list")) - self.label_79.setText(_translate("SemiAutomaticClassificationPlugin", "Algorithm band weight")) - self.reset_weights_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

\n" -"")) - self.set_weight_value_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set

\n" -"")) - self.label_131.setText(_translate("SemiAutomaticClassificationPlugin", "Set weight")) - self.weight_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value

")) - self.label_93.setText(_translate("SemiAutomaticClassificationPlugin", "Automatic weight")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_algorithm_weight), _translate("SemiAutomaticClassificationPlugin", "Algorithm band weight")) + self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_RGB), _translate("SemiAutomaticClassificationPlugin", "RGB composite")) self.point_distance_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Minimum distance between points

")) self.point_grid_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size of a grid cell within points are created randomly

")) self.label_48.setText(_translate("SemiAutomaticClassificationPlugin", " Create random points")) @@ -9563,14 +6711,11 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.USGS_library_textBrowser.setHtml(_translate("SemiAutomaticClassificationPlugin", "\n" "\n" +"\n" "


")) self.label.setText(_translate("SemiAutomaticClassificationPlugin", "

USGS Spectral Library Version 7 downloaded from https://crustal.usgs.gov/speclab/QueryAll07a.php.
Reference: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.

")) self.label_129.setText(_translate("SemiAutomaticClassificationPlugin", " Library Description (requires internet connection)")) self.toolBox_4.setItemText(self.toolBox_4.indexOf(self.page_8), _translate("SemiAutomaticClassificationPlugin", "Download USGS Spectral Library")) - self.label_9.setText(_translate("SemiAutomaticClassificationPlugin", "

Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)

")) - self.open_library_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.toolBox_4.setItemText(self.toolBox_4.indexOf(self.page_6), _translate("SemiAutomaticClassificationPlugin", "Import library file")) self.open_shapefile_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) self.label_120.setText(_translate("SemiAutomaticClassificationPlugin", "

Select a vector (*.shp;*.gpkg)

")) self.C_ID_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

C ID field

")) @@ -9582,580 +6727,204 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.MC_ID_combo_2.setText(_translate("SemiAutomaticClassificationPlugin", "C ID field")) self.label_121.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID field")) self.label_122.setText(_translate("SemiAutomaticClassificationPlugin", "MC Name field")) - self.label_2.setText(_translate("SemiAutomaticClassificationPlugin", " Import vector")) - self.signature_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add ROI spectral signature to signature list

")) - self.signature_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate sig.")) - self.import_shapefile_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import vector

")) - self.import_shapefile_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.toolBox_4.setItemText(self.toolBox_4.indexOf(self.page_9), _translate("SemiAutomaticClassificationPlugin", "Import vector")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_Import), _translate("SemiAutomaticClassificationPlugin", "Import signatures")) - self.label_97.setText(_translate("SemiAutomaticClassificationPlugin", "

Export as SCP file (*.scp)

")) - self.export_SCP_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export highlighted spectral signatures

\n" -"")) - self.export_CSV_library_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory where highlighted spectral signatures are saved as .csv

")) - self.export_CSV_library_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.label_96.setText(_translate("SemiAutomaticClassificationPlugin", "Export ")) - self.label_222.setText(_translate("SemiAutomaticClassificationPlugin", "

Export as shapefile (*.shp) or geopackage (*.gpkg)

")) - self.label_20.setText(_translate("SemiAutomaticClassificationPlugin", "

Export as CSV file (.csv)

")) - self.export_SHP_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export highlighted spectral signatures

\n" -"")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_export), _translate("SemiAutomaticClassificationPlugin", "Export signatures")) - self.reset_threshold_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

\n" -"")) - self.signature_threshold_tableWidget.setSortingEnabled(True) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "MC Name")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "C ID")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(3) - item.setText(_translate("SemiAutomaticClassificationPlugin", "C Name")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(4) - item.setText(_translate("SemiAutomaticClassificationPlugin", "MD Threshold")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(5) - item.setText(_translate("SemiAutomaticClassificationPlugin", "ML Threshold")) - item = self.signature_threshold_tableWidget.horizontalHeaderItem(6) - item.setText(_translate("SemiAutomaticClassificationPlugin", "SAM Threshold")) - self.label_80.setText(_translate("SemiAutomaticClassificationPlugin", " Signature threshold")) - self.label_85.setText(_translate("SemiAutomaticClassificationPlugin", "Set threshold = σ *")) - self.multiplicative_threshold_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value that will be multiplied by standard deviation

")) - self.automatic_threshold_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set automatic threshold σ

")) - self.label_132.setText(_translate("SemiAutomaticClassificationPlugin", "Set threshold")) - self.threshold_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value

")) - self.set_threshold_value_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set

\n" -"")) - self.label_88.setText(_translate("SemiAutomaticClassificationPlugin", " Automatic thresholds")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_threshold), _translate("SemiAutomaticClassificationPlugin", "Signature threshold")) - self.LCS_tableWidget.setSortingEnabled(True) - item = self.LCS_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID")) - item = self.LCS_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "MC Name")) - item = self.LCS_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "C ID")) - item = self.LCS_tableWidget.horizontalHeaderItem(3) - item.setText(_translate("SemiAutomaticClassificationPlugin", "C Name")) - item = self.LCS_tableWidget.horizontalHeaderItem(4) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Color [overlap MC_ID-C_ID]")) - self.label_86.setText(_translate("SemiAutomaticClassificationPlugin", " LC Signature threshold")) - self.signature_spectral_plot_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add highlighted signatures to spectral signature plot

")) - self.signature_spectral_plot_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_102.setText(_translate("SemiAutomaticClassificationPlugin", "Min Max")) - self.set_min_max_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set automatic threshold Min Max

")) - self.label_101.setText(_translate("SemiAutomaticClassificationPlugin", "σ *")) - self.multiplicative_threshold_doubleSpinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value that will be multiplied by standard deviation

")) - self.automatic_threshold_pushButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set automatic threshold σ

")) - self.label_89.setText(_translate("SemiAutomaticClassificationPlugin", "From pixel")) - self.LCS_pointerButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Activate pointer for setting thresholds from pixel

")) - self.LCS_include_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, signature threshold is extended to include pixel signature

")) - self.LCS_cut_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, signature threshold is reduced to exclude pixel signature

")) - self.label_178.setText(_translate("SemiAutomaticClassificationPlugin", "From ROI")) - self.LCS_ROI_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set thresholds from temporary ROI

")) - self.label_125.setText(_translate("SemiAutomaticClassificationPlugin", "Automatic thresholds")) - self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_LCS_threshold), _translate("SemiAutomaticClassificationPlugin", "LCS threshold")) - self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_basic_tools), _translate("SemiAutomaticClassificationPlugin", "Basic tools")) - self.remember_user_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, remember user name and password locally in QGIS

")) - self.remember_user_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "remember")) - self.password_usgs_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Password

")) - self.password_scihub_label_3.setText(_translate("SemiAutomaticClassificationPlugin", "Password")) - self.label_180.setText(_translate("SemiAutomaticClassificationPlugin", "

Login Landsat (https://ers.cr.usgs.gov)

")) - self.user_usgs_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

User name

")) - self.user_scihub_label_2.setText(_translate("SemiAutomaticClassificationPlugin", "User")) - self.remember_user_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, remember user name and password locally in QGIS

")) - self.remember_user_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "remember")) - self.password_usgs_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Password

")) - self.password_scihub_label_4.setText(_translate("SemiAutomaticClassificationPlugin", "Password")) - self.label_191.setText(_translate("SemiAutomaticClassificationPlugin", "

Login ASTER and MODIS (https://urs.earthdata.nasa.gov)

")) - self.user_usgs_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

User name

")) - self.user_scihub_label_3.setText(_translate("SemiAutomaticClassificationPlugin", "User")) - self.user_scihub_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

User name

")) - self.password_scihub_label.setText(_translate("SemiAutomaticClassificationPlugin", "Password")) - self.label_147.setText(_translate("SemiAutomaticClassificationPlugin", "

Login Sentinels

")) - self.remember_user_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, remember user name and password locally in QGIS

")) - self.remember_user_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "remember")) - self.user_scihub_label.setText(_translate("SemiAutomaticClassificationPlugin", "User")) - self.password_scihub_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Password

")) - self.password_scihub_label_2.setText(_translate("SemiAutomaticClassificationPlugin", "Service")) - self.sentinel_service_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Service

")) - self.reset_sentinel_service_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.reset_sentinel_service_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.sentinel2_alternative_search_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use alternative search for Sentinel-2 (no authentication required)

")) - self.sentinel2_alternative_search_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use alternative search for Sentinel-2 (no authentication required)")) - self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_login), _translate("SemiAutomaticClassificationPlugin", "Login data")) - self.remove_image_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.remove_image_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.toolButton_display.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Display preview of highlighted images in map

")) - self.toolButton_display.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.clear_table_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.clear_table_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.export_table_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export table to text file

")) - self.export_table_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.import_table_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import table from text file

")) - self.import_table_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.image_preview_label.setText(_translate("SemiAutomaticClassificationPlugin", "Preview")) - self.download_images_tableWidget.setSortingEnabled(True) - item = self.download_images_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Product")) - item = self.download_images_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "ProductID")) - item = self.download_images_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "AcquisitionDate")) - item = self.download_images_tableWidget.horizontalHeaderItem(3) - item.setText(_translate("SemiAutomaticClassificationPlugin", "CloudCover")) - item = self.download_images_tableWidget.horizontalHeaderItem(4) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Zone/Path")) - item = self.download_images_tableWidget.horizontalHeaderItem(5) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Row/DayNight")) - item = self.download_images_tableWidget.horizontalHeaderItem(6) - item.setText(_translate("SemiAutomaticClassificationPlugin", "min_lat")) - item = self.download_images_tableWidget.horizontalHeaderItem(7) - item.setText(_translate("SemiAutomaticClassificationPlugin", "min_lon")) - item = self.download_images_tableWidget.horizontalHeaderItem(8) - item.setText(_translate("SemiAutomaticClassificationPlugin", "max_lat")) - item = self.download_images_tableWidget.horizontalHeaderItem(9) - item.setText(_translate("SemiAutomaticClassificationPlugin", "max_lon")) - item = self.download_images_tableWidget.horizontalHeaderItem(10) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Collection/Size")) - item = self.download_images_tableWidget.horizontalHeaderItem(11) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Preview")) - item = self.download_images_tableWidget.horizontalHeaderItem(12) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Collection/ID")) - item = self.download_images_tableWidget.horizontalHeaderItem(13) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Collection/Image")) - self.label_100.setText(_translate("SemiAutomaticClassificationPlugin", " Product list")) - self.products_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) - self.products_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) - self.toolButton_OSM.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add OpenStreetMap to the map

")) - self.toolButton_OSM.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_205.setText(_translate("SemiAutomaticClassificationPlugin", "

Add OpenStreetMap to the map

")) - self.label_206.setText(_translate("SemiAutomaticClassificationPlugin", "

OpenStreetMap contributors. The cartography is licensed as CC BY-SA. Tile Usage Policy)

")) - self.label_103.setText(_translate("SemiAutomaticClassificationPlugin", " Search parameters")) - self.selectUL_toolButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set area in the map

")) - self.LX_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right X

")) - self.LX_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X (Lon)")) - self.UX_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left X

")) - self.UX_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X (Lon)")) - self.label_105.setText(_translate("SemiAutomaticClassificationPlugin", "LR")) - self.label_107.setText(_translate("SemiAutomaticClassificationPlugin", "UL")) - self.LY_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right Y

")) - self.LY_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y (Lat)")) - self.UY_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left Y

")) - self.UY_lineEdit_3.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y (Lat)")) - self.show_area_radioButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Show / hide area

")) - self.show_area_radioButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Show")) - self.find_images_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Find images

")) - self.label_35.setText(_translate("SemiAutomaticClassificationPlugin", "Find")) - self.landsat_satellite_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a product

")) - self.dateEdit_from.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) - self.label_110.setText(_translate("SemiAutomaticClassificationPlugin", "Max cloud cover (%)")) - self.dateEdit_to.setDisplayFormat(_translate("SemiAutomaticClassificationPlugin", "yyyy-MM-dd")) - self.label_112.setText(_translate("SemiAutomaticClassificationPlugin", "to")) - self.label_111.setText(_translate("SemiAutomaticClassificationPlugin", "Date from")) - self.cloud_cover_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Maximum cloud cover percentage

")) - self.label_114.setText(_translate("SemiAutomaticClassificationPlugin", "Products")) - self.label_194.setText(_translate("SemiAutomaticClassificationPlugin", "Results")) - self.label_113.setText(_translate("SemiAutomaticClassificationPlugin", "Advanced search")) - self.imageID_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter images

")) - self.result_number_spinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Maximum number of results (images)

")) - self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_search), _translate("SemiAutomaticClassificationPlugin", "Search")) - self.checkBox_band_6.setText(_translate("SemiAutomaticClassificationPlugin", "6 (Landsat 1-8)")) - self.checkBox_band_4.setText(_translate("SemiAutomaticClassificationPlugin", "4 (Landsat 1-8)")) - self.checkBox_band_1.setText(_translate("SemiAutomaticClassificationPlugin", "1 (Landsat 4-8)")) - self.checkBox_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "3 (Landsat 4-8)")) - self.checkBox_band_12.setText(_translate("SemiAutomaticClassificationPlugin", "Ancillary data")) - self.checkBox_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "2 (Landsat 4-8)")) - self.checkBox_band_11.setText(_translate("SemiAutomaticClassificationPlugin", "11 (Landsat 8)")) - self.checkBox_band_5.setText(_translate("SemiAutomaticClassificationPlugin", "5 (Landsat 1-8)")) - self.check_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all

")) - self.check_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_108.setText(_translate("SemiAutomaticClassificationPlugin", " Landsat bands")) - self.checkBoxs_band_9.setText(_translate("SemiAutomaticClassificationPlugin", "8A")) - self.checkBoxs_band_1.setText(_translate("SemiAutomaticClassificationPlugin", "1")) - self.check_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all

")) - self.check_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_118.setText(_translate("SemiAutomaticClassificationPlugin", " Sentinel-2 bands")) - self.checkBoxs_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "2")) - self.checkBoxs_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "3")) - self.checkBoxs_band_4.setText(_translate("SemiAutomaticClassificationPlugin", "4")) - self.checkBoxs_band_5.setText(_translate("SemiAutomaticClassificationPlugin", "5")) - self.checkBoxs_band_6.setText(_translate("SemiAutomaticClassificationPlugin", "6")) - self.checkBoxs_band_7.setText(_translate("SemiAutomaticClassificationPlugin", "7")) - self.checkBoxs_band_12.setText(_translate("SemiAutomaticClassificationPlugin", "11")) - self.checkBoxs_band_8.setText(_translate("SemiAutomaticClassificationPlugin", "8")) - self.checkBoxs_band_10.setText(_translate("SemiAutomaticClassificationPlugin", "9")) - self.ancillary_data_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Ancillary data")) - self.checkBoxs_band_13.setText(_translate("SemiAutomaticClassificationPlugin", "12")) - self.checkBoxs_band_11.setText(_translate("SemiAutomaticClassificationPlugin", "10")) - self.checkBoxs3_band_6.setText(_translate("SemiAutomaticClassificationPlugin", "6")) - self.checkBoxs3_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "2")) - self.checkBoxs3_band_5.setText(_translate("SemiAutomaticClassificationPlugin", "5")) - self.checkBoxs3_band_8.setText(_translate("SemiAutomaticClassificationPlugin", "8")) - self.checkBoxs3_band_1.setText(_translate("SemiAutomaticClassificationPlugin", "1")) - self.checkBoxs3_band_16.setText(_translate("SemiAutomaticClassificationPlugin", "16")) - self.checkBoxs3_band_10.setText(_translate("SemiAutomaticClassificationPlugin", "10")) - self.checkBoxs3_band_12.setText(_translate("SemiAutomaticClassificationPlugin", "12")) - self.s3_ancillary_data_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Ancillary data")) - self.checkBoxs3_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "3")) - self.label_127.setText(_translate("SemiAutomaticClassificationPlugin", " Sentinel-3 bands")) - self.checkBoxs3_band_20.setText(_translate("SemiAutomaticClassificationPlugin", "20")) - self.checkBoxs3_band_17.setText(_translate("SemiAutomaticClassificationPlugin", "17")) - self.checkBoxs3_band_14.setText(_translate("SemiAutomaticClassificationPlugin", "14")) - self.checkBoxs3_band_9.setText(_translate("SemiAutomaticClassificationPlugin", "9")) - self.checkBoxs3_band_13.setText(_translate("SemiAutomaticClassificationPlugin", "13")) - self.checkBoxs3_band_19.setText(_translate("SemiAutomaticClassificationPlugin", "19")) - self.check_toolButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all

")) - self.check_toolButton_3.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.checkBoxs3_band_7.setText(_translate("SemiAutomaticClassificationPlugin", "7")) - self.checkBoxs3_band_4.setText(_translate("SemiAutomaticClassificationPlugin", "4")) - self.checkBoxs3_band_11.setText(_translate("SemiAutomaticClassificationPlugin", "11")) - self.checkBoxs3_band_15.setText(_translate("SemiAutomaticClassificationPlugin", "15")) - self.checkBoxs3_band_21.setText(_translate("SemiAutomaticClassificationPlugin", "21")) - self.checkBoxs3_band_18.setText(_translate("SemiAutomaticClassificationPlugin", "18")) - self.checkBoxs_goes_band_1.setText(_translate("SemiAutomaticClassificationPlugin", "1")) - self.label_272.setText(_translate("SemiAutomaticClassificationPlugin", " GOES bands")) - self.checkBoxs_goes_band_5.setText(_translate("SemiAutomaticClassificationPlugin", "5")) - self.checkBoxs_goes_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "3")) - self.checkBoxs_goes_band_4.setText(_translate("SemiAutomaticClassificationPlugin", "4")) - self.checkBoxs_goes_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "2")) - self.checkBoxs_goes_band_6.setText(_translate("SemiAutomaticClassificationPlugin", "6")) - self.check_toolButton_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select all

")) - self.check_toolButton_4.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.checkBox_band_8.setText(_translate("SemiAutomaticClassificationPlugin", "8 (Landsat 7, 8)")) - self.checkBox_band_10.setText(_translate("SemiAutomaticClassificationPlugin", "10 (Landsat 8)")) - self.checkBox_band_9.setText(_translate("SemiAutomaticClassificationPlugin", "9 (Landsat 8)")) - self.checkBox_band_7.setText(_translate("SemiAutomaticClassificationPlugin", "7 (Landsat 1-8)")) - self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_options), _translate("SemiAutomaticClassificationPlugin", "Download options")) - self.label_258.setText(_translate("SemiAutomaticClassificationPlugin", "

Download

")) - self.preprocess_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Preprocess images

")) - self.preprocess_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Preprocess images")) - self.load_in_QGIS_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Load images in QGIS after download

")) - self.load_in_QGIS_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Load bands in QGIS")) - self.download_if_preview_in_legend_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Download images from list only if the corresponding previews are loaded in QGIS

")) - self.download_if_preview_in_legend_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Only if preview in Layers")) - self.export_links_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export download links to a text file

")) - self.export_links_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.download_images_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.download_images_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.virtual_download_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)

")) - self.virtual_download_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual download")) - self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_download_products), _translate("SemiAutomaticClassificationPlugin", "Download products")) - self.label_36.setText(_translate("SemiAutomaticClassificationPlugin", "Directory containing Landsat bands")) - self.label_37.setText(_translate("SemiAutomaticClassificationPlugin", " Landsat conversion to TOA reflectance and brightness temperature")) - self.celsius_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable calculation of temperature in Celsius from thermal band

")) - self.celsius_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", " Brightness temperature in Celsius")) - self.DOS1_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)

")) - self.DOS1_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", " Apply DOS1 atmospheric correction")) - self.nodata_spinBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.nodata_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) + self.label_2.setText(_translate("SemiAutomaticClassificationPlugin", " Import vector")) + self.signature_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add ROI spectral signature to signature list

")) + self.signature_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate sig.")) + self.import_shapefile_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import vector

")) + self.import_shapefile_pushButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.toolBox_4.setItemText(self.toolBox_4.indexOf(self.page_9), _translate("SemiAutomaticClassificationPlugin", "Import vector")) + self.label_9.setText(_translate("SemiAutomaticClassificationPlugin", "

Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)

")) + self.open_library_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) + self.toolBox_4.setItemText(self.toolBox_4.indexOf(self.page_6), _translate("SemiAutomaticClassificationPlugin", "Import library file")) + self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_Import), _translate("SemiAutomaticClassificationPlugin", "Import signatures")) + self.label_97.setText(_translate("SemiAutomaticClassificationPlugin", "

Export as training file (*.scpx)

")) + self.export_SCP_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export highlighted spectral signatures

\n" +"")) + self.export_CSV_library_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory where highlighted spectral signatures are saved as .csv

")) + self.export_CSV_library_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.label_96.setText(_translate("SemiAutomaticClassificationPlugin", "Export ")) + self.label_222.setText(_translate("SemiAutomaticClassificationPlugin", "

Export geometries as shapefile (*.shp) or geopackage (*.gpkg)

")) + self.label_20.setText(_translate("SemiAutomaticClassificationPlugin", "

Export spectral signatures as CSV file (.csv)

")) + self.export_SHP_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export highlighted spectral signatures

\n" +"")) + self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_export), _translate("SemiAutomaticClassificationPlugin", "Export signatures")) + self.reset_threshold_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

\n" +"")) + self.signature_threshold_tableWidget.setSortingEnabled(True) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(0) + item.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(1) + item.setText(_translate("SemiAutomaticClassificationPlugin", "MC Name")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(2) + item.setText(_translate("SemiAutomaticClassificationPlugin", "C ID")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(3) + item.setText(_translate("SemiAutomaticClassificationPlugin", "C Name")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(4) + item.setText(_translate("SemiAutomaticClassificationPlugin", "Minimum Distance")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(5) + item.setText(_translate("SemiAutomaticClassificationPlugin", "Maximum Likelihood")) + item = self.signature_threshold_tableWidget.horizontalHeaderItem(6) + item.setText(_translate("SemiAutomaticClassificationPlugin", "Spectral Angle Mapping")) + self.label_80.setText(_translate("SemiAutomaticClassificationPlugin", " Signature threshold")) + self.label_85.setText(_translate("SemiAutomaticClassificationPlugin", "Set threshold = σ *")) + self.multiplicative_threshold_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value that will be multiplied by standard deviation

")) + self.automatic_threshold_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set automatic threshold σ

")) + self.label_132.setText(_translate("SemiAutomaticClassificationPlugin", "Set threshold")) + self.threshold_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a value

")) + self.set_threshold_value_pushButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set

\n" +"")) + self.label_88.setText(_translate("SemiAutomaticClassificationPlugin", " Automatic thresholds")) + self.tabWidget_5.setTabText(self.tabWidget_5.indexOf(self.tab_threshold), _translate("SemiAutomaticClassificationPlugin", "Signature threshold")) + self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_basic_tools), _translate("SemiAutomaticClassificationPlugin", "Basic tools")) + self.label_36.setText(_translate("SemiAutomaticClassificationPlugin", "Directory containing bands")) + self.label_37.setText(_translate("SemiAutomaticClassificationPlugin", "Conversion to reflectance and temperature")) self.label_41.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select MTL file (if not in Landsat directory)

")) - self.label_41.setText(_translate("SemiAutomaticClassificationPlugin", "Select MTL file")) + self.label_41.setText(_translate("SemiAutomaticClassificationPlugin", "Select metadata file (optional)")) self.toolButton_directoryInput.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory

")) self.toolButton_directoryInput.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.pansharpening_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Perform pan-sharpening (Brovey Transform)

")) - self.pansharpening_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Perform pansharpening (Landsat 7 or 8)")) self.create_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) self.create_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.add_new_bandset_checkBox_1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_1.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) + self.DOS1_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)

")) + self.DOS1_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", " Apply DOS1 atmospheric correction")) + self.add_new_bandset_radioButton_1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) + self.add_new_bandset_radioButton_1.setText(_translate("SemiAutomaticClassificationPlugin", "Create a new Band set")) self.toolButton_directoryInput_MTL.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.landsat_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.landsat_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - item = self.landsat_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "RADIANCE_MULT")) - item = self.landsat_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "RADIANCE_ADD")) - item = self.landsat_tableWidget.horizontalHeaderItem(3) - item.setText(_translate("SemiAutomaticClassificationPlugin", "REFLECTANCE_MULT")) - item = self.landsat_tableWidget.horizontalHeaderItem(4) - item.setText(_translate("SemiAutomaticClassificationPlugin", "REFLECTANCE_ADD")) - item = self.landsat_tableWidget.horizontalHeaderItem(5) - item.setText(_translate("SemiAutomaticClassificationPlugin", "RADIANCE_MAXIMUM")) - item = self.landsat_tableWidget.horizontalHeaderItem(6) - item.setText(_translate("SemiAutomaticClassificationPlugin", "REFLECTANCE_MAXIMUM")) - item = self.landsat_tableWidget.horizontalHeaderItem(7) - item.setText(_translate("SemiAutomaticClassificationPlugin", "K1_CONSTANT")) - item = self.landsat_tableWidget.horizontalHeaderItem(8) - item.setText(_translate("SemiAutomaticClassificationPlugin", "K2_CONSTANT")) - item = self.landsat_tableWidget.horizontalHeaderItem(9) - item.setText(_translate("SemiAutomaticClassificationPlugin", "LMAX")) - item = self.landsat_tableWidget.horizontalHeaderItem(10) - item.setText(_translate("SemiAutomaticClassificationPlugin", "LMIN")) - item = self.landsat_tableWidget.horizontalHeaderItem(11) - item.setText(_translate("SemiAutomaticClassificationPlugin", "QCALMAX")) - item = self.landsat_tableWidget.horizontalHeaderItem(12) - item.setText(_translate("SemiAutomaticClassificationPlugin", "QCALMIN")) + self.nodata_spinBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) + self.nodata_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) + self.nodata_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) + self.bands_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) + item = self.bands_tableWidget.horizontalHeaderItem(0) + item.setText(_translate("SemiAutomaticClassificationPlugin", "product")) + item = self.bands_tableWidget.horizontalHeaderItem(1) + item.setText(_translate("SemiAutomaticClassificationPlugin", "spacecraft")) + item = self.bands_tableWidget.horizontalHeaderItem(2) + item.setText(_translate("SemiAutomaticClassificationPlugin", "processing_level")) + item = self.bands_tableWidget.horizontalHeaderItem(3) + item.setText(_translate("SemiAutomaticClassificationPlugin", "band_name")) + item = self.bands_tableWidget.horizontalHeaderItem(4) + item.setText(_translate("SemiAutomaticClassificationPlugin", "product_path")) + item = self.bands_tableWidget.horizontalHeaderItem(5) + item.setText(_translate("SemiAutomaticClassificationPlugin", "scale")) + item = self.bands_tableWidget.horizontalHeaderItem(6) + item.setText(_translate("SemiAutomaticClassificationPlugin", "offset")) + item = self.bands_tableWidget.horizontalHeaderItem(7) + item.setText(_translate("SemiAutomaticClassificationPlugin", "nodata")) + item = self.bands_tableWidget.horizontalHeaderItem(8) + item.setText(_translate("SemiAutomaticClassificationPlugin", "date")) + item = self.bands_tableWidget.horizontalHeaderItem(9) + item.setText(_translate("SemiAutomaticClassificationPlugin", "k1")) + item = self.bands_tableWidget.horizontalHeaderItem(10) + item.setText(_translate("SemiAutomaticClassificationPlugin", "k2")) + item = self.bands_tableWidget.horizontalHeaderItem(11) + item.setText(_translate("SemiAutomaticClassificationPlugin", "band_number")) + item = self.bands_tableWidget.horizontalHeaderItem(12) + item.setText(_translate("SemiAutomaticClassificationPlugin", "e_sun")) + item = self.bands_tableWidget.horizontalHeaderItem(13) + item.setText(_translate("SemiAutomaticClassificationPlugin", "sun_elevation")) + item = self.bands_tableWidget.horizontalHeaderItem(14) + item.setText(_translate("SemiAutomaticClassificationPlugin", "earth_sun_distance")) self.pushButton_remove_band.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) self.pushButton_remove_band.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.satellite_label.setText(_translate("SemiAutomaticClassificationPlugin", "Satellite")) - self.satellite_label_3.setText(_translate("SemiAutomaticClassificationPlugin", "Sun elevation")) - self.date_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

DATE ACQUIRED

")) - self.satellite_label_2.setText(_translate("SemiAutomaticClassificationPlugin", "Date (YYYY-MM-DD)")) - self.satellite_label_4.setText(_translate("SemiAutomaticClassificationPlugin", "Earth sun distance")) - self.sun_elev_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

SUN ELEVATION

")) - self.earth_sun_dist_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Earth sun distance

")) self.label_74.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.satellite_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. LANDSAT8)

")) self.label_161.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.pushButton_Conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.pushButton_Conversion.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.landsat_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.landsat_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_Landsat), _translate("SemiAutomaticClassificationPlugin", "Landsat")) - self.S1_label_95.setText(_translate("SemiAutomaticClassificationPlugin", "Select SNAP xml graph (optional)")) - self.S1_toolButton_directoryInput_xml.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.S1_label_97.setText(_translate("SemiAutomaticClassificationPlugin", "Polarization")) - self.VH_checkBox_S1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select VH polarization

")) - self.VH_checkBox_S1.setText(_translate("SemiAutomaticClassificationPlugin", "VH")) - self.VV_checkBox_S1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select VV polarization

")) - self.VV_checkBox_S1.setText(_translate("SemiAutomaticClassificationPlugin", "VV")) - self.label_209.setText(_translate("SemiAutomaticClassificationPlugin", " Sentinel-1 conversion (ESA SNAP software required)")) - self.S1_create_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.S1_create_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.add_new_bandset_checkBox_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_6.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.S1_toolButton_fileInput.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.label_207.setText(_translate("SemiAutomaticClassificationPlugin", "Sentinel-1 file")) - self.projection_checkBox_S1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, project the output to the same projection as selected Band set

")) - self.projection_checkBox_S1.setText(_translate("SemiAutomaticClassificationPlugin", "Raster projection as Band set")) - self.band_set_comb_spinBox_11.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.convert_to_db_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, convert to dB

")) - self.convert_to_db_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", " convert to dB")) - self.S1_nodata_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.S1_nodata_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.S1_nodata_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.label_210.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_6.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.sentinel1_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.sentinel1_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_Sentinel1), _translate("SemiAutomaticClassificationPlugin", "Sentinel-1")) - self.label_90.setText(_translate("SemiAutomaticClassificationPlugin", "Directory containing Sentinel-2 bands")) - self.S2_toolButton_directoryInput.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory

")) - self.S2_toolButton_directoryInput.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.DOS1_checkBox_S2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the DOS1 atmospheric correction

")) - self.DOS1_checkBox_S2.setText(_translate("SemiAutomaticClassificationPlugin", " Apply DOS1 atmospheric correction")) - self.S2_nodata_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.S2_nodata_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.S2_nodata_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.label_91.setText(_translate("SemiAutomaticClassificationPlugin", " Sentinel-2 conversion")) - self.S2_label_93.setText(_translate("SemiAutomaticClassificationPlugin", "Select metadata file (MTD_MSI)")) - self.S2_toolButton_directoryInput_xml2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.S2_create_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.S2_create_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.add_new_bandset_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.preprocess_b_1_9_10_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.preprocess_b_1_9_10_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Preprocess bands 1, 9, 10")) - self.S2_satellite_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. Sentinel-2A)

")) - self.satellite_label_5.setText(_translate("SemiAutomaticClassificationPlugin", "Satellite")) - self.satellite_label_6.setText(_translate("SemiAutomaticClassificationPlugin", "Product")) - self.S2_product_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. Sentinel-2A)

")) - self.label_92.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.date_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

DATE ACQUIRED

")) - self.satellite_label_15.setText(_translate("SemiAutomaticClassificationPlugin", "Date (YYYY-MM-DD)")) - self.sentinel_2_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.sentinel_2_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - item = self.sentinel_2_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Quantification value")) - item = self.sentinel_2_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Solar irradiance")) - self.S2_pushButton_remove_band.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.S2_pushButton_remove_band.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_162.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_2.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.sentinel2_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.sentinel2_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_Sentinel2), _translate("SemiAutomaticClassificationPlugin", "Sentinel-2")) - self.S2_nodata_spinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.S3_nodata_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.S3_nodata_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.label_109.setText(_translate("SemiAutomaticClassificationPlugin", " Sentinel-3 conversion")) - self.S3_create_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.S3_create_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.label_106.setText(_translate("SemiAutomaticClassificationPlugin", "Directory containing Sentinel-3 bands")) - self.S3_toolButton_directoryInput.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory

")) - self.S3_toolButton_directoryInput.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.DOS1_checkBox_S3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the DOS1 atmospheric correction

")) - self.DOS1_checkBox_S3.setText(_translate("SemiAutomaticClassificationPlugin", " Apply DOS1 atmospheric correction")) - self.add_new_bandset_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.sentinel_3_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.sentinel_3_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - self.S3_pushButton_remove_band.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.S3_pushButton_remove_band.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.S3_satellite_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. Sentinel-3A)

")) - self.satellite_label_12.setText(_translate("SemiAutomaticClassificationPlugin", "Satellite")) - self.satellite_label_14.setText(_translate("SemiAutomaticClassificationPlugin", "Product")) - self.S3_product_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. Sentinel-3A)

")) - self.label_115.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.label_181.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_5.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.sentinel3_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.sentinel3_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_Sentinel3), _translate("SemiAutomaticClassificationPlugin", "Sentinel-3")) - self.nodata_spinBox_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.nodata_checkBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_5.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.toolButton_directoryInput_ASTER.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.toolButton_directoryInput_ASTER.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.DOS1_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)

")) - self.DOS1_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", " Apply DOS1 atmospheric correction")) - self.label_67.setText(_translate("SemiAutomaticClassificationPlugin", " ASTER conversion to TOA reflectance and brightness temperature")) - self.label_55.setText(_translate("SemiAutomaticClassificationPlugin", "Select file ASTER L1T (.hdf)")) - self.create_bandset_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.create_bandset_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.add_new_bandset_checkBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_4.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.celsius_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable calculation of temperature in Celsius from thermal band

")) - self.celsius_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", " Brightness temperature in Celsius")) - self.ASTER_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.ASTER_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - item = self.ASTER_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "UnitConversionCoeff")) - item = self.ASTER_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "PixelSize")) - self.pushButton_remove_band_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.pushButton_remove_band_2.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.date_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

DATE ACQUIRED

")) - self.earth_sun_dist_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Earth sun distance

")) - self.satellite_label_9.setText(_translate("SemiAutomaticClassificationPlugin", "Earth sun \n" -"distance")) - self.satellite_label_8.setText(_translate("SemiAutomaticClassificationPlugin", "Date\n" -" (YYYYMMDD)")) - self.satellite_label_7.setText(_translate("SemiAutomaticClassificationPlugin", "Sun elevation")) - self.sun_elev_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

SUN ELEVATION

")) - self.ulm_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left

")) - self.satellite_label_10.setText(_translate("SemiAutomaticClassificationPlugin", "UTM zone")) - self.utm_zone_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

UTM zone

")) - self.satellite_label_11.setText(_translate("SemiAutomaticClassificationPlugin", "UPPERLEFTM")) - self.satellite_label_17.setText(_translate("SemiAutomaticClassificationPlugin", "LOWERRIGHTM")) - self.lrm_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right

")) - self.label_160.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.label_163.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_3.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.aster_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.aster_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_ASTER), _translate("SemiAutomaticClassificationPlugin", "ASTER")) - self.label_218.setText(_translate("SemiAutomaticClassificationPlugin", " MODIS conversion")) - self.create_bandset_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.create_bandset_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.add_new_bandset_checkBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_5.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.label_219.setText(_translate("SemiAutomaticClassificationPlugin", "Select file MODIS (.hdf)")) - self.toolButton_directoryInput_MODIS.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.toolButton_directoryInput_MODIS.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.nodata_spinBox_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.nodata_checkBox_7.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_7.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.reproject_modis_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reproject bands to WGS 84

")) - self.reproject_modis_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Reproject to WGS 84")) - self.MODIS_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.MODIS_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - item = self.MODIS_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "UnitConversionCoeff")) - self.pushButton_remove_band_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.pushButton_remove_band_3.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.satellite_label_16.setText(_translate("SemiAutomaticClassificationPlugin", "Date (YYYY-MM-DD)")) - self.MODIS_ID_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

DATE ACQUIRED

")) - self.satellite_label_13.setText(_translate("SemiAutomaticClassificationPlugin", "ID")) - self.MODIS_date_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

DATE ACQUIRED

")) - self.label_220.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.label_221.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_4.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.modis_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.modis_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_MODIS), _translate("SemiAutomaticClassificationPlugin", "MODIS")) + self.landsat_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.landsat_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_Landsat), _translate("SemiAutomaticClassificationPlugin", "Image conversion")) self.label_142.setText(_translate("SemiAutomaticClassificationPlugin", " Convert vector to raster")) self.label_64.setText(_translate("SemiAutomaticClassificationPlugin", "Select the vector")) self.vector_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the vector

")) self.toolButton_reload_16.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_16.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.field_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the value field of the vector

")) - self.field_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use the value field of the vector")) - self.field_comboBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the value field

")) - self.constant_value_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use constant value

")) - self.constant_value_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use constant value")) - self.constant_value_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Value

")) self.label_157.setText(_translate("SemiAutomaticClassificationPlugin", "Select the type of conversion")) self.conversion_type_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the type of conversion

")) + self.conversion_type_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "pixel_center")) + self.conversion_type_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "all_touched")) + self.conversion_type_combo.setItemText(2, _translate("SemiAutomaticClassificationPlugin", "area_based")) + self.label_158.setText(_translate("SemiAutomaticClassificationPlugin", "Area precision")) + self.area_precision_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Area precision for "area_based" method

")) + self.area_precision_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "20")) + self.nodata_checkBox_10.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) + self.nodata_checkBox_10.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) + self.nodata_spinBox_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) + self.constant_value_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use constant value

")) + self.constant_value_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use constant value")) + self.constant_value_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Value

")) + self.field_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the value field of the vector

")) + self.field_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use the value field of the vector")) + self.field_comboBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the value field

")) self.label_156.setText(_translate("SemiAutomaticClassificationPlugin", "Select the reference raster")) + self.extent_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, align to reference raster

")) + self.extent_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Minimum extent")) self.toolButton_reload_17.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_17.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.label_169.setText(_translate("SemiAutomaticClassificationPlugin", "Pixel size")) + self.pixel_size_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output pixel size

")) self.reference_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the reference raster

")) - self.extent_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the same extent as reference raster

")) - self.extent_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Same extent as reference raster")) self.label_167.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.convert_vector_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.convert_vector_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.vector_to_raster.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.vector_to_raster.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.vector_to_raster.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.vector_to_raster.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_spectral_distance), _translate("SemiAutomaticClassificationPlugin", "Vector to raster")) self.label_128.setText(_translate("SemiAutomaticClassificationPlugin", " Clip band set")) - self.nodata_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.band_set_comb_spinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_251.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.label_62.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) - self.label_16.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) self.output_clip_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) self.output_clip_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "clip")) + self.clip_virtual_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, output bands are virtual rasters

")) + self.clip_virtual_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster output")) + self.label_62.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) + self.band_set_comb_spinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.label_251.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) + self.show_area_radioButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Show / hide area

")) + self.show_area_radioButton_3.setText(_translate("SemiAutomaticClassificationPlugin", "Show")) + self.LY_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right Y

")) + self.LY_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y")) + self.label_11.setText(_translate("SemiAutomaticClassificationPlugin", "UL")) self.LX_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right X

")) self.LX_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X")) - self.UX_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left X

")) - self.UX_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X")) + self.selectUL_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set area in the map

")) + self.label_12.setText(_translate("SemiAutomaticClassificationPlugin", "LR")) self.UY_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left Y

")) self.UY_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y")) - self.LY_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower right Y

")) - self.LY_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Y")) - self.label_12.setText(_translate("SemiAutomaticClassificationPlugin", "LR")) - self.selectUL_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set area in the map

")) + self.UX_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper left X

")) + self.UX_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "X")) + self.coordinates_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use coordinates for clipping rasters

")) + self.coordinates_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use coordinates for clipping")) self.label_29.setText(_translate("SemiAutomaticClassificationPlugin", " Clip coordinates")) - self.show_area_radioButton_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Show / hide area

")) - self.show_area_radioButton_3.setText(_translate("SemiAutomaticClassificationPlugin", "Show")) - self.label_11.setText(_translate("SemiAutomaticClassificationPlugin", "UL")) self.shapefile_comboBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the vector for clipping

")) - self.shapefile_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use vector boundaries for clipping rasters

")) - self.shapefile_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use vector for clipping")) self.toolButton_reload_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_8.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.temporary_ROI_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use temporary ROI boundaries for clipping rasters

")) - self.temporary_ROI_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use temporary ROI for clipping")) self.vector_field_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, clip iterating through each vector polygon and add field value to the output name

")) self.vector_field_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use vector field for output name")) self.class_field_comboBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the vector field

")) + self.temporary_ROI_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use temporary ROI boundaries for clipping rasters

")) + self.temporary_ROI_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use temporary ROI for clipping")) + self.vector_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use vector boundaries for clipping rasters

")) + self.vector_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use vector for clipping")) self.label_164.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.clip_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.clip_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.clip_multiple_rasters.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.clip_multiple_rasters.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_clip), _translate("SemiAutomaticClassificationPlugin", "Clip multiple rasters")) + self.clip_multiple_rasters.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.clip_multiple_rasters.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_clip), _translate("SemiAutomaticClassificationPlugin", "Clip raster bands")) self.band_set_comb_spinBox_14.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) self.label_264.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.label_249.setText(_translate("SemiAutomaticClassificationPlugin", " Reproject raster bands")) - self.raster_align_comboBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the reference raster

")) - self.use_align_raster_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Align to raster

")) - self.use_align_raster_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Align to raster")) + self.label_249.setText(_translate("SemiAutomaticClassificationPlugin", " Reproject and resample band set")) + self.align_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Align to raster

")) + self.align_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Align to raster")) self.toolButton_reload_25.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_25.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) self.same_extent_raster_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Keep the same extent as the reference raster

")) self.same_extent_raster_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "same extent as reference")) - self.epsg_code_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

EPSG value

")) - self.use_epsg_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use EPSG value

")) - self.use_epsg_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use EPSG code")) + self.raster_align_comboBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the reference raster

")) + self.epsg_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use EPSG code

")) + self.epsg_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use EPSG code")) + self.y_resolution_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Y resolution

")) self.label_267.setText(_translate("SemiAutomaticClassificationPlugin", " Y resolution")) self.label_266.setText(_translate("SemiAutomaticClassificationPlugin", " X resolution")) + self.epsg_code_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

EPSG value

")) self.x_resolution_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

X resolution

")) - self.y_resolution_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Y resolution

")) self.resample_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, new pixel size is original pixel size times this factor

")) self.resample_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Resample pixel factor")) self.resample_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Resample factor

")) @@ -10186,9 +6955,15 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_265.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) self.reproj_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) self.reproj_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "reproj")) + self.virtual_output_checkBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use virtual output to merge multiprocess parts

")) + self.virtual_output_checkBox_4.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual output")) + self.compress_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, compress raster output

")) + self.compress_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Compress")) + self.resample_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Compression method

")) + self.resample_lineEdit_2.setText(_translate("SemiAutomaticClassificationPlugin", "LZW")) self.label_263.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.reproject_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.reproject_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.reproject_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.reproject_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.reproject_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.reproject_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_reproject_bands), _translate("SemiAutomaticClassificationPlugin", "Reproject raster bands")) @@ -10201,38 +6976,42 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_61.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) self.output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) self.output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "split")) - self.split_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.split_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.split_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.split_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.split_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.split_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_split_raster), _translate("SemiAutomaticClassificationPlugin", "Split raster bands")) self.label_252.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) self.band_set_comb_spinBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.stack_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.stack_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.stack_raster_bands.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.stack_raster_bands.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.stack_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.stack_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) self.label_223.setText(_translate("SemiAutomaticClassificationPlugin", " Stack band set")) self.label_226.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_stack_bands), _translate("SemiAutomaticClassificationPlugin", "Stack raster bands")) self.label_134.setText(_translate("SemiAutomaticClassificationPlugin", " Mosaic of band sets")) - self.label_135.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) self.nodata_checkBox_9.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) self.nodata_checkBox_9.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.nodata_spinBox_10.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.mosaic_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) - self.mosaic_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "mosaic")) - self.label_144.setText(_translate("SemiAutomaticClassificationPlugin", "Band set list")) - self.mosaic_band_sets_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

List of band set numbers separated by comma ,
Use * for selecting all the band sets

")) - self.mosaic_band_sets_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "1, 2")) self.mosaic_virtual_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, output bands are virtual rasters

")) self.mosaic_virtual_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster output")) + self.mosaic_output_prefix.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output prefix

")) + self.mosaic_output_prefix.setText(_translate("SemiAutomaticClassificationPlugin", "mosaic_")) + self.nodata_spinBox_10.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) + self.mosaic_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name

")) + self.mosaic_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "band_")) + self.label_135.setText(_translate("SemiAutomaticClassificationPlugin", "Output name")) + self.label_137.setText(_translate("SemiAutomaticClassificationPlugin", "Output prefix")) + self.mosaic_band_sets_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

List of band set numbers separated by comma ,
Use# for selecting all the band sets

")) + self.mosaic_band_sets_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "1, 2")) + self.label_144.setText(_translate("SemiAutomaticClassificationPlugin", "Band set list")) self.mosaic_bandsets_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.mosaic_bandsets_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.mosaic_bandsets.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.mosaic_bandsets.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.mosaic_bandsets.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.mosaic_bandsets.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.label_182.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_mosaic_band_sets), _translate("SemiAutomaticClassificationPlugin", "Mosaic band sets")) + self.label_138.setText(_translate("SemiAutomaticClassificationPlugin", " Mask of band set")) self.label_260.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) self.band_set_comb_spinBox_9.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) self.classification_name_combo_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification

")) @@ -10241,255 +7020,274 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_186.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) self.toolButton_reload_23.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_23.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_140.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) self.mask_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) - self.mask_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "mask")) - self.cloud_buffer_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) + self.mask_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "mask_")) self.cloud_buffer_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, create a buffer for class values

")) self.cloud_buffer_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use buffer of pixel size")) self.nodata_spinBox_11.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) self.label_141.setText(_translate("SemiAutomaticClassificationPlugin", "Output NoData value")) + self.cloud_buffer_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) + self.label_140.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) + self.mask_virtual_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, output bands are virtual rasters

")) + self.mask_virtual_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster output")) self.cloud_mask_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.cloud_mask_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.cloud_masking.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.cloud_masking.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.cloud_masking.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.cloud_masking.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.label_185.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.label_138.setText(_translate("SemiAutomaticClassificationPlugin", " Mask of band set")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_cloud_mask), _translate("SemiAutomaticClassificationPlugin", "Cloud masking")) - self.GOES_nodata_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

No data value

")) - self.GOES_nodata_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.GOES_nodata_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.label_273.setText(_translate("SemiAutomaticClassificationPlugin", " GOES conversion")) - self.GOES_create_bandset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create the Band set automatically and use the checked Band set tools

")) - self.GOES_create_bandset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create Band set and use Band set tools")) - self.label_274.setText(_translate("SemiAutomaticClassificationPlugin", "Directory containing GOES bands")) - self.GOES_toolButton_directoryInput.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory

")) - self.GOES_toolButton_directoryInput.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.add_new_bandset_checkBox_7.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a new band set where bands are added

")) - self.add_new_bandset_checkBox_7.setText(_translate("SemiAutomaticClassificationPlugin", "Add bands in a new Band set")) - self.GOES_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit metadata

")) - item = self.GOES_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band")) - self.GOES_pushButton_remove_band.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.GOES_pushButton_remove_band.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_277.setText(_translate("SemiAutomaticClassificationPlugin", "Metadata")) - self.satellite_label_20.setText(_translate("SemiAutomaticClassificationPlugin", "Satellite")) - self.GOES_satellite_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Satellite (e.g. Sentinel-3A)

")) - self.label_278.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pushButton_Conversion_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pushButton_Conversion_8.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.goes_conversion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.goes_conversion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_GOES), _translate("SemiAutomaticClassificationPlugin", "GOES")) - self.label_283.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.label_281.setText(_translate("SemiAutomaticClassificationPlugin", "Matrix file (optional)")) - self.toolButton_input_matrix.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) - self.label_279.setText(_translate("SemiAutomaticClassificationPlugin", "Output name prefix")) - self.neighbor_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) - self.neighbor_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "neighbor")) - self.neighbor_virtual_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, output bands are virtual rasters

")) - self.neighbor_virtual_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create virtual raster output")) - self.neighbor_pixels.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.neighbor_pixels.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.class_neighbor_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.class_neighbor_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.label_286.setText(_translate("SemiAutomaticClassificationPlugin", " Neighbor pixels")) - self.statistic_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter a value

")) - self.statistic_name_combobox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a statistic

")) - self.label_284.setText(_translate("SemiAutomaticClassificationPlugin", "Select a statistic")) - self.label_285.setText(_translate("SemiAutomaticClassificationPlugin", " Statistic")) - self.label_282.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.label_280.setText(_translate("SemiAutomaticClassificationPlugin", "Neighbor distance in pixels")) - self.band_set_comb_spinBox_15.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.class_neighbor_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Distance in pixels

")) - self.circular_structure_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) - self.circular_structure_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) - self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_neighbor_pixels), _translate("SemiAutomaticClassificationPlugin", "Neighbor pixels")) + self.tabWidget_preprocessing.setTabText(self.tabWidget_preprocessing.indexOf(self.tab_cloud_mask), _translate("SemiAutomaticClassificationPlugin", "Masking bands")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_preprocessing), _translate("SemiAutomaticClassificationPlugin", "Preprocessing")) + self.label_72.setText(_translate("SemiAutomaticClassificationPlugin", " Combination of band values")) + self.band_set_comb_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.label_250.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set (of classifications)")) + self.nodata_checkBox_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) + self.nodata_checkBox_12.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) + self.nodata_spinBox_16.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) + self.band_combination.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.band_combination.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.label_253.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.calculateBandSetComb_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.calculateBandSetComb_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.band_combination.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.band_combination.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.label_250.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set (of classifications)")) - self.band_set_comb_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_72.setText(_translate("SemiAutomaticClassificationPlugin", " Combination of band values")) self.toolBox_band_set_combination.setItemText(self.toolBox_band_set_combination.indexOf(self.page_29), _translate("SemiAutomaticClassificationPlugin", "Input")) self.band_set_comb_textBrowser.setHtml(_translate("SemiAutomaticClassificationPlugin", "\n" "\n" +"\n" "


")) self.toolBox_band_set_combination.setItemText(self.toolBox_band_set_combination.indexOf(self.page_30), _translate("SemiAutomaticClassificationPlugin", "Output")) - self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_bandset_combination_2), _translate("SemiAutomaticClassificationPlugin", "Band combination")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_bandset_combination_2), _translate("SemiAutomaticClassificationPlugin", "Combination")) + self.label_292.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) + self.label_294.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set (of classifications)")) + self.band_set_comb_spinBox_16.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.label_295.setText(_translate("SemiAutomaticClassificationPlugin", "Output name")) + self.output_name_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter output name

")) + self.output_name_lineEdit_2.setText(_translate("SemiAutomaticClassificationPlugin", "dilation_")) + self.virtual_output_checkBox_1.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use virtual output to merge multiprocess parts

")) + self.virtual_output_checkBox_1.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual output")) + self.label_291.setText(_translate("SemiAutomaticClassificationPlugin", "Class values")) + self.dilation_classes_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter class values separated by , or -

")) + self.band_dilation_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.band_dilation_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.label_290.setText(_translate("SemiAutomaticClassificationPlugin", "Size in pixels")) + self.dilation_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) + self.circular_structure_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) + self.circular_structure_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) + self.band_dilation.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.band_dilation.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.label_293.setText(_translate("SemiAutomaticClassificationPlugin", " Band dilation")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.band_dilation_tab), _translate("SemiAutomaticClassificationPlugin", "Dilation")) + self.label_202.setText(_translate("SemiAutomaticClassificationPlugin", " Band erosion")) + self.classification_erosion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.classification_erosion.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.label_151.setText(_translate("SemiAutomaticClassificationPlugin", "Class values")) + self.erosion_classes_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter class values separated by , or -

")) + self.label_296.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set (of classifications)")) + self.band_set_comb_spinBox_17.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.class_erosion_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.class_erosion_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.label_175.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) + self.label_149.setText(_translate("SemiAutomaticClassificationPlugin", "Size in pixels")) + self.erosion_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) + self.circular_structure_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) + self.circular_structure_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) + self.label_297.setText(_translate("SemiAutomaticClassificationPlugin", "Output name")) + self.output_name_lineEdit_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter output name

")) + self.output_name_lineEdit_3.setText(_translate("SemiAutomaticClassificationPlugin", "erosion_")) + self.virtual_output_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use virtual output to merge multiprocess parts

")) + self.virtual_output_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual output")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.band_erosion_tab), _translate("SemiAutomaticClassificationPlugin", "Erosion")) + self.label_195.setText(_translate("SemiAutomaticClassificationPlugin", " Band sieve")) + self.label_298.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set (of classifications)")) + self.band_set_comb_spinBox_18.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.label_174.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) + self.sieve_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.sieve_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.classification_sieve.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.classification_sieve.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.label_133.setText(_translate("SemiAutomaticClassificationPlugin", "Size threshold")) + self.sieve_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size threshold in pixels

")) + self.label_136.setText(_translate("SemiAutomaticClassificationPlugin", "Pixel connection")) + self.sieve_connection_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Pixel connection

")) + self.sieve_connection_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "4")) + self.sieve_connection_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "8")) + self.label_299.setText(_translate("SemiAutomaticClassificationPlugin", "Output name")) + self.output_name_lineEdit_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter output name

")) + self.output_name_lineEdit_4.setText(_translate("SemiAutomaticClassificationPlugin", "sieve_")) + self.virtual_output_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use virtual output to merge multiprocess parts

")) + self.virtual_output_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual output")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.band_sieve_tab), _translate("SemiAutomaticClassificationPlugin", "Sieve")) self.label_58.setText(_translate("SemiAutomaticClassificationPlugin", " Principal Components Analysis of band set")) + self.band_set_comb_spinBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.pca_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.pca_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.nodata_spinBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) self.nodata_checkBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) self.nodata_checkBox_4.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) + self.pca_components_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of components

")) self.num_comp_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate this number of components only

")) self.num_comp_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Number of components")) - self.nodata_spinBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.pca_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.pca_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) self.label_254.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.band_set_comb_spinBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.pca_components_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of components

")) self.label_166.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.pca.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.pca.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.pca.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.pca.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.toolBox_PCA.setItemText(self.toolBox_PCA.indexOf(self.page_16), _translate("SemiAutomaticClassificationPlugin", "Input")) self.toolBox_PCA.setItemText(self.toolBox_PCA.indexOf(self.page_17), _translate("SemiAutomaticClassificationPlugin", "Output")) self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.PCA_tab), _translate("SemiAutomaticClassificationPlugin", "PCA")) - self.label_78.setText(_translate("SemiAutomaticClassificationPlugin", " Clustering of band set")) - self.isodata_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use ISODATA

")) - self.isodata_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "ISODATA")) - self.band_set_comb_spinBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_230.setText(_translate("SemiAutomaticClassificationPlugin", "Method ")) - self.label_255.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.kmeans_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use K-means

")) - self.kmeans_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "&K-means ")) - self.label_225.setText(_translate("SemiAutomaticClassificationPlugin", "Max number of iterations")) - self.thresh_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Threshold

")) - self.std_dev_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Threshold

")) - self.kmean_threshold_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold

")) - self.kmean_threshold_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Distance threshold")) - self.nodata_spinBox_9.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.kmeans_iter_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set the maximum number of iterations

")) - self.label_228.setText(_translate("SemiAutomaticClassificationPlugin", "ISODATA max standard deviation")) - self.nodata_checkBox_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_8.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.kmeans_classes_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of classes

")) - self.label_224.setText(_translate("SemiAutomaticClassificationPlugin", "Number of classes")) - self.label_229.setText(_translate("SemiAutomaticClassificationPlugin", "ISODATA minimum class size in pixels")) - self.min_size_class_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Minimum class size in pixels

")) - self.min_distance_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use Minimum Distance algorithm

")) - self.min_distance_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Minimum Distance")) - self.kmean_save_siglist_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save the resulting signatures to Signature list

")) - self.kmean_save_siglist_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Save resulting signatures to Signature list")) - self.label_227.setText(_translate("SemiAutomaticClassificationPlugin", "Distance algorithm")) - self.label_104.setText(_translate("SemiAutomaticClassificationPlugin", " Seed signatures")) - self.kmean_siglist_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use signatures in Signature list as seed signatures

")) - self.kmean_siglist_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use Signature list as seed signatures")) - self.kmean_randomsiglist_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate seed signatures from random pixels

")) - self.kmean_randomsiglist_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Use random seed signatures")) - self.kmean_minmax_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate seed signatures from minimum and maximum values of bands

")) - self.kmean_minmax_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Seed signatures from band values")) - self.spectral_angle_map_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use Spectral Angle Mapping algorithm (only for K-means)

")) - self.spectral_angle_map_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Spectral Angle Mapping")) - self.label_179.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.kmeans_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.kmeans_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.clustering.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.clustering.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.toolBox_kmeans.setItemText(self.toolBox_kmeans.indexOf(self.page_18), _translate("SemiAutomaticClassificationPlugin", "Input")) - self.toolBox_kmeans.setItemText(self.toolBox_kmeans.indexOf(self.page_23), _translate("SemiAutomaticClassificationPlugin", "Output")) - self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_kmeans), _translate("SemiAutomaticClassificationPlugin", "Clustering")) - self.min_distance_radioButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use Minimum Distance algorithm

")) - self.min_distance_radioButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Minimum Distance")) - self.label_231.setText(_translate("SemiAutomaticClassificationPlugin", "Distance algorithm")) - self.spectral_angle_map_radioButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use Spectral Angle Mapping algorithm (only for K-means)

")) - self.spectral_angle_map_radioButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Spectral Angle Mapping")) - self.label_137.setText(_translate("SemiAutomaticClassificationPlugin", "Spectral distance of band sets")) - self.distance_threshold_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate a raster of changes where distance is above threshold

")) - self.distance_threshold_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Distance threshold")) - self.thresh_doubleSpinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Threshold

")) - self.label_256.setText(_translate("SemiAutomaticClassificationPlugin", "Select first input band set")) - self.band_set_comb_spinBox_7.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_257.setText(_translate("SemiAutomaticClassificationPlugin", "Select second input band set")) - self.band_set_comb_spinBox_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_183.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.spectral_distance_bandsets_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.spectral_distance_bandsets_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.spectral_distance.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.spectral_distance.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_spectral_dist), _translate("SemiAutomaticClassificationPlugin", "Spectral distance")) - self.label_32.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) - self.macroclass_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of macroclasses for the classification

")) - self.macroclass_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID")) - self.class_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of classes for the classification

")) - self.class_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "C ID")) - self.algorithm_weight_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab Algorithm band weight

")) - self.algorithm_weight_button.setText(_translate("SemiAutomaticClassificationPlugin", "W")) - self.algorithm_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a classification algorithm

")) - self.algorithm_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "Minimum Distance")) - self.algorithm_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "Maximum Likelihood")) - self.algorithm_combo.setItemText(2, _translate("SemiAutomaticClassificationPlugin", "Spectral Angle Mapping")) - self.band_set_comb_spinBox_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_261.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) self.label_240.setText(_translate("SemiAutomaticClassificationPlugin", " Algorithm")) - self.alg_threshold_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a classification threshold for all signatures

")) - self.algorithm_threshold_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab Signature threshold

")) - self.algorithm_threshold_button.setText(_translate("SemiAutomaticClassificationPlugin", "W")) - self.label_234.setText(_translate("SemiAutomaticClassificationPlugin", "Threshold")) - self.label_243.setText(_translate("SemiAutomaticClassificationPlugin", "Classification")) - self.LC_signature_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the Land Cover Signature Classification is used

")) - self.LC_signature_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "LCS")) - self.label_235.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) - self.LC_signature_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab LCS threshold

")) - self.LCS_leave_unclassified_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification

")) - self.LCS_leave_unclassified_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "only overlap")) - self.label_241.setText(_translate("SemiAutomaticClassificationPlugin", " Land Cover Signature Classification")) - self.LCS_class_algorithm_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification

")) - self.LCS_class_algorithm_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Algorithm")) - self.label_242.setText(_translate("SemiAutomaticClassificationPlugin", " Classification output")) - self.resetQmlButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.resetQmlButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.label_238.setText(_translate("SemiAutomaticClassificationPlugin", "Load qml style")) - self.qml_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select qml style

")) - self.qml_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.qml_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Qml file path

")) - self.mask_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select an optional mask vector

")) - self.mask_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Apply mask")) - self.resetMaskButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.resetMaskButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.mask_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Path of the optional mask shapefile

")) - self.vector_output_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Create a classification shapefile after the classification process

")) - self.vector_output_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Create vector")) - self.report_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Calculate a classification report

")) - self.report_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Classification report")) - self.alg_files_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification

")) - self.alg_files_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Save algorithm files")) + self.label_261.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) + self.label_243.setText(_translate("SemiAutomaticClassificationPlugin", " Input")) + self.band_set_comb_spinBox_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.linear_scaling_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Linear scaling normalization

")) + self.linear_scaling_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Linear scaling")) + self.z_score_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Z-score normalizatin

")) + self.z_score_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Z-score")) + self.input_normalization_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use input normalization

")) + self.input_normalization_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use input normalization")) + self.label_32.setText(_translate("SemiAutomaticClassificationPlugin", "Use training")) + self.macroclass_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of macroclasses for the classification

")) + self.macroclass_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Macroclass ID")) + self.class_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of classes for the classification

")) + self.class_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Class ID")) + self.classification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.classification.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.label_239.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) + self.save_classifier_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Save classifier to file

")) + self.save_classifier_button.setText(_translate("SemiAutomaticClassificationPlugin", " Save classifier")) + self.load_classifier_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a previously saved classifier

")) + self.load_classifier_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.button_classification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.button_classification.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.label_239.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.classification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_classification), _translate("SemiAutomaticClassificationPlugin", "Classification")) - self.label_233.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) - self.macroclass_checkBox_rf.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of macroclasses for the classification

")) - self.macroclass_checkBox_rf.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID")) - self.class_checkBox_rf.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the ID of classes for the classification

")) - self.class_checkBox_rf.setText(_translate("SemiAutomaticClassificationPlugin", "C ID")) - self.band_set_comb_spinBox_13.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_262.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.label_245.setText(_translate("SemiAutomaticClassificationPlugin", "Random Forest classification (ESA SNAP software required)")) + self.label_255.setText(_translate("SemiAutomaticClassificationPlugin", "Load classifier")) + self.confidence_raster_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.label_235.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) + self.signature_raster_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save a raster for each signature distance

")) + self.signature_raster_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Save signature raster")) + self.single_threshold_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use signature thresholds

")) + self.single_threshold_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Signature threshold")) + self.signature_threshold_button_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab Signature threshold

")) + self.signature_threshold_button_2.setText(_translate("SemiAutomaticClassificationPlugin", "W")) + self.alg_threshold_SpinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a classification threshold for all signatures

")) + self.single_threshold_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use single threshold for all the spectral signatures

")) + self.single_threshold_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Single threshold")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_max_like), _translate("SemiAutomaticClassificationPlugin", "Maximum Likelihood")) + self.signature_raster_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save a raster for each signature distance

")) + self.signature_raster_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Save signature raster")) + self.label_237.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) + self.single_threshold_checkBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use single threshold for all the spectral signatures

")) + self.single_threshold_checkBox_4.setText(_translate("SemiAutomaticClassificationPlugin", "Single threshold")) + self.alg_threshold_SpinBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a classification threshold for all signatures

")) + self.single_threshold_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use signature thresholds

")) + self.single_threshold_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Signature threshold")) + self.signature_threshold_button_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab Signature threshold

")) + self.signature_threshold_button_4.setText(_translate("SemiAutomaticClassificationPlugin", "W")) + self.confidence_raster_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_mindist), _translate("SemiAutomaticClassificationPlugin", "Minimum Distance")) + self.label_329.setText(_translate("SemiAutomaticClassificationPlugin", "Activation")) + self.alpha_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Weight decay (also L2 regularization term) for Adam optimizer

")) + self.batch_size_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples

")) + self.batch_size_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "auto")) + self.label_238.setText(_translate("SemiAutomaticClassificationPlugin", "Training proportion")) + self.label_328.setText(_translate("SemiAutomaticClassificationPlugin", "Batch size")) + self.label_256.setText(_translate("SemiAutomaticClassificationPlugin", "Use framework")) + self.scikit_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use scikit-learn framework

")) + self.scikit_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "scikit-learn")) + self.pytorch_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use PyTorch framework

")) + self.pytorch_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "PyTorch")) + self.max_iterations_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sets the maximum number of iterations

")) + self.label_262.setText(_translate("SemiAutomaticClassificationPlugin", "Max iter")) + self.activation_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sets the activation function

")) + self.activation_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "relu")) + self.label_242.setText(_translate("SemiAutomaticClassificationPlugin", "Alpha")) + self.learning_rate_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sets initial learning rate

")) + self.training_proportion_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Proportion of data to be used as training and the remaining part as test

")) + self.label_330.setText(_translate("SemiAutomaticClassificationPlugin", "Hidden layer sizes")) + self.hidden_layers_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)

")) + self.hidden_layers_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "100")) + self.label_241.setText(_translate("SemiAutomaticClassificationPlugin", "Learning rate init")) + self.cross_validation_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, perform cross validation

")) + self.cross_validation_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Cross validation")) + self.best_estimator_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, find the best estimator iteratively

")) + self.best_estimator_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Find best estimator with steps")) + self.steps_SpinBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of steps

")) + self.confidence_raster_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_mlp), _translate("SemiAutomaticClassificationPlugin", "Multi-Layer Perceptron")) + self.label_155.setText(_translate("SemiAutomaticClassificationPlugin", "Number of trees")) + self.max_features_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features

")) + self.best_estimator_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, find the best estimator iteratively

")) + self.best_estimator_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Find best estimator with steps")) + self.class_weight_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, balanced weight is computed inversely proportional to class frequency

")) + self.class_weight_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Balanced class weight")) + self.label_153.setText(_translate("SemiAutomaticClassificationPlugin", "Max features")) + self.min_split_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Minimum number of samples required to split an internal node

")) + self.cross_validation_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, perform cross validation

")) + self.cross_validation_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Cross validation")) + self.label_160.setText(_translate("SemiAutomaticClassificationPlugin", "Minimum number to split")) + self.ovr_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, perform One-Vs-Rest classification

")) + self.ovr_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "One-Vs-Rest")) self.number_trees_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of trees

")) - self.label_237.setText(_translate("SemiAutomaticClassificationPlugin", "Number of trees")) - self.number_training_samples_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of training samples

")) - self.label_236.setText(_translate("SemiAutomaticClassificationPlugin", "Number of training samples ")) - self.evaluate_classifier_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Evaluate classifier

")) - self.evaluate_classifier_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Evaluate classifier")) - self.evaluate_feature_power_set_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, evaluate feature power set

")) - self.evaluate_feature_power_set_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Evaluate feature power set")) - self.label_248.setText(_translate("SemiAutomaticClassificationPlugin", "Max")) - self.rf_power_min_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Minumum power

")) - self.label_247.setText(_translate("SemiAutomaticClassificationPlugin", "Min")) - self.rf_power_max_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Maximum power

")) - self.save_classifier_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save classifier

")) - self.save_classifier_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Save classifier")) - self.label_244.setText(_translate("SemiAutomaticClassificationPlugin", "Load classifier")) - self.classifier_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a previosly saved classifier

")) - self.classifier_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.classifier_lineEdit_.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Classifier file path

")) - self.resetClassifierButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.resetClassifierButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.button_random_forest.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.button_random_forest.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.label_246.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.random_forest.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.random_forest.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.toolBox_random_forest.setItemText(self.toolBox_random_forest.indexOf(self.page_21), _translate("SemiAutomaticClassificationPlugin", "Input")) - self.toolBox_random_forest.setItemText(self.toolBox_random_forest.indexOf(self.page_25), _translate("SemiAutomaticClassificationPlugin", "Output")) - self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_random_forest), _translate("SemiAutomaticClassificationPlugin", "Random forest")) + self.confidence_raster_checkBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox_4.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.steps_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of steps

")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_random_forest), _translate("SemiAutomaticClassificationPlugin", "Random Forest")) + self.signature_threshold_button_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open tab Signature threshold

")) + self.signature_threshold_button_3.setText(_translate("SemiAutomaticClassificationPlugin", "W")) + self.alg_threshold_SpinBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set a classification threshold for all signatures

")) + self.label_236.setText(_translate("SemiAutomaticClassificationPlugin", "Use")) + self.single_threshold_checkBox_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use single threshold for all the spectral signatures

")) + self.single_threshold_checkBox_6.setText(_translate("SemiAutomaticClassificationPlugin", "Single threshold")) + self.single_threshold_checkBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, use signature thresholds

")) + self.single_threshold_checkBox_5.setText(_translate("SemiAutomaticClassificationPlugin", "Signature threshold")) + self.confidence_raster_checkBox_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox_5.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.signature_raster_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save a raster for each signature distance

")) + self.signature_raster_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Save signature raster")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_sam), _translate("SemiAutomaticClassificationPlugin", "Spectral Angle Mapping")) + self.param_c_SpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Regularization parameter C

")) + self.label_173.setText(_translate("SemiAutomaticClassificationPlugin", "Kernel")) + self.gamma_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Kernel coefficient gamma

")) + self.gamma_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "scale")) + self.cross_validation_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, perform cross validation

")) + self.cross_validation_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Cross validation")) + self.kernel_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Sets the kernel

")) + self.kernel_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "rbf")) + self.label_163.setText(_translate("SemiAutomaticClassificationPlugin", "Gamma")) + self.label_162.setText(_translate("SemiAutomaticClassificationPlugin", "Regularization parameter C")) + self.best_estimator_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, find the best estimator iteratively

")) + self.best_estimator_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Find best estimator with steps")) + self.class_weight_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, balanced weight is computed inversely proportional to class frequency

")) + self.class_weight_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Balanced class weight")) + self.steps_SpinBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Number of steps

")) + self.confidence_raster_checkBox_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, calculate classification confidence raster

")) + self.confidence_raster_checkBox_6.setText(_translate("SemiAutomaticClassificationPlugin", "Calculate classification confidence raster")) + self.toolBox_classification.setItemText(self.toolBox_classification.indexOf(self.page_svm), _translate("SemiAutomaticClassificationPlugin", "Support Vector Machine")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_classification), _translate("SemiAutomaticClassificationPlugin", "Classification")) + self.label_283.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) + self.label_281.setText(_translate("SemiAutomaticClassificationPlugin", "Matrix file (optional)")) + self.toolButton_input_matrix.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a file

")) + self.label_279.setText(_translate("SemiAutomaticClassificationPlugin", "Output name")) + self.neighbor_output_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Output name prefix

")) + self.neighbor_output_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "neighbor_")) + self.neighbor_virtual_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, output bands are virtual rasters

")) + self.neighbor_virtual_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Virtual output")) + self.neighbor_pixels.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.neighbor_pixels.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) + self.class_neighbor_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) + self.class_neighbor_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.label_286.setText(_translate("SemiAutomaticClassificationPlugin", " Band neighbor")) + self.statistic_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter a value

")) + self.statistic_name_combobox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a statistic

")) + self.label_284.setText(_translate("SemiAutomaticClassificationPlugin", "Select a statistic")) + self.label_285.setText(_translate("SemiAutomaticClassificationPlugin", " Statistic")) + self.label_282.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) + self.label_280.setText(_translate("SemiAutomaticClassificationPlugin", "Neighbor distance in pixels")) + self.band_set_comb_spinBox_15.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) + self.class_neighbor_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Distance in pixels

")) + self.circular_structure_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) + self.circular_structure_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) + self.tabWidget_4.setTabText(self.tabWidget_4.indexOf(self.tab_neighbor_pixels), _translate("SemiAutomaticClassificationPlugin", "Neighbor pixels")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_band_processing), _translate("SemiAutomaticClassificationPlugin", "Band processing")) self.label_33.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification to assess")) self.label_34.setText(_translate("SemiAutomaticClassificationPlugin", "Select the reference vector or raster")) @@ -10508,35 +7306,16 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_168.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.calculateMatrix_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.calculateMatrix_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.accuracy.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.accuracy.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.accuracy.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.accuracy.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.toolBox_accuracy.setItemText(self.toolBox_accuracy.indexOf(self.page_10), _translate("SemiAutomaticClassificationPlugin", "Input")) self.error_matrix_textBrowser.setHtml(_translate("SemiAutomaticClassificationPlugin", "\n" "\n" +"\n" "


")) self.toolBox_accuracy.setItemText(self.toolBox_accuracy.indexOf(self.page_11), _translate("SemiAutomaticClassificationPlugin", "Output")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_accuracy), _translate("SemiAutomaticClassificationPlugin", "Accuracy")) - self.mask_unchanged_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels

")) - self.mask_unchanged_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Report unchanged pixels")) - self.classification_reference_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the reference classification raster

")) - self.label_40.setText(_translate("SemiAutomaticClassificationPlugin", "Select the new classification")) - self.label_38.setText(_translate("SemiAutomaticClassificationPlugin", "Select the reference classification")) - self.new_classification_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a new raster to be compared with the reference raster

")) - self.toolButton_reload_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_5.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.toolButton_reload_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_6.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_116.setText(_translate("SemiAutomaticClassificationPlugin", " Land cover change")) - self.label_169.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.calculateLandCoverChange_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.calculateLandCoverChange_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.land_cover_change.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.land_cover_change.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.toolBox_landCoverChange.setItemText(self.toolBox_landCoverChange.indexOf(self.page_12), _translate("SemiAutomaticClassificationPlugin", "Input")) - self.toolBox_landCoverChange.setItemText(self.toolBox_landCoverChange.indexOf(self.page_13), _translate("SemiAutomaticClassificationPlugin", "Output")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_landCoverChange), _translate("SemiAutomaticClassificationPlugin", "Land cover change")) self.classification_report_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification raster

")) self.label_44.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) self.nodata_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the report

")) @@ -10547,8 +7326,8 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_170.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.calculateReport_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.calculateReport_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.classification_report.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification_report.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.classification_report.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.classification_report.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.label_148.setText(_translate("SemiAutomaticClassificationPlugin", " Classification report")) self.toolBox_class_report.setItemText(self.toolBox_class_report.indexOf(self.page_14), _translate("SemiAutomaticClassificationPlugin", "Input")) self.toolBox_class_report.setItemText(self.toolBox_class_report.indexOf(self.page_15), _translate("SemiAutomaticClassificationPlugin", "Output")) @@ -10572,33 +7351,16 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_200.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.calculatecrossClass_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.calculatecrossClass_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.cross_classification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.cross_classification.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.cross_classification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.cross_classification.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.toolBox_cross_classification.setItemText(self.toolBox_cross_classification.indexOf(self.page_19), _translate("SemiAutomaticClassificationPlugin", "Input")) self.cross_matrix_textBrowser.setHtml(_translate("SemiAutomaticClassificationPlugin", "\n" "\n" +"\n" "


")) self.toolBox_cross_classification.setItemText(self.toolBox_cross_classification.indexOf(self.page_22), _translate("SemiAutomaticClassificationPlugin", "Output")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_cross_classification), _translate("SemiAutomaticClassificationPlugin", "Cross classification")) - self.label_188.setText(_translate("SemiAutomaticClassificationPlugin", " Class signature")) - self.classification_name_combo_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification

")) - self.label_201.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) - self.toolButton_reload_22.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_22.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_259.setText(_translate("SemiAutomaticClassificationPlugin", "Select input band set")) - self.band_set_comb_spinBox_8.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Band set number

")) - self.label_184.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.class_signature_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.class_signature_Button.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.class_signature_save_siglist_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, save the resulting signatures to Signature list

")) - self.class_signature_save_siglist_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Save resulting signatures to Signature list")) - self.class_signature.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.class_signature.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.toolBox_class_signature.setItemText(self.toolBox_class_signature.indexOf(self.page_20), _translate("SemiAutomaticClassificationPlugin", "Input")) - self.toolBox_class_signature.setItemText(self.toolBox_class_signature.indexOf(self.page_24), _translate("SemiAutomaticClassificationPlugin", "Output")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_class_signature), _translate("SemiAutomaticClassificationPlugin", "Class signature")) self.label_189.setText(_translate("SemiAutomaticClassificationPlugin", " Classification to vector")) self.label_63.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) self.classification_vector_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification raster

")) @@ -10615,8 +7377,8 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.convert_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.convert_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) self.label_171.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.classification_to_vector.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification_to_vector.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.classification_to_vector.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.classification_to_vector.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_class_to_vector), _translate("SemiAutomaticClassificationPlugin", "Classification to vector")) self.label_65.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) self.reclassification_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification raster

")) @@ -10652,116 +7414,9 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_172.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) self.reclassify_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.reclassify_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.reclassification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.reclassification.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.reclassification.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Script

")) + self.reclassification.setText(_translate("SemiAutomaticClassificationPlugin", " Script")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_reclassification), _translate("SemiAutomaticClassificationPlugin", "Reclassification")) - self.label_193.setText(_translate("SemiAutomaticClassificationPlugin", " Edit raster")) - self.undo_edit_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Undo edit (only for ROI polygons)

")) - self.undo_edit_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.label_173.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.label_66.setText(_translate("SemiAutomaticClassificationPlugin", "Select the input raster")) - self.edit_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the raster to edit

")) - self.toolButton_reload_14.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_14.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.use_constant_val_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use constant value

")) - self.use_constant_val_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use constant value")) - self.value_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Value

")) - self.use_expression_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use expression

")) - self.use_expression_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use expression")) - self.expression_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter expression

")) - self.expression_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "where(raster == 1, 2, raster)")) - self.label_81.setText(_translate("SemiAutomaticClassificationPlugin", " Edit raster values")) - self.use_field_vector_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use the value field of the vector

")) - self.use_field_vector_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use the value field of the vector")) - self.field_comboBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the value field

")) - self.edit_val_use_vector_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit values using a vector

")) - self.edit_val_use_vector_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", " Edit values using a vector")) - self.vector_name_combo_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the vector

")) - self.toolButton_reload_20.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_20.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.edit_val_use_ROI_radioButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Edit values using temporary ROIs

")) - self.edit_val_use_ROI_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", " Edit values using ROI polygons")) - self.label_158.setText(_translate("SemiAutomaticClassificationPlugin", " Edit options")) - self.raster_set_value_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.raster_set_value_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.edit_raster_using_vector.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.edit_raster_using_vector.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab), _translate("SemiAutomaticClassificationPlugin", "Edit raster")) - self.label_70.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) - self.sieve_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification

")) - self.toolButton_reload_15.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_15.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_133.setText(_translate("SemiAutomaticClassificationPlugin", "Size threshold")) - self.sieve_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size threshold in pixels

")) - self.label_136.setText(_translate("SemiAutomaticClassificationPlugin", "Pixel connection")) - self.sieve_connection_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Pixel connection

")) - self.sieve_connection_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "4")) - self.sieve_connection_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "8")) - self.label_174.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.sieve_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.sieve_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.classification_sieve.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification_sieve.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.label_195.setText(_translate("SemiAutomaticClassificationPlugin", " Classification sieve")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_sieve), _translate("SemiAutomaticClassificationPlugin", "Classification sieve")) - self.label_202.setText(_translate("SemiAutomaticClassificationPlugin", " Classification erosion")) - self.label_146.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) - self.erosion_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification

")) - self.toolButton_reload_18.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_18.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_149.setText(_translate("SemiAutomaticClassificationPlugin", "Size in pixels")) - self.erosion_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) - self.circular_structure_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) - self.circular_structure_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) - self.label_151.setText(_translate("SemiAutomaticClassificationPlugin", "Class values")) - self.erosion_classes_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter class values separated by , or -

")) - self.label_175.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.class_erosion_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.class_erosion_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.classification_erosion.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification_erosion.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_erosion), _translate("SemiAutomaticClassificationPlugin", "Classification erosion")) - self.label_204.setText(_translate("SemiAutomaticClassificationPlugin", " Classification dilation")) - self.label_152.setText(_translate("SemiAutomaticClassificationPlugin", "Select the classification")) - self.dilation_raster_name_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the classification

")) - self.toolButton_reload_19.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_19.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_153.setText(_translate("SemiAutomaticClassificationPlugin", "Size in pixels")) - self.dilation_threshold_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Size in pixels

")) - self.circular_structure_checkBox_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels

")) - self.circular_structure_checkBox_2.setText(_translate("SemiAutomaticClassificationPlugin", "Circular")) - self.label_155.setText(_translate("SemiAutomaticClassificationPlugin", "Class values")) - self.dilation_classes_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter class values separated by , or -

")) - self.label_176.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.class_dilation_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.class_dilation_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.classification_dilation.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.classification_dilation.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_dilation), _translate("SemiAutomaticClassificationPlugin", "Classification dilation")) - self.label_212.setText(_translate("SemiAutomaticClassificationPlugin", " Zonal stat rasters")) - self.label_77.setText(_translate("SemiAutomaticClassificationPlugin", "Select the input raster")) - self.classification_name_combo_5.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the raster to edit

")) - self.toolButton_reload_24.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.toolButton_reload_24.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.nodata_checkBox_10.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_10.setText(_translate("SemiAutomaticClassificationPlugin", "Use value as NoData")) - self.nodata_spinBox_12.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.class_field_comboBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the vector field

")) - self.label_214.setText(_translate("SemiAutomaticClassificationPlugin", "Select the reference vector or raster")) - self.buttonReload_shape_6.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) - self.buttonReload_shape_6.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.label_213.setText(_translate("SemiAutomaticClassificationPlugin", "Vector field")) - self.reference_name_combo_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select the reference vector or raster

")) - self.statistic_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter a value

")) - self.statistic_name_combobox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a statistic

")) - self.label_232.setText(_translate("SemiAutomaticClassificationPlugin", "Select a statistic")) - self.label_216.setText(_translate("SemiAutomaticClassificationPlugin", " Statistic")) - self.zonal_stat_raster_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.zonal_stat_raster_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.label_215.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.zonal_stat_raster.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.zonal_stat_raster.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) - self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_zonal_stats_rasters), _translate("SemiAutomaticClassificationPlugin", " Zonal stat rasters")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_postProcessing), _translate("SemiAutomaticClassificationPlugin", "Postprocessing")) self.toolButton_reload_13.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Refresh list

")) self.toolButton_reload_13.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) @@ -10769,83 +7424,18 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): item = self.tableWidget_band_calc.horizontalHeaderItem(0) item.setText(_translate("SemiAutomaticClassificationPlugin", "Variable")) item = self.tableWidget_band_calc.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Band name")) + item.setText(_translate("SemiAutomaticClassificationPlugin", "Output")) self.bandcalc_filter_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Filter

")) self.bandcalc_filter_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "Filter")) self.label_71.setText(_translate("SemiAutomaticClassificationPlugin", " Band list")) - self.plainTextEdit_calc.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter an expression (e.g. "raster1" + "raster2" )

")) - self.toolButton_less.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Less than

")) - self.toolButton_less.setText(_translate("SemiAutomaticClassificationPlugin", "<")) - self.toolButton_greater.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Greater than

")) - self.toolButton_greater.setText(_translate("SemiAutomaticClassificationPlugin", ">")) - self.toolButton_lbracket.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open parenthesis

")) - self.toolButton_lbracket.setText(_translate("SemiAutomaticClassificationPlugin", "(")) - self.toolButton_rbracket.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Close parenthesis

")) - self.toolButton_rbracket.setText(_translate("SemiAutomaticClassificationPlugin", ")")) - self.toolButton_power.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Power

")) - self.toolButton_power.setText(_translate("SemiAutomaticClassificationPlugin", "^")) - self.toolButton_sqrt.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Square root

")) - self.toolButton_sqrt.setText(_translate("SemiAutomaticClassificationPlugin", "√")) - self.toolButton_plus.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Plus

")) - self.toolButton_plus.setText(_translate("SemiAutomaticClassificationPlugin", "+")) - self.toolButton_minus.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Minus

")) - self.toolButton_minus.setText(_translate("SemiAutomaticClassificationPlugin", "-")) - self.toolButton_product.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Multiplication

")) - self.toolButton_product.setText(_translate("SemiAutomaticClassificationPlugin", "*")) - self.toolButton_ratio.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Division

")) - self.toolButton_ratio.setText(_translate("SemiAutomaticClassificationPlugin", "/")) - self.toolButton_equal.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Equals

")) - self.toolButton_equal.setText(_translate("SemiAutomaticClassificationPlugin", "==")) - self.toolButton_unequal.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Not equals

")) - self.toolButton_unequal.setText(_translate("SemiAutomaticClassificationPlugin", "!=")) - self.toolButton_import_expression.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a text file to add custom functions

")) + self.label_band_calc.setText(_translate("SemiAutomaticClassificationPlugin", " Expression")) + self.plainTextEdit_calc.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter an expression

")) item = self.band_calc_function_tableWidget.horizontalHeaderItem(0) item.setText(_translate("SemiAutomaticClassificationPlugin", "Functions")) - self.band_calc_tabWidget.setTabText(self.band_calc_tabWidget.indexOf(self.tab_expression), _translate("SemiAutomaticClassificationPlugin", "Expression")) - self.decision_rules_tableWidget.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter one or more rules separated by semicolon (e.g. "raster1" > 0; "raster2" > 0 )

")) - item = self.decision_rules_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Value")) - item = self.decision_rules_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Rule")) - self.remove_rule_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Delete row

")) - self.remove_rule_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.move_up_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted rule up

")) - self.move_up_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.import_rules_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import rules from text file

")) - self.import_rules_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.clear_rules_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.clear_rules_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.add_rule_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Add row

")) - self.add_rule_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.move_down_toolButton_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Move highlighted rule down

")) - self.move_down_toolButton_2.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.export_rules_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export rules to text file

")) - self.export_rules_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - self.band_calc_tabWidget.setTabText(self.band_calc_tabWidget.indexOf(self.tab_decision_rules), _translate("SemiAutomaticClassificationPlugin", "Decision rules")) - self.nodata_as_value_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, input NoData pixels will be evaluated as regular values

")) - self.nodata_as_value_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Input NoData \n" -" as value")) - self.nodata_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) - self.nodata_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Use value\n" -"as NoData")) - self.nodata_spinBox_13.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) - self.label_4.setText(_translate("SemiAutomaticClassificationPlugin", "Calculation\n" -"data type")) - self.calc_type_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a type

")) - self.calc_type_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "Float32")) - self.calc_type_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "Int32")) - self.calc_type_combo.setItemText(2, _translate("SemiAutomaticClassificationPlugin", "UInt32")) - self.calc_type_combo.setItemText(3, _translate("SemiAutomaticClassificationPlugin", "Int16")) - self.calc_type_combo.setItemText(4, _translate("SemiAutomaticClassificationPlugin", "UInt16")) - self.calc_type_combo.setItemText(5, _translate("SemiAutomaticClassificationPlugin", "Byte")) - self.label_83.setText(_translate("SemiAutomaticClassificationPlugin", "Extent:")) - self.intersection_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the extent of raster ouput equals the intersection of input rasters

")) - self.intersection_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Intersection")) - self.extent_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the extent of raster ouput equals the extent of selected raster

")) - self.extent_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Same as")) - self.raster_extent_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a raster

")) - self.align_radioButton.setText(_translate("SemiAutomaticClassificationPlugin", "Align")) + self.toolButton_import_expression.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Open a text file to add custom functions

")) self.label_84.setText(_translate("SemiAutomaticClassificationPlugin", "Output raster")) + self.label_5.setText(_translate("SemiAutomaticClassificationPlugin", "Output\n" +"data type")) self.raster_type_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a type

")) self.raster_type_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "Float32")) self.raster_type_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "Int32")) @@ -10856,8 +7446,12 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.label_268.setText(_translate("SemiAutomaticClassificationPlugin", "Output \n" "NoData value")) self.nodata_spinBox_4.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value of the output raster

")) - self.nodata_mask_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, every NoData pixel in input will be NoData pixel in output

")) - self.nodata_mask_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "NoData mask")) + self.label_152.setText(_translate("SemiAutomaticClassificationPlugin", "NoData\n" +"mask")) + self.nodata_mask_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Use NoData mask

")) + self.nodata_mask_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "False")) + self.nodata_mask_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "True")) + self.nodata_mask_combo.setItemText(2, _translate("SemiAutomaticClassificationPlugin", "None")) self.set_scale_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, set a scale

")) self.set_scale_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Set \n" "scale")) @@ -10865,27 +7459,49 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.set_offset_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, set an offset

")) self.set_offset_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Set \n" "offset")) - self.band_calc.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Function to Batch

")) - self.band_calc.setText(_translate("SemiAutomaticClassificationPlugin", " BATCH")) + self.offset_doubleSpinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "Offset")) + self.label_83.setText(_translate("SemiAutomaticClassificationPlugin", "Extent:")) + self.raster_extent_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select an extent

")) + self.UL_X_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upperleft X

")) + self.UL_X_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "UL X")) + self.UL_Y_linedit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Upper-left Y

")) + self.UL_Y_linedit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "UL Y")) + self.LR_X_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower-right X

")) + self.LR_X_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "LR X")) + self.LR_Y_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Lower-right Y

")) + self.LR_Y_lineEdit.setPlaceholderText(_translate("SemiAutomaticClassificationPlugin", "LR Y")) + self.label_116.setText(_translate("SemiAutomaticClassificationPlugin", "Align")) + self.raster_extent_combo_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a raster

")) + self.label_146.setText(_translate("SemiAutomaticClassificationPlugin", "Pixel\n" +"size")) + self.resolution_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Pixel size

")) self.toolButton_calculate.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) self.toolButton_calculate.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) + self.nodata_as_value_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, input NoData pixels will be evaluated as regular values

")) + self.nodata_as_value_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Input NoData \n" +" as value")) + self.nodata_checkBox_3.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, pixels equal to NoData value will be excluded from the output raster

")) + self.nodata_checkBox_3.setText(_translate("SemiAutomaticClassificationPlugin", "Use value\n" +"as NoData")) + self.nodata_spinBox_13.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

NoData value

")) + self.label_4.setText(_translate("SemiAutomaticClassificationPlugin", "Calculation\n" +"data type")) + self.calc_type_combo.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a type

")) + self.calc_type_combo.setItemText(0, _translate("SemiAutomaticClassificationPlugin", "Float32")) + self.calc_type_combo.setItemText(1, _translate("SemiAutomaticClassificationPlugin", "Int32")) + self.calc_type_combo.setItemText(2, _translate("SemiAutomaticClassificationPlugin", "UInt32")) + self.calc_type_combo.setItemText(3, _translate("SemiAutomaticClassificationPlugin", "Int16")) + self.calc_type_combo.setItemText(4, _translate("SemiAutomaticClassificationPlugin", "UInt16")) + self.calc_type_combo.setItemText(5, _translate("SemiAutomaticClassificationPlugin", "Byte")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_band_calc), _translate("SemiAutomaticClassificationPlugin", "Band calc")) - self.label_73.setText(_translate("SemiAutomaticClassificationPlugin", "Batch")) - self.plainTextEdit_batch.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enter a batch function

")) - self.export_batch_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export batch to text file

")) - self.export_batch_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) + self.label_73.setText(_translate("SemiAutomaticClassificationPlugin", "Script (copy the code in a Python shell)")) self.clear_batch_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) self.clear_batch_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.import_batch_toolButton.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Import batch from text file

")) - self.import_batch_toolButton.setText(_translate("SemiAutomaticClassificationPlugin", "Plot")) - item = self.batch_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Functions")) - self.label_177.setText(_translate("SemiAutomaticClassificationPlugin", " Run")) - self.check_batch.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Check batch function

")) - self.check_batch.setText(_translate("SemiAutomaticClassificationPlugin", " CHECK")) - self.toolButton_run_batch.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Run

")) - self.toolButton_run_batch.setText(_translate("SemiAutomaticClassificationPlugin", " RUN")) - self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_batch), _translate("SemiAutomaticClassificationPlugin", "Batch")) + self.copy_script.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Copy Script to clipboard

")) + self.copy_script.setText(_translate("SemiAutomaticClassificationPlugin", "Copy")) + self.save_script_button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Save Script to file

")) + self.save_script_button.setText(_translate("SemiAutomaticClassificationPlugin", " Save to file")) + self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_script), _translate("SemiAutomaticClassificationPlugin", "Script")) self.label_28.setText(_translate("SemiAutomaticClassificationPlugin", " System")) self.RAM_spinBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set available RAM for processes

")) self.label_23.setText(_translate("SemiAutomaticClassificationPlugin", "Available RAM (MB)")) @@ -10908,36 +7524,15 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.temp_directory_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select a directory

")) self.temp_directory_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.label_87.setText(_translate("SemiAutomaticClassificationPlugin", "Temporary directory")) - self.SNAP_label.setText(_translate("SemiAutomaticClassificationPlugin", "

ESA SNAP GPT executable

")) - self.label_276.setText(_translate("SemiAutomaticClassificationPlugin", "Python executable path")) - self.label_288.setText(_translate("SemiAutomaticClassificationPlugin", "Python modules path")) self.label_275.setText(_translate("SemiAutomaticClassificationPlugin", "GDAL installation directory")) - self.SNAP_GPT_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Path to the GPT executable (e.g. C:\\Program Files\\snap\\bin\\gpt.exe)

")) - self.python_path_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Path to the Python executable (e.g. /usr/local/bin/python3)

")) - self.python_path_lineEdit_2.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).
Multiple paths can be entered separated by ;

Restart is required.

")) self.gdal_path_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Path to the GDAL directory containing tools such as gdal_translate and gdalwarp (e.g. /usr/bin)

")) self.label_211.setText(_translate("SemiAutomaticClassificationPlugin", "External programs")) self.sound_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the sound when the process is finished

")) self.sound_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Play sound when finished")) - self.virtual_raster_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, create virtual rasters for certain temporary files

")) - self.virtual_raster_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Use virtual raster for temp files")) self.label_45.setText(_translate("SemiAutomaticClassificationPlugin", "Calculation process")) self.raster_compression_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, a lossless compression is applied to rasters in order to save disk space

")) self.raster_compression_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Raster compression")) - self.parallel_writing_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.

")) - self.parallel_writing_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Enable writing verification")) self.settings_tabWidget.setTabText(self.settings_tabWidget.indexOf(self.tabWidgetProcessing), _translate("SemiAutomaticClassificationPlugin", "Processing")) - self.label_31.setText(_translate("SemiAutomaticClassificationPlugin", "C Name field")) - self.Info_field_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set the Class name field

[max 10 characters]

")) - self.label_24.setText(_translate("SemiAutomaticClassificationPlugin", " Field names of training input")) - self.ID_field_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set the Class ID field name

[max 10 characters]

")) - self.MID_field_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set the Macroclass ID field name

[max 10 characters]

")) - self.label_10.setText(_translate("SemiAutomaticClassificationPlugin", "C ID field")) - self.MCInfo_field_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Set the Macroclass name field

[max 10 characters]

")) - self.label_17.setText(_translate("SemiAutomaticClassificationPlugin", "MC ID field")) - self.label_46.setText(_translate("SemiAutomaticClassificationPlugin", "MC Name field")) - self.reset_field_names_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) - self.reset_field_names_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) self.label_21.setText(_translate("SemiAutomaticClassificationPlugin", " ROI style")) self.change_color_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Select temporary ROI color

")) self.label_22.setText(_translate("SemiAutomaticClassificationPlugin", "ROI color")) @@ -10945,15 +7540,15 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.transparency_Slider.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Change temporary ROI transparency

")) self.reset_color_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) self.reset_color_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.label_95.setText(_translate("SemiAutomaticClassificationPlugin", " Dock")) + self.download_news_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, news about the SCP are downloaded on startup and displayed in Dock

")) + self.download_news_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Download news on startup")) self.label_68.setText(_translate("SemiAutomaticClassificationPlugin", " Variable name")) self.variable_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Variable name for expressions

")) self.variable_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "raster")) - self.label_69.setText(_translate("SemiAutomaticClassificationPlugin", " Variable name for expressions (tab Reclassification and Edit raster)")) + self.label_69.setText(_translate("SemiAutomaticClassificationPlugin", " Variable name for expressions")) self.reset_variable_name_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) self.reset_variable_name_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.label_95.setText(_translate("SemiAutomaticClassificationPlugin", " Dock")) - self.download_news_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

If checked, news about the SCP are downloaded on startup and displayed in Dock

")) - self.download_news_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Download news on startup")) self.label_76.setText(_translate("SemiAutomaticClassificationPlugin", " Project")) self.reset_group_name_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Reset

")) self.reset_group_name_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) @@ -10963,49 +7558,36 @@ def retranslateUi(self, SemiAutomaticClassificationPlugin): self.group_name_lineEdit.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Group name

")) self.group_name_lineEdit.setText(_translate("SemiAutomaticClassificationPlugin", "Class_temp_group")) self.settings_tabWidget.setTabText(self.settings_tabWidget.indexOf(self.tabWidgetInterface), _translate("SemiAutomaticClassificationPlugin", "Interface")) - self.log_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the Log of events

")) - self.log_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Record events in a Log file")) + self.test_dependencies_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Test dependencies

")) + self.label_43.setText(_translate("SemiAutomaticClassificationPlugin", " Test")) + self.label_42.setText(_translate("SemiAutomaticClassificationPlugin", "Test dependencies")) self.exportLog_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Export the Log file

")) self.exportLog_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) - self.clearLog_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Clear the Log file content

")) - self.clearLog_Button.setText(_translate("SemiAutomaticClassificationPlugin", "Import library")) + self.log_checkBox.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Enable/Disable the detailed Log of events in a local text file

")) + self.log_checkBox.setText(_translate("SemiAutomaticClassificationPlugin", "Record detailed events in a Log file")) self.label_30.setText(_translate("SemiAutomaticClassificationPlugin", " Log file")) - item = self.log_tableWidget.horizontalHeaderItem(0) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Date")) - item = self.log_tableWidget.horizontalHeaderItem(1) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Function")) - item = self.log_tableWidget.horizontalHeaderItem(2) - item.setText(_translate("SemiAutomaticClassificationPlugin", "Message")) - self.test_dependencies_Button.setToolTip(_translate("SemiAutomaticClassificationPlugin", "

Test dependencies

")) - self.label_42.setText(_translate("SemiAutomaticClassificationPlugin", "Test dependencies")) - self.label_43.setText(_translate("SemiAutomaticClassificationPlugin", " Test")) self.settings_tabWidget.setTabText(self.settings_tabWidget.indexOf(self.tabWidgetDebug), _translate("SemiAutomaticClassificationPlugin", "Debug")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_Settings), _translate("SemiAutomaticClassificationPlugin", "Settings")) self.plugin_label.setText(_translate("SemiAutomaticClassificationPlugin", "Semi-Automatic Classification Plugin")) self.textBrowser.setHtml(_translate("SemiAutomaticClassificationPlugin", "\n" "\n" -"

Developed by Luca Congedo (ing.congedoluca@gmail.com), the Semi-Automatic Classification Plugin (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.

\n" -"

It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.

\n" -"

For more information and tutorials visit the official site From GIS to Remote Sensing.

\n" -"

From GIS to Remote Sensing

\n" -"


Please join the
Semi-Automatic Classification Plugin group on Facebook or GitHub discussions

\n" -"


\n" -"

This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).

\n" -"

Some tools require the additional installation of: ESA SNAP

\n" +"\n" +"

Developed by Luca Congedo (ing.congedoluca@gmail.com), the Semi-Automatic Classification Plugin (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.

\n" +"

It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.

\n" +"

For more information and tutorials visit the official site From GIS to Remote Sensing.

\n" "
\n" -"

How to cite:

\n" -"

Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172

\n" +"

How to cite:

\n" +"

Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172

\n" "
\n" -"


The Semi-Automatic Classification Plugin is developed by Luca Congedo.

\n" +"

The Semi-Automatic Classification Plugin is developed by Luca Congedo.

\n" "

Translators:

\n" -"

Language: Author

\n" +"

Language: Author name

\n" +"
\n" "

Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.

\n" "

Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

\n" "

See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see <http://www.gnu.org/licenses/>.

")) self.SCP_tabs.setTabText(self.SCP_tabs.indexOf(self.tab_About), _translate("SemiAutomaticClassificationPlugin", "About")) self.main_tabWidget.setTabText(self.main_tabWidget.indexOf(self.tool_tab), _translate("SemiAutomaticClassificationPlugin", "Tool")) self.main_tabWidget.setTabText(self.main_tabWidget.indexOf(self.help_tab), _translate("SemiAutomaticClassificationPlugin", "Help")) - from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin.ui b/ui/ui_semiautomaticclassificationplugin.ui old mode 100644 new mode 100755 index 50693b5..4a8541b --- a/ui/ui_semiautomaticclassificationplugin.ui +++ b/ui/ui_semiautomaticclassificationplugin.ui @@ -9,8 +9,8 @@ 0 0 - 951 - 529 + 959 + 558 @@ -56,6 +56,9 @@ Qt::Horizontal + + 4 + false @@ -85,6 +88,9 @@ 1 + + 2 + @@ -165,6 +171,21 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg + + + Download products + + + + 75 + true + + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg + + Basic tools @@ -179,24 +200,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg - - - Algorithm band weight - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_weight_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_weight_tool.svg - - - - - Band set list - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg - - Export signatures @@ -215,15 +218,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import_spectral_library.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import_spectral_library.svg - - - LCS threshold - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg - - Multiple ROI creation @@ -235,7 +229,7 @@ - RGB list + RGB composite @@ -252,21 +246,6 @@ - - - Download products - - - - 75 - true - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg - - Preprocessing @@ -283,25 +262,16 @@ - ASTER - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_aster_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_aster_tool.svg - - - - - GOES + Clip raster bands - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_goes_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_goes_tool.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg - Landsat + Image conversion @@ -310,52 +280,7 @@ - MODIS - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_modis_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_modis_tool.svg - - - - - Sentinel-1 - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel1_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel1_tool.svg - - - - - Sentinel-2 - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel_tool.svg - - - - - Sentinel-3 - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel3_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sentinel3_tool.svg - - - - - Clip multiple rasters - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_clip_tool.svg - - - - - Cloud masking + Masking bands @@ -371,15 +296,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_mosaic_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_mosaic_tool.svg - - - Neighbor pixels - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg - - Reproject raster bands @@ -433,7 +349,16 @@ - Band combination + Classification + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg + + + + + Combination @@ -442,47 +367,47 @@ - Classification + Dilation - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg - Clustering + Erosion - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_kmeans_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_kmeans_tool.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg - PCA + Sieve - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg - Random forest + Neighbor - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_random_forest.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_random_forest.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_neighbor_pixels.svg - Spectral distance + PCA - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_spectral_distance.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_spectral_distance.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pca_tool.svg @@ -509,24 +434,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg - - - Classification dilation - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_dilation.svg - - - - - Classification erosion - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_erosion.svg - - Classification report @@ -545,24 +452,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_to_vector_tool.svg - - - Classification sieve - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_classification_sieve.svg - - - - - Class signature - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_signature_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_signature_tool.svg - - Cross classification @@ -572,24 +461,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cross_classification.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_cross_classification.svg - - - Edit raster - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_edit_raster.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_edit_raster.svg - - - - - Land cover change - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_land_cover_change.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_land_cover_change.svg - - Reclassification @@ -599,15 +470,6 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reclassification_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reclassification_tool.svg - - - Zonal stat raster - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_zonal_stat_raster_tool.svg - - @@ -626,7 +488,7 @@ - Batch + Script @@ -702,40 +564,6 @@ :/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png:/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png - - - Support the SCP - - - - 75 - true - false - - - - - - 92 - 184 - 92 - - - - - - - 255 - 255 - 255 - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg - - @@ -779,7 +607,7 @@ Tool - + @@ -807,342 +635,391 @@ Band set - - - - - - - - 0 - 0 - + + + 3 + + + 3 + + + 3 + + + 3 + + + + + Qt::Horizontal + + + 0 + + + false + + + + + 60 + 0 + + + + + 500 + 16777215 + + + + + 2 - - QFrame::Sunken + + QLayout::SetMinimumSize - - Wavelength -quick settings + + 0 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 0 - - false + + 0 - - - - - - <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> + + 0 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken + + + + + 30 + 0 + - - Wavelength -unit + + <html><head/><body><p>Filter</p></body></html> - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + Filter - - + + - 100 + 150 0 - - <html><head/><body><p>Wavelength unit</p></body></html> - - - - - - - <html><head/><body><p>Export band set to text file</p></body></html> + + QAbstractItemView::NoEditTriggers - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import band set from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - 0 - 2020 - 1 - 1 - - - - - 2045 - 12 - 31 - - - - - 1972 - 1 - 1 - - - - yyyy-MM-dd - - + true - - - 2020 - 1 - 1 - + + QAbstractItemView::SelectRows - - - - - - Date + + Qt::SolidLine + + true + + + + Band set table + + - - - - - - - - Qt::Vertical - - - false - - - - - 0 - 0 - - - - - 0 - 50 - - - - - 1 - - - 1 - - - 1 - - - 1 - - - - - - - Qt::Vertical + + + + + + <html><head/><body><p>Move highlighted band sets up</p></body></html> - + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg + + - 20 - 40 + 22 + 22 - + - - - - 0 - 0 - + + + <html><head/><body><p>Add a new band set</p></body></html> - background-color : #656565; color : white + margin: 0px;padding: 0px - - QFrame::Panel + + Plot - - QFrame::Sunken + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Move highlighted band sets down</p></body></html> + + + margin: 0px;padding: 0px; - Single band list + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg + + + + 22 + 22 + - - - - 0 - 0 - + + + <html><head/><body><p>Remove selected band sets</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + + + - <html><head/><body><p>Filter</p></body></html> + <html><head/><body><p>Sort band sets by date</p></body></html> - - Filter + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_date.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_date.svg + + + + 22 + 22 + - - - - - - - 0 - 0 - + + + + <html><head/><body><p>Display RGB composite in map of selected band sets</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg + + + + 22 + 22 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + + background-color : #5a5a5a; color : white; font: bold - - - 0 - 30 - + + QFrame::Panel QFrame::Sunken - - QAbstractItemView::NoEditTriggers - - - true + + Band quick settings - - QAbstractItemView::SelectRows + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - false - - - true - - - false - - - - Band - - - - - - + + + + + + + 0 + 0 + 0 + 2020 + 1 + 1 + + + + + 2045 + 12 + 31 + + + + + 1972 + 1 + 1 + + + + yyyy-MM-dd + + + true + + + + 2020 + 1 + 1 + + + + + + + + + 100 + 0 + + - <html><head/><body><p >Refresh list</p></body></html> + <html><head/><body><p>Wavelength unit</p></body></html> - - margin: 0px;padding: 0px + + + + + + + 0 + 0 + + + + QFrame::Sunken - Plot + Wavelength unit - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 22 - 22 - + + + + + + Date - - + + - <html><head/><body><p>Select all / Unselect all</p></body></html> + <html><head/><body><p>Open a csv file of wavelength values</p></body></html> margin: 0px;padding: 0px; - - Plot - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg @@ -1152,26 +1029,32 @@ unit - - + + - <html><head/><body><p>Add band to Band set</p></body></html> + <html><head/><body><p>Select a configuration for setting band center wavelengths</p></body></html> - - margin: 0px;padding: 0px + + + + + + + 0 + 0 + + + + QFrame::Sunken - Plot + Wavelength - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 22 - 22 - + + false @@ -1179,67 +1062,6 @@ unit - - - - - - - - 0 - 0 - - - - - 0 - 50 - - - - - 1 - - - 1 - - - 1 - - - 1 - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Band set definition - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - @@ -1278,120 +1100,249 @@ QTabBar::tab:selected { font: bold; color: green; } - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - + + + + + + <html><head/><body><p>Create a virtual raster of active band set</p></body></html> + + + Create virtual raster +of band set + + - - - - - - <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted band up</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted band down</p></body></html> + + + + <html><head/><body><p>Calculate expression in Band calc</p></body></html> + + + Band calc expressions + + + + + + + <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> + + + Create raster of band set +(stack bands) + + + + + + + <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> + + + Build band overviews + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Band set tools + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Band set definition + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Active band set + + + 1 + + + 1 + + + 1 + + + + + + + Date + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + <html><head/><body><p>Filter images</p></body></html> + + + 10000 + + + + + + + QFrame::Sunken + + + Root directory + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + <html><head/><body><p>Filter images</p></body></html> + + + 10000 + + + + + + + + + + + + + <html><head/><body><p >Delete row</p></body></html> - margin: 0px;padding: 0px; + margin: 0px;padding: 0px - Import library + Plot - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg @@ -1401,20 +1352,20 @@ QTabBar::tab:selected { font: bold; color: green; } - - + + - <html><head/><body><p>Add a new band set</p></body></html> + <html><head/><body><p><span >Reset</span></p></body></html> - margin: 0px;padding: 0px + margin: 0px;padding: 0px; - Plot + Import library - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_bandset_tool.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg @@ -1424,235 +1375,343 @@ QTabBar::tab:selected { font: bold; color: green; } - - - - - - - - - - - - - - - - <html><head/><body><p>Create a virtual raster of active band set</p></body></html> - - - Create virtual raster of band set - - - - - - - <html><head/><body><p>Calculate expression in Band calc</p></body></html> - - - Band calc expressions - - - - - - - <html><head/><body><p>Create a .tif raster stacking the bands of the active band set</p></body></html> - - - Create raster of band set -(stack bands) - - - - - - - <html><head/><body><p>Build band overviews (external pyramids) of active band set for faster visualization</p></body></html> - - - Build band overviews - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Band set tools - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Import band set from text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Export band set to text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 22 + 22 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + <html><head/><body><p>Sort bands by name (priority to ending number)</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p><span >Open a file</span></p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Move highlighted band down</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Add bands loaded in QGIS</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Move highlighted band up</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg + + + + 22 + 22 + + + + + + + + + + + + + + + + + + + Download products + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + QTabBar::tab { +padding: 10px; +min-height: 18px; +} - - - 34 - 34 - + + QTabWidget::North - - Qt::ToolButtonTextBesideIcon + + 0 - - - - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Multiband image list - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Select a multiband image</p></body></html> - - - - - - - - - - Basic tools - - - - - - - - - 0 - - - - 20 - 20 - - - - true - - - - RGB list - - - - - - - - + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg + + + Search + + + + + + + + + + <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg + + + + 22 + 22 + + + + + + + + QFrame::Sunken + + + <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + QFrame::Sunken + + + <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -1661,13048 +1720,1549 @@ QTabBar::tab:selected { font: bold; color: green; } QFrame::Sunken - RGB list + Search parameters Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>Sort RGB automatically</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted RGB down</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted RGB up</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p >Add row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Export RGB list to text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import RGB list from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - QAbstractItemView::DoubleClicked - - - true - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - 50 - - - true - - - 20 - - - - RGB - - - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Automatic RGB - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Band combinations - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Add all combinations of bands</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - Band set list - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Band set list - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Filter</p></body></html> - - - Filter - - - - - - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - 68 - - - true - - - 20 - - - - Number - - - - - Bands - - - - - Date - - - - - - - - - - <html><head/><body><p>Move highlighted Band sets down</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted Band sets up</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Add row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_rgb_tool.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p >Add row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Export Band set list to file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import Band set list from file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>Sort band sets by date</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg - - - - 22 - 22 - - - - - - - - - - - Algorithm band weight - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Algorithm band weight - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - <html><head/><body><p >Reset</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - <html><head/><body><p >Set</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - Set weight - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set a value</p></body></html> - - - 1000.000000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Automatic weight - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - QTabWidget::North - - - -1 - - - - - - - - - - Multiple ROI creation - - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p align="justify">Minimum distance between points</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 999999999 - - - 100 - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 999999999 - - - 10000 - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Create random points - - - - - - - - 0 - 0 - - - - Create points - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - QFrame::Sunken - - - Number of points - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 999999999 - - - 100 - - - - - - - <html><head/><body><p>Create points</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Create random points with a minimum distance</p></body></html> - - - min distance - - - - - - - <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> - - - inside grid - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Create stratified random points</p></body></html> - - - stratified for the values - - - - - - - - 0 - 0 - - - - - 400 - 0 - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - - - raster > 0 - - - 10000 - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - QFrame::Sunken - - - of first band of band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Point coordinates and ROI definition - - - - - - - true - - - false - - - 90 - - - 24 - - - - X - - - - - Y - - - - - MC ID - - - - - MC Name - - - - - C ID - - - - - C Name - - - - - Min - - - - - Max - - - - - Dist - - - - - Rapid ROI band - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Add row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p >Export point list to text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Import point list from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - - - Calculate sig. - - - true - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - - Import signatures - - - - - - 2 - - - - - 0 - 0 - 357 - 448 - - - - Download USGS Spectral Library - - - - - - - - <html><head/><body><p>Select a chapter</p></body></html> - - - - - - - <html><head/><body><p>Select a library</p></body></html> - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - <html><head/><body><p>Select a chapter</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - <html><head/><body><p>Select a library</p></body></html> - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Import spectral library - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Import spectral library</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> - - - true - - - - - - - - 8 - - - - QFrame::Panel - - - QFrame::Sunken - - - <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - - true - - - true - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Library Description (requires internet connection) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - 0 - 0 - 604 - 53 - - - - Import library file - - - - - - - - QFrame::Sunken - - - <html><head/><body><p>Select a file: SCP file (*.scp) ; USGS library (*.asc) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 0 - 0 - 417 - 165 - - - - Import vector - - - - - - - - <html><head/><body><p>Open a file</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>C ID field</p></body></html> - - - - - - - - 1 - 0 - - - - <html><head/><body><p>MC ID field</p></body></html> - - - - - - - - 1 - 0 - - - - <html><head/><body><p>MC Name field</p></body></html> - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - C Name field - - - - - - - - 1 - 0 - - - - <html><head/><body><p>C Name field</p></body></html> - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Vector fields - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - C ID field - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - MC ID field - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - MC Name field - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Import vector - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> - - - Calculate sig. - - - true - - - - - - - <html><head/><body><p>Import vector</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - - - - - - Export signatures - - - - - - - - QFrame::Sunken - - - <html><head/><body><p>Export as SCP file (*.scp)</p></body></html> - - - - - - - <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Export - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - QFrame::Sunken - - - <html><head/><body><p>Export as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> - - - - - - - QFrame::Sunken - - - <html><head/><body><p>Export as CSV file (.csv)</p></body></html> - - - - - - - <html><head/><body><p >Export highlighted spectral signatures</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Signature threshold - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - <html><head/><body><p >Reset</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - - - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectItems - - - true - - - 50 - - - true - - - 20 - - - - MC ID - - - - - MC Name - - - - - C ID - - - - - C Name - - - - - MD Threshold - - - - - ML Threshold - - - - - SAM Threshold - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Signature threshold - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - QFrame::Sunken - - - Set threshold = σ * - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - 1 - - - 10000.000000000000000 - - - 1.000000000000000 - - - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - Set threshold - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set a value</p></body></html> - - - 4 - - - 10000.000000000000000 - - - 0.000000000000000 - - - - - - - <html><head/><body><p >Set</p></body></html> - - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Automatic thresholds - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - LCS threshold - - - - - - - - - 0 - 0 - - - - QAbstractItemView::SelectedClicked - - - true - - - true - - - 50 - - - true - - - 20 - - - - MC ID - - - - - MC Name - - - - - C ID - - - - - C Name - - - - - Color [overlap MC_ID-C_ID] - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - LC Signature threshold - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - <html><head/><body><p >Add highlighted signatures to spectral signature plot</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg - - - - 22 - 22 - - - - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Min Max - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QFrame::Sunken - - - σ * - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - 1 - - - 10000.000000000000000 - - - 1.000000000000000 - - - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - From pixel - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg - - - - 22 - 22 - - - - - - - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg - - - true - - - - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - From ROI - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Automatic thresholds - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - - - - - Download products - - - - - - - - QTabBar::tab { -padding: 10px; -min-height: 18px; -} - - - QTabWidget::North - - - 1 - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg - - - Login data - - - - - - - - <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - - - remember - - - true - - - - - - - <html><head/><body><p>Password</p></body></html> - - - - - - - Password - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - <html><head/><body><p>Login Landsat (<a href="https://ers.cr.usgs.gov"><span style=" text-decoration: underline; color:#ffffff;">https://ers.cr.usgs.gov</span></a>)</p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>User name</p></body></html> - - - - - - - User - - - - - - - - - - - <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - - - remember - - - true - - - - - - - <html><head/><body><p>Password</p></body></html> - - - - - - - Password - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - <html><head/><body><p>Login ASTER and MODIS (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>User name</p></body></html> - - - - - - - User - - - - - - - - - - - <html><head/><body><p>User name</p></body></html> - - - - - - - Password - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - <html><head/><body><p>Login Sentinels</p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>If checked, remember user name and password locally in QGIS</p></body></html> - - - remember - - - true - - - - - - - User - - - - - - - <html><head/><body><p>Password</p></body></html> - - - - - - - - - Service - - - - - - - <html><head/><body><p>Service</p></body></html> - - - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - - - <html><head/><body><p>If checked, use alternative search for Sentinel-2 (no authentication required)</p></body></html> - - - Use alternative search for Sentinel-2 (no authentication required) - - - - - - - - - Qt::Vertical - - - - 20 - 251 - - - - - - - - - verticalSpacer_44 - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_search.svg - - - Search - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Export table to text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import table from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - - - - 0 - 0 - - - - - 300 - 300 - - - - QFrame::Panel - - - QFrame::Sunken - - - Preview - - - Qt::AlignCenter - - - - - - - - - - - QFrame::Sunken - - - QAbstractItemView::NoEditTriggers - - - true - - - true - - - QAbstractItemView::SelectRows - - - true - - - 20 - - - - Product - - - - - ProductID - - - - - AcquisitionDate - - - - - CloudCover - - - - - Zone/Path - - - - - Row/DayNight - - - - - min_lat - - - - - min_lon - - - - - max_lat - - - - - max_lon - - - - - Collection/Size - - - - - Preview - - - - - Collection/ID - - - - - Collection/Image - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Product list - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Filter</p></body></html> - - - Filter - - - - - - - - - - - - - <html><head/><body><p>Add OpenStreetMap to the map</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_osm_add.svg - - - - 22 - 22 - - - - - - - - QFrame::Sunken - - - <html><head/><body><p><span style=" color:#000000;">Add OpenStreetMap to the map</span></p></body></html> - - - Qt::AlignCenter - - - true - - - - - - - QFrame::Sunken - - - <html><head/><body><p>(© <a href="http://www.openstreetmap.org/copyright"><span style=" text-decoration: underline; color:#0000ff;">OpenStreetMap</span></a> contributors. The cartography is licensed as CC BY-SA. <a href="https://operations.osmfoundation.org/policies/tiles/"><span style=" text-decoration: underline; color:#0000ff;">Tile Usage Policy</span></a>)</p></body></html> - - - Qt::AlignCenter - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Search parameters - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p>Set area in the map</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Lower right X</p></body></html> - - - - - - 15 - - - X (Lon) - - - - - - - <html><head/><body><p>Upper left X</p></body></html> - - - 15 - - - X (Lon) - - - - - - - QFrame::Sunken - - - LR - - - Qt::AlignCenter - - - - - - - QFrame::Sunken - - - UL - - - Qt::AlignCenter - - - - - - - <html><head/><body><p>Lower right Y</p></body></html> - - - 15 - - - Y (Lat) - - - - - - - <html><head/><body><p>Upper left Y</p></body></html> - - - 15 - - - Y (Lat) - - - - - - - <html><head/><body><p>Show / hide area</p></body></html> - - - Show - - - true - - - false - - - - - - - - - <html><head/><body><p>Find images</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg - - - - 22 - 22 - - - - - - - - Find - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p>Select a product</p></body></html> - - - - - - - - 0 - 0 - 0 - 2016 - 1 - 1 - - - - - 2045 - 12 - 31 - - - - - 1972 - 1 - 1 - - - - yyyy-MM-dd - - - true - - - - 2016 - 1 - 1 - - - - - - - - QFrame::Sunken - - - Max cloud cover (%) - - - Qt::AlignCenter - - - - - - - - 2045 - 12 - 31 - - - - - 1980 - 1 - 2 - - - - yyyy-MM-dd - - - true - - - - 2045 - 12 - 31 - - - - - - - - QFrame::Sunken - - - to - - - Qt::AlignCenter - - - - - - - QFrame::Sunken - - - Date from - - - Qt::AlignCenter - - - - - - - - 50 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Maximum cloud cover percentage</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 100 - - - 10 - - - 100 - - - - - - - QFrame::Sunken - - - Products - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - QFrame::Sunken - - - Results - - - Qt::AlignCenter - - - - - - - QFrame::Sunken - - - Advanced search - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - <html><head/><body><p>Filter images</p></body></html> - - - 10000 - - - - - - - - 50 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Maximum number of results (images)</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 5 - - - 2000 - - - 5 - - - 20 - - - - - - - - - - - - - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_options.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_options.svg - - - Download options - - - - - - - - 6 (Landsat 1-8) - - - true - - - - - - - 4 (Landsat 1-8) - - - true - - - - - - - 1 (Landsat 4-8) - - - true - - - - - - - 3 (Landsat 4-8) - - - true - - - - - - - Ancillary data - - - true - - - - - - - 2 (Landsat 4-8) - - - true - - - - - - - 11 (Landsat 8) - - - true - - - - - - - 5 (Landsat 1-8) - - - true - - - - - - - <html><head/><body><p >Select all</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Landsat bands - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 8A - - - true - - - - - - - 1 - - - true - - - - - - - <html><head/><body><p >Select all</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Sentinel-2 bands - - - - - - - 2 - - - true - - - - - - - 3 - - - true - - - - - - - 4 - - - true - - - - - - - 5 - - - true - - - - - - - 6 - - - true - - - - - - - 7 - - - true - - - - - - - 11 - - - true - - - - - - - 8 - - - true - - - - - - - 9 - - - true - - - - - - - Ancillary data - - - true - - - - - - - 12 - - - true - - - - - - - 10 - - - true - - - - - - - - - - - 6 - - - true - - - - - - - 2 - - - true - - - - - - - 5 - - - true - - - - - - - 8 - - - true - - - - - - - 1 - - - true - - - - - - - 16 - - - true - - - - - - - 10 - - - true - - - - - - - 12 - - - true - - - - - - - Ancillary data - - - true - - - - - - - 3 - - - true - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Sentinel-3 bands - - - - - - - 20 - - - true - - - - - - - 17 - - - true - - - - - - - 14 - - - true - - - - - - - 9 - - - true - - - - - - - 13 - - - true - - - - - - - 19 - - - true - - - - - - - <html><head/><body><p >Select all</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg - - - - 22 - 22 - - - - - - - - 7 - - - true - - - - - - - 4 - - - true - - - - - - - 11 - - - true - - - - - - - 15 - - - true - - - - - - - 21 - - - true - - - - - - - 18 - - - true - - - - - - - - - - - 1 - - - true - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - GOES bands - - - - - - - 5 - - - true - - - - - - - 3 - - - true - - - - - - - 4 - - - true - - - - - - - 2 - - - true - - - - - - - 6 - - - true - - - - - - - <html><head/><body><p >Select all</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg - - - - 22 - 22 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 8 (Landsat 7, 8) - - - true - - - - - - - 10 (Landsat 8) - - - true - - - - - - - 9 (Landsat 8) - - - true - - - - - - - 7 (Landsat 1-8) - - - true - - - - - - - - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>Preprocess images</p></body></html> - - - Preprocess images - - - true - - - - - - - <html><head/><body><p>Load images in QGIS after download</p></body></html> - - - Load bands in QGIS - - - true - - - - - - - <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> - - - Only if preview in Layers - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Export download links to a text file</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> - - - Virtual download - - - - - - - - - - - - - Preprocessing - - - - - - - - - 0 - - - - 20 - 20 - - - - true - - - - Landsat - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - - 50 - false - - - - QFrame::Sunken - - - Directory containing Landsat bands - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Landsat conversion to TOA reflectance and brightness temperature - - - - - - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> - - - Brightness temperature in Celsius - - - false - - - false - - - - - - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - - Apply DOS1 atmospheric correction - - - false - - - false - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> - - - QFrame::Sunken - - - Select MTL file - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p >Select a directory</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg - - - - 22 - 22 - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - <html><head/><body><p>Perform pan-sharpening (Brovey Transform)</p></body></html> - - - Perform pansharpening (Landsat 7 or 8) - - - false - - - false - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - 155 - - - - Band - - - - - RADIANCE_MULT - - - - - RADIANCE_ADD - - - - - REFLECTANCE_MULT - - - - - REFLECTANCE_ADD - - - - - RADIANCE_MAXIMUM - - - - - REFLECTANCE_MAXIMUM - - - - - K1_CONSTANT - - - - - K2_CONSTANT - - - - - LMAX - - - - - LMIN - - - - - QCALMAX - - - - - QCALMIN - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Satellite - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Sun elevation - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Date (YYYY-MM-DD) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Earth sun distance - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>SUN ELEVATION</p></body></html> - - - - - - - <html><head/><body><p>Earth sun distance</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - <html><head/><body><p>Satellite (e.g. LANDSAT8)</p></body></html> - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Sentinel-1 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select SNAP xml graph (optional) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Polarization - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Select VH polarization</p></body></html> - - - VH - - - true - - - false - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Select VV polarization</p></body></html> - - - VV - - - true - - - false - - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Sentinel-1 conversion (ESA SNAP software required) - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Sentinel-1 file - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>If checked, project the output to the same projection as selected Band set</p></body></html> - - - Raster projection as Band set - - - false - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>If checked, convert to dB</p></body></html> - - - convert to dB - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - - - - - Qt::Vertical - - - - 20 - 296 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 782 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Sentinel-2 - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Directory containing Sentinel-2 bands - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p >Select a directory</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> - - - Apply DOS1 atmospheric correction - - - false - - - false - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Sentinel-2 conversion - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select metadata file (MTD_MSI) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Preprocess bands 1, 9, 10 - - - false - - - - - - - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Satellite - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Product - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-2A)</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Date (YYYY-MM-DD) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - Qt::ElideMiddle - - - 155 - - - true - - - - Band - - - - - Quantification value - - - - - Solar irradiance - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Sentinel-3 - - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Sentinel-3 conversion - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Directory containing Sentinel-3 bands - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p >Select a directory</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction</p></body></html> - - - Apply DOS1 atmospheric correction - - - false - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - Qt::ElideMiddle - - - 155 - - - true - - - - Band - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Satellite - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Product - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - - ASTER - - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - <html><head/><body><p>Open a file</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> - - - Apply DOS1 atmospheric correction - - - false - - - false - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - ASTER conversion to TOA reflectance and brightness temperature - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select file ASTER L1T (.hdf) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - <html><head/><body><p>Enable/Disable calculation of temperature in Celsius from thermal band</p></body></html> - - - Brightness temperature in Celsius - - - false - - - false - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - 155 - - - true - - - - Band - - - - - UnitConversionCoeff - - - - - PixelSize - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - - - - - - - <html><head/><body><p>Earth sun distance</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Earth sun -distance - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Date - (YYYYMMDD) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Sun elevation - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>SUN ELEVATION</p></body></html> - - - - - - - <html><head/><body><p>Upper left</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - UTM zone - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>UTM zone</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - UPPERLEFTM - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - LOWERRIGHTM - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Lower right</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - MODIS - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - MODIS conversion - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select file MODIS (.hdf) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Open a file</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -100000 - - - 100000 - - - -999 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - <html><head/><body><p>Reproject bands to WGS 84</p></body></html> - - - Reproject to WGS 84 - - - true - - - false - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - 155 - - - true - - - - Band - - - - - UnitConversionCoeff - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Date (YYYY-MM-DD) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - ID - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>DATE ACQUIRED</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Vector to raster - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Convert vector to raster - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the vector - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - Use the value field of the vector - - - true - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the value field</p></body></html> - - - - - - - - - - - <html><head/><body><p>Use constant value</p></body></html> - - - Use constant value - - - - - - - <html><head/><body><p>Value</p></body></html> - - - -100000 - - - 100000 - - - 1 - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the type of conversion - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the type of conversion</p></body></html> - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the reference raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - - - - - - - <html><head/><body><p>Use the same extent as reference raster</p></body></html> - - - Same extent as reference raster - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Clip multiple rasters - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Clip band set - - - - - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - - 0 - 0 - - - - - 50 - false - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - - 100 - 16777215 - - - - - 50 - false - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - QFrame::Sunken - - - Use value as NoData - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - clip - - - 10 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Lower right X</p></body></html> - - - 10 - - - X - - - - - - - <html><head/><body><p>Upper left X</p></body></html> - - - 10 - - - X - - - - - - - <html><head/><body><p>Upper left Y</p></body></html> - - - 10 - - - Y - - - - - - - <html><head/><body><p>Lower right Y</p></body></html> - - - 10 - - - Y - - - - - - - QFrame::Sunken - - - LR - - - Qt::AlignCenter - - - - - - - <html><head/><body><p>Set area in the map</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Clip coordinates - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Show / hide area</p></body></html> - - - Show - - - true - - - false - - - - - - - QFrame::Sunken - - - UL - - - Qt::AlignCenter - - - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the vector for clipping</p></body></html> - - - - - - - <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> - - - Use vector for clipping - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> - - - Use temporary ROI for clipping - - - - - - - - - <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> - - - Use vector field for output name - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Reproject raster bands - - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 605 - 20 - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Reproject raster bands - - - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the reference raster</p></body></html> - - - - - - - <html><head/><body><p>Align to raster</p></body></html> - - - Align to raster - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> - - - same extent as reference - - - - - - - - - - - <html><head/><body><p>EPSG value</p></body></html> - - - - - - 10 - - - - - - - <html><head/><body><p>Use EPSG value</p></body></html> - - - Use EPSG code - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Y resolution - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - X resolution - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>X resolution</p></body></html> - - - - - - 10 - - - - - - - <html><head/><body><p>Y resolution</p></body></html> - - - - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> - - - Resample pixel factor - - - - - - - <html><head/><body><p>Resample factor</p></body></html> - - - 1 - - - 10 - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Resampling method - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the resampling method</p></body></html> - - - - nearest_neighbour - - - - - average - - - - - sum - - - - - maximum - - - - - minimum - - - - - mode - - - - - median - - - - - first_quartile - - - - - third_quartile - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Output type - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select a type</p></body></html> - - - - Auto - - - - - Float32 - - - - - Int32 - - - - - UInt32 - - - - - Int16 - - - - - UInt16 - - - - - Byte - - - - - - - - - - - - <html><head/><body><p>If checked, change output NoData value</p></body></html> - - - Change output NoData value - - - - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - -2147483647 - - - 2147483647 - - - -32768 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - reproj - - - 10 - - - - - - - - - Qt::Vertical - - - - 20 - 198 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - - Split raster bands - - - - - - Qt::Vertical - - - - 20 - 302 - - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the image to be split</p></body></html> - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Split raster bands - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select a multiband raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - split - - - 10 - - - - - - - - - - - Qt::Horizontal - - - - 667 - 38 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Stack raster bands - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - Qt::Horizontal - - - - 647 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 339 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Stack band set - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - Mosaic band sets - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Mosaic of band sets - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - mosaic - - - 10 - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Band set list - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use * for selecting all the band sets</p></body></html> - - - 1, 2 - - - - - - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - - Create virtual raster output - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - Cloud masking - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - - - - 0 - 0 - - - - - 400 - 26 - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - - 10000 - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Mask class values - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - mask - - - 10 - - - - - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - 1 - - - 1000 - - - 1 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - <html><head/><body><p>If checked, create a buffer for class values</p></body></html> - - - Use buffer of pixel size - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - -32768 - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Output NoData value - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - Qt::Vertical - - - - 20 - 173 - - - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Mask of band set - - - - - - - - - - GOES - - - - - - - - - - <html><head/><body><p>No data value</p></body></html> - - - -999 - - - 100000 - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - GOES conversion - - - - - - - <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> - - - Create Band set and use Band set tools - - - true - - - false - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Directory containing GOES bands - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p >Select a directory</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - - <html><head/><body><p>Create a new band set where bands are added</p></body></html> - - - Add bands in a new Band set - - - true - - - false - - - - - - - - - - - <html><head/><body><p>Edit metadata</p></body></html> - - - Qt::ElideMiddle - - - 155 - - - true - - - - Band - - - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Metadata - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Satellite - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Satellite (e.g. Sentinel-3A)</p></body></html> - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - - Neighbor pixels - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - - 50 - false - - - - QFrame::Sunken - - - Matrix file (optional) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p><span >Open a file</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Output name prefix - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Output name prefix</p></body></html> - - - neighbor - - - 10 - - - - - - - - - <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> - - - Create virtual raster output - - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Neighbor pixels - - - - - - - - - - - - 0 - 0 - - - - - 200 - 16777215 - - - - <html><head/><body><p>Enter a value</p></body></html> - - - - - - 10000 - - - - - - - - 1 - 0 - - - - - 200 - 16777215 - - - - <html><head/><body><p>Select a statistic</p></body></html> - - - - - - - QFrame::Sunken - - - Select a statistic - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Statistic - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Neighbor distance in pixels - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - <html><head/><body><p>Distance in pixels</p></body></html> - - - 1 - - - 1000 - - - 1 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - - Circular - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - Band processing - - - - - - - - - 0 - - - - 20 - 20 - - - - true - - - - Band combination - - - - - - 0 - - - - - 0 - 0 - 723 - 351 - - - - Input - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select input band set (of classifications) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Combination of band values - - - - - - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - 120 - - - false - - - - - - - - - - - - - - PCA - - - - - - - - - 0 - - - - - 0 - 0 - 459 - 196 - - - - Input - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Principal Components Analysis of band set - - - - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - - - - - <html><head/><body><p>If checked, calculate this number of components only</p></body></html> - - - Number of components - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -999999999 - - - 999999999 - - - 0 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - - - - - <html><head/><body><p>Number of components</p></body></html> - - - 2 - - - 1000 - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - + + + + - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft + <html><head/><body><p>Set area in the map</p></body></html> margin: 0px;padding: 0px; - - BATCH - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg - 34 - 34 + 22 + 22 - - Qt::ToolButtonTextBesideIcon - - - - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - - Courier 10 Pitch - - - - true + + + + <html><head/><body><p>Lower right X</p></body></html> - - QTextEdit::NoWrap + + - - 160 + + 15 - - false + + X (Lon) - - - - - - - - - - - Clustering - - - - - - - - - 0 - - - - - 0 - 0 - 764 - 390 - - - - Input - - - - - - - - background-color : #656565; color : white + + + + <html><head/><body><p>Upper left X</p></body></html> - - QFrame::Panel + + 15 + + + X (Lon) + + + + QFrame::Sunken - Clustering of band set + LR + + + Qt::AlignCenter - - - - - - - - <html><head/><body><p>If checked, use ISODATA</p></body></html> + + + + QFrame::Sunken - ISODATA - - - false + UL - - false + + Qt::AlignCenter - - + + - <html><head/><body><p>Band set number</p></body></html> + <html><head/><body><p>Lower right Y</p></body></html> - - 1 + + 15 - - 100000 + + Y (Lat) - - - - - 0 - 0 - - - - QFrame::Sunken + + + + <html><head/><body><p>Upper left Y</p></body></html> - - Method + + 15 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + Y (Lat) - - - - - 0 - 0 - - - - QFrame::Sunken + + + + <html><head/><body><p>Show / hide area</p></body></html> - Select input band set + Show - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + true + + + false - - + + + + + + <html><head/><body><p>Find images</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_search_images.svg + + + + 22 + 22 + + + + + + + + Find + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + <html><head/><body><p>Select a product</p></body></html> + + + + + + + + 0 + 0 + 0 + 2016 + 1 + 1 + + + + + 2045 + 12 + 31 + + + + + 1972 + 1 + 1 + + + + yyyy-MM-dd + + + true + + + + 2016 + 1 + 1 + + + + + + + + QFrame::Sunken + + + Max cloud cover (%) + + + Qt::AlignCenter + + + + + + + + 2045 + 12 + 31 + + + + + 1980 + 1 + 2 + + + + yyyy-MM-dd + + + true + + + + 2045 + 12 + 31 + + + + + + + + QFrame::Sunken + + + to + + + Qt::AlignCenter + + + + + + + QFrame::Sunken + + + Date from + + + Qt::AlignCenter + + + + + + + + 50 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Maximum cloud cover percentage</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 100 + + + 10 + + + 100 + + + + + + + QFrame::Sunken + + + Products + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFrame::Sunken + + + Results + + + Qt::AlignCenter + + + + + + + QFrame::Sunken + + + Advanced search + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + <html><head/><body><p>Filter images</p></body></html> + + + 10000 + + + + + + + + 50 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Maximum number of results (images)</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 5 + + + 2000 + + + 5 + + + 20 + + + + + + + + + + + + + + + + + - <html><head/><body><p>If checked, use K-means</p></body></html> - - - &K-means - - - true - - - false + <html><head/><body><p >Delete row</p></body></html> - - - - - - Qt::Horizontal + + margin: 0px;padding: 0px; - - - 40 - 20 - + + Plot - - - - - - Qt::Horizontal + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - + - 40 - 20 + 22 + 22 - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Max number of iterations - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - <html><head/><body><p>Threshold</p></body></html> - - - 7 - - - 0.000001000000000 - - - 10000000.000000000000000 - - - 0.000010000000000 - - - 0.000100000000000 - - - - - + - <html><head/><body><p>Threshold</p></body></html> - - - 7 - - - 0.000001000000000 - - - 1000000000.000000000000000 - - - 0.000010000000000 - - - 0.000100000000000 + <html><head/><body><p>Display preview of highlighted images in map</p></body></html> - - - - - - <html><head/><body><p>If checked, for K-means: iteration is terminated if distance is lower than threshold; for ISODATA: signatures are merged if distance is greater than threshold</p></body></html> + + margin: 0px;padding: 0px; - Distance threshold - - - true - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -999999999 + Plot - - 999999999 + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_image_preview.svg - - 0 + + + 22 + 22 + - - + + - <html><head/><body><p>Set the maximum number of iterations</p></body></html> - - - 1 - - - 1000 - - - 10 - - - - - - - - 0 - 0 - + <html><head/><body><p><span >Reset</span></p></body></html> - - QFrame::Sunken + + margin: 0px;padding: 0px; - ISODATA max standard deviation - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true + Import library - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - Use value as NoData + + + 22 + 22 + - - + + - <html><head/><body><p>Number of classes</p></body></html> - - - 1 - - - 1000 - - - 10 - - - - - - - - 0 - 0 - + <html><head/><body><p>Export table to text file</p></body></html> - - QFrame::Sunken + + margin: 0px;padding: 0px - Number of classes - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Plot - - - - - - Qt::Horizontal + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - + - 40 - 20 - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - ISODATA minimum class size in pixels - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true + 22 + 22 + - - + + - <html><head/><body><p>Minimum class size in pixels</p></body></html> + <html><head/><body><p>Import table from text file</p></body></html> - - 1 + + margin: 0px;padding: 0px - - 1000000 + + Plot - - 10 + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg + + + + 22 + 22 + + + + + + + + 0 + 0 + + + + + 300 + 300 + + + + QFrame::Panel + + + QFrame::Sunken + + + Preview + + + Qt::AlignCenter + + + + + - - - - - - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> - - - Minimum Distance - - - true - - - false - - - - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - Save resulting signatures to Signature list - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Distance algorithm - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Seed signatures - - - - - - - - - - - - - <html><head/><body><p>If checked, use signatures in Signature list as seed signatures</p></body></html> - - - Use Signature list as seed signatures - - - false - - - false - - - - - - - <html><head/><body><p>If checked, calculate seed signatures from random pixels</p></body></html> - - - Use random seed signatures - - - false - - - false - - - - - - - <html><head/><body><p>If checked, calculate seed signatures from minimum and maximum values of bands</p></body></html> - - - Seed signatures from band values - - - true - - - false - - - - - - - - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - Spectral Angle Mapping - - - false - - - false - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Vertical - - - - 38 - 0 - - - - - + + + + QFrame::Sunken + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + QAbstractItemView::SelectRows + + + true + + + true + + + 22 + + + + product + + + + + image + + + + + product_id + + + + + acquisition_date + + + + + cloud_cover + + + + + zone_path + + + + + row + + + + + min_lat + + + + + min_lon + + + + + max_lat + + + + + max_lon + + + + + collection + + + + + size + + + + + preview + + + + + uid + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Product list + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Filter</p></body></html> + + + Filter + + + + + + + + + + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_login.svg + + + Login data + + + + + + Qt::Vertical + + + + 20 + 251 + + + + + + + + + + <html><head/><body><p>If checked, remember user name and password locally in QGIS (WARNING: password is stored unencrypted)</p></body></html> + + + remember + + + + + + + <html><head/><body><p>Password</p></body></html> + + + + + + + Password + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + <html><head/><body><p>Login Harmonized Landsat Sentinel-2 (<a href="https://urs.earthdata.nasa.gov"><span style=" text-decoration: underline; color:#ffffff;">https://urs.earthdata.nasa.gov</span></a>)</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>User name</p></body></html> + + + + + + + User + + + + + + + verticalSpacer_44 + + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + <html><head/><body><p><span style=" color:#ffffff;"> Download</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>Load images in QGIS after download</p></body></html> + + + Load bands in QGIS + + + + + + + <html><head/><body><p>Download images from list only if the corresponding previews are loaded in QGIS</p></body></html> + + + Only if preview in Layers + + + true + + + + + + + <html><head/><body><p>Export download links to a text file</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>If checked, download as virtual file only the portion of the image defined by search coordinates (does not work for all the sources)</p></body></html> + + + Virtual download + + + + + + + <html><head/><body><p>Preprocess images</p></body></html> + + + Preprocess images + + + true + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 1 + + + true + + + + + + + <html><head/><body><p>Sentinel</p></body></html> + + + 8A + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 4 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 11 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 5 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 6 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 7 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 2 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 9 + + + true + + + + + + + <html><head/><body><p >Select all</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg + + + + 22 + 22 + + + + + + + + Ancillary data + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 3 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 8 + + + true + + + + + + + <html><head/><body><p>Landsat / Sentinel</p></body></html> + + + 10 + + + true + + + + + + + <html><head/><body><p>Sentinel</p></body></html> + + + 12 + + + true + + + + + + + Bands + + + + + + + + + + + + Basic tools + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + + + + 20 + 20 + + + + true + + + + RGB composite + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + RGB composite + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Sort RGB automatically</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_order_by_name.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Move highlighted RGB down</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg + + + + 22 + 22 + + + - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - 160 - - - false - - - - + + + <html><head/><body><p>Move highlighted RGB up</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg + + + + 22 + 22 + + + - - - - - - - - Spectral distance - - - - + - - - <html><head/><body><p>If checked, use Minimum Distance algorithm</p></body></html> + + + + + <html><head/><body><p >Add row</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Export RGB list to text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Import RGB list from text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p><span >Reset</span></p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p >Delete row</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + - - Minimum Distance + + QAbstractItemView::DoubleClicked - + true - - false + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + 50 + + + true + + + 22 + + + + RGB + + - - + + + + + + - + 0 0 + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + QFrame::Sunken - Distance algorithm + Automatic RGB Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - <html><head/><body><p>If checked, use Spectral Angle Mapping algorithm (only for K-means)</p></body></html> - - - Spectral Angle Mapping - - - false - - - false - - - - - + + - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Spectral distance of band sets - - - - - - - - - - - <html><head/><body><p>If checked, calculate a raster of changes where distance is above threshold</p></body></html> - - - Distance threshold - - - true - - - - - - - <html><head/><body><p>Threshold</p></body></html> - - - 7 - - - 0.000001000000000 - - - 1000.000000000000000 - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - + - + 0 0 @@ -14711,63 +3271,38 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Select first input band set + Band combinations Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 - - - 2 - - - - - - - - 0 - 0 - + <html><head/><body><p>Add all combinations of bands</p></body></html> - - QFrame::Sunken + + margin: 0px;padding: 0px; - Select second input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Band set number</p></body></html> + Import library - - 1 + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - 100000 + + + 22 + 22 + - - + + Qt::Horizontal @@ -14781,522 +3316,295 @@ p, li { white-space: pre-wrap; } - - - - - - - - background-color : #656565; color : white + + + + + + + Multiple ROI creation + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p align="justify">Minimum distance between points</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 999999999 + + + 100 + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p align="justify">Size of a grid cell within points are created randomly</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 999999999 + + + 10000 + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Create random points + + + + + + + + 0 + 0 + - - QFrame::Panel + + Create points + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + QFrame::Sunken - Run + Number of points Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - Qt::Horizontal + + + + + 0 + 0 + - + 40 - 20 + 0 - - - - - - Qt::Vertical - - + - 38 - 37 + 100 + 16777215 - - - - - - - 75 - true - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; + <html><head/><body><p align="justify">Number of points created randomly</p></body></html> - - RUN + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + 1 - - - 34 - 34 - + + 999999999 - - Qt::ToolButtonTextBesideIcon + + 100 - - - - - 75 - true - - + + - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft + <html><head/><body><p>Create points</p></body></html> margin: 0px;padding: 0px; - - BATCH - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - 34 - 34 + 22 + 22 - - Qt::ToolButtonTextBesideIcon + + + + + + <html><head/><body><p>Create random points with a minimum distance</p></body></html> + + + min distance - - - - - - - Classification - - - - - - - - - - - 0 - 0 - - - - Use - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - MC ID - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - C ID - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Open tab Algorithm band weight</p></body></html> - - - margin: 0px;padding: 0px; - - - W - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_weight_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_weight_tool.svg - - - - 22 - 22 - - - - - + + + + <html><head/><body><p>Create random points inside each cell of a grid with this size</p></body></html> + + + inside grid + + - - - - - 0 - 0 - + + + + Qt::Horizontal - + - 100 - 0 + 40 + 20 - - <html><head/><body><p>Select a classification algorithm</p></body></html> - - - - Minimum Distance - - - - - Maximum Likelihood - - - - - Spectral Angle Mapping - - - + - - + + - <html><head/><body><p>Band set number</p></body></html> - - - 1 + <html><head/><body><p>Create stratified random points</p></body></html> - - 100000 + + stratified for the values - - + + - + 0 0 - - QFrame::Sunken + + + 400 + 0 + + + + <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. raster &gt; 0; raster == 1 )</p></body></html> - Select input band set + raster > 0 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 10000 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken + + + + <html><head/><body><p>Band set number</p></body></html> - - Algorithm + + 1 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 100000 - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 4 - - - 10000.000000000000000 - - - - - - - <html><head/><body><p>Open tab Signature threshold</p></body></html> - - - margin: 0px;padding: 0px; - - - W - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Threshold - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - + + QFrame::Sunken - Classification + of first band of band set Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - <html><head/><body><p>If checked, the Land Cover Signature Classification is used</p></body></html> - - - LCS - - - - - - - - 0 - 0 - - - - Use - - - - - - - <html><head/><body><p>Open tab LCS threshold</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>If checked, the selected Algorithm is used only for class overlapping pixels of the Land Cover Signature Classification</p></body></html> - - - only overlap - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Land Cover Signature Classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>If checked, the selected Algorithm is used for unclassified pixels of the Land Cover Signature Classification</p></body></html> - - - Algorithm - - - - - - - + + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -15305,217 +3613,247 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Classification output + Point coordinates and ROI definition - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + true + + false + + + 90 + + + 24 + + + + X + + + + + Y + + + + + MC ID + + + + + MC Name + + + + + C ID + + + + + C Name + + + + + Min + + + + + Max + + + + + Dist + + + + + Rapid ROI band + + - - - - 4 - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - Load qml style - - - - - - - <html><head/><body><p><span >Select qml style</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - false - - - <html><head/><body><p>Qml file path</p></body></html> - - - - - - - - - - - <html><head/><body><p>Select an optional mask vector</p></body></html> - - - Apply mask - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - false - - - <html><head/><body><p>Path of the optional mask shapefile</p></body></html> - - - Qt::ImhUrlCharactersOnly - - - - - + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p >Add row</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p >Delete row</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p >Export point list to text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p >Import point list from text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - - - <html><head/><body><p>Create a classification shapefile after the classification process</p></body></html> - - - Create vector - - - - - - - <html><head/><body><p>Calculate a classification report</p></body></html> - - - Classification report - - - - - - - <html><head/><body><p>If enabled, the rasters calculated by the classification algorithm (one per signature) are saved along with the classification</p></body></html> + + + + + + Qt::Horizontal - - Save algorithm files + + + 40 + 20 + - + - - - - - - - - - 75 - true - - + + - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; + <html><head/><body><p>Add ROI spectral signatures to signature list</p></body></html> - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - + Calculate sig. - - Qt::ToolButtonTextBesideIcon + + true - - + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -15531,34 +3869,8 @@ p, li { white-space: pre-wrap; } - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + 75 @@ -15566,7 +3878,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>Function to Batch</p></body></html> + <html><head/><body><p><span >Run</span></p></body></html> Qt::RightToLeft @@ -15575,11 +3887,11 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - BATCH + RUN - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg @@ -15598,116 +3910,52 @@ p, li { white-space: pre-wrap; } - + - Random forest + Import signatures - + - - - - + - 0 + 2 - + 0 0 - 634 - 327 + 461 + 432 - Input + Download USGS Spectral Library - - - - - - - - - - 0 - 0 - - - - Use - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - - - MC ID - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - - - C ID - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + + + + <html><head/><body><p>Select a chapter</p></body></html> + + - + - <html><head/><body><p>Band set number</p></body></html> - - - 1 - - - 100000 + <html><head/><body><p>Select a library</p></body></html> - - + + + + + - + 0 0 @@ -15716,92 +3964,30 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Select input band set - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + <html><head/><body><p>Select a chapter</p></body></html> - - - - background-color : #656565; color : white - - - QFrame::Panel + + + + + 0 + 0 + QFrame::Sunken - - - Random Forest classification (ESA SNAP software required) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Number of trees</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 1.000000000000000 - - - 1000000.000000000000000 - - - 1.000000000000000 - - - 10.000000000000000 - - - + + + <html><head/><body><p>Select a library</p></body></html> + + + + + - - - - 0 - 0 - - - - - 150 - 16777215 - - - - Number of trees - - - - - + Qt::Horizontal @@ -15813,404 +3999,291 @@ p, li { white-space: pre-wrap; } - - - - - + - + 0 0 - - - 100 - 16777215 - - - - <html><head/><body><p>Number of training samples</p></body></html> + + Import spectral library - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 1.000000000000000 - - - 1000000.000000000000000 - - - 100.000000000000000 - - - 5000.000000000000000 + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - 0 - 0 - - - - - 208 - 16777215 - + + + + <html><head/><body><p>Import spectral library</p></body></html> - - Number of training samples + + margin: 0px;padding: 0px; - - - - - - Qt::Horizontal + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - + - 40 - 20 + 22 + 22 - + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Evaluate classifier</p></body></html> - - - Evaluate classifier - - - - - - - - 0 - 0 - - - - <html><head/><body><p>If checked, evaluate feature power set</p></body></html> - - - Evaluate feature power set - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Max - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Minumum power</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 1.000000000000000 - - - 1000000.000000000000000 - - - 1.000000000000000 - - - 2.000000000000000 - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Min - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>Maximum power</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 1.000000000000000 - - - 1000000.000000000000000 - - - 1.000000000000000 - - - 7.000000000000000 - - - - - - - - 0 - 0 - - - - <html><head/><body><p>If checked, save classifier</p></body></html> - - - Save classifier - - - - - - - - - - - - 0 - 0 - + + + + QFrame::Panel - - Load classifier + + QFrame::Sunken + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans'; font-size:9pt;"><br /></p></body></html> + + + true - - - - <html><head/><body><p>Select a previosly saved classifier</p></body></html> + + + + + 8 + - - margin: 0px;padding: 0px; + + QFrame::Panel + + + QFrame::Sunken - Import library + <html><head/><body><p>USGS Spectral Library Version 7 downloaded from <a href="https://crustal.usgs.gov/speclab/QueryAll07a.php"><span style=" text-decoration: underline; color:#0000ff;">https://crustal.usgs.gov/speclab/QueryAll07a.php</span></a>.<br/><span style=" font-weight:600;">Reference</span>: Kokaly, R.F., Clark, R.N., Swayze, G.A., Livo, K.E., Hoefen, T.M., Pearson, N.C., Wise, R.A., Benzel, W.M., Lowers, H.A., Driscoll, R.L., and Klein, A.J., 2017, USGS Spectral Library Version 7: U.S. Geological Survey Data Series 1035, 61 p., https://doi.org/10.3133/ds1035.</p></body></html> - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg + + true - - - 22 - 22 - + + true - - - - false - - - <html><head/><body><p>Classifier file path</p></body></html> + + + + background-color : #5a5a5a; color : white; font: bold - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> + + QFrame::Panel - - margin: 0px;padding: 0px; + + QFrame::Sunken - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg + Library Description (requires internet connection) - - - 22 - 22 - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - 75 - true - - + + + + + + 0 + 0 + 461 + 169 + + + + Import vector + + + + + + - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft + <html><head/><body><p>Open a file</p></body></html> margin: 0px;padding: 0px; - - RUN - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - 34 - 34 + 20 + 20 - - Qt::ToolButtonTextBesideIcon - - - - - background-color : #656565; color : white - - - QFrame::Panel + + + + + 0 + 0 + QFrame::Sunken - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + <html><head/><body><p>Select a vector (*.shp;*.gpkg)</p></body></html> - - + + + + + + + 1 + 0 + + + + <html><head/><body><p>C ID field</p></body></html> + + + + + + + + 1 + 0 + + + + <html><head/><body><p>MC ID field</p></body></html> + + + + + + + + 1 + 0 + + + + <html><head/><body><p>MC Name field</p></body></html> + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + C Name field + + + + + + + + 1 + 0 + + + + <html><head/><body><p>C Name field</p></body></html> + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Vector fields + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + C ID field + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + MC ID field + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + MC Name field + + + + + + + Qt::Vertical @@ -16222,51 +4295,76 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + + Import vector + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Add ROI spectral signature to signature list</p></body></html> + + + Calculate sig. + + + true + + + + + + + <html><head/><body><p>Import vector</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + + + + 22 + 22 + + + + + - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft + + + + QFrame::Panel - - margin: 0px;padding: 0px; + + QFrame::Sunken - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon + @@ -16274,195 +4372,42 @@ p, li { white-space: pre-wrap; } - + 0 0 - 98 - 90 + 771 + 53 - Output + Import library file - + - + - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - 160 - - - false - - - - - - - - - - - - - - - - - - Postprocessing - - - - - - - - - 0 - - - - 20 - 20 - - - - true - - - - Accuracy - - - - - - 0 - - - - - 0 - 0 - 723 - 351 - - - - Input - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification to assess - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select the reference vector or raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification to assess</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; + + + QFrame::Sunken - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - + <html><head/><body><p>Select a file: training file (*.scpx; *.scp) ; USGS library (*.zip) ; ASTER library (*.txt) ; CSV (*.csv)</p></body></html> - - + + - <html><head/><body><p >Refresh list</p></body></html> + <html><head/><body><p><span >Open a file</span></p></body></html> margin: 0px;padding: 0px; - - Plot - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg @@ -16472,132 +4417,178 @@ p, li { white-space: pre-wrap; } - - - - - 1 - 0 - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Accuracy assessment - - - - - - - - - - 0 - 0 - - - - - 6 - 0 - + + + + Qt::Vertical - + - 100 - 200 + 20 + 40 - - QFrame::Sunken - - - Vector field - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the field of the classification code </p></body></html> - - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - 0 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + - - - - + + + + + + + + + Export signatures + + + + + + + + QFrame::Sunken + + + <html><head/><body><p>Export as training file (*.scpx)</p></body></html> + + + + + + + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> + + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Select a directory where highlighted spectral signatures are saved as .csv</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg + + + + 22 + 22 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Export + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + QFrame::Sunken + + + <html><head/><body><p>Export geometries as shapefile (*.shp) or geopackage (*.gpkg)</p></body></html> + + + + + + + QFrame::Sunken + + + <html><head/><body><p>Export spectral signatures as CSV file (.csv)</p></body></html> + + + + + + + <html><head/><body><p >Export highlighted spectral signatures</p></body></html> + + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Signature threshold + + + + + + + + + + Qt::Vertical @@ -16609,1258 +4600,3816 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 40 - 20 - + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + <html><head/><body><p >Reset</p></body></html> + - - - - - background-color : #656565; color : white + margin: 0px;padding: 0px; - - QFrame::Panel + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - QFrame::Sunken + + + 22 + 22 + + + + + + + + + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectItems + + + true + + + 50 + + + true + + + 22 + + + + MC ID + + + + + MC Name + + + + + C ID + + + + + C Name + + + + + Minimum Distance + + + + + Maximum Likelihood + + + + + Spectral Angle Mapping + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Signature threshold + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + QFrame::Sunken + + + Set threshold = σ * + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> + + + 1 + + + 10000.000000000000000 + + + 1.000000000000000 + + + + + + + <html><head/><body><p>Set automatic threshold σ</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + + + + 22 + 22 + + + + + + + + - Run + Set threshold Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN + + + + <html><head/><body><p>Set a value</p></body></html> - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + 4 - - - 34 - 34 - + + 10000.000000000000000 - - Qt::ToolButtonTextBesideIcon + + 0.000000000000000 - - - - - 75 - true - - + + - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft + <html><head/><body><p >Set</p></body></html> + margin: 0px;padding: 0px; - - BATCH - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - 34 - 34 + 22 + 22 - - Qt::ToolButtonTextBesideIcon - - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - 120 - - - false - - - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Automatic thresholds + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + Preprocessing + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + + + + 20 + 20 + + + + true + + + + Image conversion + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + + 50 + false + + + + QFrame::Sunken + + + Directory containing bands + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Conversion to reflectance and temperature + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + <html><head/><body><p>Select MTL file (if not in Landsat directory)</p></body></html> + + + QFrame::Sunken + + + Select metadata file (optional) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p >Select a directory</p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_dir.svg + + + + 22 + 22 + + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + + + + <html><head/><body><p>Create the Band set automatically and use the checked Band set tools</p></body></html> + + + Create Band set and use Band set tools + + + true + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - - - - - - Land cover change - - - - - - 0 - - - - - 0 - 0 - 723 - 351 - - - - Input - - - - - - - <html><head/><body><p align="justify">If enabled, pixels having the same values in both classifications will be reported; if not enabled, 0 value is set for unchanged pixels</p></body></html> - - - Report unchanged pixels - - - true - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the reference classification raster</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select the new classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the reference classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select a new raster to be compared with the reference raster</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Land cover change - - - - - - + + + <html><head/><body><p>Enable/Disable the DOS1 atmospheric correction (thermal band is not corrected)</p></body></html> + + + Apply DOS1 atmospheric correction + + + false + + + false + + + + + + + <html><head/><body><p>Create a new band set where bands are added</p></body></html> + + + Create a new Band set + + + true + + - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + + + + <html><head/><body><p><span >Open a file</span></p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg + + + + 22 + 22 + + + + + + + + + + <html><head/><body><p>No data value</p></body></html> + + + -999 + + + 100000 + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + <html><head/><body><p>Edit metadata</p></body></html> + + + false + + + 155 + + + + product + + + + + spacecraft + + + + + processing_level + + + + + band_name + + + + + product_path + + + + + scale + + + + + offset + + + + + nodata + + + + + date + + + + + k1 + + + + + k2 + + + + + band_number + + + + + e_sun + + + + + sun_elevation + + + + + earth_sun_distance + + + + + + + + + + <html><head/><body><p >Delete row</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + + + + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Metadata + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Vector to raster + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Convert vector to raster + + + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the vector + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the vector</p></body></html> + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the type of conversion + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the type of conversion</p></body></html> + + + + pixel_center + - - - - - - 0 - 0 - 98 - 90 - - - - Output - - + + + all_touched + + + + + area_based + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::Sunken + + + Area precision + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Area precision for &quot;area_based&quot; method</p></body></html> + + + 20 + + + + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + <html><head/><body><p>Use constant value</p></body></html> + + + Use constant value + + + + + + + <html><head/><body><p>Value</p></body></html> + + + -100000 + + + 100000 + + + 1 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + <html><head/><body><p>Use the value field of the vector</p></body></html> + + + Use the value field of the vector + + + true + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the value field</p></body></html> + + + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the reference raster + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>If checked, align to reference raster</p></body></html> + + + Minimum extent + + + true + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Pixel size + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Output pixel size</p></body></html> + + + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the reference raster</p></body></html> + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Clip raster bands + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Clip band set + + + + + + + + + + + <html><head/><body><p>Output name prefix</p></body></html> + + + clip + + + 10 + + + + + + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + + Create virtual raster output + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 100 + 16777215 + + + + + 50 + false + + + + QFrame::Sunken + + + Output name prefix + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + + 0 + 0 + + + + + 50 + false + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + <html><head/><body><p>Show / hide area</p></body></html> + + + Show + + + true + + + false + + + + + + + <html><head/><body><p>Lower right Y</p></body></html> + + + 10 + + + Y + + + + + + + QFrame::Sunken + + + UL + + + Qt::AlignCenter + + + + + + + <html><head/><body><p>Lower right X</p></body></html> + + + 10 + + + X + + + + + + + <html><head/><body><p>Set area in the map</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_pointer_tool.svg + + + + 22 + 22 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::Sunken + + + LR + + + Qt::AlignCenter + + + + + + + <html><head/><body><p>Upper left Y</p></body></html> + + + 10 + + + Y + + + + + + + <html><head/><body><p>Upper left X</p></body></html> + + + 10 + + + X + + + + + + + <html><head/><body><p>Use coordinates for clipping rasters</p></body></html> + + + Use coordinates for clipping + + + true + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Clip coordinates + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the vector for clipping</p></body></html> + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - 160 - - - false - - - - + + + <html><head/><body><p>If checked, clip iterating through each vector polygon and add field value to the output name</p></body></html> + + + Use vector field for output name + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the vector field</p></body></html> + + - - + + + + + <html><head/><body><p>Use temporary ROI boundaries for clipping rasters</p></body></html> + + + Use temporary ROI for clipping + + + + + + + <html><head/><body><p>Use vector boundaries for clipping rasters</p></body></html> + + + Use vector for clipping + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Reproject raster bands + + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 605 + 20 + + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Reproject and resample band set + + + + + + + + + + + <html><head/><body><p>Align to raster</p></body></html> + + + Align to raster + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Keep the same extent as the reference raster</p></body></html> + + + same extent as reference + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the reference raster</p></body></html> + + + + - - - - - Classification report - - - - - - - - - 0 - - - - - 0 - 0 - 723 - 351 - - - - Input - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> - - - Use value as NoData - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - 0 - - - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - + + + + + + <html><head/><body><p>Use EPSG code</p></body></html> + + + Use EPSG code + + + true + + + + + + + <html><head/><body><p>Y resolution</p></body></html> + + + + + + 10 + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Y resolution + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + X resolution + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>EPSG value</p></body></html> + + + + + + 10 + + + + + + + <html><head/><body><p>X resolution</p></body></html> + + + + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + <html><head/><body><p>If checked, new pixel size is original pixel size times this factor</p></body></html> + + + Resample pixel factor + + + + + + + <html><head/><body><p>Resample factor</p></body></html> + + + 1 + + + 10 + + + + + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Resampling method + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the resampling method</p></body></html> + + + + nearest_neighbour + - - - - - - Qt::Horizontal - - - - 358 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Vertical - - - - 20 - 82 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + average + + + + + sum + + + + + maximum + + + + + minimum + + + + + mode + + + + + median + + + + + first_quartile + + + + + third_quartile + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Output type + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select a type</p></body></html> + + + + Auto + - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Classification report - - - - + + + Float32 + - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - 160 - - - false - - - - + + + Int32 + - - - + + + UInt32 + + + + + Int16 + + + + + UInt16 + + + + + Byte + + + + + - - - - - Cross classification - - - - - - 0 + + + + + + <html><head/><body><p>If checked, change output NoData value</p></body></html> + + + Change output NoData value + + + + + + + <html><head/><body><p>NoData value of the output raster</p></body></html> + + + -2147483647 + + + 2147483647 + + + -32768 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFrame::Sunken + + + Output name prefix + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Output name prefix</p></body></html> + + + reproj + + + 10 + + + + + + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> + + + Virtual output + + + + + + + + + + + <html><head/><body><p>If checked, compress raster output</p></body></html> + + + Compress + + + true + + + + + + + <html><head/><body><p>Compression method</p></body></html> + + + LZW + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 198 + - - - - 0 - 0 - 723 - 351 - - - - Input - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Cross classification - - - - - - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - - - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 6 - 0 - - - - - 100 - 200 - - - - QFrame::Sunken - - - Vector field - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the vector field</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the reference vector or raster</p></body></html> - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Select the reference vector or raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> - - - Calculate linear regression - - - - + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + + + Split raster bands + + + + + + Qt::Vertical + + + + 20 + 302 + + + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the image to be split</p></body></html> + + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Split raster bands + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select a multiband raster + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Output name prefix + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Output name prefix</p></body></html> + + + split + + + 10 + + + + + + + + + + + Qt::Horizontal + + + + 667 + 38 + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Stack raster bands + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + Qt::Horizontal + + + + 647 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 339 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Stack band set + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + Mosaic band sets + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Mosaic of band sets + + + + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + + Create virtual raster output + + + + + + + <html><head/><body><p>Output prefix</p></body></html> + + + mosaic_ + + + 10 + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + + + + + <html><head/><body><p>Output name</p></body></html> + + + band_ + + + 10 + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Output name + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Output prefix + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>List of band set numbers separated by comma ,<br/>Use# for selecting all the band sets</p></body></html> + + + 1, 2 + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Band set list + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Masking bands + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Mask of band set + + + + + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the classification</p></body></html> + + + + + + + + 0 + 0 + + + + + 400 + 26 + + + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> + + + + + + 10000 + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Mask class values + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the classification + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + + + + <html><head/><body><p>Output name prefix</p></body></html> + + + mask_ + + + 10 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - - - 0 - 0 - 98 - 90 - - - - Output - - - - - - - - Courier 10 Pitch - - - - true - - - QTextEdit::NoWrap - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> - - - 120 - - - false - - - - + + + true + + + <html><head/><body><p>If checked, create a buffer for class values</p></body></html> + + + Use buffer of pixel size + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + -32768 + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Output NoData value + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Size in pixels</p></body></html> + + + 1 + + + 1000 + + + 1 + + - - + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Output name prefix + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + + Create virtual raster output + + + + + + + + + Qt::Vertical + + + + 20 + 173 + + + + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + - + + + + + + + Band processing + + + + + + + + + 5 + + + + 20 + 20 + + + + true + + - Class signature + Combination - + - - - - + 0 - + 0 0 - 387 - 196 + 336 + 221 Input - + - + - + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -17869,81 +8418,42 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Class signature + Combination of band values - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + 0 @@ -17954,47 +8464,102 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Select input band set + Select input band set (of classifications) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + true + - - + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -999999999 + + + 999999999 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 75 + true + + - <html><head/><body><p>Band set number</p></body></html> + <html><head/><body><p>Function to Script</p></body></html> - - 1 + + Qt::RightToLeft - - 100000 + + margin: 0px;padding: 0px; - - - - - - Qt::Horizontal + + Script - + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + - 40 - 20 + 34 + 34 - + + Qt::ToolButtonTextBesideIcon + + - - - - - - + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -18010,8 +8575,8 @@ p, li { white-space: pre-wrap; } - - + + 75 @@ -18045,85 +8610,37 @@ p, li { white-space: pre-wrap; } - - + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 - - + + - Qt::Vertical + Qt::Horizontal - 38 - 37 + 40 + 20 - - - - <html><head/><body><p>If checked, save the resulting signatures to Signature list</p></body></html> - - - Save resulting signatures to Signature list - - - true - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + 0 @@ -18135,173 +8652,56 @@ p, li { white-space: pre-wrap; } Output - + - + - + Courier 10 Pitch - - - true - - - QTextEdit::NoWrap - - - 160 - - - false - - - - - - - - - - - - - - Classification to vector - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Classification to vector - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the code field</p></body></html> - - - - C_ID - - - - - MC_ID - + + + true + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> + + + 120 + + + false + + + + - - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - Use code from Signature list - - - - - - - - 0 - 0 - - + + + + + + + + + Dilation + + + + + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -18310,26 +8710,174 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Symbology + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select input band set (of classifications) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFrame::Sunken + + + Output name + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Enter output name</p></body></html> + + + dilation_ + + + 10000 + + + + + + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> + + + Virtual output + + + + + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Class values + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 400 + 26 + + + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> + + + + + + 10000 + + + + + + + + + Qt::Horizontal - - Dissolve output + + + 40 + 20 + - + - - - - - - + + Qt::Vertical @@ -18341,21 +8889,111 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal + + + + + 75 + true + - + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + - 40 - 20 + 34 + 34 - + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Size in pixels + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Size in pixels</p></body></html> + + + 1 + + + 1000 + + + 1 + + + + + + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + + Circular + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - + + 75 @@ -18363,7 +9001,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span >Run</span></p></body></html> + <html><head/><body><p>Function to Script</p></body></html> Qt::RightToLeft @@ -18372,11 +9010,11 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - RUN + Script - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg @@ -18389,10 +9027,14 @@ p, li { white-space: pre-wrap; } - - + + + + + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -18401,15 +9043,43 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Run + Band dilation - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + Erosion + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Band erosion - - + + + + + + 75 @@ -18417,7 +9087,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>Function to Batch</p></body></html> + <html><head/><body><p>Function to Script</p></body></html> Qt::RightToLeft @@ -18426,7 +9096,7 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - BATCH + Script @@ -18443,93 +9113,295 @@ p, li { white-space: pre-wrap; } - - - - - - - Reclassification - - - - - - - - - 0 - 0 - + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Class values + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 400 + 26 + + + + <html><head/><body><p>Enter class values separated by , or -</p></body></html> + + + + + + 10000 + + + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select input band set (of classifications) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal - + - 229 - 0 + 40 + 20 - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification raster</p></body></html> - - + - - + + + + + 75 + true + + - <html><head/><body><p >Refresh list</p></body></html> + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft margin: 0px;padding: 0px; - Plot + RUN - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - 22 - 22 + 34 + 34 + + Qt::ToolButtonTextBesideIcon + - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + - - - background-color : #656565; color : white + + + + 0 + 0 + - - QFrame::Panel + + + 229 + 0 + QFrame::Sunken - Reclassification + Size in pixels + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Size in pixels</p></body></html> + + + 1 + + + 1000 + + + 1 + + + + + + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + + + Circular + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFrame::Sunken + + + Output name + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Enter output name</p></body></html> + + + erosion_ + + + 10000 + + + + + + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> + + + Virtual output @@ -18537,64 +9409,97 @@ p, li { white-space: pre-wrap; } - - - - - - <html><head/><body><p>Calculate unique values</p></body></html> - + + + + + Sieve + + + + + + - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> + background-color : #5a5a5a; color : white; font: bold - - calculate C ID to MC ID values + + QFrame::Panel - - - - - - - 0 - 0 - + + QFrame::Sunken - Calculate unique values - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Band sieve - - - - - 0 - 0 - - + + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select input band set (of classifications) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -18603,444 +9508,613 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Values + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + + + + 75 + true + + - <html><head/><body><p>Set incremental new values</p></body></html> + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft margin: 0px;padding: 0px; + + RUN + - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - 22 - 22 + 34 + 34 + + Qt::ToolButtonTextBesideIcon + - - - - - 0 - 0 - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; - Incremental new values + Script - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon - - - - - - - - true + + + + Qt::Horizontal - - false + + + 40 + 20 + - - true - - - 24 - - - - Old value - - - - - New value - - - + - - - - - - <html><head/><body><p >Add row</p></body></html> + + + + + + + 0 + 0 + - - margin: 0px;padding: 0px; + + + 229 + 0 + - - Plot + + QFrame::Sunken - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg + + Size threshold - - - 22 - 22 - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; + <html><head/><body><p>Size threshold in pixels</p></body></html> - - Plot + + 2 - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + 10000 - - - 22 - 22 - + + 2 - - + + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 - - - - Qt::Vertical + + + + + 0 + 0 + - + - 20 - 40 + 229 + 0 - + + QFrame::Sunken + + + Pixel connection + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - + + + + + 1 + 0 + + + + + 80 + 16777215 + + - <html><head/><body><p>Import reclassification table from text file</p></body></html> + <html><head/><body><p>Pixel connection</p></body></html> - - margin: 0px;padding: 0px + + + 4 + + + + + 8 + + + + + + + + + + + + QFrame::Sunken - Plot + Output name - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + - <html><head/><body><p>Export reclassification table to text file</p></body></html> - - - margin: 0px;padding: 0px + <html><head/><body><p>Enter output name</p></body></html> - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + sieve_ - - - 22 - 22 - + + 10000 - - - - Qt::Vertical + + + + <html><head/><body><p>If checked, use virtual output to merge multiprocess parts</p></body></html> - - - 20 - 40 - + + Virtual output - + - - - - - - - - <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - Use code from Signature list - - - false - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the code field</p></body></html> - + + + + + PCA + + + + + + + + + 0 + + + + + 0 + 0 + 493 + 202 + + + + Input + + + + - - MC_ID - + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Principal Components Analysis of band set + + + + + + + + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -999999999 + + + 999999999 + + + 0 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>Number of components</p></body></html> + + + 2 + + + 1000 + + + + + + + <html><head/><body><p>If checked, calculate this number of components only</p></body></html> + + + Number of components + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - - C_ID - + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Symbology - - + + + + + + 0 + 0 + 98 + 90 + + + + Output + + + + + + + + + Courier 10 Pitch + + + + true + + + QTextEdit::NoWrap + + + 160 + + + false + + + + - - + + - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + + + Classification + + + + + + + 75 + false + true + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Algorithm + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - - - - Edit raster - - - - - - - background-color : #656565; color : white - - - QFrame::Panel + + + + + + 0 + 0 + QFrame::Sunken - Edit raster - - - - - - - - - - - false - - - <html><head/><body><p>Undo edit (only for ROI polygons)</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_edit_raster.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_edit_raster.svg + Select input band set - - - 22 - 22 - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -19049,547 +10123,1866 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Run + Input Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - + + + + <html><head/><body><p>Band set number</p></body></html> + + + 1 + + + 100000 + + + + + + + - + 0 0 - - - 229 - 0 - - - - QFrame::Sunken + + <html><head/><body><p>Linear scaling normalization</p></body></html> - Select the input raster + Linear scaling - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + false - - + + - - 1 + + 0 0 - <html><head/><body><p>Select the raster to edit</p></body></html> + <html><head/><body><p>Z-score normalizatin</p></body></html> - - - - - - <html><head/><body><p >Refresh list</p></body></html> + + Z-score - - margin: 0px;padding: 0px; + + true - - Plot + + false - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + + + Qt::Horizontal - + - 22 - 22 + 40 + 20 - + - - - - - - + + + + + 0 + 0 + + - <html><head/><body><p>Use constant value</p></body></html> + <html><head/><body><p>If checked, use input normalization</p></body></html> - Use constant value + Use input normalization - true + false + + + + - - - <html><head/><body><p>Value</p></body></html> - - - -2147483647 + + + + 0 + 0 + - - 2147483647 + + Use training - - - Qt::Horizontal - - - - 40 - 20 - + + + + 0 + 0 + - - - - - - - - - <html><head/><body><p>Use expression</p></body></html> + <html><head/><body><p>Use the ID of macroclasses for the classification</p></body></html> - Use expression + Macroclass ID + + + true + + + false - + - + 0 0 - - - 400 - 26 - - - <html><head/><body><p>Enter expression</p></body></html> + <html><head/><body><p>Use the ID of classes for the classification</p></body></html> - where(raster == 1, 2, raster) + Class ID - - 10000 + + false + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - Qt::Horizontal + + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + - + + <html><head/><body><p>Save classifier to file</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Save classifier + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + - 40 - 20 + 34 + 34 - + + Qt::ToolButtonTextBesideIcon + + - - - - Qt::Vertical + + + + <html><head/><body><p>Select a previously saved classifier</p></body></html> - + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg + + - 20 - 40 + 22 + 22 - + - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Edit raster values - - - - + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + - - - - - - <html><head/><body><p>Use the value field of the vector</p></body></html> - - - Use the value field of the vector - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the value field</p></body></html> - - + + + + + 0 + 0 + + + + Load classifier + + + + + + + + + 2 + + + + + 0 + 0 + 705 + 113 + + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_options.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_options.svg + + + Maximum Likelihood + + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Use + + + + + + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> + + + Save signature raster + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> + + + Signature threshold + + + + + + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + + + margin: 0px;padding: 0px; + + + W + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg + + + + 22 + 22 + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + 100.000000000000000 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> + + + Single threshold + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - - - - <html><head/><body><p>Edit values using a vector</p></body></html> - - - Edit values using a vector - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the vector</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - + + + + + 0 + 0 + 555 + 113 + + + + Minimum Distance + + + + + + + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> + + + Save signature raster + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Use + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> + + + Single threshold + + + false + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + 100.000000000000000 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> + + + Signature threshold + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + + + margin: 0px;padding: 0px; + + + W + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + - - - - - - - <html><head/><body><p>Edit values using temporary ROIs</p></body></html> - - - Edit values using ROI polygons - - - true - - + + + + + 0 + 0 + 732 + 243 + + + + Multi-Layer Perceptron + + + + + + + + Activation + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Weight decay (also L2 regularization term) for Adam optimizer</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 5 + + + 0.000010000000000 + + + 1000.000000000000000 + + + 0.000100000000000 + + + 0.010000000000000 + + + + + + + <html><head/><body><p>Sets the number of samples per batch for optimizer; if auto, the batch is the minimum value between 200 and the number of samples</p></body></html> + + + auto + + + 10000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Training proportion + + + + + + + Batch size + + + + + + + + + + 0 + 0 + + + + Use framework + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Use scikit-learn framework</p></body></html> + + + scikit-learn + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Use PyTorch framework</p></body></html> + + + PyTorch + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Sets the maximum number of iterations</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 1.000000000000000 + + + 100000.000000000000000 + + + 10.000000000000000 + + + 200.000000000000000 + + + + + + + Max iter + + + + + + + <html><head/><body><p>Sets the activation function</p></body></html> + + + relu + + + 10000 + + + + + + + Alpha + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Sets initial learning rate</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + 0.000100000000000 + + + 1000.000000000000000 + + + 0.010000000000000 + + + 0.001000000000000 + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Proportion of data to be used as training and the remaining part as test</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + 0.010000000000000 + + + 1.000000000000000 + + + 0.100000000000000 + + + 0.900000000000000 + + + + + + + Hidden layer sizes + + + + + + + <html><head/><body><p>List of values separated by comma, where each value defines the number of neurons in a hidden layer (e.g.: 200, 100 for two hidden layers of 200 and 100 neurons respectively)</p></body></html> + + + 100 + + + 10000 + + + + + + + Learning rate init + + + + + + + <html><head/><body><p>If checked, perform cross validation</p></body></html> + + + Cross validation + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> + + + Find best estimator with steps + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Number of steps</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 1.000000000000000 + + + 100.000000000000000 + + + 1.000000000000000 + + + 5.000000000000000 + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Edit options - - + + + + + 0 + 0 + 644 + 206 + + + + Random Forest + + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Number of trees + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Parameter for node splitting, if empty all features are considered, if sqrt the square root of all the features, if integer number the number of features, if float number a fraction of all the features</p></body></html> + + + + + + 10000 + + + + + + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> + + + Find best estimator with steps + + + + + + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> + + + Balanced class weight + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QFrame::Sunken + + + Max features + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Minimum number of samples required to split an internal node</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 1.000000000000000 + + + 10000.000000000000000 + + + 1.000000000000000 + + + 2.000000000000000 + + + + + + + <html><head/><body><p>If checked, perform cross validation</p></body></html> + + + Cross validation + + + true + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Minimum number to split + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, perform One-Vs-Rest classification</p></body></html> + + + One-Vs-Rest + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Number of trees</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 2.000000000000000 + + + 10000.000000000000000 + + + 10.000000000000000 + + + 10.000000000000000 + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Number of steps</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 1.000000000000000 + + + 100.000000000000000 + + + 1.000000000000000 + + + 5.000000000000000 + + + + - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - Classification sieve - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification</p></body></html> - - + + + + + 0 + 0 + 548 + 113 + + + + Spectral Angle Mapping + + + + + + + + <html><head/><body><p>Open tab Signature threshold</p></body></html> + + + margin: 0px;padding: 0px; + + + W + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_threshold_tool.svg + + + + 22 + 22 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Set a classification threshold for all signatures</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + 100.000000000000000 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Use + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use single threshold for all the spectral signatures</p></body></html> + + + Single threshold + + + false + + + + + + + + 0 + 0 + + + + <html><head/><body><p>If checked, use signature thresholds</p></body></html> + + + Signature threshold + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + + + + <html><head/><body><p>If checked, save a raster for each signature distance</p></body></html> + + + Save signature raster + + + + - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - + + + + + + 0 + 0 + 523 + 176 + + + + Support Vector Machine + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Regularization parameter C</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + 1.000000000000000 + + + 10000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + QFrame::Sunken + + + Kernel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Kernel coefficient gamma</p></body></html> + + + scale + + + 10000 + + + + + + + <html><head/><body><p>If checked, perform cross validation</p></body></html> + + + Cross validation + + + true + + + + + + + <html><head/><body><p>Sets the kernel</p></body></html> + + + rbf + + + 10000 + + + + + + + QFrame::Sunken + + + Gamma + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Regularization parameter C + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>If checked, find the best estimator iteratively</p></body></html> + + + Find best estimator with steps + + + + + + + <html><head/><body><p>If checked, balanced weight is computed inversely proportional to class frequency</p></body></html> + + + Balanced class weight + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Number of steps</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 1.000000000000000 + + + 100.000000000000000 + + + 1.000000000000000 + + + 5.000000000000000 + + + + + + + <html><head/><body><p>If checked, calculate classification confidence raster</p></body></html> + + + Calculate classification confidence raster + + + + + + + + + + + + Neighbor pixels + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - - - + + + + - + 0 0 - - - 229 - 0 - + + QFrame::Panel QFrame::Sunken - Size threshold - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Size threshold in pixels</p></body></html> - - - 2 - - - 10000 + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + 0 @@ -19602,69 +11995,99 @@ p, li { white-space: pre-wrap; } 0 + + + 50 + false + + QFrame::Sunken - Pixel connection + Matrix file (optional) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - 1 - 0 - + + + + <html><head/><body><p><span >Open a file</span></p></body></html> - + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg + + - 80 - 16777215 + 22 + 22 - - <html><head/><body><p>Pixel connection</p></body></html> - + + + + - - 4 - + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Output name + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - 8 - + + + <html><head/><body><p>Output name prefix</p></body></html> + + + neighbor_ + + + 10 + + - + + + + <html><head/><body><p>If checked, output bands are virtual rasters</p></body></html> + + + Virtual output + + + + - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - + + 75 @@ -19672,7 +12095,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span >Run</span></p></body></html> + <html><head/><body><p>Function to Script</p></body></html> Qt::RightToLeft @@ -19681,11 +12104,11 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - RUN + Script - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg @@ -19698,8 +12121,21 @@ p, li { white-space: pre-wrap; } - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + 75 @@ -19707,7 +12143,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>Function to Batch</p></body></html> + <html><head/><body><p><span >Run</span></p></body></html> Qt::RightToLeft @@ -19715,77 +12151,26 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Classification sieve - - - - - - - - - - Classification erosion - - - - - - - - background-color : #656565; color : white + + RUN - - QFrame::Panel + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - QFrame::Sunken + + + 34 + 34 + - - Classification erosion + + Qt::ToolButtonTextBesideIcon - - - - - - + + Qt::Vertical @@ -19797,88 +12182,139 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + - + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Band neighbor + + + + + + + + + - + 0 0 - + - 229 - 0 + 200 + 16777215 - - QFrame::Sunken + + <html><head/><body><p>Enter a value</p></body></html> - Select the classification + - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 10000 - - + + 1 0 + + + 200 + 16777215 + + - <html><head/><body><p>Select the classification</p></body></html> + <html><head/><body><p>Select a statistic</p></body></html> - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; + + + + QFrame::Sunken - Plot + Select a statistic - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + + + + + + Qt::Horizontal + + - 22 - 22 + 40 + 20 + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Statistic + - - - - + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select input band set + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + 0 @@ -19895,41 +12331,44 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - Size in pixels + Neighbor distance in pixels Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + - <html><head/><body><p>Size in pixels</p></body></html> + <html><head/><body><p>Band set number</p></body></html> 1 - 1000 - - - 1 + 100000 - - + + - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> + <html><head/><body><p>Distance in pixels</p></body></html> - - Circular + + 1 + + + 1000 + + + 1 - - + + Qt::Horizontal @@ -19941,646 +12380,1288 @@ p, li { white-space: pre-wrap; } - - - - - - - - - 0 - 0 - - - - QFrame::Sunken + + + + <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - Class values - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Circular + + + + - - - - 0 - 0 - + + + Qt::Horizontal - + - 400 - 26 + 40 + 20 - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - - 10000 - - + + + + + + + + + + + + + + + Postprocessing + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + + + + 20 + 20 + + + + true + + + + Accuracy + + + + + + 0 + + + + + 0 + 0 + 731 + 388 + + + + Input + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the classification to assess + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select the reference vector or raster + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the classification to assess</p></body></html> + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the reference vector or raster</p></body></html> + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Accuracy assessment + + + + + + + + + + 0 + 0 + + + + + 6 + 0 + + + + + 100 + 200 + + + + QFrame::Sunken + + + Vector field + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the field of the classification code </p></body></html> + + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + + + 0 + 0 + 98 + 90 + + + + Output + + + + + + + + + Courier 10 Pitch + + + + true + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> + + + 120 + + + false + + + + + + + + - + - Classification dilation + Classification report - + - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Classification dilation - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the classification - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the classification</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Size in pixels - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Size in pixels</p></body></html> - - - 1 - - - 1000 - - - 1 - - - - - - - <html><head/><body><p>If checked, neighbor pixels are calculated inside a circle of radius equal to the distance in pixels</p></body></html> - - - Circular - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - QFrame::Sunken - - - Class values - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 400 - 26 - - - - <html><head/><body><p>Enter class values separated by , or -</p></body></html> - - - - - - 10000 - - + + + + + + 0 + + + + + 0 + 0 + 488 + 172 + + + + Input + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the classification raster</p></body></html> + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the classification + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the report</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + 0 + + + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 75 - true - - - - <html><head/><body><p><span >Run</span></p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - RUN - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - - margin: 0px;padding: 0px; - - - BATCH - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 34 - 34 - - - - Qt::ToolButtonTextBesideIcon - - - - + + + + + + Qt::Horizontal + + + + 358 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Vertical + + + + 20 + 82 + + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Classification report + + + + + + + + + + + 0 + 0 + 98 + 90 + + + + Output + + + + + + + + + Courier 10 Pitch + + + + true + + + QTextEdit::NoWrap + + + 160 + + + false + + + + + + + + - + - Zonal stat rasters + Cross classification - + - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Zonal stat rasters - - - - - - - - - - - - 0 - 0 - - - - - 229 - 0 - - - - QFrame::Sunken - - - Select the input raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select the raster to edit</p></body></html> - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - + + + 0 + + + + + 0 + 0 + 500 + 266 + + + + Input + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Cross classification + + + + - - - - - - - - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> - - - Use value as NoData - - + + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + + + + + + + + 0 + 0 + + + + + 229 + 0 + + + + QFrame::Sunken + + + Select the classification + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 6 + 0 + + + + + 100 + 200 + + + + QFrame::Sunken + + + Vector field + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the vector field</p></body></html> + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the classification</p></body></html> + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select the reference vector or raster</p></body></html> + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + Select the reference vector or raster + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>If checked, calculate linear regression and create rasters using the values of regression coefficients</p></body></html> + + + Calculate linear regression + + + + - - - - <html><head/><body><p>NoData value</p></body></html> - - - -2147483647 - - - 2147483647 - - + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Run + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + <html><head/><body><p><span >Run</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + RUN + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Script + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + + 0 + 0 + 98 + 90 + + + + Output + + + + + + + + + Courier 10 Pitch + + + + true + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier 10 Pitch'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> + + + 120 + + + false + + + + - - + + - - - - - - - 1 - 0 - + + + + + Classification to vector + + + + + + + + background-color : #5a5a5a; color : white; font: bold - - <html><head/><body><p>Select the vector field</p></body></html> + + QFrame::Panel + + + QFrame::Sunken + + + Classification to vector + + + + - + 0 0 + + + 229 + 0 + + QFrame::Sunken - Select the reference vector or raster + Select the classification Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + + + + 1 + 0 + + + + <html><head/><body><p>Select the classification raster</p></body></html> + + + + + <html><head/><body><p >Refresh list</p></body></html> @@ -20602,39 +13683,12 @@ p, li { white-space: pre-wrap; } + + + + - - - - 0 - 0 - - - - - 6 - 0 - - - - - 100 - 200 - - - - QFrame::Sunken - - - Vector field - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - + 1 @@ -20642,106 +13696,94 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>Select the reference vector or raster</p></body></html> + <html><head/><body><p>Select the code field</p></body></html> + + + C_ID + + + + + MC_ID + + - - - - - - - - - 0 - 0 - - - - - 200 - 16777215 - - + + - <html><head/><body><p>Enter a value</p></body></html> + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> - - - - 10000 + Use code from Signature list - - + + - - 1 + + 0 0 - - - 200 - 16777215 - + + background-color : #5a5a5a; color : white; font: bold - - <html><head/><body><p>Select a statistic</p></body></html> + + QFrame::Panel - - - - QFrame::Sunken - Select a statistic + Symbology - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + <html><head/><body><p>If checked, the polygons are dissolved to avoid discontinuity between processed blocks (slower)</p></body></html> + + + Dissolve output - - + + + + + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken + + + + Qt::Horizontal - - Statistic + + + 40 + 20 + - + - - - - - + 75 @@ -20776,9 +13818,9 @@ p, li { white-space: pre-wrap; } - + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -20794,34 +13836,8 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + 75 @@ -20829,7 +13845,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>Function to Batch</p></body></html> + <html><head/><body><p>Function to Script</p></body></html> Qt::RightToLeft @@ -20838,7 +13854,7 @@ p, li { white-space: pre-wrap; } margin: 0px;padding: 0px; - BATCH + Script @@ -20859,1570 +13875,1346 @@ p, li { white-space: pre-wrap; } - - - - - - - Band calc - - - - - - Qt::Vertical - - - false - - - - - 0 - 0 - - - - - 0 - 150 - - - - - 1 - - - 1 - - - 1 - - - 1 - + + + Reclassification + + - - - - - - - <html><head/><body><p >Refresh list</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg - - - - 22 - 22 - - - - - - - - + + + - + 0 0 - - <html><head/><body><p>Band list</p></body></html> - - - QFrame::WinPanel + + + 229 + 0 + QFrame::Sunken - - true + + Select the classification - - QAbstractItemView::NoSelection + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - QAbstractItemView::SelectRows + + + + + + + 1 + 0 + - - 2 + + <html><head/><body><p>Select the classification raster</p></body></html> - - 200 - - - true - - - - Variable - - - - - Band name - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Filter</p></body></html> - - - Filter - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Band list - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 250 - - - - - - - QTabBar::tab { -padding: 10px; -min-height: 18px; -} - - - QTabWidget::North - - - 0 - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_expression.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_expression.svg - - - Expression - - - - - - Qt::Horizontal + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + + + background-color : #5a5a5a; color : white; font: bold - - false + + QFrame::Panel + + + QFrame::Sunken + + + Reclassification - - - - 100 - 0 - - - - - 16777215 - 400 - - - - - 11 - - - - <html><head/><body><p>Enter an expression (e.g. &quot;raster1&quot; + &quot;raster2&quot; )</p></body></html> - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 300 - 16777215 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Less than</p></body></html> - - - < - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Greater than</p></body></html> - - - > - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Open parenthesis</p></body></html> - - - ( - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Close parenthesis</p></body></html> - - - ) - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Power</p></body></html> - - - ^ - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Square root</p></body></html> - - - - - - - - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Plus</p></body></html> - - - + - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Minus</p></body></html> - - - - - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Multiplication</p></body></html> - - - * - - - - - - - - 25 - 25 - - - - <html><head/><body><p>Division</p></body></html> - - - / - - - - - - - - 45 - 25 - - - - <html><head/><body><p>Equals</p></body></html> - - - == - - - - - - - - 45 - 25 - - - - <html><head/><body><p>Not equals</p></body></html> - - - != - - - - - - - - - <html><head/><body><p>Open a text file to add custom functions</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - - - - 22 - 22 - - - - - - - - - - - - - - - 0 - 0 - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::SingleSelection - - - true - - - false - - - - Functions - - - - - - - - - - - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_rules.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_rules.svg - - - Decision rules - - - - - - - - - 10 - - - - <html><head/><body><p>Enter one or more rules separated by semicolon (e.g. &quot;raster1&quot; &gt; 0; &quot;raster2&quot; &gt; 0 )</p></body></html> - - - true - - - - Value - - - - - Rule - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Move highlighted rule up</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_up.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import rules from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p >Add row</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg - - - - 22 - 22 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>Move highlighted rule down</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_move_down.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Export rules to text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - - - - + + - - - + + + - <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> + <html><head/><body><p>Calculate unique values</p></body></html> + + + margin: 0px;padding: 0px; - - Input NoData - as value + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + + + + 22 + 22 + - - + + - <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + <html><head/><body><p>Enable this for reclassification from C ID to MC ID; if checked, unique values are calculated from the Signature list, setting old value C ID and new value MC ID</p></body></html> - Use value -as NoData + calculate C ID to MC ID values - - - - <html><head/><body><p>NoData value</p></body></html> + + + + + 0 + 0 + - - -2147483647 + + Calculate unique values - - 2147483647 + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + - Calculation -data type + Values - - + + + + <html><head/><body><p>Set incremental new values</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + + + + 22 + 22 + + + + + + - - 1 + + 0 0 - - <html><head/><body><p>Select a type</p></body></html> + + Incremental new values - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + true + + + false + + + true + + + 24 + + - Float32 + Old value - - + + - Int32 + New value + + + + + + + + + <html><head/><body><p >Add row</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add.svg + + + + 22 + 22 + + + - - - UInt32 - + + + + <html><head/><body><p >Delete row</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Import reclassification table from text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Export reclassification table to text file</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + - - - Int16 - + + + + + + + + + + + + <html><head/><body><p>Use the codes from Signature list table for vector symbology</p></body></html> + + + Use code from Signature list + + + false + + - - - UInt16 - + + + + + 1 + 0 + + + + <html><head/><body><p>Select the code field</p></body></html> + + + + MC_ID + + + + + C_ID + + + - - - Byte - + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Symbology + + - + - - + + + + + + Qt::Horizontal - 214 + 40 20 - - - - - 0 - 0 - - - - - 40 - 0 - + + + + background-color : #5a5a5a; color : white; font: bold - - - 120 - 16777215 - + + QFrame::Panel QFrame::Sunken - Extent: + Run Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the intersection of input rasters</p></body></html> - - - Intersection - - - true + + + + + 75 + true + - - - - - <html><head/><body><p>If checked, the extent of raster ouput equals the extent of selected raster</p></body></html> - - - Same as + <html><head/><body><p><span >Run</span></p></body></html> - - - - - - - 1 - 0 - + + Qt::RightToLeft - - <html><head/><body><p>Select a raster</p></body></html> + + margin: 0px;padding: 0px; - - - - - Align - - - true - - - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Output raster - - - - - - - - - - 1 - 0 - - - - <html><head/><body><p>Select a type</p></body></html> - - - - Float32 - - - - - Int32 - - - - - UInt32 - - - - - Int16 - - - - - UInt16 - - - - - Byte - - - - - - - - - 0 - 0 - + RUN - - - 50 - 0 - + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg - + - 130 - 16777215 + 34 + 34 - - QFrame::Sunken - - - Output -NoData value - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + Qt::ToolButtonTextBesideIcon - - - - <html><head/><body><p>NoData value of the output raster</p></body></html> - - - -2147483647 - - - 2147483647 - - - -32768 + + + + + 75 + true + - - - - - <html><head/><body><p>If checked, every NoData pixel in input will be NoData pixel in output</p></body></html> + <html><head/><body><p>Function to Script</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; - NoData mask + Script - - true + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - - - <html><head/><body><p>If checked, set a scale</p></body></html> + + + 34 + 34 + - - Set -scale + + Qt::ToolButtonTextBesideIcon - - - - - 0 - 0 - - + + + + + + + + + + + Band calc + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + Qt::Vertical + + + false + + + + + 0 + 0 + + + + + 0 + 150 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + + + + <html><head/><body><p >Refresh list</p></body></html> + + + margin: 0px;padding: 0px + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reload.svg + + + + 22 + 22 + + + + + + + + - 100 - 16777215 + 16777215 + 300 - <html><head/><body><p>Scale</p></body></html> + <html><head/><body><p>Band list</p></body></html> - - 7 + + QFrame::WinPanel - - -9999999999999999455752309870428160.000000000000000 + + QFrame::Sunken - - 9999999999999999455752309870428160.000000000000000 + + true - - 1.000000000000000 + + QAbstractItemView::NoSelection - - - - - - <html><head/><body><p>If checked, set an offset</p></body></html> + + QAbstractItemView::SelectRows - - Set -offset + + 2 + + 200 + + + true + + + + Variable + + + + + Output + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Filter</p></body></html> + + + Filter + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Band list + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 100 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 2 + + + - + - + 0 0 - - - 100 - 16777215 - - - - 7 - - - -9999999999999999455752309870428160.000000000000000 - - - 9999999999999999455752309870428160.000000000000000 - - - 0.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - <html><head/><body><p>Function to Batch</p></body></html> - - - Qt::RightToLeft - - margin: 0px;padding: 0px; + background-color : #5a5a5a; color : white; font: bold - - BATCH + + QFrame::Panel - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + QFrame::Sunken - - - 34 - 34 - + + Expression - - Qt::ToolButtonTextBesideIcon + + true - - - - 75 - true - + + + Qt::Horizontal - - <html><head/><body><p><span >Run</span></p></body></html> + + false - - Qt::RightToLeft + + + + 11 + + + + <html><head/><body><p>Enter an expression</p></body></html> + + + + + + + + + 250 + 16777215 + + + + QFrame::Sunken + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SingleSelection + + + true + + + false + + + + Functions + + + + + + + + + + + + + <html><head/><body><p>Open a text file to add custom functions</p></body></html> margin: 0px;padding: 0px; - - RUN - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_run.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg - 34 - 34 + 22 + 22 - - Qt::ToolButtonTextBesideIcon - - - - - - - - - Batch - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Batch - - + + + + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Output raster + + + + + + + + + Output +data type + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select a type</p></body></html> + + + + Float32 + + + + + Int32 + + + + + UInt32 + + + + + Int16 + + + + + UInt16 + + + + + Byte + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 130 + 16777215 + + + + QFrame::Sunken + + + Output +NoData value + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>NoData value of the output raster</p></body></html> + + + -2147483647 + + + 2147483647 + + + -32768 + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 120 + 16777215 + + + + QFrame::Sunken + + + NoData +mask + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 90 + 16777215 + + + + <html><head/><body><p>Use NoData mask</p></body></html> + + + + False + + + + + True + + + + + None + + + + + + + + <html><head/><body><p>If checked, set a scale</p></body></html> + + + Set +scale + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>Scale</p></body></html> + + + 0 + + + -9999999999999999455752309870428160.000000000000000 + + + 9999999999999999455752309870428160.000000000000000 + + + 1.000000000000000 + + + + + + + <html><head/><body><p>If checked, set an offset</p></body></html> + + + Set +offset + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Offset + + + 0 + + + -9999999999999999455752309870428160.000000000000000 + + + 9999999999999999455752309870428160.000000000000000 + + + 0.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - 0 - 0 - - - - - 100 - 0 - - - - Qt::Horizontal - - - false - - - - - 200 - 0 - - - - - 11 - - - - <html><head/><body><p>Enter a batch function</p></body></html> - - - - - - - - - 0 - 0 - - - - - 100 - 400 - - - - - 250 - 16777215 - - - - - 1 + + + + + + 0 + 0 + - - 1 + + + 40 + 0 + - - 1 + + + 120 + 16777215 + - - 1 + + QFrame::Sunken - - - - - - <html><head/><body><p>Export batch to text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Import batch from text file</p></body></html> - - - margin: 0px;padding: 0px - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import.svg - - - - 22 - 22 - - - - - - - - - - - 0 - 0 - - - - - 300 - 16777215 - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::SingleSelection - - - true - - - false - - - - Functions - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Run - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - + + Extent: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + + 150 + 0 + + + + <html><head/><body><p>Select an extent</p></body></html> + + + + + + + + 200 + 16777215 + + + + <html><head/><body><p>Upperleft X</p></body></html> + + + UL X + + + + + + + + 200 + 16777215 + + + + <html><head/><body><p>Upper-left Y</p></body></html> + + + UL Y + + + + + + + + 200 + 16777215 + + + + <html><head/><body><p>Lower-right X</p></body></html> + + + LR X + + + + + + + + 200 + 16777215 + + + + <html><head/><body><p>Lower-right Y</p></body></html> + + + LR Y + + + - - - Qt::Horizontal + + + + 0 + 0 + - + 40 - 20 + 0 - + + + 120 + 16777215 + + + + QFrame::Sunken + + + Align + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + - - - - 75 - true - + + + + 1 + 0 + + + + + 150 + 0 + - <html><head/><body><p>Check batch function</p></body></html> + <html><head/><body><p>Select a raster</p></body></html> - - Qt::RightToLeft + + + + + + + 40 + 0 + - - margin: 0px;padding: 0px; + + QFrame::Sunken - CHECK + Pixel +size - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch_check.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch_check.svg + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + + + + + - 34 - 34 + 100 + 16777215 - - Qt::ToolButtonTextBesideIcon + + <html><head/><body><p>Pixel size</p></body></html> - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + 75 @@ -22460,6 +15252,289 @@ offset + + + + + + <html><head/><body><p>If checked, input NoData pixels will be evaluated as regular values</p></body></html> + + + Input NoData + as value + + + + + + + <html><head/><body><p>If checked, pixels equal to NoData value will be excluded from the output raster</p></body></html> + + + Use value +as NoData + + + + + + + <html><head/><body><p>NoData value</p></body></html> + + + -2147483647 + + + 2147483647 + + + + + + + Calculation +data type + + + + + + + + 1 + 0 + + + + <html><head/><body><p>Select a type</p></body></html> + + + + Float32 + + + + + Int32 + + + + + UInt32 + + + + + Int16 + + + + + UInt16 + + + + + Byte + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Script + + + + + + + 0 + 0 + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Script (copy the code in a Python shell) + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Qt::Horizontal + + + false + + + + + 200 + 0 + + + + + 11 + + + + color:rgb(0, 225, 0); +background-color: rgb(27, 27, 27); + + + + + + false + + + + + + + + + + <html><head/><body><p><span >Reset</span></p></body></html> + + + margin: 0px;padding: 0px; + + + Import library + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg + + + + 22 + 22 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + <html><head/><body><p><span style=" font-weight:400;">Copy Script to clipboard</span></p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Copy + + + + 34 + 34 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 75 + true + + + + <html><head/><body><p>Save Script to file</p></body></html> + + + Qt::RightToLeft + + + margin: 0px;padding: 0px; + + + Save to file + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + + + @@ -22485,6 +15560,18 @@ offset Settings + + 3 + + + 3 + + + 3 + + + 3 + @@ -22503,7 +15590,7 @@ offset - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -22676,7 +15763,7 @@ offset - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -22789,7 +15876,7 @@ offset - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -22821,45 +15908,6 @@ offset - - - - - 0 - 0 - - - - QFrame::Sunken - - - <html><head/><body><p><a href="https://step.esa.int/main/download/snap-download/"><span style=" text-decoration: underline; color:#0000ff;">ESA SNAP GPT executable</span></a></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - QFrame::Sunken - - - Python executable path - - - - - - - QFrame::Sunken - - - Python modules path - - - @@ -22874,27 +15922,6 @@ offset - - - - <html><head/><body><p>Path to the GPT executable (e.g. C:\Program Files\snap\bin\gpt.exe)</p></body></html> - - - - - - - <html><head/><body><p>Path to the Python executable (e.g. /usr/local/bin/python3)</p></body></html> - - - - - - - <html><head/><body><p>Path to Python modules (e.g. /Applications/QGIS.app/Contents/MacOS/lib/python3.8/site-packages).<br/>Multiple paths can be entered separated by ;</p><p>Restart is required.</p></body></html> - - - @@ -22907,7 +15934,7 @@ offset - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -22940,23 +15967,10 @@ offset - - - - <html><head/><body><p>If checked, create virtual rasters for certain temporary files</p></body></html> - - - Use virtual raster for temp files - - - true - - - - + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -22969,7 +15983,7 @@ offset - + <html><head/><body><p>If checked, a lossless compression is applied to rasters in order to save disk space</p></body></html> @@ -22982,19 +15996,8 @@ offset - - - - - - <html><head/><body><p>If checked, the output raster is compared to output calculation to avoid writing errors. It could slightly slow the process.</p></body></html> - - - Enable writing verification - - - - + + @@ -23019,149 +16022,11 @@ offset - - - - - QFrame::Panel - - - QFrame::Sunken - - - C Name field - - - - - - - <html><head/><body><p>Set the Class name field</p><p>[max 10 characters]</p></body></html> - - - 10 - - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Field names of training input - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set the Class ID field name</p><p>[max 10 characters]</p></body></html> - - - 10 - - - - - - - <html><head/><body><p>Set the Macroclass ID field name</p><p>[max 10 characters]</p></body></html> - - - 10 - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - C ID field - - - - - - - <html><head/><body><p>Set the Macroclass name field</p><p>[max 10 characters]</p></body></html> - - - 10 - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - MC ID field - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - MC Name field - - - - - - - <html><head/><body><p><span >Reset</span></p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg - - - - 22 - 22 - - - - - - - - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -23282,7 +16147,56 @@ offset - + + + + + + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken + + + Dock + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> + + + Download news on startup + + + true + + + + + + @@ -23325,7 +16239,7 @@ offset - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -23334,7 +16248,7 @@ offset QFrame::Sunken - Variable name for expressions (tab Reclassification and Edit raster) + Variable name for expressions Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -23366,61 +16280,12 @@ offset - - - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Dock - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>If checked, news about the SCP are downloaded on startup and displayed in Dock</p></body></html> - - - Download news on startup - - - true - - - - - - + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -23516,45 +16381,25 @@ offset - Debug - - - - - - - <html><head/><body><p>Enable/Disable the Log of events</p></body></html> - - - Record events in a Log file - - - false - - - false - - - - - + + + + + - <html><head/><body><p>Export the Log file</p></body></html> + <html><head/><body><p>Test dependencies</p></body></html> margin: 0px;padding: 0px; - - Import library - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg @@ -23564,82 +16409,89 @@ offset - - - - <html><head/><body><p>Clear the Log file content</p></body></html> - + + - margin: 0px;padding: 0px; + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel + + + QFrame::Sunken - Import library + Test - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg + + + + + + Qt::Horizontal - + - 22 - 22 + 40 + 20 + + + + + + Test dependencies + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + - - - - background-color : #656565; color : white + + + + Qt::Vertical + + + + 20 + 40 + + + + + QFrame::Panel QFrame::Sunken - - Log file - - - - - - + true - - - - Date - - - - - Function - - - - - Message - - + - - - - + + + + - <html><head/><body><p>Test dependencies</p></body></html> + <html><head/><body><p>Export the Log file</p></body></html> margin: 0px;padding: 0px; + + Import library + - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export.svg @@ -23649,33 +16501,26 @@ offset - - - - Test dependencies + + + + <html><head/><body><p>Enable/Disable the detailed Log of events in a local text file</p></body></html> - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + Record detailed events in a Log file - - - - - - Qt::Horizontal + + false - - - 40 - 20 - + + false - + - + - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -23684,10 +16529,23 @@ offset QFrame::Sunken - Test + Log file + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -23710,9 +16568,31 @@ offset About + + 3 + + + 3 + + + 3 + + + 3 + - + + + + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg + + + + QFrame::NoFrame @@ -23732,7 +16612,23 @@ offset + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + font: bold + QFrame::NoFrame @@ -23750,6 +16646,19 @@ offset + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -23766,22 +16675,18 @@ offset <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Developed by </span><a href="http://www.researchgate.net/profile/Luca_Congedo"><span style=" font-family:'Droid Sans'; text-decoration: underline; color:#0057ae;">Luca Congedo</span></a><span style=" font-family:'Droid Sans';"> (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans';"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">For more information and tutorials visit the official site </span><span style=" font-family:'Droid Sans'; font-weight:600;">From GIS to Remote Sensing.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=sacp"><span style=" font-family:'Droid Sans'; font-size:24pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:9pt;"><br />Please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Droid Sans'; font-size:9pt; text-decoration: underline; color:#0057ae;">Semi-Automatic Classification Plugin group on Facebook</span></a><span style=" font-size:9pt;"> or </span><a href="https://github.com/semiautomaticgit/SemiAutomaticClassificationPlugin/discussions"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">GitHub discussions</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">This plugin requires the installation of GDAL, OGR, Numpy, SciPy, and Matplotlib (already bundled with QGIS).</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-style:italic;">Some tools require the additional installation of: ESA SNAP</span></p> +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Developed by Luca Congedo (ing.congedoluca@gmail.com), the </span><span style=" font-family:'Droid Sans'; font-size:10pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:10pt;"> (SCP) is a free open source plugin for QGIS that allows for the semi-automatic classification (also supervised classification) of remote sensing images.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">It provides several tools for the download of free images, the preprocessing, the postprocessing, and the raster calculation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">For more information and tutorials visit the official site </span><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:10pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a><span style=" font-family:'Droid Sans'; font-size:9pt;">.</span></p> <hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to cite:</span></p> -<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">How to cite:</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p> <hr /> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;"><br />The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">The Semi-Automatic Classification Plugin is developed by Luca Congedo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Translators:</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author<br /></span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Language: Author name</span></p> +<hr /> <p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:8pt;">See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Semi-Automatic Classification Plugin. If not, see &lt;</span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Droid Sans'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Droid Sans'; font-size:8pt;">&gt;.</span></p></body></html> diff --git a/ui/ui_semiautomaticclassificationplugin_dock_class.py b/ui/ui_semiautomaticclassificationplugin_dock_class.py old mode 100644 new mode 100755 index 9ff3dbe..d6a314e --- a/ui/ui_semiautomaticclassificationplugin_dock_class.py +++ b/ui/ui_semiautomaticclassificationplugin_dock_class.py @@ -2,16 +2,19 @@ # Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin_dock_class.ui' # -# Created by: PyQt5 UI code generator 5.11.3 +# Created by: PyQt5 UI code generator 5.15.9 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_DockClass(object): def setupUi(self, DockClass): DockClass.setObjectName("DockClass") - DockClass.resize(397, 496) + DockClass.resize(440, 505) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -39,29 +42,38 @@ def setupUi(self, DockClass): sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) self.tab.setSizePolicy(sizePolicy) self.tab.setObjectName("tab") - self.gridLayout_14 = QtWidgets.QGridLayout(self.tab) - self.gridLayout_14.setObjectName("gridLayout_14") - self.gridLayout_11 = QtWidgets.QGridLayout() - self.gridLayout_11.setObjectName("gridLayout_11") + self.gridLayout_8 = QtWidgets.QGridLayout(self.tab) + self.gridLayout_8.setObjectName("gridLayout_8") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.plugin_version_label2 = QtWidgets.QLabel(self.tab) + self.plugin_version_label2.setStyleSheet("background-color: rgb(32, 97, 118); color : white; font: bold") + self.plugin_version_label2.setFrameShape(QtWidgets.QFrame.Panel) + self.plugin_version_label2.setFrameShadow(QtWidgets.QFrame.Raised) + self.plugin_version_label2.setText("") + self.plugin_version_label2.setAlignment(QtCore.Qt.AlignCenter) + self.plugin_version_label2.setObjectName("plugin_version_label2") + self.horizontalLayout_2.addWidget(self.plugin_version_label2) + self.gridLayout_8.addLayout(self.horizontalLayout_2, 0, 0, 1, 1) self.gridLayout_40 = QtWidgets.QGridLayout() self.gridLayout_40.setHorizontalSpacing(8) self.gridLayout_40.setObjectName("gridLayout_40") - self.batch_toolButton = QtWidgets.QToolButton(self.tab) - self.batch_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.batch_toolButton.setIcon(icon) - self.batch_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.batch_toolButton.setObjectName("batch_toolButton") - self.gridLayout_40.addWidget(self.batch_toolButton, 0, 9, 1, 1) self.postprocessing_toolButton_2 = QtWidgets.QToolButton(self.tab) self.postprocessing_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.postprocessing_toolButton_2.setIcon(icon1) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.postprocessing_toolButton_2.setIcon(icon) self.postprocessing_toolButton_2.setIconSize(QtCore.QSize(22, 22)) self.postprocessing_toolButton_2.setObjectName("postprocessing_toolButton_2") - self.gridLayout_40.addWidget(self.postprocessing_toolButton_2, 0, 7, 1, 1) + self.gridLayout_40.addWidget(self.postprocessing_toolButton_2, 0, 8, 1, 1) + self.bandset_toolButton = QtWidgets.QToolButton(self.tab) + self.bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.bandset_toolButton.setIcon(icon1) + self.bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.bandset_toolButton.setObjectName("bandset_toolButton") + self.gridLayout_40.addWidget(self.bandset_toolButton, 0, 0, 1, 1) self.preprocessing_toolButton_2 = QtWidgets.QToolButton(self.tab) self.preprocessing_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") icon2 = QtGui.QIcon() @@ -69,54 +81,48 @@ def setupUi(self, DockClass): self.preprocessing_toolButton_2.setIcon(icon2) self.preprocessing_toolButton_2.setIconSize(QtCore.QSize(22, 22)) self.preprocessing_toolButton_2.setObjectName("preprocessing_toolButton_2") - self.gridLayout_40.addWidget(self.preprocessing_toolButton_2, 0, 5, 1, 1) - self.bandset_toolButton = QtWidgets.QToolButton(self.tab) - self.bandset_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + self.gridLayout_40.addWidget(self.preprocessing_toolButton_2, 0, 6, 1, 1) + self.band_processing_toolButton = QtWidgets.QToolButton(self.tab) + self.band_processing_toolButton.setStyleSheet("margin: 0px;padding: 0px;") icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.bandset_toolButton.setIcon(icon3) - self.bandset_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.bandset_toolButton.setObjectName("bandset_toolButton") - self.gridLayout_40.addWidget(self.bandset_toolButton, 0, 0, 1, 1) + icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.band_processing_toolButton.setIcon(icon3) + self.band_processing_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.band_processing_toolButton.setObjectName("band_processing_toolButton") + self.gridLayout_40.addWidget(self.band_processing_toolButton, 0, 7, 1, 1) + self.batch_toolButton = QtWidgets.QToolButton(self.tab) + self.batch_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.batch_toolButton.setIcon(icon4) + self.batch_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.batch_toolButton.setObjectName("batch_toolButton") + self.gridLayout_40.addWidget(self.batch_toolButton, 0, 10, 1, 1) + self.basic_tools_toolButton = QtWidgets.QToolButton(self.tab) + self.basic_tools_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.basic_tools_toolButton.setIcon(icon5) + self.basic_tools_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.basic_tools_toolButton.setObjectName("basic_tools_toolButton") + self.gridLayout_40.addWidget(self.basic_tools_toolButton, 0, 2, 1, 1) self.bandcalc_toolButton_2 = QtWidgets.QToolButton(self.tab) self.bandcalc_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.bandcalc_toolButton_2.setIcon(icon4) + icon6 = QtGui.QIcon() + icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.bandcalc_toolButton_2.setIcon(icon6) self.bandcalc_toolButton_2.setIconSize(QtCore.QSize(22, 22)) self.bandcalc_toolButton_2.setObjectName("bandcalc_toolButton_2") - self.gridLayout_40.addWidget(self.bandcalc_toolButton_2, 0, 8, 1, 1) + self.gridLayout_40.addWidget(self.bandcalc_toolButton_2, 0, 9, 1, 1) self.download_images_toolButton_2 = QtWidgets.QToolButton(self.tab) self.download_images_toolButton_2.setStyleSheet("margin: 0px;padding: 0px;") - icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.download_images_toolButton_2.setIcon(icon5) + icon7 = QtGui.QIcon() + icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.download_images_toolButton_2.setIcon(icon7) self.download_images_toolButton_2.setIconSize(QtCore.QSize(22, 22)) self.download_images_toolButton_2.setObjectName("download_images_toolButton_2") - self.gridLayout_40.addWidget(self.download_images_toolButton_2, 0, 2, 1, 1) - self.band_processing_toolButton = QtWidgets.QToolButton(self.tab) - self.band_processing_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.band_processing_toolButton.setIcon(icon6) - self.band_processing_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.band_processing_toolButton.setObjectName("band_processing_toolButton") - self.gridLayout_40.addWidget(self.band_processing_toolButton, 0, 6, 1, 1) - self.basic_tools_toolButton = QtWidgets.QToolButton(self.tab) - self.basic_tools_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.basic_tools_toolButton.setIcon(icon7) - self.basic_tools_toolButton.setIconSize(QtCore.QSize(22, 22)) - self.basic_tools_toolButton.setObjectName("basic_tools_toolButton") - self.gridLayout_40.addWidget(self.basic_tools_toolButton, 0, 1, 1, 1) - self.gridLayout_11.addLayout(self.gridLayout_40, 1, 0, 1, 1) - self.plugin_version_label2 = QtWidgets.QLabel(self.tab) - self.plugin_version_label2.setText("") - self.plugin_version_label2.setAlignment(QtCore.Qt.AlignCenter) - self.plugin_version_label2.setObjectName("plugin_version_label2") - self.gridLayout_11.addWidget(self.plugin_version_label2, 0, 0, 1, 1) - self.gridLayout_14.addLayout(self.gridLayout_11, 0, 1, 1, 1) + self.gridLayout_40.addWidget(self.download_images_toolButton_2, 0, 1, 1, 1) + self.gridLayout_8.addLayout(self.gridLayout_40, 1, 0, 1, 1) self.gridLayout_12 = QtWidgets.QGridLayout() self.gridLayout_12.setObjectName("gridLayout_12") self.label_35 = QtWidgets.QLabel(self.tab) @@ -125,21 +131,32 @@ def setupUi(self, DockClass): font.setItalic(False) font.setWeight(75) self.label_35.setFont(font) - self.label_35.setStyleSheet("background-color : #656565; color : white; font: bold;") - self.label_35.setFrameShape(QtWidgets.QFrame.Panel) - self.label_35.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_35.setFrameShape(QtWidgets.QFrame.NoFrame) + self.label_35.setFrameShadow(QtWidgets.QFrame.Plain) self.label_35.setObjectName("label_35") self.gridLayout_12.addWidget(self.label_35, 0, 0, 1, 1) self.main_textBrowser = QtWidgets.QTextBrowser(self.tab) self.main_textBrowser.setHtml("\n" "\n" +"\n" "


") self.main_textBrowser.setOpenExternalLinks(True) self.main_textBrowser.setObjectName("main_textBrowser") - self.gridLayout_12.addWidget(self.main_textBrowser, 1, 0, 1, 1) - self.gridLayout_14.addLayout(self.gridLayout_12, 1, 1, 1, 1) + self.gridLayout_12.addWidget(self.main_textBrowser, 2, 0, 1, 1) + self.rs_version = QtWidgets.QLabel(self.tab) + self.rs_version.setMaximumSize(QtCore.QSize(16777215, 10)) + font = QtGui.QFont() + font.setBold(True) + font.setItalic(False) + font.setWeight(75) + self.rs_version.setFont(font) + self.rs_version.setStyleSheet("color: rgb(237, 51, 59);") + self.rs_version.setFrameShape(QtWidgets.QFrame.NoFrame) + self.rs_version.setFrameShadow(QtWidgets.QFrame.Plain) + self.rs_version.setObjectName("rs_version") + self.gridLayout_12.addWidget(self.rs_version, 1, 0, 1, 1) + self.gridLayout_8.addLayout(self.gridLayout_12, 2, 0, 1, 1) self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.userguide_toolButton_2 = QtWidgets.QPushButton(self.tab) @@ -151,7 +168,7 @@ def setupUi(self, DockClass): self.userguide_toolButton_2.setFont(font) self.userguide_toolButton_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.userguide_toolButton_2.setStyleSheet("color: white;\n" -"background-color: rgb(51, 122, 183);\n" +"background-color: rgb(32, 97, 118);\n" "selection-color: yellow;\n" "selection-background-color: blue;\n" "font: bold 14px;\n" @@ -171,7 +188,7 @@ def setupUi(self, DockClass): self.help_toolButton_2.setFont(font) self.help_toolButton_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.help_toolButton_2.setStyleSheet("color: white;\n" -"background-color: rgb(51, 122, 183);\n" +"background-color: rgb(32, 97, 118);\n" "selection-color: yellow;\n" "selection-background-color: blue;\n" "font: bold 14px;\n" @@ -182,37 +199,21 @@ def setupUi(self, DockClass): "padding: 2px;") self.help_toolButton_2.setObjectName("help_toolButton_2") self.verticalLayout.addWidget(self.help_toolButton_2) - self.support_toolButton = QtWidgets.QPushButton(self.tab) - self.support_toolButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) - self.support_toolButton.setStyleSheet("color: white;\n" -"background-color: rgb(92, 184, 92);\n" -"selection-color: yellow;\n" -"selection-background-color: blue;\n" -"font: bold 14px;\n" -"border-style: inset;\n" -"border-width: 2px;\n" -"border-radius: 6px;\n" -"border-color: white;\n" -"padding: 2px;") - icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.support_toolButton.setIcon(icon8) - self.support_toolButton.setFlat(False) - self.support_toolButton.setObjectName("support_toolButton") - self.verticalLayout.addWidget(self.support_toolButton) self.label = QtWidgets.QLabel(self.tab) + self.label.setStyleSheet("background-color: rgb(255, 255, 255);") self.label.setFrameShape(QtWidgets.QFrame.StyledPanel) self.label.setTextFormat(QtCore.Qt.RichText) self.label.setScaledContents(True) self.label.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft) self.label.setWordWrap(True) self.label.setOpenExternalLinks(True) + self.label.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse) self.label.setObjectName("label") self.verticalLayout.addWidget(self.label) - self.gridLayout_14.addLayout(self.verticalLayout, 2, 1, 1, 1) - icon9 = QtGui.QIcon() - icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_home.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_dock.addTab(self.tab, icon9, "") + self.gridLayout_8.addLayout(self.verticalLayout, 3, 0, 1, 1) + icon8 = QtGui.QIcon() + icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_home.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget_dock.addTab(self.tab, icon8, "") self.tab_2 = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) @@ -228,9 +229,9 @@ def setupUi(self, DockClass): self.gridLayout_19.setObjectName("gridLayout_19") self.button_new_input = QtWidgets.QToolButton(self.tab_2) self.button_new_input.setStyleSheet("margin: 0px;padding: 0px;") - icon10 = QtGui.QIcon() - icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.button_new_input.setIcon(icon10) + icon9 = QtGui.QIcon() + icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_new_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.button_new_input.setIcon(icon9) self.button_new_input.setIconSize(QtCore.QSize(22, 22)) self.button_new_input.setObjectName("button_new_input") self.gridLayout_19.addWidget(self.button_new_input, 0, 1, 1, 1) @@ -240,17 +241,17 @@ def setupUi(self, DockClass): self.gridLayout_19.addWidget(self.trainingFile_lineEdit, 0, 2, 1, 1) self.trainingFile_toolButton = QtWidgets.QToolButton(self.tab_2) self.trainingFile_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon11 = QtGui.QIcon() - icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.trainingFile_toolButton.setIcon(icon11) + icon10 = QtGui.QIcon() + icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_open_file.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.trainingFile_toolButton.setIcon(icon10) self.trainingFile_toolButton.setIconSize(QtCore.QSize(22, 22)) self.trainingFile_toolButton.setObjectName("trainingFile_toolButton") self.gridLayout_19.addWidget(self.trainingFile_toolButton, 0, 0, 1, 1) self.button_reset_input = QtWidgets.QToolButton(self.tab_2) self.button_reset_input.setStyleSheet("margin: 0px;padding: 0px;") - icon12 = QtGui.QIcon() - icon12.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.button_reset_input.setIcon(icon12) + icon11 = QtGui.QIcon() + icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_reset.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.button_reset_input.setIcon(icon11) self.button_reset_input.setIconSize(QtCore.QSize(22, 22)) self.button_reset_input.setObjectName("button_reset_input") self.gridLayout_19.addWidget(self.button_reset_input, 0, 3, 1, 1) @@ -261,7 +262,7 @@ def setupUi(self, DockClass): font.setItalic(False) font.setWeight(75) self.label_48.setFont(font) - self.label_48.setStyleSheet("background-color : #656565; color : white; font: bold;") + self.label_48.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") self.label_48.setFrameShape(QtWidgets.QFrame.Panel) self.label_48.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_48.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -276,26 +277,26 @@ def setupUi(self, DockClass): self.merge_signature_toolButton = QtWidgets.QToolButton(self.tab_2) self.merge_signature_toolButton.setStyleSheet("margin: 0px;padding: 0px;") self.merge_signature_toolButton.setText("") - icon13 = QtGui.QIcon() - icon13.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_merge_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.merge_signature_toolButton.setIcon(icon13) + icon12 = QtGui.QIcon() + icon12.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_merge_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.merge_signature_toolButton.setIcon(icon12) self.merge_signature_toolButton.setIconSize(QtCore.QSize(22, 22)) self.merge_signature_toolButton.setObjectName("merge_signature_toolButton") self.verticalLayout_4.addWidget(self.merge_signature_toolButton) self.calculate_signature_toolButton = QtWidgets.QToolButton(self.tab_2) self.calculate_signature_toolButton.setStyleSheet("margin: 0px;padding: 0px;") self.calculate_signature_toolButton.setText("") - icon14 = QtGui.QIcon() - icon14.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.calculate_signature_toolButton.setIcon(icon14) + icon13 = QtGui.QIcon() + icon13.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.calculate_signature_toolButton.setIcon(icon13) self.calculate_signature_toolButton.setIconSize(QtCore.QSize(22, 22)) self.calculate_signature_toolButton.setObjectName("calculate_signature_toolButton") self.verticalLayout_4.addWidget(self.calculate_signature_toolButton) self.delete_Signature_Button = QtWidgets.QToolButton(self.tab_2) self.delete_Signature_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon15 = QtGui.QIcon() - icon15.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_delete_signature.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.delete_Signature_Button.setIcon(icon15) + icon14 = QtGui.QIcon() + icon14.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.delete_Signature_Button.setIcon(icon14) self.delete_Signature_Button.setIconSize(QtCore.QSize(22, 22)) self.delete_Signature_Button.setObjectName("delete_Signature_Button") self.verticalLayout_4.addWidget(self.delete_Signature_Button) @@ -303,17 +304,17 @@ def setupUi(self, DockClass): self.verticalLayout_4.addItem(spacerItem1) self.signature_spectral_plot_toolButton = QtWidgets.QToolButton(self.tab_2) self.signature_spectral_plot_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon16 = QtGui.QIcon() - icon16.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.signature_spectral_plot_toolButton.setIcon(icon16) + icon15 = QtGui.QIcon() + icon15.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.signature_spectral_plot_toolButton.setIcon(icon15) self.signature_spectral_plot_toolButton.setIconSize(QtCore.QSize(22, 22)) self.signature_spectral_plot_toolButton.setObjectName("signature_spectral_plot_toolButton") self.verticalLayout_4.addWidget(self.signature_spectral_plot_toolButton) self.scatterPlot_toolButton = QtWidgets.QToolButton(self.tab_2) self.scatterPlot_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon17 = QtGui.QIcon() - icon17.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.scatterPlot_toolButton.setIcon(icon17) + icon16 = QtGui.QIcon() + icon16.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.scatterPlot_toolButton.setIcon(icon16) self.scatterPlot_toolButton.setIconSize(QtCore.QSize(22, 22)) self.scatterPlot_toolButton.setObjectName("scatterPlot_toolButton") self.verticalLayout_4.addWidget(self.scatterPlot_toolButton) @@ -321,17 +322,17 @@ def setupUi(self, DockClass): self.verticalLayout_4.addItem(spacerItem2) self.import_library_toolButton = QtWidgets.QToolButton(self.tab_2) self.import_library_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon18 = QtGui.QIcon() - icon18.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import_spectral_library.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.import_library_toolButton.setIcon(icon18) + icon17 = QtGui.QIcon() + icon17.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_import_spectral_library.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.import_library_toolButton.setIcon(icon17) self.import_library_toolButton.setIconSize(QtCore.QSize(22, 22)) self.import_library_toolButton.setObjectName("import_library_toolButton") self.verticalLayout_4.addWidget(self.import_library_toolButton) self.export_signature_list_toolButton = QtWidgets.QToolButton(self.tab_2) self.export_signature_list_toolButton.setStyleSheet("margin: 0px;padding: 0px;") - icon19 = QtGui.QIcon() - icon19.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export_spectral_library.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.export_signature_list_toolButton.setIcon(icon19) + icon18 = QtGui.QIcon() + icon18.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_export_spectral_library.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.export_signature_list_toolButton.setIcon(icon18) self.export_signature_list_toolButton.setIconSize(QtCore.QSize(22, 22)) self.export_signature_list_toolButton.setObjectName("export_signature_list_toolButton") self.verticalLayout_4.addWidget(self.export_signature_list_toolButton) @@ -394,10 +395,12 @@ def setupUi(self, DockClass): self.ROI_ID_spin.setObjectName("ROI_ID_spin") self.gridLayout_27.addWidget(self.ROI_ID_spin, 1, 1, 1, 2) self.ROI_Class_line = QtWidgets.QLineEdit(self.tab_2) + self.ROI_Class_line.setText("") self.ROI_Class_line.setMaxLength(80) self.ROI_Class_line.setObjectName("ROI_Class_line") self.gridLayout_27.addWidget(self.ROI_Class_line, 1, 4, 1, 1) self.ROI_Macroclass_line = QtWidgets.QLineEdit(self.tab_2) + self.ROI_Macroclass_line.setText("") self.ROI_Macroclass_line.setMaxLength(80) self.ROI_Macroclass_line.setObjectName("ROI_Macroclass_line") self.gridLayout_27.addWidget(self.ROI_Macroclass_line, 0, 4, 1, 1) @@ -406,17 +409,17 @@ def setupUi(self, DockClass): self.horizontalLayout.setObjectName("horizontalLayout") self.undo_save_Button = QtWidgets.QToolButton(self.tab_2) self.undo_save_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon20 = QtGui.QIcon() - icon20.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.undo_save_Button.setIcon(icon20) + icon19 = QtGui.QIcon() + icon19.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.undo_save_Button.setIcon(icon19) self.undo_save_Button.setIconSize(QtCore.QSize(22, 22)) self.undo_save_Button.setObjectName("undo_save_Button") self.horizontalLayout.addWidget(self.undo_save_Button) self.redo_save_Button = QtWidgets.QToolButton(self.tab_2) self.redo_save_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon21 = QtGui.QIcon() - icon21.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_redo_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.redo_save_Button.setIcon(icon21) + icon20 = QtGui.QIcon() + icon20.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_redo_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.redo_save_Button.setIcon(icon20) self.redo_save_Button.setIconSize(QtCore.QSize(22, 22)) self.redo_save_Button.setObjectName("redo_save_Button") self.horizontalLayout.addWidget(self.redo_save_Button) @@ -437,17 +440,17 @@ def setupUi(self, DockClass): self.horizontalLayout.addWidget(self.signature_checkBox) self.button_Save_ROI = QtWidgets.QToolButton(self.tab_2) self.button_Save_ROI.setStyleSheet("margin: 0px;padding: 0px;") - icon22 = QtGui.QIcon() - icon22.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.button_Save_ROI.setIcon(icon22) + icon21 = QtGui.QIcon() + icon21.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_roi.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.button_Save_ROI.setIcon(icon21) self.button_Save_ROI.setIconSize(QtCore.QSize(22, 22)) self.button_Save_ROI.setObjectName("button_Save_ROI") self.horizontalLayout.addWidget(self.button_Save_ROI) self.verticalLayout_2.addLayout(self.horizontalLayout) self.gridLayout_7.addLayout(self.verticalLayout_2, 0, 0, 1, 1) - icon23 = QtGui.QIcon() - icon23.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_training_input.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_dock.addTab(self.tab_2, icon23, "") + icon22 = QtGui.QIcon() + icon22.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_training_input.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget_dock.addTab(self.tab_2, icon22, "") self.tab_12 = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) @@ -459,10 +462,30 @@ def setupUi(self, DockClass): self.gridLayout_2.setObjectName("gridLayout_2") self.gridLayout_4 = QtWidgets.QGridLayout() self.gridLayout_4.setObjectName("gridLayout_4") + self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5.setObjectName("gridLayout_5") + self.rapidROI_band_spinBox = QtWidgets.QSpinBox(self.tab_12) + self.rapidROI_band_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.rapidROI_band_spinBox.setMinimum(1) + self.rapidROI_band_spinBox.setMaximum(10000) + self.rapidROI_band_spinBox.setProperty("value", 1) + self.rapidROI_band_spinBox.setObjectName("rapidROI_band_spinBox") + self.gridLayout_5.addWidget(self.rapidROI_band_spinBox, 0, 1, 1, 1) + self.rapid_ROI_checkBox = QtWidgets.QCheckBox(self.tab_12) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.rapid_ROI_checkBox.sizePolicy().hasHeightForWidth()) + self.rapid_ROI_checkBox.setSizePolicy(sizePolicy) + self.rapid_ROI_checkBox.setChecked(True) + self.rapid_ROI_checkBox.setObjectName("rapid_ROI_checkBox") + self.gridLayout_5.addWidget(self.rapid_ROI_checkBox, 0, 0, 1, 1) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_5.addItem(spacerItem4, 0, 2, 1, 1) + self.gridLayout_4.addLayout(self.gridLayout_5, 1, 0, 1, 1) self.horizontalLayout_8 = QtWidgets.QHBoxLayout() self.horizontalLayout_8.setObjectName("horizontalLayout_8") self.display_cursor_checkBox = QtWidgets.QCheckBox(self.tab_12) - self.display_cursor_checkBox.setChecked(True) self.display_cursor_checkBox.setObjectName("display_cursor_checkBox") self.horizontalLayout_8.addWidget(self.display_cursor_checkBox) self.vegetation_index_comboBox = QtWidgets.QComboBox(self.tab_12) @@ -475,42 +498,38 @@ def setupUi(self, DockClass): self.custom_index_lineEdit.setObjectName("custom_index_lineEdit") self.horizontalLayout_8.addWidget(self.custom_index_lineEdit) self.gridLayout_4.addLayout(self.horizontalLayout_8, 0, 0, 1, 1) - self.gridLayout_5 = QtWidgets.QGridLayout() - self.gridLayout_5.setObjectName("gridLayout_5") - self.rapid_ROI_checkBox = QtWidgets.QCheckBox(self.tab_12) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rapid_ROI_checkBox.sizePolicy().hasHeightForWidth()) - self.rapid_ROI_checkBox.setSizePolicy(sizePolicy) - self.rapid_ROI_checkBox.setChecked(True) - self.rapid_ROI_checkBox.setObjectName("rapid_ROI_checkBox") - self.gridLayout_5.addWidget(self.rapid_ROI_checkBox, 0, 0, 1, 1) - self.rapidROI_band_spinBox = QtWidgets.QSpinBox(self.tab_12) - self.rapidROI_band_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.rapidROI_band_spinBox.setMinimum(1) - self.rapidROI_band_spinBox.setMaximum(10000) - self.rapidROI_band_spinBox.setProperty("value", 1) - self.rapidROI_band_spinBox.setObjectName("rapidROI_band_spinBox") - self.gridLayout_5.addWidget(self.rapidROI_band_spinBox, 0, 1, 1, 1) - self.gridLayout_4.addLayout(self.gridLayout_5, 1, 0, 1, 1) self.gridLayout_3 = QtWidgets.QGridLayout() self.gridLayout_3.setObjectName("gridLayout_3") - self.auto_refresh_ROI_radioButton = QtWidgets.QRadioButton(self.tab_12) - self.auto_refresh_ROI_radioButton.setAutoExclusive(False) - self.auto_refresh_ROI_radioButton.setObjectName("auto_refresh_ROI_radioButton") - self.gridLayout_3.addWidget(self.auto_refresh_ROI_radioButton, 0, 1, 1, 1) - self.auto_calculate_ROI_signature_radioButton = QtWidgets.QRadioButton(self.tab_12) - self.auto_calculate_ROI_signature_radioButton.setAutoExclusive(False) - self.auto_calculate_ROI_signature_radioButton.setObjectName("auto_calculate_ROI_signature_radioButton") - self.gridLayout_3.addWidget(self.auto_calculate_ROI_signature_radioButton, 0, 0, 1, 1) + self.auto_refresh_ROI_checkBox = QtWidgets.QCheckBox(self.tab_12) + self.auto_refresh_ROI_checkBox.setAutoExclusive(False) + self.auto_refresh_ROI_checkBox.setObjectName("auto_refresh_ROI_checkBox") + self.gridLayout_3.addWidget(self.auto_refresh_ROI_checkBox, 0, 1, 1, 1) + self.auto_calculate_ROI_signature_checkBox = QtWidgets.QCheckBox(self.tab_12) + self.auto_calculate_ROI_signature_checkBox.setAutoExclusive(False) + self.auto_calculate_ROI_signature_checkBox.setObjectName("auto_calculate_ROI_signature_checkBox") + self.gridLayout_3.addWidget(self.auto_calculate_ROI_signature_checkBox, 0, 0, 1, 1) self.gridLayout_4.addLayout(self.gridLayout_3, 2, 0, 1, 1) + spacerItem5 = QtWidgets.QSpacerItem(20, 360, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_4.addItem(spacerItem5, 5, 0, 1, 1) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.label_46 = QtWidgets.QLabel(self.tab_12) + self.label_46.setObjectName("label_46") + self.horizontalLayout_3.addWidget(self.label_46) + self.max_buffer_spinBox = QtWidgets.QSpinBox(self.tab_12) + self.max_buffer_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.max_buffer_spinBox.setMinimum(1) + self.max_buffer_spinBox.setMaximum(100) + self.max_buffer_spinBox.setProperty("value", 5) + self.max_buffer_spinBox.setObjectName("max_buffer_spinBox") + self.horizontalLayout_3.addWidget(self.max_buffer_spinBox) + spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem6) + self.gridLayout_4.addLayout(self.horizontalLayout_3, 3, 0, 1, 1) self.gridLayout_2.addLayout(self.gridLayout_4, 0, 0, 1, 1) - spacerItem4 = QtWidgets.QSpacerItem(20, 360, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_2.addItem(spacerItem4, 1, 0, 1, 1) - icon24 = QtGui.QIcon() - icon24.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_options.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget_dock.addTab(self.tab_12, icon24, "") + icon23 = QtGui.QIcon() + icon23.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_options.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget_dock.addTab(self.tab_12, icon23, "") self.tab_4 = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) @@ -576,23 +595,22 @@ def setupUi(self, DockClass): def retranslateUi(self, DockClass): _translate = QtCore.QCoreApplication.translate - DockClass.setWindowTitle(_translate("DockClass", "SCP &Dock")) - self.batch_toolButton.setToolTip(_translate("DockClass", "

Batch

")) + DockClass.setWindowTitle(_translate("DockClass", "SCP Dock")) self.postprocessing_toolButton_2.setToolTip(_translate("DockClass", "

Postprocessing

")) - self.preprocessing_toolButton_2.setToolTip(_translate("DockClass", "

Preprocessing

")) self.bandset_toolButton.setToolTip(_translate("DockClass", "

Band set

")) - self.bandcalc_toolButton_2.setToolTip(_translate("DockClass", "

Band calc

")) - self.download_images_toolButton_2.setToolTip(_translate("DockClass", "

Download products

")) + self.preprocessing_toolButton_2.setToolTip(_translate("DockClass", "

Preprocessing

")) self.band_processing_toolButton.setToolTip(_translate("DockClass", "

Band processing

")) + self.batch_toolButton.setToolTip(_translate("DockClass", "

Batch

")) self.basic_tools_toolButton.setToolTip(_translate("DockClass", "

Basic tools

")) + self.bandcalc_toolButton_2.setToolTip(_translate("DockClass", "

Band calc

")) + self.download_images_toolButton_2.setToolTip(_translate("DockClass", "

Download products

")) self.label_35.setText(_translate("DockClass", " News")) + self.rs_version.setText(_translate("DockClass", "

")) self.userguide_toolButton_2.setToolTip(_translate("DockClass", "

User manual

")) self.userguide_toolButton_2.setText(_translate("DockClass", "User manual")) self.help_toolButton_2.setToolTip(_translate("DockClass", "

Ask a question

")) - self.help_toolButton_2.setText(_translate("DockClass", "Ask a question")) - self.support_toolButton.setToolTip(_translate("DockClass", "

Support the SCP

")) - self.support_toolButton.setText(_translate("DockClass", "Support the SCP")) - self.label.setText(_translate("DockClass", "

How to cite:

Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172

")) + self.help_toolButton_2.setText(_translate("DockClass", "Support forum")) + self.label.setText(_translate("DockClass", "

To cite the Semi-Automatic Classification Plugin in your work:

Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, https://doi.org/10.21105/joss.03172

")) self.tabWidget_dock.setTabText(self.tabWidget_dock.indexOf(self.tab), _translate("DockClass", "Home")) self.button_new_input.setToolTip(_translate("DockClass", "

Create a new training input

")) self.trainingFile_lineEdit.setToolTip(_translate("DockClass", "

Input file path

")) @@ -620,36 +638,35 @@ def retranslateUi(self, DockClass): self.label_42.setText(_translate("DockClass", "C ID")) self.label_45.setText(_translate("DockClass", "MC Name")) self.label_44.setText(_translate("DockClass", "MC ID")) - self.ROI_ID_spin.setToolTip(_translate("DockClass", "

The class ID of the ROI signature

")) + self.ROI_ID_spin.setToolTip(_translate("DockClass", "

The class ID of the ROI signature (should be unique)

")) self.ROI_Class_line.setToolTip(_translate("DockClass", "

The class name of the ROI signature

")) - self.ROI_Class_line.setText(_translate("DockClass", "C 1")) self.ROI_Macroclass_line.setToolTip(_translate("DockClass", "

The macroclass name of the ROI signature

")) - self.ROI_Macroclass_line.setText(_translate("DockClass", "MC 1")) self.undo_save_Button.setToolTip(_translate("DockClass", "

Undo ROI save

")) self.undo_save_Button.setText(_translate("DockClass", "Import library")) self.redo_save_Button.setToolTip(_translate("DockClass", "

Redo ROI save

")) self.redo_save_Button.setText(_translate("DockClass", "Import library")) - self.save_input_checkBox.setToolTip(_translate("DockClass", "

Automatically save training input when a ROI is saved in it

")) + self.save_input_checkBox.setToolTip(_translate("DockClass", "

Automatically save the training input whenever a ROI is saved in it

")) self.save_input_checkBox.setText(_translate("DockClass", "Autosave")) self.signature_checkBox.setToolTip(_translate("DockClass", "

Add ROI spectral signature to signature list

")) self.signature_checkBox.setText(_translate("DockClass", "Signature")) self.button_Save_ROI.setToolTip(_translate("DockClass", "

Save temporary ROI to training input

")) self.button_Save_ROI.setText(_translate("DockClass", "Import library")) self.tabWidget_dock.setTabText(self.tabWidget_dock.indexOf(self.tab_2), _translate("DockClass", "Training input")) + self.rapidROI_band_spinBox.setToolTip(_translate("DockClass", "

Band number

")) + self.rapid_ROI_checkBox.setToolTip(_translate("DockClass", "

Calculate temporary ROI only on one band

")) + self.rapid_ROI_checkBox.setText(_translate("DockClass", "Rapid ROI b.")) self.display_cursor_checkBox.setToolTip(_translate("DockClass", "

Display a vegetation index value with the cursor

")) self.display_cursor_checkBox.setText(_translate("DockClass", "Display")) self.vegetation_index_comboBox.setToolTip(_translate("DockClass", "

Select a vegetation index

")) self.vegetation_index_comboBox.setItemText(0, _translate("DockClass", "NDVI")) self.vegetation_index_comboBox.setItemText(1, _translate("DockClass", "EVI")) self.vegetation_index_comboBox.setItemText(2, _translate("DockClass", "Custom")) - self.custom_index_lineEdit.setToolTip(_translate("DockClass", "

Custom expression (e.g. bandset#b4 / bandset#b3 )

")) - self.rapid_ROI_checkBox.setToolTip(_translate("DockClass", "

Calculate temporary ROI only on one band

")) - self.rapid_ROI_checkBox.setText(_translate("DockClass", "Rapid ROI b.")) - self.rapidROI_band_spinBox.setToolTip(_translate("DockClass", "

Band number

")) - self.auto_refresh_ROI_radioButton.setToolTip(_translate("DockClass", "

Automatically refresh the temporary ROI, as the parameters change

")) - self.auto_refresh_ROI_radioButton.setText(_translate("DockClass", "A&uto-refresh ROI")) - self.auto_calculate_ROI_signature_radioButton.setToolTip(_translate("DockClass", "

Automatically calculate signature plot of temporary ROI

")) - self.auto_calculate_ROI_signature_radioButton.setText(_translate("DockClass", "Auto-plot")) + self.custom_index_lineEdit.setToolTip(_translate("DockClass", "

Custom expression (e.g. "b1" / "b2" or "#NIR#" / "#RED#")

")) + self.auto_refresh_ROI_checkBox.setToolTip(_translate("DockClass", "

Automatically refresh the temporary ROI, as the parameters change

")) + self.auto_refresh_ROI_checkBox.setText(_translate("DockClass", "A&uto-refresh ROI")) + self.auto_calculate_ROI_signature_checkBox.setToolTip(_translate("DockClass", "

Automatically calculate signature plot of temporary ROI

")) + self.auto_calculate_ROI_signature_checkBox.setText(_translate("DockClass", "Auto-plot")) + self.label_46.setText(_translate("DockClass", "Maximum training buffer")) + self.max_buffer_spinBox.setToolTip(_translate("DockClass", "

Maximum training buffer for undo and redo actions (higher values require more memory)

")) self.tabWidget_dock.setTabText(self.tabWidget_dock.indexOf(self.tab_12), _translate("DockClass", " ROI options")) - from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin_dock_class.ui b/ui/ui_semiautomaticclassificationplugin_dock_class.ui old mode 100644 new mode 100755 index 8afb664..a44c13f --- a/ui/ui_semiautomaticclassificationplugin_dock_class.ui +++ b/ui/ui_semiautomaticclassificationplugin_dock_class.ui @@ -6,8 +6,8 @@ 0 0 - 397 - 496 + 440 + 505 @@ -17,7 +17,7 @@ - SCP &Dock + SCP Dock @@ -61,178 +61,20 @@ Home - - - - - - - 8 - - - - - <html><head/><body><p>Batch</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Postprocessing</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Preprocessing</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Band set</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p><span >Band calc</span></p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Download products</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Band processing</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Basic tools</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg - - - - 22 - 22 - - - - - - - + + + + + + background-color: rgb(32, 97, 118); color : white; font: bold + + + QFrame::Panel + + + QFrame::Raised + @@ -243,7 +85,174 @@ - + + + + 8 + + + + + <html><head/><body><p>Postprocessing</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_post_process.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p><span >Band set</span></p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandset_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Preprocessing</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_class_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Band processing</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_band_processing.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Batch</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_batch.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Basic tools</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_roi_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p><span >Band calc</span></p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_bandcalc_tool.svg + + + + 22 + 22 + + + + + + + + <html><head/><body><p>Download products</p></body></html> + + + margin: 0px;padding: 0px; + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_download_arrow.svg + + + + 22 + 22 + + + + + + + @@ -254,27 +263,24 @@ true
- - background-color : #656565; color : white; font: bold; - - QFrame::Panel + QFrame::NoFrame - QFrame::Sunken + QFrame::Plain News - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;"><br /></span></p></body></html> @@ -282,9 +288,38 @@ p, li { white-space: pre-wrap; } + + + + + 16777215 + 10 + + + + + 75 + false + true + + + + color: rgb(237, 51, 59); + + + QFrame::NoFrame + + + QFrame::Plain + + + <html><head/><body><p></p></body></html> + + + - + @@ -304,7 +339,7 @@ p, li { white-space: pre-wrap; } color: white; -background-color: rgb(51, 122, 183); +background-color: rgb(32, 97, 118); selection-color: yellow; selection-background-color: blue; font: bold 14px; @@ -337,7 +372,7 @@ padding: 2px; color: white; -background-color: rgb(51, 122, 183); +background-color: rgb(32, 97, 118); selection-color: yellow; selection-background-color: blue; font: bold 14px; @@ -348,49 +383,20 @@ border-color: white; padding: 2px; - Ask a question + Support forum - - - PointingHandCursor - - - <html><head/><body><p><span style=" color:#ffffff;">Support the SCP</span></p></body></html> - + - color: white; -background-color: rgb(92, 184, 92); -selection-color: yellow; -selection-background-color: blue; -font: bold 14px; -border-style: inset; -border-width: 2px; -border-radius: 6px; -border-color: white; -padding: 2px; - - - Support the SCP - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg - - - false + background-color: rgb(255, 255, 255); - - - - QFrame::StyledPanel - <html><head/><body><p><span style=" font-weight:600;">How to cite</span>:</p><p>Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, <a href="https://doi.org/10.21105/joss.03172"><span style=" text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">To cite the Semi-Automatic Classification Plugin in your work:</span></p><p><span style=" font-size:10pt;">Congedo, Luca, (2021). Semi-Automatic Classification Plugin: A Python tool for the download and processing of remote sensing images in QGIS. Journal of Open Source Software, 6(64), 3172, </span><a href="https://doi.org/10.21105/joss.03172"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">https://doi.org/10.21105/joss.03172</span></a></p></body></html> Qt::RichText @@ -407,6 +413,9 @@ padding: 2px; true + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + @@ -517,7 +526,7 @@ padding: 2px;
- background-color : #656565; color : white; font: bold; + background-color : #5a5a5a; color : white; font: bold QFrame::Panel @@ -609,7 +618,7 @@ padding: 2px; - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_delete_signature.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_delete_signature.svg + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg @@ -855,7 +864,7 @@ padding: 2px; - <html><head/><body><p>The class ID of the ROI signature</p></body></html> + <html><head/><body><p>The class ID of the ROI signature (should be unique)</p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -877,7 +886,7 @@ padding: 2px; <html><head/><body><p>The class name of the ROI signature</p></body></html> - C 1 + 80 @@ -890,7 +899,7 @@ padding: 2px; <html><head/><body><p>The macroclass name of the ROI signature</p></body></html> - MC 1 + 80 @@ -963,7 +972,7 @@ padding: 2px; - <html><head/><body><p>Automatically save training input when a ROI is saved in it</p></body></html> + <html><head/><body><p>Automatically save the training input whenever a ROI is saved in it</p></body></html> Autosave @@ -1038,6 +1047,61 @@ padding: 2px; + + + + + + <html><head/><body><p>Band number</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 10000 + + + 1 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> + + + Rapid ROI b. + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -1048,9 +1112,6 @@ padding: 2px; Display - - true - @@ -1078,49 +1139,7 @@ padding: 2px; - <html><head/><body><p>Custom expression (e.g. bandset#b4 / bandset#b3 )</p></body></html> - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Calculate temporary ROI only on one band</p></body></html> - - - Rapid ROI b. - - - true - - - - - - - <html><head/><body><p>Band number</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 10000 - - - 1 + <html><head/><body><p>Custom expression (e.g. &quot;b1&quot; / &quot;b2&quot; or &quot;#NIR#&quot; / &quot;#RED#&quot;)</p></body></html> @@ -1129,7 +1148,7 @@ padding: 2px; - + <html><head/><body><p>Automatically refresh the temporary ROI, as the parameters change</p></body></html> @@ -1142,7 +1161,7 @@ padding: 2px; - + <html><head/><body><p>Automatically calculate signature plot of temporary ROI</p></body></html> @@ -1156,21 +1175,64 @@ padding: 2px; + + + + Qt::Vertical + + + + 20 + 360 + + + + + + + + + + Maximum training buffer + + + + + + + <html><head/><body><p>Maximum training buffer for undo and redo actions (higher values require more memory)</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 100 + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - - - - Qt::Vertical - - - - 20 - 360 - - - - diff --git a/ui/ui_semiautomaticclassificationplugin_scatter_plot.py b/ui/ui_semiautomaticclassificationplugin_scatter_plot.py old mode 100644 new mode 100755 index b8c0bb7..41c45fd --- a/ui/ui_semiautomaticclassificationplugin_scatter_plot.py +++ b/ui/ui_semiautomaticclassificationplugin_scatter_plot.py @@ -2,12 +2,15 @@ # Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin_scatter_plot.ui' # -# Created by: PyQt5 UI code generator 5.11.3 +# Created by: PyQt5 UI code generator 5.15.9 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_ScatterPlot(object): def setupUi(self, ScatterPlot): ScatterPlot.setObjectName("ScatterPlot") @@ -20,25 +23,28 @@ def setupUi(self, ScatterPlot): icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) ScatterPlot.setWindowIcon(icon) + ScatterPlot.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.gridLayout_5 = QtWidgets.QGridLayout(ScatterPlot) self.gridLayout_5.setObjectName("gridLayout_5") self.splitter = QtWidgets.QSplitter(ScatterPlot) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setChildrenCollapsible(False) self.splitter.setObjectName("splitter") - self.widget = QtWidgets.QWidget(self.splitter) - self.widget.setObjectName("widget") - self.gridLayout_2 = QtWidgets.QGridLayout(self.widget) + self.layoutWidget = QtWidgets.QWidget(self.splitter) + self.layoutWidget.setObjectName("layoutWidget") + self.gridLayout_2 = QtWidgets.QGridLayout(self.layoutWidget) self.gridLayout_2.setContentsMargins(0, 0, 0, 0) self.gridLayout_2.setObjectName("gridLayout_2") - self.scatter_list_plot_tableWidget = QtWidgets.QTableWidget(self.widget) + self.scatter_list_plot_tableWidget = QtWidgets.QTableWidget(self.layoutWidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.scatter_list_plot_tableWidget.sizePolicy().hasHeightForWidth()) self.scatter_list_plot_tableWidget.setSizePolicy(sizePolicy) self.scatter_list_plot_tableWidget.setMinimumSize(QtCore.QSize(0, 50)) + self.scatter_list_plot_tableWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.scatter_list_plot_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.scatter_list_plot_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.scatter_list_plot_tableWidget.setObjectName("scatter_list_plot_tableWidget") self.scatter_list_plot_tableWidget.setColumnCount(6) self.scatter_list_plot_tableWidget.setRowCount(0) @@ -56,14 +62,14 @@ def setupUi(self, ScatterPlot): self.scatter_list_plot_tableWidget.setHorizontalHeaderItem(5, item) self.scatter_list_plot_tableWidget.horizontalHeader().setDefaultSectionSize(62) self.scatter_list_plot_tableWidget.horizontalHeader().setStretchLastSection(True) - self.scatter_list_plot_tableWidget.verticalHeader().setDefaultSectionSize(20) + self.scatter_list_plot_tableWidget.verticalHeader().setDefaultSectionSize(22) self.gridLayout_2.addWidget(self.scatter_list_plot_tableWidget, 0, 0, 1, 1) - self.widget1 = QtWidgets.QWidget(self.splitter) - self.widget1.setObjectName("widget1") - self.gridLayout_3 = QtWidgets.QGridLayout(self.widget1) + self.layoutWidget1 = QtWidgets.QWidget(self.splitter) + self.layoutWidget1.setObjectName("layoutWidget1") + self.gridLayout_3 = QtWidgets.QGridLayout(self.layoutWidget1) self.gridLayout_3.setContentsMargins(0, 0, 0, 0) self.gridLayout_3.setObjectName("gridLayout_3") - self.Scatter_Widget_2 = ScatterWidget2(self.widget1) + self.Scatter_Widget_2 = ScatterWidget2(self.layoutWidget1) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -86,18 +92,6 @@ def setupUi(self, ScatterPlot): self.gridLayout.setObjectName("gridLayout") self.gridLayout_6 = QtWidgets.QGridLayout() self.gridLayout_6.setObjectName("gridLayout_6") - self.label_26 = QtWidgets.QLabel(self.frame) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(True) - font.setWeight(75) - self.label_26.setFont(font) - self.label_26.setStyleSheet("background-color : #656565; color : white") - self.label_26.setFrameShape(QtWidgets.QFrame.Panel) - self.label_26.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_26.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_26.setObjectName("label_26") - self.gridLayout_6.addWidget(self.label_26, 9, 0, 1, 1) self.horizontalLayout_8 = QtWidgets.QHBoxLayout() self.horizontalLayout_8.setObjectName("horizontalLayout_8") self.label_49 = QtWidgets.QLabel(self.frame) @@ -117,62 +111,48 @@ def setupUi(self, ScatterPlot): self.scatter_ROI_Button.setObjectName("scatter_ROI_Button") self.horizontalLayout_8.addWidget(self.scatter_ROI_Button) self.gridLayout_6.addLayout(self.horizontalLayout_8, 6, 0, 1, 1) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.precision_checkBox = QtWidgets.QCheckBox(self.frame) + self.precision_checkBox.setObjectName("precision_checkBox") + self.horizontalLayout_2.addWidget(self.precision_checkBox) + self.precision_comboBox = QtWidgets.QComboBox(self.frame) + self.precision_comboBox.setObjectName("precision_comboBox") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.precision_comboBox.addItem("") + self.horizontalLayout_2.addWidget(self.precision_comboBox) + self.gridLayout_6.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_6.addItem(spacerItem, 8, 0, 1, 1) self.gridLayout_14 = QtWidgets.QGridLayout() self.gridLayout_14.setObjectName("gridLayout_14") - self.horizontalLayout_7 = QtWidgets.QHBoxLayout() - self.horizontalLayout_7.setObjectName("horizontalLayout_7") - self.show_polygon_area_pushButton = QtWidgets.QToolButton(self.frame) - self.show_polygon_area_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.show_polygon_area_pushButton.setText("") - icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_show_raster.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.show_polygon_area_pushButton.setIcon(icon2) - self.show_polygon_area_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.show_polygon_area_pushButton.setObjectName("show_polygon_area_pushButton") - self.horizontalLayout_7.addWidget(self.show_polygon_area_pushButton) - self.add_signature_list_pushButton = QtWidgets.QToolButton(self.frame) - self.add_signature_list_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.add_signature_list_pushButton.setText("") - icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.add_signature_list_pushButton.setIcon(icon3) - self.add_signature_list_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.add_signature_list_pushButton.setObjectName("add_signature_list_pushButton") - self.horizontalLayout_7.addWidget(self.add_signature_list_pushButton) - self.gridLayout_14.addLayout(self.horizontalLayout_7, 1, 3, 1, 1) - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_14.addItem(spacerItem, 3, 3, 1, 1) - self.value_label_2 = QtWidgets.QLabel(self.frame) - font = QtGui.QFont() - font.setFamily("Liberation Mono") - font.setBold(True) - font.setWeight(75) - self.value_label_2.setFont(font) - self.value_label_2.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.value_label_2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.value_label_2.setObjectName("value_label_2") - self.gridLayout_14.addWidget(self.value_label_2, 7, 3, 1, 1) self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.fitToAxes_pushButton_2 = QtWidgets.QToolButton(self.frame) self.fitToAxes_pushButton_2.setStyleSheet("margin: 0px;padding: 0px;") self.fitToAxes_pushButton_2.setText("") - icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.fitToAxes_pushButton_2.setIcon(icon4) + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.fitToAxes_pushButton_2.setIcon(icon2) self.fitToAxes_pushButton_2.setIconSize(QtCore.QSize(22, 22)) self.fitToAxes_pushButton_2.setObjectName("fitToAxes_pushButton_2") self.horizontalLayout_4.addWidget(self.fitToAxes_pushButton_2) self.save_plot_pushButton_2 = QtWidgets.QToolButton(self.frame) self.save_plot_pushButton_2.setStyleSheet("margin: 0px;padding: 0px;") self.save_plot_pushButton_2.setText("") - icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_plot_image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.save_plot_pushButton_2.setIcon(icon5) + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_plot_image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.save_plot_pushButton_2.setIcon(icon3) self.save_plot_pushButton_2.setIconSize(QtCore.QSize(22, 22)) self.save_plot_pushButton_2.setObjectName("save_plot_pushButton_2") self.horizontalLayout_4.addWidget(self.save_plot_pushButton_2) - self.gridLayout_14.addLayout(self.horizontalLayout_4, 6, 3, 1, 1) + self.gridLayout_14.addLayout(self.horizontalLayout_4, 3, 3, 1, 1) self.label_27 = QtWidgets.QLabel(self.frame) font = QtGui.QFont() font.setFamily("FreeSans") @@ -184,7 +164,7 @@ def setupUi(self, ScatterPlot): self.label_27.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_27.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) self.label_27.setObjectName("label_27") - self.gridLayout_14.addWidget(self.label_27, 4, 3, 1, 1) + self.gridLayout_14.addWidget(self.label_27, 1, 3, 1, 1) self.horizontalLayout_6 = QtWidgets.QHBoxLayout() self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.label_50 = QtWidgets.QLabel(self.frame) @@ -204,69 +184,18 @@ def setupUi(self, ScatterPlot): self.colormap_comboBox.setMinimumSize(QtCore.QSize(100, 0)) self.colormap_comboBox.setObjectName("colormap_comboBox") self.horizontalLayout_6.addWidget(self.colormap_comboBox) - self.plot_color_ROI_pushButton = QtWidgets.QToolButton(self.frame) - self.plot_color_ROI_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.plot_color_ROI_pushButton.setText("") - self.plot_color_ROI_pushButton.setIcon(icon1) - self.plot_color_ROI_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.plot_color_ROI_pushButton.setObjectName("plot_color_ROI_pushButton") - self.horizontalLayout_6.addWidget(self.plot_color_ROI_pushButton) - self.gridLayout_14.addLayout(self.horizontalLayout_6, 5, 3, 1, 1) - self.horizontalLayout_5 = QtWidgets.QHBoxLayout() - self.horizontalLayout_5.setObjectName("horizontalLayout_5") - self.label_51 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_51.sizePolicy().hasHeightForWidth()) - self.label_51.setSizePolicy(sizePolicy) - self.label_51.setObjectName("label_51") - self.horizontalLayout_5.addWidget(self.label_51) - self.extent_comboBox = QtWidgets.QComboBox(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.extent_comboBox.sizePolicy().hasHeightForWidth()) - self.extent_comboBox.setSizePolicy(sizePolicy) - self.extent_comboBox.setObjectName("extent_comboBox") - self.extent_comboBox.addItem("") - self.extent_comboBox.addItem("") - self.horizontalLayout_5.addWidget(self.extent_comboBox) - self.gridLayout_14.addLayout(self.horizontalLayout_5, 2, 3, 1, 1) - self.gridLayout_6.addLayout(self.gridLayout_14, 11, 0, 1, 1) - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() - self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.draw_polygons_pushButton = QtWidgets.QToolButton(self.frame) - self.draw_polygons_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.draw_polygons_pushButton.setIcon(icon6) - self.draw_polygons_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.draw_polygons_pushButton.setObjectName("draw_polygons_pushButton") - self.horizontalLayout_3.addWidget(self.draw_polygons_pushButton) - self.label_22 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_22.sizePolicy().hasHeightForWidth()) - self.label_22.setSizePolicy(sizePolicy) - self.label_22.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_22.setObjectName("label_22") - self.horizontalLayout_3.addWidget(self.label_22) - self.polygon_color_Button = QtWidgets.QPushButton(self.frame) - self.polygon_color_Button.setStyleSheet("background-color : #FFAA00") - self.polygon_color_Button.setText("") - self.polygon_color_Button.setObjectName("polygon_color_Button") - self.horizontalLayout_3.addWidget(self.polygon_color_Button) - self.remove_polygons_pushButton = QtWidgets.QToolButton(self.frame) - self.remove_polygons_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.remove_polygons_pushButton.setIcon(icon7) - self.remove_polygons_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.remove_polygons_pushButton.setObjectName("remove_polygons_pushButton") - self.horizontalLayout_3.addWidget(self.remove_polygons_pushButton) - self.gridLayout_6.addLayout(self.horizontalLayout_3, 10, 0, 1, 1) + self.gridLayout_14.addLayout(self.horizontalLayout_6, 2, 3, 1, 1) + self.value_label_2 = QtWidgets.QLabel(self.frame) + font = QtGui.QFont() + font.setFamily("Liberation Mono") + font.setBold(True) + font.setWeight(75) + self.value_label_2.setFont(font) + self.value_label_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.value_label_2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.value_label_2.setObjectName("value_label_2") + self.gridLayout_14.addWidget(self.value_label_2, 4, 3, 1, 1) + self.gridLayout_6.addLayout(self.gridLayout_14, 9, 0, 1, 1) self.gridLayout_40 = QtWidgets.QGridLayout() self.gridLayout_40.setObjectName("gridLayout_40") self.label_48 = QtWidgets.QLabel(self.frame) @@ -317,62 +246,25 @@ def setupUi(self, ScatterPlot): self.bandX_spinBox.setObjectName("bandX_spinBox") self.gridLayout_38.addWidget(self.bandX_spinBox, 0, 1, 1, 1) self.gridLayout_6.addLayout(self.gridLayout_38, 1, 0, 1, 1) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.precision_checkBox = QtWidgets.QCheckBox(self.frame) - self.precision_checkBox.setObjectName("precision_checkBox") - self.horizontalLayout_2.addWidget(self.precision_checkBox) - self.precision_comboBox = QtWidgets.QComboBox(self.frame) - self.precision_comboBox.setObjectName("precision_comboBox") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.precision_comboBox.addItem("") - self.horizontalLayout_2.addWidget(self.precision_comboBox) - self.gridLayout_6.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout_6.addItem(spacerItem1, 8, 0, 1, 1) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.remove_Signature_Button = QtWidgets.QToolButton(self.frame) self.remove_Signature_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.remove_Signature_Button.setIcon(icon8) + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.remove_Signature_Button.setIcon(icon4) self.remove_Signature_Button.setIconSize(QtCore.QSize(22, 22)) self.remove_Signature_Button.setObjectName("remove_Signature_Button") self.horizontalLayout.addWidget(self.remove_Signature_Button) self.plot_temp_ROI_pushButton = QtWidgets.QToolButton(self.frame) self.plot_temp_ROI_pushButton.setStyleSheet("margin: 0px;padding: 0px;") self.plot_temp_ROI_pushButton.setText("") - icon9 = QtGui.QIcon() - icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_temp_ROI.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.plot_temp_ROI_pushButton.setIcon(icon9) + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_temp_ROI.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.plot_temp_ROI_pushButton.setIcon(icon5) self.plot_temp_ROI_pushButton.setIconSize(QtCore.QSize(22, 22)) self.plot_temp_ROI_pushButton.setObjectName("plot_temp_ROI_pushButton") self.horizontalLayout.addWidget(self.plot_temp_ROI_pushButton) - self.plot_display_pushButton = QtWidgets.QToolButton(self.frame) - self.plot_display_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.plot_display_pushButton.setText("") - icon10 = QtGui.QIcon() - icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_display.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.plot_display_pushButton.setIcon(icon10) - self.plot_display_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.plot_display_pushButton.setObjectName("plot_display_pushButton") - self.horizontalLayout.addWidget(self.plot_display_pushButton) - self.plot_image_pushButton = QtWidgets.QToolButton(self.frame) - self.plot_image_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.plot_image_pushButton.setText("") - icon11 = QtGui.QIcon() - icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.plot_image_pushButton.setIcon(icon11) - self.plot_image_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.plot_image_pushButton.setObjectName("plot_image_pushButton") - self.horizontalLayout.addWidget(self.plot_image_pushButton) self.gridLayout_6.addLayout(self.horizontalLayout, 7, 0, 1, 1) self.gridLayout.addLayout(self.gridLayout_6, 0, 0, 1, 1) self.gridLayout_5.addWidget(self.frame, 1, 1, 1, 1) @@ -382,9 +274,11 @@ def setupUi(self, ScatterPlot): font = QtGui.QFont() font.setFamily("FreeSans") font.setBold(True) + font.setItalic(False) font.setWeight(75) self.label_25.setFont(font) - self.label_25.setStyleSheet("background-color : #656565; color : white") + self.label_25.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_25.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_25.setFrameShape(QtWidgets.QFrame.Panel) self.label_25.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_25.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -393,9 +287,8 @@ def setupUi(self, ScatterPlot): self.gridLayout_5.addLayout(self.gridLayout_4, 0, 0, 1, 2) self.retranslateUi(ScatterPlot) - self.colormap_comboBox.setCurrentIndex(-1) - self.extent_comboBox.setCurrentIndex(0) self.precision_comboBox.setCurrentIndex(1) + self.colormap_comboBox.setCurrentIndex(-1) QtCore.QMetaObject.connectSlotsByName(ScatterPlot) def retranslateUi(self, ScatterPlot): @@ -414,30 +307,8 @@ def retranslateUi(self, ScatterPlot): item.setText(_translate("ScatterPlot", "C Name")) item = self.scatter_list_plot_tableWidget.horizontalHeaderItem(5) item.setText(_translate("ScatterPlot", "Color")) - self.label_26.setText(_translate("ScatterPlot", " Scatter raster")) self.label_49.setText(_translate("ScatterPlot", "Calculate")) self.scatter_ROI_Button.setToolTip(_translate("ScatterPlot", "

Calculate scatter plot

")) - self.show_polygon_area_pushButton.setToolTip(_translate("ScatterPlot", "

Calculate and display scatter raster

")) - self.add_signature_list_pushButton.setToolTip(_translate("ScatterPlot", "

Calculate and save to signature list

")) - self.value_label_2.setText(_translate("ScatterPlot", "x=0.000000 y=0.000000")) - self.fitToAxes_pushButton_2.setToolTip(_translate("ScatterPlot", "

Automatically fit the plot to data

")) - self.save_plot_pushButton_2.setToolTip(_translate("ScatterPlot", "

Save the plot to file (jpg, png, pdf)

")) - self.label_27.setText(_translate("ScatterPlot", " Plot")) - self.label_50.setText(_translate("ScatterPlot", "Colormap")) - self.colormap_comboBox.setToolTip(_translate("ScatterPlot", "

Select a colormap

")) - self.plot_color_ROI_pushButton.setToolTip(_translate("ScatterPlot", "

Set colormap for highlighted spectral plots

")) - self.label_51.setText(_translate("ScatterPlot", "Extent")) - self.extent_comboBox.setToolTip(_translate("ScatterPlot", "

Select extent of scatter raster

")) - self.extent_comboBox.setItemText(0, _translate("ScatterPlot", "same as display")) - self.extent_comboBox.setItemText(1, _translate("ScatterPlot", "same as image")) - self.draw_polygons_pushButton.setToolTip(_translate("ScatterPlot", "

Create selection polygons

")) - self.label_22.setText(_translate("ScatterPlot", "color")) - self.polygon_color_Button.setToolTip(_translate("ScatterPlot", "

Select polygon color

")) - self.remove_polygons_pushButton.setToolTip(_translate("ScatterPlot", "

Remove selection polygons

")) - self.label_48.setText(_translate("ScatterPlot", "Band Y")) - self.bandY_spinBox.setToolTip(_translate("ScatterPlot", "

Band Y

")) - self.label_46.setText(_translate("ScatterPlot", "Band X")) - self.bandX_spinBox.setToolTip(_translate("ScatterPlot", "

Band X

")) self.precision_checkBox.setToolTip(_translate("ScatterPlot", "

Use custom decimal precision

")) self.precision_checkBox.setText(_translate("ScatterPlot", "Precision")) self.precision_comboBox.setToolTip(_translate("ScatterPlot", "

Select decimal precision:

4 = 10^−4

3 = 10^−3

2 = 10^−2

1 = 10^−1

0 = 1

-1 = 10

-2 = 10^2

-3 = 10^3

")) @@ -449,12 +320,19 @@ def retranslateUi(self, ScatterPlot): self.precision_comboBox.setItemText(5, _translate("ScatterPlot", "-1")) self.precision_comboBox.setItemText(6, _translate("ScatterPlot", "-2")) self.precision_comboBox.setItemText(7, _translate("ScatterPlot", "-3")) + self.fitToAxes_pushButton_2.setToolTip(_translate("ScatterPlot", "

Automatically fit the plot to data

")) + self.save_plot_pushButton_2.setToolTip(_translate("ScatterPlot", "

Save the plot to file (jpg, png, pdf)

")) + self.label_27.setText(_translate("ScatterPlot", " Plot")) + self.label_50.setText(_translate("ScatterPlot", "Colormap")) + self.colormap_comboBox.setToolTip(_translate("ScatterPlot", "

Select a colormap for selected rows

")) + self.value_label_2.setText(_translate("ScatterPlot", "x=0.000000 y=0.000000")) + self.label_48.setText(_translate("ScatterPlot", "Band Y")) + self.bandY_spinBox.setToolTip(_translate("ScatterPlot", "

Band Y

")) + self.label_46.setText(_translate("ScatterPlot", "Band X")) + self.bandX_spinBox.setToolTip(_translate("ScatterPlot", "

Band X

")) self.remove_Signature_Button.setToolTip(_translate("ScatterPlot", "

Delete row

")) self.remove_Signature_Button.setText(_translate("ScatterPlot", "Plot")) self.plot_temp_ROI_pushButton.setToolTip(_translate("ScatterPlot", "

Calculate scatter plot from temporary ROI

")) - self.plot_display_pushButton.setToolTip(_translate("ScatterPlot", "

Calculate scatter plot from the current display extent

")) - self.plot_image_pushButton.setToolTip(_translate("ScatterPlot", "

Calculate scatter plot from entire image

")) self.label_25.setText(_translate("ScatterPlot", " Scatter list")) - from .scatterwidget2 import ScatterWidget2 from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin_scatter_plot.ui b/ui/ui_semiautomaticclassificationplugin_scatter_plot.ui old mode 100644 new mode 100755 index 4654698..a4ecfe0 --- a/ui/ui_semiautomaticclassificationplugin_scatter_plot.ui +++ b/ui/ui_semiautomaticclassificationplugin_scatter_plot.ui @@ -23,6 +23,9 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg
+ + + @@ -32,7 +35,7 @@ false - + @@ -48,9 +51,15 @@ 50 + + + QAbstractItemView::NoEditTriggers + + QAbstractItemView::SelectRows + true @@ -61,7 +70,7 @@ true - 20 + 22 @@ -97,7 +106,7 @@ - + @@ -136,32 +145,6 @@ - - - - - FreeSans - 75 - true - - - - background-color : #656565; color : white - - - QFrame::Panel - - - QFrame::Sunken - - - Scatter raster - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - @@ -199,92 +182,86 @@ - - - - - - - - <html><head/><body><p>Calculate and display scatter raster</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_show_raster.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_show_raster.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Calculate and save to signature list</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg - - - - 22 - 22 - - - - - - - - - - Qt::Vertical + + + + + + <html><head/><body><p>Use custom decimal precision</p></body></html> - - - 20 - 40 - + + Precision - + - - - - - Liberation Mono - 75 - true - - - - QFrame::StyledPanel - - - QFrame::Sunken + + + + <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - x=0.000000 y=0.000000 + + 1 + + + 4 + + + + + 3 + + + + + 2 + + + + + 1 + + + + + 0 + + + + + -1 + + + + + -2 + + + + + -3 + + - + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -334,7 +311,7 @@ - + @@ -360,7 +337,7 @@ - + @@ -390,151 +367,32 @@ - <html><head/><body><p>Select a colormap</p></body></html> + <html><head/><body><p>Select a colormap for selected rows</p></body></html> -1 - - - - <html><head/><body><p>Set colormap for highlighted spectral plots</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - - - 0 - 0 - - - - Extent - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Select extent of scatter raster</p></body></html> - - - 0 - - - - same as display - - - - - same as image - - - - - - - - - - - - - - <html><head/><body><p>Create selection polygons</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_edit_polygon.svg - - - - 22 - 22 - + + + + + Liberation Mono + 75 + true + - - - - - - - 0 - 0 - + + QFrame::StyledPanel QFrame::Sunken - color - - - - - - - <html><head/><body><p>Select polygon color</p></body></html> - - - background-color : #FFAA00 - - - - - - - - - - <html><head/><body><p>Remove selection polygons</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_reset_polygon.svg - - - - 22 - 22 - + x=0.000000 y=0.000000 @@ -648,83 +506,6 @@ - - - - - - <html><head/><body><p>Use custom decimal precision</p></body></html> - - - Precision - - - - - - - <html><head/><body><p>Select decimal precision:</p><p>4 = 10^<span style=" vertical-align:super;">−4</span></p><p>3 = 10^<span style=" vertical-align:super;">−3</span></p><p>2 = 10^<span style=" vertical-align:super;">−2</span></p><p>1 = 10^<span style=" vertical-align:super;">−1</span></p><p>0 = 1</p><p>-1 = 10</p><p>-2 = 10^<span style=" vertical-align:super;">2</span></p><p>-3 = 10^<span style=" vertical-align:super;">3</span></p></body></html> - - - 1 - - - - 4 - - - - - 3 - - - - - 2 - - - - - 1 - - - - - 0 - - - - - -1 - - - - - -2 - - - - - -3 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -773,52 +554,6 @@ - - - - <html><head/><body><p>Calculate scatter plot from the current display extent</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_display.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_display.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Calculate scatter plot from entire image</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_image.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_scatter_raster_image.svg - - - - 22 - 22 - - - - @@ -835,11 +570,15 @@ FreeSans 75 + false true - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel diff --git a/ui/ui_semiautomaticclassificationplugin_signature_plot.py b/ui/ui_semiautomaticclassificationplugin_signature_plot.py old mode 100644 new mode 100755 index 7b2431f..ede8467 --- a/ui/ui_semiautomaticclassificationplugin_signature_plot.py +++ b/ui/ui_semiautomaticclassificationplugin_signature_plot.py @@ -2,16 +2,19 @@ # Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin_signature_plot.ui' # -# Created by: PyQt5 UI code generator 5.11.3 +# Created by: PyQt5 UI code generator 5.15.9 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_SpectralSignaturePlot(object): def setupUi(self, SpectralSignaturePlot): SpectralSignaturePlot.setObjectName("SpectralSignaturePlot") - SpectralSignaturePlot.resize(996, 564) + SpectralSignaturePlot.resize(1069, 564) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -20,6 +23,7 @@ def setupUi(self, SpectralSignaturePlot): icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) SpectralSignaturePlot.setWindowIcon(icon) + SpectralSignaturePlot.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.gridLayout_6 = QtWidgets.QGridLayout(SpectralSignaturePlot) self.gridLayout_6.setObjectName("gridLayout_6") self.splitter = QtWidgets.QSplitter(SpectralSignaturePlot) @@ -32,6 +36,7 @@ def setupUi(self, SpectralSignaturePlot): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth()) self.widget.setSizePolicy(sizePolicy) + self.widget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.widget.setObjectName("widget") self.gridLayout_8 = QtWidgets.QGridLayout(self.widget) self.gridLayout_8.setContentsMargins(0, 0, 0, 0) @@ -39,6 +44,7 @@ def setupUi(self, SpectralSignaturePlot): self.gridLayout_5 = QtWidgets.QGridLayout() self.gridLayout_5.setObjectName("gridLayout_5") self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setContentsMargins(-1, -1, -1, 0) self.gridLayout_2.setObjectName("gridLayout_2") self.signature_list_plot_tableWidget = QtWidgets.QTableWidget(self.widget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.MinimumExpanding) @@ -48,6 +54,8 @@ def setupUi(self, SpectralSignaturePlot): self.signature_list_plot_tableWidget.setSizePolicy(sizePolicy) self.signature_list_plot_tableWidget.setMinimumSize(QtCore.QSize(0, 30)) self.signature_list_plot_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.SelectedClicked) + self.signature_list_plot_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.signature_list_plot_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.signature_list_plot_tableWidget.setObjectName("signature_list_plot_tableWidget") self.signature_list_plot_tableWidget.setColumnCount(6) self.signature_list_plot_tableWidget.setRowCount(0) @@ -63,9 +71,9 @@ def setupUi(self, SpectralSignaturePlot): self.signature_list_plot_tableWidget.setHorizontalHeaderItem(4, item) item = QtWidgets.QTableWidgetItem() self.signature_list_plot_tableWidget.setHorizontalHeaderItem(5, item) - self.signature_list_plot_tableWidget.horizontalHeader().setDefaultSectionSize(65) + self.signature_list_plot_tableWidget.horizontalHeader().setDefaultSectionSize(180) self.signature_list_plot_tableWidget.horizontalHeader().setStretchLastSection(True) - self.signature_list_plot_tableWidget.verticalHeader().setDefaultSectionSize(20) + self.signature_list_plot_tableWidget.verticalHeader().setDefaultSectionSize(22) self.gridLayout_2.addWidget(self.signature_list_plot_tableWidget, 0, 0, 1, 1) self.frame = QtWidgets.QFrame(self.widget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding) @@ -74,214 +82,38 @@ def setupUi(self, SpectralSignaturePlot): sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) self.frame.setSizePolicy(sizePolicy) self.frame.setMinimumSize(QtCore.QSize(0, 20)) - self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.gridLayout_18 = QtWidgets.QGridLayout(self.frame) self.gridLayout_18.setContentsMargins(2, 2, 2, 2) self.gridLayout_18.setObjectName("gridLayout_18") - self.gridLayout_140 = QtWidgets.QGridLayout() - self.gridLayout_140.setObjectName("gridLayout_140") self.gridLayout_17 = QtWidgets.QGridLayout() self.gridLayout_17.setObjectName("gridLayout_17") - self.LCS_pointerButton_2 = QtWidgets.QToolButton(self.frame) - self.LCS_pointerButton_2.setStyleSheet("margin: 0px;padding: 0px;") - icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_pointerButton_2.setIcon(icon1) - self.LCS_pointerButton_2.setIconSize(QtCore.QSize(22, 22)) - self.LCS_pointerButton_2.setObjectName("LCS_pointerButton_2") - self.gridLayout_17.addWidget(self.LCS_pointerButton_2, 0, 3, 1, 1) - self.label_90 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_90.sizePolicy().hasHeightForWidth()) - self.label_90.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(False) - font.setWeight(50) - self.label_90.setFont(font) - self.label_90.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_90.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_90.setObjectName("label_90") - self.gridLayout_17.addWidget(self.label_90, 0, 2, 1, 1) - self.gridLayout_144 = QtWidgets.QGridLayout() - self.gridLayout_144.setObjectName("gridLayout_144") - self.LCS_cut_checkBox_2 = QtWidgets.QCheckBox(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.LCS_cut_checkBox_2.sizePolicy().hasHeightForWidth()) - self.LCS_cut_checkBox_2.setSizePolicy(sizePolicy) - self.LCS_cut_checkBox_2.setText("") - icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_cut_checkBox_2.setIcon(icon2) - self.LCS_cut_checkBox_2.setObjectName("LCS_cut_checkBox_2") - self.gridLayout_144.addWidget(self.LCS_cut_checkBox_2, 1, 0, 1, 1) - self.LCS_include_checkBox_2 = QtWidgets.QCheckBox(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.LCS_include_checkBox_2.sizePolicy().hasHeightForWidth()) - self.LCS_include_checkBox_2.setSizePolicy(sizePolicy) - self.LCS_include_checkBox_2.setText("") - icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_include_checkBox_2.setIcon(icon3) - self.LCS_include_checkBox_2.setChecked(True) - self.LCS_include_checkBox_2.setObjectName("LCS_include_checkBox_2") - self.gridLayout_144.addWidget(self.LCS_include_checkBox_2, 0, 0, 1, 1) - self.gridLayout_17.addLayout(self.gridLayout_144, 0, 5, 1, 1) - self.gridLayout_19 = QtWidgets.QGridLayout() - self.gridLayout_19.setObjectName("gridLayout_19") - self.label_91 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_91.sizePolicy().hasHeightForWidth()) - self.label_91.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(False) - font.setWeight(50) - self.label_91.setFont(font) - self.label_91.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_91.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_91.setObjectName("label_91") - self.gridLayout_19.addWidget(self.label_91, 0, 0, 1, 1) - self.LCS_ROI_button_2 = QtWidgets.QToolButton(self.frame) - self.LCS_ROI_button_2.setStyleSheet("margin: 0px;padding: 0px;") - icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.LCS_ROI_button_2.setIcon(icon4) - self.LCS_ROI_button_2.setIconSize(QtCore.QSize(22, 22)) - self.LCS_ROI_button_2.setObjectName("LCS_ROI_button_2") - self.gridLayout_19.addWidget(self.LCS_ROI_button_2, 0, 1, 1, 1) - self.gridLayout_17.addLayout(self.gridLayout_19, 0, 0, 1, 1) - spacerItem = QtWidgets.QSpacerItem(0, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_17.addItem(spacerItem, 0, 1, 1, 1) - spacerItem1 = QtWidgets.QSpacerItem(0, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_17.addItem(spacerItem1, 0, 4, 1, 1) - self.gridLayout_140.addLayout(self.gridLayout_17, 2, 0, 1, 2) - self.gridLayout_14 = QtWidgets.QGridLayout() - self.gridLayout_14.setObjectName("gridLayout_14") - self.label_26 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_26.sizePolicy().hasHeightForWidth()) - self.label_26.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(True) - font.setWeight(75) - self.label_26.setFont(font) - self.label_26.setStyleSheet("background-color : #656565; color : white") - self.label_26.setFrameShape(QtWidgets.QFrame.NoFrame) - self.label_26.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_26.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_26.setObjectName("label_26") - self.gridLayout_14.addWidget(self.label_26, 0, 0, 1, 3) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.gridLayout_20 = QtWidgets.QGridLayout() - self.gridLayout_20.setObjectName("gridLayout_20") - self.set_min_max_Button = QtWidgets.QToolButton(self.frame) - self.set_min_max_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.set_min_max_Button.setIcon(icon5) - self.set_min_max_Button.setIconSize(QtCore.QSize(22, 22)) - self.set_min_max_Button.setObjectName("set_min_max_Button") - self.gridLayout_20.addWidget(self.set_min_max_Button, 0, 1, 1, 1) - self.label_102 = QtWidgets.QLabel(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_102.sizePolicy().hasHeightForWidth()) - self.label_102.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(False) - font.setWeight(50) - self.label_102.setFont(font) - self.label_102.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_102.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_102.setObjectName("label_102") - self.gridLayout_20.addWidget(self.label_102, 0, 0, 1, 1) - self.horizontalLayout_2.addLayout(self.gridLayout_20) - self.label_101 = QtWidgets.QLabel(self.frame) - font = QtGui.QFont() - font.setFamily("FreeSans") - font.setBold(False) - font.setWeight(50) - self.label_101.setFont(font) - self.label_101.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_101.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_101.setObjectName("label_101") - self.horizontalLayout_2.addWidget(self.label_101) - self.multiplicative_threshold_doubleSpinBox_2 = QtWidgets.QDoubleSpinBox(self.frame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.multiplicative_threshold_doubleSpinBox_2.sizePolicy().hasHeightForWidth()) - self.multiplicative_threshold_doubleSpinBox_2.setSizePolicy(sizePolicy) - self.multiplicative_threshold_doubleSpinBox_2.setMinimumSize(QtCore.QSize(16, 0)) - self.multiplicative_threshold_doubleSpinBox_2.setMaximumSize(QtCore.QSize(54, 16777215)) - self.multiplicative_threshold_doubleSpinBox_2.setDecimals(1) - self.multiplicative_threshold_doubleSpinBox_2.setMaximum(10000.0) - self.multiplicative_threshold_doubleSpinBox_2.setProperty("value", 1.0) - self.multiplicative_threshold_doubleSpinBox_2.setObjectName("multiplicative_threshold_doubleSpinBox_2") - self.horizontalLayout_2.addWidget(self.multiplicative_threshold_doubleSpinBox_2) - self.automatic_threshold_pushButton_2 = QtWidgets.QToolButton(self.frame) - self.automatic_threshold_pushButton_2.setStyleSheet("margin: 0px;padding: 0px;") - self.automatic_threshold_pushButton_2.setIcon(icon5) - self.automatic_threshold_pushButton_2.setIconSize(QtCore.QSize(22, 22)) - self.automatic_threshold_pushButton_2.setObjectName("automatic_threshold_pushButton_2") - self.horizontalLayout_2.addWidget(self.automatic_threshold_pushButton_2) - self.undo_threshold_Button = QtWidgets.QToolButton(self.frame) - self.undo_threshold_Button.setEnabled(False) - self.undo_threshold_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.undo_threshold_Button.setIcon(icon6) - self.undo_threshold_Button.setIconSize(QtCore.QSize(22, 22)) - self.undo_threshold_Button.setObjectName("undo_threshold_Button") - self.horizontalLayout_2.addWidget(self.undo_threshold_Button) - self.gridLayout_14.addLayout(self.horizontalLayout_2, 1, 0, 1, 3) - self.gridLayout_140.addLayout(self.gridLayout_14, 1, 0, 1, 2) - self.gridLayout_4 = QtWidgets.QGridLayout() - self.gridLayout_4.setObjectName("gridLayout_4") - self.remove_Signature_Button = QtWidgets.QToolButton(self.frame) - self.remove_Signature_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.remove_Signature_Button.setIcon(icon7) - self.remove_Signature_Button.setIconSize(QtCore.QSize(22, 22)) - self.remove_Signature_Button.setObjectName("remove_Signature_Button") - self.gridLayout_4.addWidget(self.remove_Signature_Button, 0, 0, 1, 1) self.add_signature_list_pushButton = QtWidgets.QToolButton(self.frame) self.add_signature_list_pushButton.setStyleSheet("margin: 0px;padding: 0px;") self.add_signature_list_pushButton.setText("") - icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.add_signature_list_pushButton.setIcon(icon8) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.add_signature_list_pushButton.setIcon(icon1) self.add_signature_list_pushButton.setIconSize(QtCore.QSize(22, 22)) self.add_signature_list_pushButton.setObjectName("add_signature_list_pushButton") - self.gridLayout_4.addWidget(self.add_signature_list_pushButton, 0, 1, 1, 1) + self.gridLayout_17.addWidget(self.add_signature_list_pushButton, 1, 0, 1, 1) + self.remove_Signature_Button = QtWidgets.QToolButton(self.frame) + self.remove_Signature_Button.setStyleSheet("margin: 0px;padding: 0px;") + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.remove_Signature_Button.setIcon(icon2) + self.remove_Signature_Button.setIconSize(QtCore.QSize(22, 22)) + self.remove_Signature_Button.setObjectName("remove_Signature_Button") + self.gridLayout_17.addWidget(self.remove_Signature_Button, 0, 0, 1, 1) self.calculate_spectral_distance_Button = QtWidgets.QToolButton(self.frame) self.calculate_spectral_distance_Button.setStyleSheet("margin: 0px;padding: 0px;") - icon9 = QtGui.QIcon() - icon9.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.calculate_spectral_distance_Button.setIcon(icon9) + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.calculate_spectral_distance_Button.setIcon(icon3) self.calculate_spectral_distance_Button.setIconSize(QtCore.QSize(22, 22)) self.calculate_spectral_distance_Button.setObjectName("calculate_spectral_distance_Button") - self.gridLayout_4.addWidget(self.calculate_spectral_distance_Button, 0, 2, 1, 1) - self.gridLayout_140.addLayout(self.gridLayout_4, 0, 0, 1, 2) - self.gridLayout_18.addLayout(self.gridLayout_140, 0, 0, 1, 1) + self.gridLayout_17.addWidget(self.calculate_spectral_distance_Button, 2, 0, 1, 1) + self.gridLayout_18.addLayout(self.gridLayout_17, 0, 0, 1, 1) self.gridLayout_2.addWidget(self.frame, 0, 1, 1, 1) self.gridLayout_5.addLayout(self.gridLayout_2, 1, 0, 1, 1) self.label_25 = QtWidgets.QLabel(self.widget) @@ -293,9 +125,11 @@ def setupUi(self, SpectralSignaturePlot): font = QtGui.QFont() font.setFamily("FreeSans") font.setBold(True) + font.setItalic(False) font.setWeight(75) self.label_25.setFont(font) - self.label_25.setStyleSheet("background-color : #656565; color : white") + self.label_25.setStyleSheet("background-color : #5a5a5a; color : white; font: bold") + self.label_25.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_25.setFrameShape(QtWidgets.QFrame.Panel) self.label_25.setFrameShadow(QtWidgets.QFrame.Sunken) self.label_25.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) @@ -318,11 +152,16 @@ def setupUi(self, SpectralSignaturePlot): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.Sig_Widget.sizePolicy().hasHeightForWidth()) self.Sig_Widget.setSizePolicy(sizePolicy) + self.Sig_Widget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.Sig_Widget.setObjectName("Sig_Widget") self.gridLayout_3.addWidget(self.Sig_Widget, 0, 0, 1, 1) self.gridLayout.addLayout(self.gridLayout_3, 0, 0, 1, 1) self.gridLayout_7 = QtWidgets.QGridLayout() self.gridLayout_7.setObjectName("gridLayout_7") + self.label_8 = QtWidgets.QLabel(self.tab) + self.label_8.setFrameShadow(QtWidgets.QFrame.Sunken) + self.label_8.setObjectName("label_8") + self.gridLayout_7.addWidget(self.label_8, 0, 7, 1, 1) self.band_lines_checkBox = QtWidgets.QCheckBox(self.tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -331,20 +170,7 @@ def setupUi(self, SpectralSignaturePlot): self.band_lines_checkBox.setSizePolicy(sizePolicy) self.band_lines_checkBox.setChecked(True) self.band_lines_checkBox.setObjectName("band_lines_checkBox") - self.gridLayout_7.addWidget(self.band_lines_checkBox, 0, 5, 1, 1) - self.label_8 = QtWidgets.QLabel(self.tab) - self.label_8.setFrameShadow(QtWidgets.QFrame.Sunken) - self.label_8.setObjectName("label_8") - self.gridLayout_7.addWidget(self.label_8, 0, 8, 1, 1) - self.plot_text_spinBox = QtWidgets.QSpinBox(self.tab) - self.plot_text_spinBox.setMinimumSize(QtCore.QSize(50, 0)) - self.plot_text_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) - self.plot_text_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.plot_text_spinBox.setMinimum(1) - self.plot_text_spinBox.setMaximum(100) - self.plot_text_spinBox.setProperty("value", 15) - self.plot_text_spinBox.setObjectName("plot_text_spinBox") - self.gridLayout_7.addWidget(self.plot_text_spinBox, 0, 9, 1, 1) + self.gridLayout_7.addWidget(self.band_lines_checkBox, 0, 4, 1, 1) self.gridLayout_13 = QtWidgets.QGridLayout() self.gridLayout_13.setObjectName("gridLayout_13") self.value_label = QtWidgets.QLabel(self.tab) @@ -353,41 +179,47 @@ def setupUi(self, SpectralSignaturePlot): font.setBold(True) font.setWeight(75) self.value_label.setFont(font) + self.value_label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.value_label.setFrameShape(QtWidgets.QFrame.StyledPanel) self.value_label.setFrameShadow(QtWidgets.QFrame.Sunken) self.value_label.setObjectName("value_label") self.gridLayout_13.addWidget(self.value_label, 0, 1, 1, 1) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_13.addItem(spacerItem, 0, 0, 1, 1) + self.gridLayout_7.addLayout(self.gridLayout_13, 0, 10, 1, 1) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout_7.addItem(spacerItem1, 0, 3, 1, 1) spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_13.addItem(spacerItem2, 0, 0, 1, 1) - self.gridLayout_7.addLayout(self.gridLayout_13, 0, 11, 1, 1) - self.value_range_pushButton = QtWidgets.QToolButton(self.tab) - self.value_range_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - icon10 = QtGui.QIcon() - icon10.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_edit_range.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.value_range_pushButton.setIcon(icon10) - self.value_range_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.value_range_pushButton.setObjectName("value_range_pushButton") - self.gridLayout_7.addWidget(self.value_range_pushButton, 0, 2, 1, 1) - self.fitToAxes_pushButton = QtWidgets.QToolButton(self.tab) - self.fitToAxes_pushButton.setStyleSheet("margin: 0px;padding: 0px;") - self.fitToAxes_pushButton.setText("") - icon11 = QtGui.QIcon() - icon11.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.fitToAxes_pushButton.setIcon(icon11) - self.fitToAxes_pushButton.setIconSize(QtCore.QSize(22, 22)) - self.fitToAxes_pushButton.setObjectName("fitToAxes_pushButton") - self.gridLayout_7.addWidget(self.fitToAxes_pushButton, 0, 0, 1, 1) + self.gridLayout_7.addItem(spacerItem2, 0, 6, 1, 1) + self.plot_text_spinBox = QtWidgets.QSpinBox(self.tab) + self.plot_text_spinBox.setMinimumSize(QtCore.QSize(50, 0)) + self.plot_text_spinBox.setMaximumSize(QtCore.QSize(100, 16777215)) + self.plot_text_spinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.plot_text_spinBox.setMinimum(1) + self.plot_text_spinBox.setMaximum(100) + self.plot_text_spinBox.setProperty("value", 15) + self.plot_text_spinBox.setObjectName("plot_text_spinBox") + self.gridLayout_7.addWidget(self.plot_text_spinBox, 0, 8, 1, 1) + self.grid_checkBox = QtWidgets.QCheckBox(self.tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.grid_checkBox.sizePolicy().hasHeightForWidth()) + self.grid_checkBox.setSizePolicy(sizePolicy) + self.grid_checkBox.setChecked(True) + self.grid_checkBox.setObjectName("grid_checkBox") + self.gridLayout_7.addWidget(self.grid_checkBox, 0, 5, 1, 1) self.save_plot_pushButton = QtWidgets.QToolButton(self.tab) self.save_plot_pushButton.setStyleSheet("margin: 0px;padding: 0px;") self.save_plot_pushButton.setText("") - icon12 = QtGui.QIcon() - icon12.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_plot_image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.save_plot_pushButton.setIcon(icon12) + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_save_plot_image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.save_plot_pushButton.setIcon(icon4) self.save_plot_pushButton.setIconSize(QtCore.QSize(22, 22)) self.save_plot_pushButton.setObjectName("save_plot_pushButton") self.gridLayout_7.addWidget(self.save_plot_pushButton, 0, 1, 1, 1) spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_7.addItem(spacerItem3, 0, 4, 1, 1) + self.gridLayout_7.addItem(spacerItem3, 0, 9, 1, 1) self.sigma_checkBox = QtWidgets.QCheckBox(self.tab) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -396,24 +228,20 @@ def setupUi(self, SpectralSignaturePlot): self.sigma_checkBox.setSizePolicy(sizePolicy) self.sigma_checkBox.setChecked(True) self.sigma_checkBox.setObjectName("sigma_checkBox") - self.gridLayout_7.addWidget(self.sigma_checkBox, 0, 3, 1, 1) - spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_7.addItem(spacerItem4, 0, 10, 1, 1) - self.grid_checkBox = QtWidgets.QCheckBox(self.tab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.grid_checkBox.sizePolicy().hasHeightForWidth()) - self.grid_checkBox.setSizePolicy(sizePolicy) - self.grid_checkBox.setChecked(True) - self.grid_checkBox.setObjectName("grid_checkBox") - self.gridLayout_7.addWidget(self.grid_checkBox, 0, 6, 1, 1) - spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.gridLayout_7.addItem(spacerItem5, 0, 7, 1, 1) + self.gridLayout_7.addWidget(self.sigma_checkBox, 0, 2, 1, 1) + self.fitToAxes_pushButton = QtWidgets.QToolButton(self.tab) + self.fitToAxes_pushButton.setStyleSheet("margin: 0px;padding: 0px;") + self.fitToAxes_pushButton.setText("") + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.fitToAxes_pushButton.setIcon(icon5) + self.fitToAxes_pushButton.setIconSize(QtCore.QSize(22, 22)) + self.fitToAxes_pushButton.setObjectName("fitToAxes_pushButton") + self.gridLayout_7.addWidget(self.fitToAxes_pushButton, 0, 0, 1, 1) self.gridLayout.addLayout(self.gridLayout_7, 1, 0, 1, 1) - icon13 = QtGui.QIcon() - icon13.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.tab, icon13, "") + icon6 = QtGui.QIcon() + icon6.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.tab, icon6, "") self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.gridLayout_21 = QtWidgets.QGridLayout(self.tab_2) @@ -425,9 +253,9 @@ def setupUi(self, SpectralSignaturePlot): self.value_textBrowser.setObjectName("value_textBrowser") self.gridLayout_9.addWidget(self.value_textBrowser, 0, 0, 1, 1) self.gridLayout_21.addLayout(self.gridLayout_9, 0, 0, 1, 1) - icon14 = QtGui.QIcon() - icon14.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.tab_2, icon14, "") + icon7 = QtGui.QIcon() + icon7.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_accuracy_tool.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.tab_2, icon7, "") self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.gridLayout_22 = QtWidgets.QGridLayout(self.tab_3) @@ -439,9 +267,8 @@ def setupUi(self, SpectralSignaturePlot): self.distance_textBrowser.setObjectName("distance_textBrowser") self.gridLayout_11.addWidget(self.distance_textBrowser, 0, 0, 1, 1) self.gridLayout_22.addLayout(self.gridLayout_11, 0, 0, 1, 1) - self.tabWidget.addTab(self.tab_3, icon9, "") + self.tabWidget.addTab(self.tab_3, icon3, "") self.gridLayout_6.addWidget(self.splitter, 0, 0, 1, 1) - self.widget.raise_() self.retranslateUi(SpectralSignaturePlot) self.tabWidget.setCurrentIndex(0) @@ -463,43 +290,25 @@ def retranslateUi(self, SpectralSignaturePlot): item.setText(_translate("SpectralSignaturePlot", "C Name")) item = self.signature_list_plot_tableWidget.horizontalHeaderItem(5) item.setText(_translate("SpectralSignaturePlot", "Color")) - self.LCS_pointerButton_2.setToolTip(_translate("SpectralSignaturePlot", "

Activate pointer for setting thresholds from pixel

")) - self.label_90.setText(_translate("SpectralSignaturePlot", "From\n" -"pixel")) - self.LCS_cut_checkBox_2.setToolTip(_translate("SpectralSignaturePlot", "

If checked, signature threshold is reduced to exclude pixel signature

")) - self.LCS_include_checkBox_2.setToolTip(_translate("SpectralSignaturePlot", "

If checked, signature threshold is extended to include pixel signature

")) - self.label_91.setText(_translate("SpectralSignaturePlot", "From\n" -"ROI")) - self.LCS_ROI_button_2.setToolTip(_translate("SpectralSignaturePlot", "

Set thresholds from temporary ROI

")) - self.label_26.setText(_translate("SpectralSignaturePlot", "Automatic thresholds")) - self.set_min_max_Button.setToolTip(_translate("SpectralSignaturePlot", "

Set automatic threshold Min Max

")) - self.label_102.setText(_translate("SpectralSignaturePlot", "Min Max")) - self.label_101.setText(_translate("SpectralSignaturePlot", "σ *")) - self.multiplicative_threshold_doubleSpinBox_2.setToolTip(_translate("SpectralSignaturePlot", "

Set a value that will be multiplied by standard deviation

")) - self.automatic_threshold_pushButton_2.setToolTip(_translate("SpectralSignaturePlot", "

Set automatic threshold σ

")) - self.undo_threshold_Button.setToolTip(_translate("SpectralSignaturePlot", "

Undo thresholds

")) - self.undo_threshold_Button.setText(_translate("SpectralSignaturePlot", "Import library")) + self.add_signature_list_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Add highlighted spectral signatures to signature list

")) self.remove_Signature_Button.setToolTip(_translate("SpectralSignaturePlot", "

Delete row

")) self.remove_Signature_Button.setText(_translate("SpectralSignaturePlot", "Plot")) - self.add_signature_list_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Add highlighted spectral signatures to signature list

")) - self.calculate_spectral_distance_Button.setToolTip(_translate("SpectralSignaturePlot", "

Calculate spectral distances

")) + self.calculate_spectral_distance_Button.setToolTip(_translate("SpectralSignaturePlot", "

Calculate spectral distances of highlighted signatures

")) self.calculate_spectral_distance_Button.setText(_translate("SpectralSignaturePlot", "Plot")) self.label_25.setText(_translate("SpectralSignaturePlot", " Signature list")) - self.band_lines_checkBox.setToolTip(_translate("SpectralSignaturePlot", "

Plot the value range (standard deviation or defined minimum and maximum) for each signature

")) - self.band_lines_checkBox.setText(_translate("SpectralSignaturePlot", "Band lines")) self.label_8.setText(_translate("SpectralSignaturePlot", "Max characters")) - self.plot_text_spinBox.setToolTip(_translate("SpectralSignaturePlot", "

Text lenght of names in the spectral plot legend

")) + self.band_lines_checkBox.setToolTip(_translate("SpectralSignaturePlot", "

Plot vertical lines for each band value

")) + self.band_lines_checkBox.setText(_translate("SpectralSignaturePlot", "Band lines")) self.value_label.setText(_translate("SpectralSignaturePlot", "x=0.000000 y=0.000000")) - self.value_range_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Change value range interactively in the plot

")) - self.fitToAxes_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Automatically fit the plot to data

")) + self.plot_text_spinBox.setToolTip(_translate("SpectralSignaturePlot", "

Text lenght of names in the spectral plot legend

")) + self.grid_checkBox.setToolTip(_translate("SpectralSignaturePlot", "

Plot the axis grid

")) + self.grid_checkBox.setText(_translate("SpectralSignaturePlot", "Grid")) self.save_plot_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Save the plot to file (jpg, png, pdf)

")) self.sigma_checkBox.setToolTip(_translate("SpectralSignaturePlot", "

Plot the value range (standard deviation or defined minimum and maximum) for each signature

")) self.sigma_checkBox.setText(_translate("SpectralSignaturePlot", "Plot value range")) - self.grid_checkBox.setToolTip(_translate("SpectralSignaturePlot", "

Plot the value range (standard deviation or defined minimum and maximum) for each signature

")) - self.grid_checkBox.setText(_translate("SpectralSignaturePlot", "Grid")) + self.fitToAxes_pushButton.setToolTip(_translate("SpectralSignaturePlot", "

Automatically fit the plot to data

")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("SpectralSignaturePlot", "Plot")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("SpectralSignaturePlot", "Signature details")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("SpectralSignaturePlot", "Spectral distances")) - from .sigwidget2 import SigWidget2 from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin_signature_plot.ui b/ui/ui_semiautomaticclassificationplugin_signature_plot.ui old mode 100644 new mode 100755 index 2cdc3f2..e4fd67d --- a/ui/ui_semiautomaticclassificationplugin_signature_plot.ui +++ b/ui/ui_semiautomaticclassificationplugin_signature_plot.ui @@ -6,7 +6,7 @@ 0 0 - 996 + 1069 564
@@ -23,6 +23,9 @@ :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg + + + @@ -39,11 +42,17 @@ 0 + + + + + 0 + @@ -61,17 +70,23 @@ QAbstractItemView::SelectedClicked + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + true - 65 + 180 true - 20 + 22 @@ -119,12 +134,6 @@ 20 - - QFrame::StyledPanel - - - QFrame::Raised - 2 @@ -139,444 +148,75 @@ 2 - - - - - - - <html><head/><body><p>Activate pointer for setting thresholds from pixel</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_set_tool.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - - FreeSans - 50 - false - - - - QFrame::Sunken - - - From -pixel - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>If checked, signature threshold is reduced to exclude pixel signature</p></body></html> - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_minus.svg - - - - - - - - 0 - 0 - - - - <html><head/><body><p>If checked, signature threshold is extended to include pixel signature</p></body></html> - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_plus.svg - - - true - - - - - - - - - - - - 0 - 0 - - - - - FreeSans - 50 - false - - - - QFrame::Sunken - - - From -ROI - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Set thresholds from temporary ROI</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_LCS_threshold_ROI_tool.svg - - - - 22 - 22 - - - - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - + + + + + <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> + + + margin: 0px;padding: 0px; + + + + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg + + + + 22 + 22 + + + - - - - - - - 0 - 0 - - - - - FreeSans - 75 - true - - - - background-color : #656565; color : white - - - QFrame::NoFrame - - - QFrame::Sunken - - - Automatic thresholds - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - <html><head/><body><p>Set automatic threshold Min Max</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - - 0 - 0 - - - - - FreeSans - 50 - false - - - - QFrame::Sunken - - - Min Max - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - FreeSans - 50 - false - - - - QFrame::Sunken - - - σ * - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 16 - 0 - - - - - 54 - 16777215 - - - - <html><head/><body><p>Set a value that will be multiplied by standard deviation</p></body></html> - - - 1 - - - 10000.000000000000000 - - - 1.000000000000000 - - - - - - - <html><head/><body><p>Set automatic threshold σ</p></body></html> - - - margin: 0px;padding: 0px; - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_enter.svg - - - - 22 - 22 - - - - - - - - false - - - <html><head/><body><p>Undo thresholds</p></body></html> - - - margin: 0px;padding: 0px; - - - Import library - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_undo_lcs_threshold.svg - - - - 22 - 22 - - - - - - - + + + + <html><head/><body><p >Delete row</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg + + + + 22 + 22 + + + - - - - - - <html><head/><body><p >Delete row</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_remove.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Add highlighted spectral signatures to signature list</p></body></html> - - - margin: 0px;padding: 0px; - - - - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_add_sign_tool.svg - - - - 22 - 22 - - - - - - - - <html><head/><body><p>Calculate spectral distances</p></body></html> - - - margin: 0px;padding: 0px; - - - Plot - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg - - - - 22 - 22 - - - - - + + + + <html><head/><body><p>Calculate spectral distances of highlighted signatures</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_calculate_spectral_distances.svg + + + + 22 + 22 + + + @@ -597,11 +237,15 @@ ROI FreeSans 75 + false true - background-color : #656565; color : white + background-color : #5a5a5a; color : white; font: bold + + + QFrame::Panel @@ -650,13 +294,26 @@ ROI 0 + + + - + + + + QFrame::Sunken + + + Max characters + + + + @@ -665,7 +322,7 @@ ROI - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + <html><head/><body><p>Plot vertical lines for each band value</p></body></html> Band lines @@ -675,48 +332,7 @@ ROI - - - - QFrame::Sunken - - - Max characters - - - - - - - - 50 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100 - - - 15 - - - - + @@ -727,6 +343,9 @@ ROI true
+ + + QFrame::StyledPanel @@ -753,46 +372,79 @@ ROI - - - - <html><head/><body><p>Change value range interactively in the plot</p></body></html> + + + + Qt::Horizontal - - margin: 0px;padding: 0px; + + + 40 + 20 + - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_edit_range.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_sign_edit_range.svg + + + + + + Qt::Horizontal - + - 22 - 22 + 40 + 20 - + - - + + + + + 50 + 0 + + + + + 100 + 16777215 + + - <html><head/><body><p>Automatically fit the plot to data</p></body></html> + <html><head/><body><p align="justify">Text lenght of names in the spectral plot legend</p></body></html> - - margin: 0px;padding: 0px; + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + 1 - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg + + 100 - - - 22 - 22 - + + 15 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Plot the axis grid</p></body></html> + + + Grid + + + true @@ -819,8 +471,8 @@ ROI - - + + Qt::Horizontal @@ -832,7 +484,7 @@ ROI - + @@ -851,50 +503,28 @@ ROI - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - + + - <html><head/><body><p>Plot the value range (standard deviation or defined minimum and maximum) for each signature</p></body></html> + <html><head/><body><p>Automatically fit the plot to data</p></body></html> - - Grid + + margin: 0px;padding: 0px; - - true + + - - - - - - Qt::Horizontal + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_fit_plot.svg - + - 40 - 20 + 22 + 22 - + @@ -950,8 +580,6 @@ ROI - - widget diff --git a/ui/ui_semiautomaticclassificationplugin_welcome.py b/ui/ui_semiautomaticclassificationplugin_welcome.py deleted file mode 100644 index 97a55ee..0000000 --- a/ui/ui_semiautomaticclassificationplugin_welcome.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin_welcome.ui' -# -# Created by: PyQt5 UI code generator 5.11.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore, QtGui, QtWidgets - -class Ui_SCP_Welcome(object): - def setupUi(self, SCP_Welcome): - SCP_Welcome.setObjectName("SCP_Welcome") - SCP_Welcome.resize(609, 355) - icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - SCP_Welcome.setWindowIcon(icon) - self.gridLayout_2 = QtWidgets.QGridLayout(SCP_Welcome) - self.gridLayout_2.setObjectName("gridLayout_2") - self.gridLayout = QtWidgets.QGridLayout() - self.gridLayout.setObjectName("gridLayout") - self.textBrowser = QtWidgets.QTextBrowser(SCP_Welcome) - self.textBrowser.setFrameShape(QtWidgets.QFrame.Panel) - self.textBrowser.setFrameShadow(QtWidgets.QFrame.Sunken) - self.textBrowser.setOpenExternalLinks(True) - self.textBrowser.setObjectName("textBrowser") - self.gridLayout.addWidget(self.textBrowser, 0, 0, 1, 1) - self.buttonBox = QtWidgets.QDialogButtonBox(SCP_Welcome) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close) - self.buttonBox.setCenterButtons(True) - self.buttonBox.setObjectName("buttonBox") - self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1) - self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1) - - self.retranslateUi(SCP_Welcome) - self.buttonBox.accepted.connect(SCP_Welcome.accept) - self.buttonBox.rejected.connect(SCP_Welcome.reject) - QtCore.QMetaObject.connectSlotsByName(SCP_Welcome) - - def retranslateUi(self, SCP_Welcome): - _translate = QtCore.QCoreApplication.translate - SCP_Welcome.setWindowTitle(_translate("SCP_Welcome", "Welcome to Semi-Automatic Classification Plugin")) - self.textBrowser.setHtml(_translate("SCP_Welcome", "\n" -"\n" -"

First time using the Semi-Automatic Classification Plugin (SCP)?

\n" -"

Please check the user manual with tutorials available in several languages.

\n" -"

You can also contribute to SCP translation.

\n" -"

For comments or questions please join the SCP group in Facebook .

\n" -"


\n" -"

From GIS to Remote Sensing

")) - -from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin_welcome.ui b/ui/ui_semiautomaticclassificationplugin_welcome.ui deleted file mode 100644 index 05f1c4a..0000000 --- a/ui/ui_semiautomaticclassificationplugin_welcome.ui +++ /dev/null @@ -1,102 +0,0 @@ - - - SCP_Welcome - - - - 0 - 0 - 609 - 355 - - - - Welcome to Semi-Automatic Classification Plugin - - - - :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg - - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">First time using the </span><span style=" font-family:'Droid Sans'; font-size:11pt; font-weight:600;">Semi-Automatic Classification Plugin</span><span style=" font-family:'Droid Sans'; font-size:11pt;"> (SCP)?</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">Please check the </span><a href="https://fromgistors.blogspot.com/p/user-manual.html."><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">user manual</span></a><span style=" font-family:'Droid Sans'; font-size:11pt;"> with tutorials available in several languages.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">You can also contribute to SCP translation.</span></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans'; font-size:11pt;">For comments or questions please join the </span><a href="https://www.facebook.com/groups/SemiAutomaticClassificationPlugin"><span style=" font-family:'Noto Sans'; font-size:11pt; text-decoration: underline; color:#0000ff;">SCP group in Facebook</span></a><span style=" font-family:'Noto Sans'; font-size:11pt;"> .</span></p> -<p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/plugins/semiautomaticclassificationplugin/icons/fromGIStoRS.png" /><a href="https://fromgistors.blogspot.com/p/semi-automatic-classification-plugin.html?spref=scp"><span style=" font-family:'Droid Sans'; font-size:14pt; text-decoration: underline; color:#0000ff;">From GIS to Remote Sensing</span></a></p></body></html> - - - true - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - true - - - - - - - - - - - - - buttonBox - accepted() - SCP_Welcome - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - SCP_Welcome - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/ui/ui_semiautomaticclassificationplugin_widget.py b/ui/ui_semiautomaticclassificationplugin_widget.py new file mode 100755 index 0000000..5178f1d --- /dev/null +++ b/ui/ui_semiautomaticclassificationplugin_widget.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'ui/ui_semiautomaticclassificationplugin_widget.ui' +# +# Created by: PyQt5 UI code generator 5.15.9 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_SCP_Widget(object): + def setupUi(self, SCP_Widget): + SCP_Widget.setObjectName("SCP_Widget") + SCP_Widget.resize(609, 355) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + SCP_Widget.setWindowIcon(icon) + self.gridLayout_2 = QtWidgets.QGridLayout(SCP_Widget) + self.gridLayout_2.setObjectName("gridLayout_2") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.gridLayout_3 = QtWidgets.QGridLayout() + self.gridLayout_3.setObjectName("gridLayout_3") + self.main_widget = QtWidgets.QWidget(SCP_Widget) + self.main_widget.setObjectName("main_widget") + self.gridLayout_5 = QtWidgets.QGridLayout(self.main_widget) + self.gridLayout_5.setObjectName("gridLayout_5") + self.listWidget = QtWidgets.QListWidget(self.main_widget) + self.listWidget.setObjectName("listWidget") + self.gridLayout_5.addWidget(self.listWidget, 0, 0, 1, 1) + self.gridLayout_3.addWidget(self.main_widget, 0, 0, 1, 1) + self.select_all_toolButton = QtWidgets.QToolButton(SCP_Widget) + self.select_all_toolButton.setStyleSheet("margin: 0px;padding: 0px;") + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.select_all_toolButton.setIcon(icon1) + self.select_all_toolButton.setIconSize(QtCore.QSize(22, 22)) + self.select_all_toolButton.setObjectName("select_all_toolButton") + self.gridLayout_3.addWidget(self.select_all_toolButton, 0, 1, 1, 1) + self.gridLayout.addLayout(self.gridLayout_3, 0, 0, 1, 1) + self.buttonBox = QtWidgets.QDialogButtonBox(SCP_Widget) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + self.buttonBox.setCenterButtons(True) + self.buttonBox.setObjectName("buttonBox") + self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1) + self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1) + + self.retranslateUi(SCP_Widget) + self.buttonBox.accepted.connect(SCP_Widget.accept) # type: ignore + self.buttonBox.rejected.connect(SCP_Widget.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(SCP_Widget) + + def retranslateUi(self, SCP_Widget): + _translate = QtCore.QCoreApplication.translate + SCP_Widget.setWindowTitle(_translate("SCP_Widget", "Semi-Automatic Classification Plugin")) + self.select_all_toolButton.setToolTip(_translate("SCP_Widget", "

Select all

")) + self.select_all_toolButton.setText(_translate("SCP_Widget", "Plot")) +from . import resources_rc diff --git a/ui/ui_semiautomaticclassificationplugin_widget.ui b/ui/ui_semiautomaticclassificationplugin_widget.ui new file mode 100755 index 0000000..5f5f214 --- /dev/null +++ b/ui/ui_semiautomaticclassificationplugin_widget.ui @@ -0,0 +1,113 @@ + + + SCP_Widget + + + + 0 + 0 + 609 + 355 + + + + Semi-Automatic Classification Plugin + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg + + + + + + + + + + + + + + + + + + + <html><head/><body><p>Select all</p></body></html> + + + margin: 0px;padding: 0px; + + + Plot + + + + :/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg:/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin_select_all.svg + + + + 22 + 22 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + + + + + + + buttonBox + accepted() + SCP_Widget + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SCP_Widget + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/ui/ui_utils.py b/ui/ui_utils.py deleted file mode 100644 index 8f5290d..0000000 --- a/ui/ui_utils.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -''' -/************************************************************************************************************************** - SemiAutomaticClassificationPlugin - - The Semi-Automatic Classification Plugin for QGIS allows for the supervised classification of remote sensing images, - providing tools for the download, the preprocessing and postprocessing of images. - - ------------------- - begin : 2012-12-29 - copyright : (C) 2012-2021 by Luca Congedo - email : ing.congedoluca@gmail.com -**************************************************************************************************************************/ - -/************************************************************************************************************************** - * - * This file is part of Semi-Automatic Classification Plugin - * - * Semi-Automatic Classification Plugin is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software Foundation, - * version 3 of the License. - * - * Semi-Automatic Classification Plugin is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * Semi-Automatic Classification Plugin. If not, see . - * -**************************************************************************************************************************/ - -''' - -cfg = __import__(str(__name__).split('.')[0] + '.core.config', fromlist=['']) - -class Ui_Utils: - - def __init__(self): - pass - -### Add a progress bar and a cancel button - def addProgressBar(self, message = '', action = ' Executing', mainMessage = None): - # remove if present - try: - cfg.progressBar.setValue(0) - except: - self.createProgressBar(mainMessage, message, action) - - # Create a progress bar and a cancel button - def createProgressBar(self, mainMessage = None, message = '', action = ' Executing'): - sizePolicy = cfg.QtWidgetsSCP.QSizePolicy(cfg.QtWidgetsSCP.QSizePolicy.Expanding, cfg.QtWidgetsSCP.QSizePolicy.Preferred) - cfg.iconLabel = cfg.QtWidgetsSCP.QLabel() - cfg.iconLabel.setMinimumSize(cfg.QtCoreSCP.QSize(20, 20)) - cfg.iconLabel.setMaximumSize(cfg.QtCoreSCP.QSize(50, 50)) - cfg.iconLabel.setSizePolicy(sizePolicy) - cfg.iconLabel.setPixmap(cfg.QtGuiSCP.QPixmap(':/plugins/semiautomaticclassificationplugin/icons/semiautomaticclassificationplugin.svg')) - cfg.msgLabelMain = cfg.QtWidgetsSCP.QLabel() - sizePolicy = cfg.QtWidgetsSCP.QSizePolicy(cfg.QtWidgetsSCP.QSizePolicy.Expanding, cfg.QtWidgetsSCP.QSizePolicy.Preferred) - cfg.msgLabelMain.setMinimumSize(cfg.QtCoreSCP.QSize(50, 0)) - cfg.msgLabelMain.setMaximumSize(cfg.QtCoreSCP.QSize(800, 30)) - cfg.msgLabelMain.setSizePolicy(sizePolicy) - font = cfg.QtGuiSCP.QFont() - font.setBold(True) - cfg.msgLabelMain.setFont(font) - cfg.msgLabelMain.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Semi-Automatic Classification Plugin')) - spacerItem = cfg.QtWidgetsSCP.QSpacerItem(40, 20, cfg.QtWidgetsSCP.QSizePolicy.Expanding, cfg.QtWidgetsSCP.QSizePolicy.Minimum) - cfg.msgLabel = cfg.QtWidgetsSCP.QLabel() - cfg.msgLabel.setMinimumSize(cfg.QtCoreSCP.QSize(50, 0)) - cfg.msgLabel.setMaximumSize(cfg.QtCoreSCP.QSize(600, 80)) - cfg.msgLabel.setSizePolicy(sizePolicy) - cfg.msgLabel.setWordWrap(True) - cfg.progressBar = cfg.QtWidgetsSCP.QProgressBar() - cfg.progressBar.setMinimum(0) - cfg.progressBar.setMaximum(100) - cfg.progressBar.setProperty('value', 0) - cfg.progressBar.setTextVisible(True) - cfg.cancelButton = cfg.QtWidgetsSCP.QPushButton() - cfg.cancelButton.setEnabled(True) - cfg.cancelButton.setText(cfg.QtWidgetsSCP.QApplication.translate('semiautomaticclassificationplugin', 'Cancel')) - cfg.qWidget = cfg.QtWidgetsSCP.QWidget() - horizontalLayout = cfg.QtWidgetsSCP.QHBoxLayout() - horizontalLayout2 = cfg.QtWidgetsSCP.QHBoxLayout() - verticalLayout = cfg.QtWidgetsSCP.QVBoxLayout(cfg.qWidget) - verticalLayout.addLayout(horizontalLayout) - verticalLayout.addLayout(horizontalLayout2) - horizontalLayout.addWidget(cfg.iconLabel) - horizontalLayout.addWidget(cfg.msgLabelMain) - horizontalLayout.addItem(spacerItem) - horizontalLayout2.addWidget(cfg.msgLabel) - horizontalLayout2.addWidget(cfg.progressBar) - horizontalLayout2.addWidget(cfg.cancelButton) - cfg.cancelButton.clicked.connect(self.cancelAction) - self.widgetBar = cfg.iface.messageBar().createMessage('', '') - cfg.iface.messageBar().findChildren(cfg.QtWidgetsSCP.QToolButton)[0].setHidden(True) - self.widgetBar.layout().addWidget(cfg.qWidget) - self.updateBar(0, message, mainMessage) - # set action to yes - cfg.actionCheck = 'Yes' - self.setInterface(False) - cfg.iface.messageBar().pushWidget(self.widgetBar, cfg.qgisCoreSCP.Qgis.Info) - - # cancel action - def cancelAction(self): - cfg.actionCheck = 'No' - cfg.uiUtls.updateBar(100, ' Canceling ...') - cfg.QtWidgetsSCP.qApp.processEvents() - # kill subprocesses - for p in range(0, len(cfg.subprocDictProc)): - try: - cfg.subprocDictProc['proc_'+ str(p)].kill() - except: - pass - # terminate multiprocessing - try: - cfg.pool.close() - cfg.pool.terminate() - except: - pass - self.removeProgressBar() - self.setInterface(True) - cfg.cnvs.setRenderFlag(True) - - # update bar value - def updateBar(self, value = None, message = '', mainMessage = None): - try: - if len(message) > 0: - cfg.msgLabel.setText(str(message)) - cfg.progressBar.setValue(value) - except: - pass - try: - if mainMessage is not None: - cfg.msgLabelMain.setText(str(mainMessage)) - except: - pass - - # remove progress bar and cancel button - def removeProgressBar(self): - try: - cfg.iface.messageBar().popWidget(self.widgetBar) - except: - pass - cfg.progressBar = None - cfg.actionCheck = 'No' - self.setInterface(True) - cfg.iface.messageBar().findChildren(cfg.QtWidgetsSCP.QToolButton)[0].setHidden(False) - - # enable disable the interface to avoid errors - def setInterface(self, state): - # classification dock - cfg.dockclassdlg.setEnabled(state) - # main interface - cfg.dlg.setEnabled(state) - # toolbar - cfg.toolBar2.setEnabled(state) - cfg.toolBar3.setEnabled(state) - \ No newline at end of file diff --git a/ui/welcome.html b/ui/welcome.html old mode 100644 new mode 100755 index 3530c17..4fba0b6 --- a/ui/welcome.html +++ b/ui/welcome.html @@ -1,9 +1,9 @@
Welcome to the Semi-Automatic Classification Plugin for QGIS
-Please, visit the user manual page for information about the plugin interface.
+Please, visit the official page for information about the plugin.
-Also, several tutorials are available about the use of this plugin.
+Also, several tutorials are available about the use of this plugin.